From d44457f79d087b52a0468609d44013e5fd9f09f0 Mon Sep 17 00:00:00 2001 From: Leaf Petersen Date: Tue, 16 Jun 2020 23:37:36 +0000 Subject: [PATCH] [Core Libraries] Eliminate the fork in the core libraries. Move the nnbd core libraries from sdk_nnbd to sdk, and updates references in build files and elsewhere accordingly. Change-Id: I09760fe1e006657aacdfe80f3b22fdf6f7e30a9f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/151121 Commit-Queue: Leaf Petersen Reviewed-by: Bob Nystrom --- BUILD.gn | 20 +- PRESUBMIT.py | 45 - WATCHLISTS | 2 - .../test/helpers/memory_compiler.dart | 2 +- pkg/compiler/tool/modular_test_suite.dart | 7 +- .../lib/src/compiler/shared_command.dart | 4 +- pkg/dev_compiler/test/modular_suite.dart | 4 +- pkg/dev_compiler/test/modular_suite_nnbd.dart | 4 +- pkg/dev_compiler/tool/check_nnbd_sdk.dart | 7 +- .../src/api_prototype/experimental_flags.dart | 2 +- .../sdk_diagnostic.dart.outline.expect | 2 +- .../general/sdk_diagnostic.dart.strong.expect | 4 +- ..._diagnostic.dart.strong.transformed.expect | 4 +- .../sdk_diagnostic.dart.outline.expect | 2 +- .../sdk_diagnostic.dart.strong.expect | 4 +- ..._diagnostic.dart.strong.transformed.expect | 4 +- .../sdk_diagnostic.dart.weak.expect | 4 +- ...dk_diagnostic.dart.weak.transformed.expect | 4 +- .../no_outline_change_22.yaml.world.1.expect | 122 +- .../no_outline_change_22.yaml.world.2.expect | 122 +- .../_fasta/generate_experimental_flags.dart | 2 +- pkg/modular_test/lib/src/loader.dart | 4 - pkg/nnbd_migration/tool/src/package.dart | 11 - pkg/nnbd_migration/tool/trial_migration.dart | 12 - .../lib/src/compiler_configuration.dart | 29 +- pkg/test_runner/lib/src/configuration.dart | 11 +- runtime/bin/BUILD.gn | 11 +- runtime/vm/BUILD.gn | 13 +- sdk/BUILD.gn | 17 + sdk/bin/dart2js | 2 +- sdk/bin/dart2js_sdk | 2 +- sdk/bin/dartanalyzer | 1 + sdk/bin/dartanalyzer_sdk | 2 +- sdk/bin/dartdevc | 2 +- sdk/bin/dartdevc_sdk | 2 +- sdk/lib/_http/crypto.dart | 29 +- sdk/lib/_http/embedder_config.dart | 2 - sdk/lib/_http/http.dart | 410 +- sdk/lib/_http/http_date.dart | 28 +- sdk/lib/_http/http_headers.dart | 261 +- sdk/lib/_http/http_impl.dart | 819 +- sdk/lib/_http/http_parser.dart | 310 +- sdk/lib/_http/http_session.dart | 62 +- sdk/lib/_http/overrides.dart | 43 +- sdk/lib/_http/websocket.dart | 61 +- sdk/lib/_http/websocket_impl.dart | 387 +- .../lib/_internal/allowed_experiments.json | 0 .../_internal/js_dev_runtime/libraries.dart | 313 - .../js_dev_runtime/patch/async_patch.dart | 56 +- .../patch/collection_patch.dart | 112 +- .../js_dev_runtime/patch/convert_patch.dart | 46 +- .../js_dev_runtime/patch/core_patch.dart | 261 +- .../js_dev_runtime/patch/developer_patch.dart | 31 +- .../js_dev_runtime/patch/internal_patch.dart | 13 +- .../js_dev_runtime/patch/io_patch.dart | 50 +- .../js_dev_runtime/patch/isolate_patch.dart | 45 +- .../js_dev_runtime/patch/js_patch.dart | 89 +- .../js_dev_runtime/patch/math_patch.dart | 42 +- .../patch/typed_data_patch.dart | 2 - .../js_dev_runtime/private/annotations.dart | 4 +- .../private/custom_hash_map.dart | 20 +- .../private/ddc_runtime/classes.dart | 10 +- .../private/ddc_runtime/errors.dart | 30 +- .../private/ddc_runtime/operations.dart | 18 +- .../private/ddc_runtime/rtti.dart | 28 +- .../private/ddc_runtime/runtime.dart | 2 - .../private/ddc_runtime/types.dart | 74 +- .../private/ddc_runtime/utils.dart | 12 +- .../js_dev_runtime/private/debugger.dart | 106 +- .../private/foreign_helper.dart | 38 +- .../private/identity_hash_map.dart | 16 +- .../js_dev_runtime/private/interceptors.dart | 18 +- .../private/isolate_helper.dart | 4 +- .../js_dev_runtime/private/js_array.dart | 105 +- .../js_dev_runtime/private/js_helper.dart | 70 +- .../js_dev_runtime/private/js_number.dart | 40 +- .../js_dev_runtime/private/js_primitives.dart | 2 - .../js_dev_runtime/private/js_rti.dart | 10 +- .../js_dev_runtime/private/js_string.dart | 22 +- .../private/linked_hash_map.dart | 51 +- .../js_dev_runtime/private/mirror_helper.dart | 1 - .../js_dev_runtime/private/native_helper.dart | 2 - .../private/native_typed_data.dart | 175 +- .../js_dev_runtime/private/profile.dart | 27 +- .../js_dev_runtime/private/regexp_helper.dart | 64 +- .../js_dev_runtime/private/string_helper.dart | 14 +- .../_internal/js_runtime/lib/annotations.dart | 2 - .../_internal/js_runtime/lib/async_patch.dart | 59 +- .../js_runtime/lib/collection_patch.dart | 249 +- .../js_runtime/lib/constant_map.dart | 43 +- .../js_runtime/lib/convert_patch.dart | 93 +- .../_internal/js_runtime/lib/core_patch.dart | 176 +- .../js_runtime/lib/developer_patch.dart | 35 +- .../js_runtime/lib/foreign_helper.dart | 2 - .../js_runtime/lib/instantiation.dart | 2 - .../js_runtime/lib/interceptors.dart | 28 +- .../js_runtime/lib/internal_patch.dart | 15 +- .../_internal/js_runtime/lib/io_patch.dart | 52 +- .../js_runtime/lib/isolate_patch.dart | 54 +- .../_internal/js_runtime/lib/js_array.dart | 87 +- .../_internal/js_runtime/lib/js_helper.dart | 236 +- .../_internal/js_runtime/lib/js_names.dart | 16 +- .../_internal/js_runtime/lib/js_number.dart | 18 +- .../_internal/js_runtime/lib/js_patch.dart | 89 +- .../js_runtime/lib/js_primitives.dart | 2 - sdk/lib/_internal/js_runtime/lib/js_rti.dart | 2 - .../_internal/js_runtime/lib/js_string.dart | 28 +- .../js_runtime/lib/linked_hash_map.dart | 76 +- .../_internal/js_runtime/lib/math_patch.dart | 12 +- .../js_runtime/lib/mirrors_patch_cfe.dart | 2 - .../js_runtime/lib/native_helper.dart | 19 +- .../js_runtime/lib/native_typed_data.dart | 195 +- .../js_runtime/lib/regexp_helper.dart | 52 +- sdk/lib/_internal/js_runtime/lib/rti.dart | 1195 +- .../lib/shared/async_await_error_codes.dart | 2 - .../js_runtime/lib/shared/embedded_names.dart | 2 - .../js_runtime/lib/shared/recipe_syntax.dart | 2 - .../js_runtime/lib/string_helper.dart | 10 +- .../js_runtime/lib/typed_data_patch.dart | 2 - .../sdk_library_metadata/lib/libraries.dart | 2 +- sdk/lib/_internal/vm/bin/builtin.dart | 37 +- sdk/lib/_internal/vm/bin/cli_patch.dart | 2 - sdk/lib/_internal/vm/bin/common_patch.dart | 4 +- sdk/lib/_internal/vm/bin/directory_patch.dart | 2 - .../_internal/vm/bin/eventhandler_patch.dart | 4 +- sdk/lib/_internal/vm/bin/file_patch.dart | 93 +- .../vm/bin/file_system_entity_patch.dart | 2 - sdk/lib/_internal/vm/bin/filter_patch.dart | 16 +- .../_internal/vm/bin/io_service_patch.dart | 18 +- sdk/lib/_internal/vm/bin/namespace_patch.dart | 6 +- sdk/lib/_internal/vm/bin/platform_patch.dart | 6 +- sdk/lib/_internal/vm/bin/process_patch.dart | 209 +- .../_internal/vm/bin/secure_socket_patch.dart | 72 +- sdk/lib/_internal/vm/bin/socket_patch.dart | 489 +- sdk/lib/_internal/vm/bin/stdio_patch.dart | 5 +- .../_internal/vm/bin/sync_socket_patch.dart | 80 +- sdk/lib/_internal/vm/bin/vmservice_io.dart | 180 +- .../_internal/vm/bin/vmservice_server.dart | 196 +- sdk/lib/_internal/vm/lib/array.dart | 67 +- sdk/lib/_internal/vm/lib/array_patch.dart | 23 +- sdk/lib/_internal/vm/lib/async_patch.dart | 52 +- sdk/lib/_internal/vm/lib/bigint_patch.dart | 228 +- sdk/lib/_internal/vm/lib/bool_patch.dart | 2 - sdk/lib/_internal/vm/lib/class_id.dart | 2 - sdk/lib/_internal/vm/lib/class_id_fasta.dart | 2 - .../_internal/vm/lib/collection_patch.dart | 233 +- sdk/lib/_internal/vm/lib/compact_hash.dart | 67 +- sdk/lib/_internal/vm/lib/convert_patch.dart | 110 +- sdk/lib/_internal/vm/lib/core_patch.dart | 29 +- sdk/lib/_internal/vm/lib/date_patch.dart | 26 +- .../_internal/vm/lib/deferred_load_patch.dart | 4 +- sdk/lib/_internal/vm/lib/developer.dart | 18 +- sdk/lib/_internal/vm/lib/double.dart | 8 +- sdk/lib/_internal/vm/lib/double_patch.dart | 19 +- sdk/lib/_internal/vm/lib/empty_source.dart | 2 - sdk/lib/_internal/vm/lib/errors_patch.dart | 127 +- sdk/lib/_internal/vm/lib/expando_patch.dart | 12 +- .../vm/lib/ffi_dynamic_library_patch.dart | 9 +- .../vm/lib/ffi_native_type_patch.dart | 2 - sdk/lib/_internal/vm/lib/ffi_patch.dart | 13 +- .../_internal/vm/lib/ffi_struct_patch.dart | 2 - sdk/lib/_internal/vm/lib/function.dart | 2 - sdk/lib/_internal/vm/lib/function_patch.dart | 21 +- sdk/lib/_internal/vm/lib/growable_array.dart | 45 +- sdk/lib/_internal/vm/lib/identical_patch.dart | 6 +- sdk/lib/_internal/vm/lib/immutable_map.dart | 33 +- sdk/lib/_internal/vm/lib/integers.dart | 44 +- sdk/lib/_internal/vm/lib/integers_patch.dart | 38 +- sdk/lib/_internal/vm/lib/internal_patch.dart | 18 +- .../vm/lib/invocation_mirror_patch.dart | 72 +- sdk/lib/_internal/vm/lib/isolate_patch.dart | 112 +- sdk/lib/_internal/vm/lib/lib_prefix.dart | 2 - sdk/lib/_internal/vm/lib/map_patch.dart | 2 - sdk/lib/_internal/vm/lib/math_patch.dart | 8 +- .../_internal/vm/lib/mirror_reference.dart | 4 +- sdk/lib/_internal/vm/lib/mirrors_impl.dart | 202 +- sdk/lib/_internal/vm/lib/mirrors_patch.dart | 6 +- sdk/lib/_internal/vm/lib/null_patch.dart | 2 - sdk/lib/_internal/vm/lib/object_patch.dart | 4 +- sdk/lib/_internal/vm/lib/print_patch.dart | 2 - sdk/lib/_internal/vm/lib/profiler.dart | 2 - sdk/lib/_internal/vm/lib/regexp_patch.dart | 62 +- .../vm/lib/schedule_microtask_patch.dart | 9 +- sdk/lib/_internal/vm/lib/stacktrace.dart | 2 - sdk/lib/_internal/vm/lib/stopwatch_patch.dart | 12 +- .../_internal/vm/lib/string_buffer_patch.dart | 48 +- sdk/lib/_internal/vm/lib/string_patch.dart | 103 +- sdk/lib/_internal/vm/lib/symbol_patch.dart | 2 - sdk/lib/_internal/vm/lib/timeline.dart | 2 - sdk/lib/_internal/vm/lib/timer_impl.dart | 49 +- sdk/lib/_internal/vm/lib/timer_patch.dart | 25 +- sdk/lib/_internal/vm/lib/type_patch.dart | 2 - .../_internal/vm/lib/typed_data_patch.dart | 296 +- sdk/lib/_internal/vm/lib/uri_patch.dart | 2 - sdk/lib/_internal/vm/lib/wasm_patch.dart | 13 +- sdk/lib/_internal/vm/lib/weak_property.dart | 2 - sdk/lib/async/async.dart | 7 +- sdk/lib/async/async_error.dart | 11 +- .../async/broadcast_stream_controller.dart | 151 +- sdk/lib/async/deferred_load.dart | 6 +- sdk/lib/async/future.dart | 142 +- sdk/lib/async/future_impl.dart | 171 +- sdk/lib/async/schedule_microtask.dart | 39 +- sdk/lib/async/stream.dart | 941 +- sdk/lib/async/stream_controller.dart | 218 +- sdk/lib/async/stream_impl.dart | 361 +- sdk/lib/async/stream_pipe.dart | 191 +- sdk/lib/async/stream_transformers.dart | 112 +- sdk/lib/async/timer.dart | 9 +- sdk/lib/async/zone.dart | 583 +- sdk/lib/cli/cli.dart | 3 - sdk/lib/cli/wait_for.dart | 27 +- sdk/lib/collection/collection.dart | 2 - sdk/lib/collection/collections.dart | 2 - sdk/lib/collection/hash_map.dart | 32 +- sdk/lib/collection/hash_set.dart | 16 +- sdk/lib/collection/iterable.dart | 28 +- sdk/lib/collection/iterator.dart | 2 - sdk/lib/collection/linked_hash_map.dart | 18 +- sdk/lib/collection/linked_hash_set.dart | 12 +- sdk/lib/collection/linked_list.dart | 61 +- sdk/lib/collection/list.dart | 128 +- sdk/lib/collection/maps.dart | 76 +- sdk/lib/collection/queue.dart | 214 +- sdk/lib/collection/set.dart | 94 +- sdk/lib/collection/splay_tree.dart | 515 +- sdk/lib/convert/ascii.dart | 24 +- sdk/lib/convert/base64.dart | 62 +- sdk/lib/convert/byte_conversion.dart | 2 - sdk/lib/convert/chunked_conversion.dart | 5 +- sdk/lib/convert/codec.dart | 2 - sdk/lib/convert/convert.dart | 2 - sdk/lib/convert/converter.dart | 2 - sdk/lib/convert/encoding.dart | 9 +- sdk/lib/convert/html_escape.dart | 13 +- sdk/lib/convert/json.dart | 174 +- sdk/lib/convert/latin1.dart | 15 +- sdk/lib/convert/line_splitter.dart | 19 +- sdk/lib/convert/string_conversion.dart | 24 +- sdk/lib/convert/utf.dart | 25 +- sdk/lib/core/annotations.dart | 10 +- sdk/lib/core/bigint.dart | 6 +- sdk/lib/core/bool.dart | 9 +- sdk/lib/core/comparable.dart | 2 - sdk/lib/core/core.dart | 4 +- sdk/lib/core/date_time.dart | 36 +- sdk/lib/core/double.dart | 6 +- sdk/lib/core/duration.dart | 12 +- sdk/lib/core/errors.dart | 108 +- sdk/lib/core/exceptions.dart | 17 +- sdk/lib/core/expando.dart | 22 +- sdk/lib/core/function.dart | 33 +- sdk/lib/core/identical.dart | 6 +- sdk/lib/core/int.dart | 6 +- sdk/lib/core/invocation.dart | 50 +- sdk/lib/core/iterable.dart | 54 +- sdk/lib/core/iterator.dart | 19 +- sdk/lib/core/list.dart | 99 +- sdk/lib/core/map.dart | 21 +- sdk/lib/core/null.dart | 8 +- sdk/lib/core/num.dart | 14 +- sdk/lib/core/object.dart | 4 +- sdk/lib/core/pattern.dart | 14 +- sdk/lib/core/print.dart | 11 +- sdk/lib/core/regexp.dart | 10 +- sdk/lib/core/set.dart | 21 +- sdk/lib/core/sink.dart | 2 - sdk/lib/core/stacktrace.dart | 2 - sdk/lib/core/stopwatch.dart | 21 +- sdk/lib/core/string.dart | 50 +- sdk/lib/core/string_buffer.dart | 8 +- sdk/lib/core/string_sink.dart | 12 +- sdk/lib/core/symbol.dart | 6 +- sdk/lib/core/type.dart | 2 - sdk/lib/core/uri.dart | 599 +- sdk/lib/developer/developer.dart | 20 +- sdk/lib/developer/extension.dart | 33 +- sdk/lib/developer/profiler.dart | 11 +- sdk/lib/developer/service.dart | 16 +- sdk/lib/developer/timeline.dart | 63 +- sdk/lib/ffi/annotations.dart | 2 - sdk/lib/ffi/dynamic_library.dart | 4 +- sdk/lib/ffi/ffi.dart | 15 +- sdk/lib/ffi/native_type.dart | 2 - sdk/lib/ffi/struct.dart | 2 - sdk/lib/html/dart2js/html_dart2js.dart | 3365 +- sdk/lib/html/dartium/nativewrappers.dart | 2 - sdk/lib/html/html_common/conversions.dart | 4 +- .../html/html_common/conversions_dart2js.dart | 11 +- sdk/lib/html/html_common/css_class_set.dart | 30 +- sdk/lib/html/html_common/device.dart | 68 +- .../html_common/filtered_element_list.dart | 14 +- sdk/lib/html/html_common/html_common.dart | 2 - .../html/html_common/html_common_dart2js.dart | 2 - sdk/lib/html/html_common/lists.dart | 2 - sdk/lib/html/html_common/metadata.dart | 4 +- .../dart2js/indexed_db_dart2js.dart | 90 +- sdk/lib/internal/async_cast.dart | 42 +- sdk/lib/internal/cast.dart | 54 +- sdk/lib/internal/errors.dart | 4 +- sdk/lib/internal/internal.dart | 53 +- sdk/lib/internal/iterable.dart | 141 +- sdk/lib/internal/linked_list.dart | 86 +- sdk/lib/internal/list.dart | 20 +- sdk/lib/internal/patch.dart | 2 - sdk/lib/internal/print.dart | 4 +- sdk/lib/internal/sort.dart | 2 - sdk/lib/internal/symbol.dart | 4 +- sdk/lib/io/bytes_builder.dart | 2 - sdk/lib/io/common.dart | 6 +- sdk/lib/io/data_transformer.dart | 38 +- sdk/lib/io/directory.dart | 14 +- sdk/lib/io/directory_impl.dart | 64 +- sdk/lib/io/embedder_config.dart | 2 - sdk/lib/io/eventhandler.dart | 4 +- sdk/lib/io/file.dart | 18 +- sdk/lib/io/file_impl.dart | 187 +- sdk/lib/io/file_system_entity.dart | 42 +- sdk/lib/io/io.dart | 2 - sdk/lib/io/io_resource_info.dart | 16 +- sdk/lib/io/io_service.dart | 2 - sdk/lib/io/io_sink.dart | 38 +- sdk/lib/io/link.dart | 25 +- sdk/lib/io/namespace_impl.dart | 2 - sdk/lib/io/network_profiling.dart | 35 +- sdk/lib/io/overrides.dart | 160 +- sdk/lib/io/platform.dart | 6 +- sdk/lib/io/platform_impl.dart | 31 +- sdk/lib/io/process.dart | 31 +- sdk/lib/io/secure_server_socket.dart | 42 +- sdk/lib/io/secure_socket.dart | 305 +- sdk/lib/io/security_context.dart | 20 +- sdk/lib/io/service_object.dart | 2 - sdk/lib/io/socket.dart | 98 +- sdk/lib/io/stdio.dart | 46 +- sdk/lib/io/string_transformer.dart | 2 - sdk/lib/io/sync_socket.dart | 8 +- sdk/lib/isolate/capability.dart | 2 - sdk/lib/isolate/isolate.dart | 98 +- sdk/lib/js/_js.dart | 2 - sdk/lib/js/_js_client.dart | 2 - sdk/lib/js/_js_server.dart | 2 - sdk/lib/js/js.dart | 28 +- sdk/lib/js_util/js_util.dart | 31 +- sdk/lib/math/jenkins_smi_hash.dart | 5 +- sdk/lib/math/math.dart | 2 - sdk/lib/math/point.dart | 29 +- sdk/lib/math/random.dart | 6 +- sdk/lib/math/rectangle.dart | 37 +- sdk/lib/mirrors/mirrors.dart | 42 +- sdk/lib/svg/dart2js/svg_dart2js.dart | 208 +- sdk/lib/typed_data/typed_data.dart | 217 +- .../typed_data/unmodifiable_typed_data.dart | 39 +- sdk/lib/vmservice/asset.dart | 18 +- sdk/lib/vmservice/client.dart | 64 +- sdk/lib/vmservice/constants.dart | 2 - sdk/lib/vmservice/devfs.dart | 163 +- sdk/lib/vmservice/message.dart | 93 +- sdk/lib/vmservice/message_router.dart | 27 +- sdk/lib/vmservice/named_lookup.dart | 20 +- sdk/lib/vmservice/running_isolate.dart | 6 +- sdk/lib/vmservice/running_isolates.dart | 94 +- sdk/lib/vmservice/vmservice.dart | 273 +- sdk/lib/vmservice_libraries.json | 10 +- sdk/lib/wasm/wasm.dart | 6 +- .../web_audio/dart2js/web_audio_dart2js.dart | 106 +- sdk/lib/web_gl/dart2js/web_gl_dart2js.dart | 476 +- sdk/lib/web_sql/dart2js/web_sql_dart2js.dart | 28 +- sdk_args.gni | 6 - sdk_nnbd/BUILD.gn | 958 - sdk_nnbd/api_readme.md | 31 - sdk_nnbd/bin/dart | 56 - sdk_nnbd/bin/dart.bat | 16 - sdk_nnbd/bin/dart2js | 55 - sdk_nnbd/bin/dart2js.bat | 60 - sdk_nnbd/bin/dart2js_developer | 6 - sdk_nnbd/bin/dart2js_developer.bat | 10 - sdk_nnbd/bin/dart2js_sdk | 58 - sdk_nnbd/bin/dart2js_sdk.bat | 57 - sdk_nnbd/bin/dart2native | 25 - sdk_nnbd/bin/dart2native.bat | 43 - sdk_nnbd/bin/dartanalyzer | 51 - sdk_nnbd/bin/dartanalyzer.bat | 70 - sdk_nnbd/bin/dartanalyzer_developer | 6 - sdk_nnbd/bin/dartanalyzer_developer.bat | 10 - sdk_nnbd/bin/dartanalyzer_sdk | 31 - sdk_nnbd/bin/dartanalyzer_sdk.bat | 52 - sdk_nnbd/bin/dartdevc | 48 - sdk_nnbd/bin/dartdevc.bat | 66 - sdk_nnbd/bin/dartdevc_sdk | 38 - sdk_nnbd/bin/dartdevc_sdk.bat | 59 - sdk_nnbd/bin/dartdoc | 26 - sdk_nnbd/bin/dartdoc.bat | 44 - sdk_nnbd/bin/dartfix | 28 - sdk_nnbd/bin/dartfix.bat | 44 - sdk_nnbd/bin/dartfmt | 31 - sdk_nnbd/bin/dartfmt.bat | 57 - sdk_nnbd/bin/dartfmt_sdk | 29 - sdk_nnbd/bin/dartfmt_sdk.bat | 44 - sdk_nnbd/bin/pub | 84 - sdk_nnbd/bin/pub.bat | 56 - sdk_nnbd/bin/pub_sdk | 50 - sdk_nnbd/bin/pub_sdk.bat | 53 - sdk_nnbd/lib/_http/crypto.dart | 455 - sdk_nnbd/lib/_http/embedder_config.dart | 11 - sdk_nnbd/lib/_http/http.dart | 2282 - sdk_nnbd/lib/_http/http_date.dart | 352 - sdk_nnbd/lib/_http/http_headers.dart | 1105 - sdk_nnbd/lib/_http/http_impl.dart | 3377 -- sdk_nnbd/lib/_http/http_parser.dart | 1160 - sdk_nnbd/lib/_http/http_session.dart | 203 - sdk_nnbd/lib/_http/http_sources.gni | 18 - sdk_nnbd/lib/_http/overrides.dart | 114 - sdk_nnbd/lib/_http/websocket.dart | 496 - sdk_nnbd/lib/_http/websocket_impl.dart | 1325 - .../js_dev_runtime/patch/async_patch.dart | 472 - .../patch/collection_patch.dart | 580 - .../js_dev_runtime/patch/convert_patch.dart | 487 - .../js_dev_runtime/patch/core_patch.dart | 3015 -- .../js_dev_runtime/patch/developer_patch.dart | 201 - .../js_dev_runtime/patch/internal_patch.dart | 57 - .../js_dev_runtime/patch/io_patch.dart | 707 - .../js_dev_runtime/patch/isolate_patch.dart | 130 - .../js_dev_runtime/patch/js_patch.dart | 442 - .../js_dev_runtime/patch/math_patch.dart | 348 - .../patch/typed_data_patch.dart | 190 - .../js_dev_runtime/private/annotations.dart | 91 - .../private/custom_hash_map.dart | 197 - .../private/ddc_runtime/classes.dart | 595 - .../private/ddc_runtime/errors.dart | 292 - .../private/ddc_runtime/operations.dart | 841 - .../private/ddc_runtime/rtti.dart | 227 - .../private/ddc_runtime/runtime.dart | 221 - .../private/ddc_runtime/types.dart | 2022 - .../private/ddc_runtime/utils.dart | 97 - .../js_dev_runtime/private/debugger.dart | 1015 - .../private/foreign_helper.dart | 285 - .../private/identity_hash_map.dart | 137 - .../js_dev_runtime/private/interceptors.dart | 233 - .../private/isolate_helper.dart | 109 - .../js_dev_runtime/private/js_array.dart | 671 - .../js_dev_runtime/private/js_helper.dart | 806 - .../js_dev_runtime/private/js_number.dart | 627 - .../js_dev_runtime/private/js_primitives.dart | 49 - .../js_dev_runtime/private/js_rti.dart | 27 - .../js_dev_runtime/private/js_string.dart | 507 - .../private/linked_hash_map.dart | 275 - .../js_dev_runtime/private/mirror_helper.dart | 9 - .../js_dev_runtime/private/native_helper.dart | 18 - .../private/native_typed_data.dart | 1826 - .../js_dev_runtime/private/preambles/README | 17 - .../js_dev_runtime/private/preambles/d8.js | 291 - .../private/preambles/jsshell.js | 19 - .../js_dev_runtime/private/profile.dart | 132 - .../js_dev_runtime/private/regexp_helper.dart | 289 - .../js_dev_runtime/private/string_helper.dart | 297 - sdk_nnbd/lib/_internal/js_runtime/.packages | 2 - .../js_runtime/interceptors_sources.gni | 5 - .../_internal/js_runtime/lib/annotations.dart | 18 - .../_internal/js_runtime/lib/async_patch.dart | 708 - .../js_runtime/lib/collection_patch.dart | 1716 - .../js_runtime/lib/constant_map.dart | 231 - .../js_runtime/lib/convert_patch.dart | 484 - .../_internal/js_runtime/lib/core_patch.dart | 2952 -- .../js_runtime/lib/developer_patch.dart | 157 - .../js_runtime/lib/foreign_helper.dart | 279 - .../js_runtime/lib/instantiation.dart | 330 - .../js_runtime/lib/interceptors.dart | 447 - .../js_runtime/lib/internal_patch.dart | 66 - .../_internal/js_runtime/lib/io_patch.dart | 707 - .../js_runtime/lib/isolate_patch.dart | 156 - .../_internal/js_runtime/lib/js_array.dart | 727 - .../_internal/js_runtime/lib/js_helper.dart | 3253 -- .../_internal/js_runtime/lib/js_names.dart | 167 - .../_internal/js_runtime/lib/js_number.dart | 707 - .../_internal/js_runtime/lib/js_patch.dart | 568 - .../js_runtime/lib/js_primitives.dart | 47 - .../lib/_internal/js_runtime/lib/js_rti.dart | 554 - .../_internal/js_runtime/lib/js_string.dart | 470 - .../js_runtime/lib/linked_hash_map.dart | 441 - .../_internal/js_runtime/lib/math_patch.dart | 329 - .../js_runtime/lib/mirrors_patch_cfe.dart | 44 - .../js_runtime/lib/native_helper.dart | 593 - .../js_runtime/lib/native_typed_data.dart | 1816 - .../_internal/js_runtime/lib/preambles/README | 17 - .../_internal/js_runtime/lib/preambles/d8.js | 348 - .../js_runtime/lib/preambles/jsshell.js | 340 - .../js_runtime/lib/regexp_helper.dart | 295 - .../lib/_internal/js_runtime/lib/rti.dart | 3167 -- .../lib/shared/async_await_error_codes.dart | 10 - .../js_runtime/lib/shared/embedded_names.dart | 454 - .../js_runtime/lib/shared/recipe_syntax.dart | 237 - .../js_runtime/lib/string_helper.dart | 331 - .../js_runtime/lib/typed_data_patch.dart | 190 - .../lib/_internal/js_runtime/pubspec.yaml | 6 - .../sdk_library_metadata/lib/libraries.dart | 331 - .../sdk_library_metadata/pubspec.yaml | 6 - sdk_nnbd/lib/_internal/vm/bin/builtin.dart | 601 - sdk_nnbd/lib/_internal/vm/bin/cli_patch.dart | 8 - .../lib/_internal/vm/bin/common_patch.dart | 75 - .../lib/_internal/vm/bin/directory_patch.dart | 71 - .../_internal/vm/bin/eventhandler_patch.dart | 15 - sdk_nnbd/lib/_internal/vm/bin/file_patch.dart | 440 - .../vm/bin/file_system_entity_patch.dart | 24 - .../lib/_internal/vm/bin/filter_patch.dart | 48 - .../_internal/vm/bin/io_service_patch.dart | 100 - .../lib/_internal/vm/bin/namespace_patch.dart | 48 - .../lib/_internal/vm/bin/platform_patch.dart | 59 - .../lib/_internal/vm/bin/process_patch.dart | 617 - .../_internal/vm/bin/secure_socket_patch.dart | 233 - .../lib/_internal/vm/bin/socket_patch.dart | 2243 - .../lib/_internal/vm/bin/stdio_patch.dart | 167 - .../_internal/vm/bin/sync_socket_patch.dart | 331 - .../lib/_internal/vm/bin/vmservice_io.dart | 266 - .../_internal/vm/bin/vmservice_server.dart | 511 - sdk_nnbd/lib/_internal/vm/lib/array.dart | 268 - .../lib/_internal/vm/lib/array_patch.dart | 100 - .../lib/_internal/vm/lib/async_patch.dart | 334 - .../lib/_internal/vm/lib/bigint_patch.dart | 2853 -- sdk_nnbd/lib/_internal/vm/lib/bool_patch.dart | 21 - sdk_nnbd/lib/_internal/vm/lib/class_id.dart | 14 - .../lib/_internal/vm/lib/class_id_fasta.dart | 41 - .../_internal/vm/lib/collection_patch.dart | 921 - .../lib/_internal/vm/lib/compact_hash.dart | 668 - .../lib/_internal/vm/lib/convert_patch.dart | 2055 - sdk_nnbd/lib/_internal/vm/lib/core_patch.dart | 207 - sdk_nnbd/lib/_internal/vm/lib/date_patch.dart | 446 - .../_internal/vm/lib/deferred_load_patch.dart | 19 - sdk_nnbd/lib/_internal/vm/lib/developer.dart | 169 - sdk_nnbd/lib/_internal/vm/lib/double.dart | 360 - .../lib/_internal/vm/lib/double_patch.dart | 119 - .../lib/_internal/vm/lib/empty_source.dart | 5 - .../lib/_internal/vm/lib/errors_patch.dart | 503 - .../lib/_internal/vm/lib/expando_patch.dart | 151 - .../vm/lib/ffi_dynamic_library_patch.dart | 58 - .../vm/lib/ffi_native_type_patch.dart | 80 - sdk_nnbd/lib/_internal/vm/lib/ffi_patch.dart | 478 - .../_internal/vm/lib/ffi_struct_patch.dart | 12 - sdk_nnbd/lib/_internal/vm/lib/function.dart | 54 - .../lib/_internal/vm/lib/function_patch.dart | 36 - .../lib/_internal/vm/lib/growable_array.dart | 410 - .../lib/_internal/vm/lib/identical_patch.dart | 13 - .../lib/_internal/vm/lib/immutable_map.dart | 229 - sdk_nnbd/lib/_internal/vm/lib/integers.dart | 735 - .../lib/_internal/vm/lib/integers_patch.dart | 308 - .../lib/_internal/vm/lib/internal_patch.dart | 190 - .../vm/lib/invocation_mirror_patch.dart | 210 - .../lib/_internal/vm/lib/isolate_patch.dart | 676 - sdk_nnbd/lib/_internal/vm/lib/lib_prefix.dart | 42 - sdk_nnbd/lib/_internal/vm/lib/map_patch.dart | 31 - sdk_nnbd/lib/_internal/vm/lib/math_patch.dart | 301 - .../_internal/vm/lib/mirror_reference.dart | 14 - .../lib/_internal/vm/lib/mirrors_impl.dart | 1499 - .../lib/_internal/vm/lib/mirrors_patch.dart | 93 - sdk_nnbd/lib/_internal/vm/lib/null_patch.dart | 16 - .../lib/_internal/vm/lib/object_patch.dart | 75 - .../lib/_internal/vm/lib/print_patch.dart | 23 - sdk_nnbd/lib/_internal/vm/lib/profiler.dart | 28 - .../lib/_internal/vm/lib/regexp_patch.dart | 417 - .../vm/lib/schedule_microtask_patch.dart | 33 - sdk_nnbd/lib/_internal/vm/lib/stacktrace.dart | 11 - .../lib/_internal/vm/lib/stopwatch_patch.dart | 52 - .../_internal/vm/lib/string_buffer_patch.dart | 202 - .../lib/_internal/vm/lib/string_patch.dart | 1416 - .../lib/_internal/vm/lib/symbol_patch.dart | 60 - sdk_nnbd/lib/_internal/vm/lib/timeline.dart | 26 - sdk_nnbd/lib/_internal/vm/lib/timer_impl.dart | 486 - .../lib/_internal/vm/lib/timer_patch.dart | 33 - sdk_nnbd/lib/_internal/vm/lib/type_patch.dart | 42 - .../_internal/vm/lib/typed_data_patch.dart | 4816 -- sdk_nnbd/lib/_internal/vm/lib/uri_patch.dart | 80 - sdk_nnbd/lib/_internal/vm/lib/wasm_patch.dart | 181 - .../lib/_internal/vm/lib/weak_property.dart | 20 - sdk_nnbd/lib/async/async.dart | 120 - sdk_nnbd/lib/async/async_error.dart | 18 - sdk_nnbd/lib/async/async_sources.gni | 23 - .../async/broadcast_stream_controller.dart | 528 - sdk_nnbd/lib/async/deferred_load.dart | 36 - sdk_nnbd/lib/async/future.dart | 952 - sdk_nnbd/lib/async/future_impl.dart | 833 - sdk_nnbd/lib/async/schedule_microtask.dart | 156 - sdk_nnbd/lib/async/stream.dart | 2232 - sdk_nnbd/lib/async/stream_controller.dart | 987 - sdk_nnbd/lib/async/stream_impl.dart | 1099 - sdk_nnbd/lib/async/stream_pipe.dart | 475 - sdk_nnbd/lib/async/stream_transformers.dart | 338 - sdk_nnbd/lib/async/timer.dart | 130 - sdk_nnbd/lib/async/zone.dart | 1630 - sdk_nnbd/lib/cli/cli.dart | 11 - sdk_nnbd/lib/cli/cli_sources.gni | 10 - sdk_nnbd/lib/cli/wait_for.dart | 153 - sdk_nnbd/lib/collection/collection.dart | 29 - .../lib/collection/collection_sources.gni | 23 - sdk_nnbd/lib/collection/collections.dart | 24 - sdk_nnbd/lib/collection/hash_map.dart | 156 - sdk_nnbd/lib/collection/hash_set.dart | 115 - sdk_nnbd/lib/collection/iterable.dart | 400 - sdk_nnbd/lib/collection/iterator.dart | 43 - sdk_nnbd/lib/collection/linked_hash_map.dart | 141 - sdk_nnbd/lib/collection/linked_hash_set.dart | 120 - sdk_nnbd/lib/collection/linked_list.dart | 266 - sdk_nnbd/lib/collection/list.dart | 569 - sdk_nnbd/lib/collection/maps.dart | 388 - sdk_nnbd/lib/collection/queue.dart | 919 - sdk_nnbd/lib/collection/set.dart | 626 - sdk_nnbd/lib/collection/splay_tree.dart | 918 - sdk_nnbd/lib/convert/ascii.dart | 291 - sdk_nnbd/lib/convert/base64.dart | 870 - sdk_nnbd/lib/convert/byte_conversion.dart | 109 - sdk_nnbd/lib/convert/chunked_conversion.dart | 84 - sdk_nnbd/lib/convert/codec.dart | 97 - sdk_nnbd/lib/convert/convert.dart | 72 - sdk_nnbd/lib/convert/convert_sources.gni | 23 - sdk_nnbd/lib/convert/converter.dart | 72 - sdk_nnbd/lib/convert/encoding.dart | 80 - sdk_nnbd/lib/convert/html_escape.dart | 228 - sdk_nnbd/lib/convert/json.dart | 1088 - sdk_nnbd/lib/convert/latin1.dart | 181 - sdk_nnbd/lib/convert/line_splitter.dart | 177 - sdk_nnbd/lib/convert/string_conversion.dart | 323 - sdk_nnbd/lib/convert/utf.dart | 691 - sdk_nnbd/lib/core/annotations.dart | 240 - sdk_nnbd/lib/core/bigint.dart | 414 - sdk_nnbd/lib/core/bool.dart | 107 - sdk_nnbd/lib/core/comparable.dart | 94 - sdk_nnbd/lib/core/core.dart | 208 - sdk_nnbd/lib/core/core_sources.gni | 43 - sdk_nnbd/lib/core/date_time.dart | 875 - sdk_nnbd/lib/core/double.dart | 218 - sdk_nnbd/lib/core/duration.dart | 295 - sdk_nnbd/lib/core/errors.dart | 643 - sdk_nnbd/lib/core/exceptions.dart | 186 - sdk_nnbd/lib/core/expando.dart | 62 - sdk_nnbd/lib/core/function.dart | 70 - sdk_nnbd/lib/core/identical.dart | 22 - sdk_nnbd/lib/core/int.dart | 356 - sdk_nnbd/lib/core/invocation.dart | 160 - sdk_nnbd/lib/core/iterable.dart | 711 - sdk_nnbd/lib/core/iterator.dart | 75 - sdk_nnbd/lib/core/list.dart | 759 - sdk_nnbd/lib/core/map.dart | 405 - sdk_nnbd/lib/core/null.dart | 24 - sdk_nnbd/lib/core/num.dart | 489 - sdk_nnbd/lib/core/object.dart | 115 - sdk_nnbd/lib/core/pattern.dart | 127 - sdk_nnbd/lib/core/print.dart | 16 - sdk_nnbd/lib/core/regexp.dart | 189 - sdk_nnbd/lib/core/set.dart | 265 - sdk_nnbd/lib/core/sink.dart | 31 - sdk_nnbd/lib/core/stacktrace.dart | 67 - sdk_nnbd/lib/core/stopwatch.dart | 124 - sdk_nnbd/lib/core/string.dart | 840 - sdk_nnbd/lib/core/string_buffer.dart | 50 - sdk_nnbd/lib/core/string_sink.dart | 31 - sdk_nnbd/lib/core/symbol.dart | 97 - sdk_nnbd/lib/core/type.dart | 10 - sdk_nnbd/lib/core/uri.dart | 4695 -- sdk_nnbd/lib/developer/developer.dart | 67 - sdk_nnbd/lib/developer/developer_sources.gni | 13 - sdk_nnbd/lib/developer/extension.dart | 162 - sdk_nnbd/lib/developer/profiler.dart | 153 - sdk_nnbd/lib/developer/service.dart | 100 - sdk_nnbd/lib/developer/timeline.dart | 385 - sdk_nnbd/lib/ffi/annotations.dart | 37 - sdk_nnbd/lib/ffi/dynamic_library.dart | 46 - sdk_nnbd/lib/ffi/ffi.dart | 593 - sdk_nnbd/lib/ffi/ffi_sources.gni | 13 - sdk_nnbd/lib/ffi/native_type.dart | 137 - sdk_nnbd/lib/ffi/struct.dart | 36 - sdk_nnbd/lib/html/dart2js/html_dart2js.dart | 41043 ---------------- sdk_nnbd/lib/html/dartium/nativewrappers.dart | 13 - .../lib/html/html_common/conversions.dart | 375 - .../html/html_common/conversions_dart2js.dart | 110 - .../lib/html/html_common/css_class_set.dart | 242 - sdk_nnbd/lib/html/html_common/device.dart | 60 - .../html_common/filtered_element_list.dart | 150 - .../lib/html/html_common/html_common.dart | 24 - .../html/html_common/html_common_dart2js.dart | 29 - sdk_nnbd/lib/html/html_common/lists.dart | 71 - sdk_nnbd/lib/html/html_common/metadata.dart | 71 - sdk_nnbd/lib/html/html_sources.gni | 5 - .../dart2js/indexed_db_dart2js.dart | 1299 - sdk_nnbd/lib/internal/async_cast.dart | 125 - sdk_nnbd/lib/internal/cast.dart | 363 - sdk_nnbd/lib/internal/errors.dart | 19 - sdk_nnbd/lib/internal/internal.dart | 431 - sdk_nnbd/lib/internal/internal_sources.gni | 19 - sdk_nnbd/lib/internal/iterable.dart | 894 - sdk_nnbd/lib/internal/linked_list.dart | 134 - sdk_nnbd/lib/internal/list.dart | 341 - sdk_nnbd/lib/internal/patch.dart | 11 - sdk_nnbd/lib/internal/print.dart | 17 - sdk_nnbd/lib/internal/sort.dart | 385 - sdk_nnbd/lib/internal/symbol.dart | 142 - sdk_nnbd/lib/io/bytes_builder.dart | 234 - sdk_nnbd/lib/io/common.dart | 114 - sdk_nnbd/lib/io/data_transformer.dart | 678 - sdk_nnbd/lib/io/directory.dart | 344 - sdk_nnbd/lib/io/directory_impl.dart | 449 - sdk_nnbd/lib/io/embedder_config.dart | 38 - sdk_nnbd/lib/io/eventhandler.dart | 9 - sdk_nnbd/lib/io/file.dart | 1011 - sdk_nnbd/lib/io/file_impl.dart | 1090 - sdk_nnbd/lib/io/file_system_entity.dart | 991 - sdk_nnbd/lib/io/io.dart | 229 - sdk_nnbd/lib/io/io_resource_info.dart | 280 - sdk_nnbd/lib/io/io_service.dart | 54 - sdk_nnbd/lib/io/io_sink.dart | 316 - sdk_nnbd/lib/io/io_sources.gni | 37 - sdk_nnbd/lib/io/link.dart | 297 - sdk_nnbd/lib/io/namespace_impl.dart | 24 - sdk_nnbd/lib/io/network_profiling.dart | 240 - sdk_nnbd/lib/io/overrides.dart | 516 - sdk_nnbd/lib/io/platform.dart | 232 - sdk_nnbd/lib/io/platform_impl.dart | 177 - sdk_nnbd/lib/io/process.dart | 699 - sdk_nnbd/lib/io/secure_server_socket.dart | 287 - sdk_nnbd/lib/io/secure_socket.dart | 1306 - sdk_nnbd/lib/io/security_context.dart | 283 - sdk_nnbd/lib/io/service_object.dart | 29 - sdk_nnbd/lib/io/socket.dart | 1097 - sdk_nnbd/lib/io/stdio.dart | 483 - sdk_nnbd/lib/io/string_transformer.dart | 130 - sdk_nnbd/lib/io/sync_socket.dart | 109 - sdk_nnbd/lib/isolate/capability.dart | 34 - sdk_nnbd/lib/isolate/isolate.dart | 788 - sdk_nnbd/lib/isolate/isolate_sources.gni | 10 - sdk_nnbd/lib/js/_js.dart | 21 - sdk_nnbd/lib/js/_js_annotations.dart | 19 - sdk_nnbd/lib/js/_js_client.dart | 22 - sdk_nnbd/lib/js/_js_server.dart | 11 - sdk_nnbd/lib/js/js.dart | 233 - sdk_nnbd/lib/js/js_sources.gni | 5 - sdk_nnbd/lib/js_util/js_util.dart | 163 - sdk_nnbd/lib/js_util/js_util_sources.gni | 5 - sdk_nnbd/lib/libraries.json | 494 - sdk_nnbd/lib/libraries.yaml | 483 - sdk_nnbd/lib/math/jenkins_smi_hash.dart | 40 - sdk_nnbd/lib/math/math.dart | 179 - sdk_nnbd/lib/math/math_sources.gni | 13 - sdk_nnbd/lib/math/point.dart | 73 - sdk_nnbd/lib/math/random.dart | 40 - sdk_nnbd/lib/math/rectangle.dart | 246 - sdk_nnbd/lib/mirrors/mirrors.dart | 1475 - sdk_nnbd/lib/mirrors/mirrors_sources.gni | 8 - sdk_nnbd/lib/svg/dart2js/svg_dart2js.dart | 4131 -- sdk_nnbd/lib/typed_data/typed_data.dart | 3455 -- .../lib/typed_data/typed_data_sources.gni | 10 - .../typed_data/unmodifiable_typed_data.dart | 342 - sdk_nnbd/lib/vmservice/asset.dart | 69 - sdk_nnbd/lib/vmservice/client.dart | 69 - sdk_nnbd/lib/vmservice/constants.dart | 22 - sdk_nnbd/lib/vmservice/devfs.dart | 394 - sdk_nnbd/lib/vmservice/message.dart | 254 - sdk_nnbd/lib/vmservice/message_router.dart | 84 - sdk_nnbd/lib/vmservice/named_lookup.dart | 68 - sdk_nnbd/lib/vmservice/running_isolate.dart | 133 - sdk_nnbd/lib/vmservice/running_isolates.dart | 220 - sdk_nnbd/lib/vmservice/vmservice.dart | 821 - sdk_nnbd/lib/vmservice/vmservice_sources.gni | 19 - sdk_nnbd/lib/vmservice_libraries.json | 14 - sdk_nnbd/lib/vmservice_libraries.yaml | 20 - sdk_nnbd/lib/wasm/wasm.dart | 91 - sdk_nnbd/lib/wasm/wasm_sources.gni | 5 - .../web_audio/dart2js/web_audio_dart2js.dart | 1302 - .../lib/web_gl/dart2js/web_gl_dart2js.dart | 4182 -- .../lib/web_sql/dart2js/web_sql_dart2js.dart | 307 - .../standalone/io/http_cookie_date_test.dart | 16 +- tests/standalone/io/http_headers_test.dart | 16 +- tests/standalone/io/http_parser_test.dart | 16 +- .../standalone/io/web_socket_error_test.dart | 2 +- tests/standalone/io/web_socket_ping_test.dart | 2 +- .../web_socket_protocol_processor_test.dart | 20 +- tools/bots/bot.py | 18 +- tools/bots/flutter/compile_flutter.sh | 2 +- tools/bots/test_matrix.json | 103 +- tools/bots/try_benchmarks.sh | 2 - tools/build.py | 20 +- tools/dom/scripts/dartdomgenerator.py | 3 +- tools/generate_idefiles.py | 1 - tools/gn.py | 27 +- tools/utils.py | 34 +- utils/compiler/BUILD.gn | 34 +- utils/dartanalyzer/BUILD.gn | 18 +- utils/dartdevc/BUILD.gn | 35 +- 785 files changed, 12338 insertions(+), 209608 deletions(-) rename {sdk_nnbd => sdk}/lib/_internal/allowed_experiments.json (100%) delete mode 100644 sdk/lib/_internal/js_dev_runtime/libraries.dart delete mode 100644 sdk_nnbd/BUILD.gn delete mode 100644 sdk_nnbd/api_readme.md delete mode 100755 sdk_nnbd/bin/dart delete mode 100644 sdk_nnbd/bin/dart.bat delete mode 100755 sdk_nnbd/bin/dart2js delete mode 100644 sdk_nnbd/bin/dart2js.bat delete mode 100755 sdk_nnbd/bin/dart2js_developer delete mode 100644 sdk_nnbd/bin/dart2js_developer.bat delete mode 100755 sdk_nnbd/bin/dart2js_sdk delete mode 100755 sdk_nnbd/bin/dart2js_sdk.bat delete mode 100755 sdk_nnbd/bin/dart2native delete mode 100644 sdk_nnbd/bin/dart2native.bat delete mode 100755 sdk_nnbd/bin/dartanalyzer delete mode 100644 sdk_nnbd/bin/dartanalyzer.bat delete mode 100755 sdk_nnbd/bin/dartanalyzer_developer delete mode 100644 sdk_nnbd/bin/dartanalyzer_developer.bat delete mode 100755 sdk_nnbd/bin/dartanalyzer_sdk delete mode 100644 sdk_nnbd/bin/dartanalyzer_sdk.bat delete mode 100755 sdk_nnbd/bin/dartdevc delete mode 100644 sdk_nnbd/bin/dartdevc.bat delete mode 100755 sdk_nnbd/bin/dartdevc_sdk delete mode 100644 sdk_nnbd/bin/dartdevc_sdk.bat delete mode 100755 sdk_nnbd/bin/dartdoc delete mode 100644 sdk_nnbd/bin/dartdoc.bat delete mode 100755 sdk_nnbd/bin/dartfix delete mode 100644 sdk_nnbd/bin/dartfix.bat delete mode 100755 sdk_nnbd/bin/dartfmt delete mode 100644 sdk_nnbd/bin/dartfmt.bat delete mode 100755 sdk_nnbd/bin/dartfmt_sdk delete mode 100644 sdk_nnbd/bin/dartfmt_sdk.bat delete mode 100755 sdk_nnbd/bin/pub delete mode 100644 sdk_nnbd/bin/pub.bat delete mode 100755 sdk_nnbd/bin/pub_sdk delete mode 100644 sdk_nnbd/bin/pub_sdk.bat delete mode 100644 sdk_nnbd/lib/_http/crypto.dart delete mode 100644 sdk_nnbd/lib/_http/embedder_config.dart delete mode 100644 sdk_nnbd/lib/_http/http.dart delete mode 100644 sdk_nnbd/lib/_http/http_date.dart delete mode 100644 sdk_nnbd/lib/_http/http_headers.dart delete mode 100644 sdk_nnbd/lib/_http/http_impl.dart delete mode 100644 sdk_nnbd/lib/_http/http_parser.dart delete mode 100644 sdk_nnbd/lib/_http/http_session.dart delete mode 100644 sdk_nnbd/lib/_http/http_sources.gni delete mode 100644 sdk_nnbd/lib/_http/overrides.dart delete mode 100644 sdk_nnbd/lib/_http/websocket.dart delete mode 100644 sdk_nnbd/lib/_http/websocket_impl.dart delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/patch/async_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/patch/collection_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/patch/convert_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/patch/core_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/patch/developer_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/patch/internal_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/patch/io_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/patch/isolate_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/patch/js_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/patch/math_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/patch/typed_data_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/private/annotations.dart delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/private/custom_hash_map.dart delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/classes.dart delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/rtti.dart delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/utils.dart delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/private/debugger.dart delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/private/foreign_helper.dart delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/private/identity_hash_map.dart delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/private/interceptors.dart delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/private/isolate_helper.dart delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/private/js_array.dart delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/private/js_helper.dart delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/private/js_number.dart delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/private/js_primitives.dart delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/private/js_rti.dart delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/private/js_string.dart delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/private/linked_hash_map.dart delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/private/mirror_helper.dart delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/private/native_helper.dart delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/private/native_typed_data.dart delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/private/preambles/README delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/private/preambles/d8.js delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/private/preambles/jsshell.js delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/private/profile.dart delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/private/regexp_helper.dart delete mode 100644 sdk_nnbd/lib/_internal/js_dev_runtime/private/string_helper.dart delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/.packages delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/interceptors_sources.gni delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/lib/annotations.dart delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/lib/async_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/lib/collection_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/lib/constant_map.dart delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/lib/convert_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/lib/core_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/lib/developer_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/lib/foreign_helper.dart delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/lib/instantiation.dart delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/lib/interceptors.dart delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/lib/internal_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/lib/io_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/lib/isolate_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/lib/js_array.dart delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/lib/js_helper.dart delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/lib/js_names.dart delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/lib/js_number.dart delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/lib/js_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/lib/js_primitives.dart delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/lib/js_rti.dart delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/lib/js_string.dart delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/lib/linked_hash_map.dart delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/lib/math_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/lib/mirrors_patch_cfe.dart delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/lib/native_helper.dart delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/lib/native_typed_data.dart delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/lib/preambles/README delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/lib/preambles/d8.js delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/lib/preambles/jsshell.js delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/lib/regexp_helper.dart delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/lib/shared/async_await_error_codes.dart delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/lib/shared/embedded_names.dart delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/lib/string_helper.dart delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/lib/typed_data_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/js_runtime/pubspec.yaml delete mode 100644 sdk_nnbd/lib/_internal/sdk_library_metadata/lib/libraries.dart delete mode 100644 sdk_nnbd/lib/_internal/sdk_library_metadata/pubspec.yaml delete mode 100644 sdk_nnbd/lib/_internal/vm/bin/builtin.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/bin/cli_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/bin/common_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/bin/directory_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/bin/eventhandler_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/bin/file_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/bin/file_system_entity_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/bin/filter_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/bin/io_service_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/bin/namespace_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/bin/platform_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/bin/process_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/bin/secure_socket_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/bin/socket_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/bin/stdio_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/bin/sync_socket_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/bin/vmservice_io.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/bin/vmservice_server.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/array.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/array_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/async_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/bigint_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/bool_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/class_id.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/class_id_fasta.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/collection_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/compact_hash.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/convert_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/core_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/date_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/deferred_load_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/developer.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/double.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/double_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/empty_source.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/errors_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/expando_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/ffi_native_type_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/ffi_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/ffi_struct_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/function.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/function_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/growable_array.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/identical_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/immutable_map.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/integers.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/integers_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/internal_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/invocation_mirror_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/isolate_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/lib_prefix.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/map_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/math_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/mirror_reference.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/mirrors_impl.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/mirrors_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/null_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/object_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/print_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/profiler.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/regexp_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/schedule_microtask_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/stacktrace.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/stopwatch_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/string_buffer_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/string_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/symbol_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/timeline.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/timer_impl.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/timer_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/type_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/typed_data_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/uri_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/wasm_patch.dart delete mode 100644 sdk_nnbd/lib/_internal/vm/lib/weak_property.dart delete mode 100644 sdk_nnbd/lib/async/async.dart delete mode 100644 sdk_nnbd/lib/async/async_error.dart delete mode 100644 sdk_nnbd/lib/async/async_sources.gni delete mode 100644 sdk_nnbd/lib/async/broadcast_stream_controller.dart delete mode 100644 sdk_nnbd/lib/async/deferred_load.dart delete mode 100644 sdk_nnbd/lib/async/future.dart delete mode 100644 sdk_nnbd/lib/async/future_impl.dart delete mode 100644 sdk_nnbd/lib/async/schedule_microtask.dart delete mode 100644 sdk_nnbd/lib/async/stream.dart delete mode 100644 sdk_nnbd/lib/async/stream_controller.dart delete mode 100644 sdk_nnbd/lib/async/stream_impl.dart delete mode 100644 sdk_nnbd/lib/async/stream_pipe.dart delete mode 100644 sdk_nnbd/lib/async/stream_transformers.dart delete mode 100644 sdk_nnbd/lib/async/timer.dart delete mode 100644 sdk_nnbd/lib/async/zone.dart delete mode 100644 sdk_nnbd/lib/cli/cli.dart delete mode 100644 sdk_nnbd/lib/cli/cli_sources.gni delete mode 100644 sdk_nnbd/lib/cli/wait_for.dart delete mode 100644 sdk_nnbd/lib/collection/collection.dart delete mode 100644 sdk_nnbd/lib/collection/collection_sources.gni delete mode 100644 sdk_nnbd/lib/collection/collections.dart delete mode 100644 sdk_nnbd/lib/collection/hash_map.dart delete mode 100644 sdk_nnbd/lib/collection/hash_set.dart delete mode 100644 sdk_nnbd/lib/collection/iterable.dart delete mode 100644 sdk_nnbd/lib/collection/iterator.dart delete mode 100644 sdk_nnbd/lib/collection/linked_hash_map.dart delete mode 100644 sdk_nnbd/lib/collection/linked_hash_set.dart delete mode 100644 sdk_nnbd/lib/collection/linked_list.dart delete mode 100644 sdk_nnbd/lib/collection/list.dart delete mode 100644 sdk_nnbd/lib/collection/maps.dart delete mode 100644 sdk_nnbd/lib/collection/queue.dart delete mode 100644 sdk_nnbd/lib/collection/set.dart delete mode 100644 sdk_nnbd/lib/collection/splay_tree.dart delete mode 100644 sdk_nnbd/lib/convert/ascii.dart delete mode 100644 sdk_nnbd/lib/convert/base64.dart delete mode 100644 sdk_nnbd/lib/convert/byte_conversion.dart delete mode 100644 sdk_nnbd/lib/convert/chunked_conversion.dart delete mode 100644 sdk_nnbd/lib/convert/codec.dart delete mode 100644 sdk_nnbd/lib/convert/convert.dart delete mode 100644 sdk_nnbd/lib/convert/convert_sources.gni delete mode 100644 sdk_nnbd/lib/convert/converter.dart delete mode 100644 sdk_nnbd/lib/convert/encoding.dart delete mode 100644 sdk_nnbd/lib/convert/html_escape.dart delete mode 100644 sdk_nnbd/lib/convert/json.dart delete mode 100644 sdk_nnbd/lib/convert/latin1.dart delete mode 100644 sdk_nnbd/lib/convert/line_splitter.dart delete mode 100644 sdk_nnbd/lib/convert/string_conversion.dart delete mode 100644 sdk_nnbd/lib/convert/utf.dart delete mode 100644 sdk_nnbd/lib/core/annotations.dart delete mode 100644 sdk_nnbd/lib/core/bigint.dart delete mode 100644 sdk_nnbd/lib/core/bool.dart delete mode 100644 sdk_nnbd/lib/core/comparable.dart delete mode 100644 sdk_nnbd/lib/core/core.dart delete mode 100644 sdk_nnbd/lib/core/core_sources.gni delete mode 100644 sdk_nnbd/lib/core/date_time.dart delete mode 100644 sdk_nnbd/lib/core/double.dart delete mode 100644 sdk_nnbd/lib/core/duration.dart delete mode 100644 sdk_nnbd/lib/core/errors.dart delete mode 100644 sdk_nnbd/lib/core/exceptions.dart delete mode 100644 sdk_nnbd/lib/core/expando.dart delete mode 100644 sdk_nnbd/lib/core/function.dart delete mode 100644 sdk_nnbd/lib/core/identical.dart delete mode 100644 sdk_nnbd/lib/core/int.dart delete mode 100644 sdk_nnbd/lib/core/invocation.dart delete mode 100644 sdk_nnbd/lib/core/iterable.dart delete mode 100644 sdk_nnbd/lib/core/iterator.dart delete mode 100644 sdk_nnbd/lib/core/list.dart delete mode 100644 sdk_nnbd/lib/core/map.dart delete mode 100644 sdk_nnbd/lib/core/null.dart delete mode 100644 sdk_nnbd/lib/core/num.dart delete mode 100644 sdk_nnbd/lib/core/object.dart delete mode 100644 sdk_nnbd/lib/core/pattern.dart delete mode 100644 sdk_nnbd/lib/core/print.dart delete mode 100644 sdk_nnbd/lib/core/regexp.dart delete mode 100644 sdk_nnbd/lib/core/set.dart delete mode 100644 sdk_nnbd/lib/core/sink.dart delete mode 100644 sdk_nnbd/lib/core/stacktrace.dart delete mode 100644 sdk_nnbd/lib/core/stopwatch.dart delete mode 100644 sdk_nnbd/lib/core/string.dart delete mode 100644 sdk_nnbd/lib/core/string_buffer.dart delete mode 100644 sdk_nnbd/lib/core/string_sink.dart delete mode 100644 sdk_nnbd/lib/core/symbol.dart delete mode 100644 sdk_nnbd/lib/core/type.dart delete mode 100644 sdk_nnbd/lib/core/uri.dart delete mode 100644 sdk_nnbd/lib/developer/developer.dart delete mode 100644 sdk_nnbd/lib/developer/developer_sources.gni delete mode 100644 sdk_nnbd/lib/developer/extension.dart delete mode 100644 sdk_nnbd/lib/developer/profiler.dart delete mode 100644 sdk_nnbd/lib/developer/service.dart delete mode 100644 sdk_nnbd/lib/developer/timeline.dart delete mode 100644 sdk_nnbd/lib/ffi/annotations.dart delete mode 100644 sdk_nnbd/lib/ffi/dynamic_library.dart delete mode 100644 sdk_nnbd/lib/ffi/ffi.dart delete mode 100644 sdk_nnbd/lib/ffi/ffi_sources.gni delete mode 100644 sdk_nnbd/lib/ffi/native_type.dart delete mode 100644 sdk_nnbd/lib/ffi/struct.dart delete mode 100644 sdk_nnbd/lib/html/dart2js/html_dart2js.dart delete mode 100644 sdk_nnbd/lib/html/dartium/nativewrappers.dart delete mode 100644 sdk_nnbd/lib/html/html_common/conversions.dart delete mode 100644 sdk_nnbd/lib/html/html_common/conversions_dart2js.dart delete mode 100644 sdk_nnbd/lib/html/html_common/css_class_set.dart delete mode 100644 sdk_nnbd/lib/html/html_common/device.dart delete mode 100644 sdk_nnbd/lib/html/html_common/filtered_element_list.dart delete mode 100644 sdk_nnbd/lib/html/html_common/html_common.dart delete mode 100644 sdk_nnbd/lib/html/html_common/html_common_dart2js.dart delete mode 100644 sdk_nnbd/lib/html/html_common/lists.dart delete mode 100644 sdk_nnbd/lib/html/html_common/metadata.dart delete mode 100644 sdk_nnbd/lib/html/html_sources.gni delete mode 100644 sdk_nnbd/lib/indexed_db/dart2js/indexed_db_dart2js.dart delete mode 100644 sdk_nnbd/lib/internal/async_cast.dart delete mode 100644 sdk_nnbd/lib/internal/cast.dart delete mode 100644 sdk_nnbd/lib/internal/errors.dart delete mode 100644 sdk_nnbd/lib/internal/internal.dart delete mode 100644 sdk_nnbd/lib/internal/internal_sources.gni delete mode 100644 sdk_nnbd/lib/internal/iterable.dart delete mode 100644 sdk_nnbd/lib/internal/linked_list.dart delete mode 100644 sdk_nnbd/lib/internal/list.dart delete mode 100644 sdk_nnbd/lib/internal/patch.dart delete mode 100644 sdk_nnbd/lib/internal/print.dart delete mode 100644 sdk_nnbd/lib/internal/sort.dart delete mode 100644 sdk_nnbd/lib/internal/symbol.dart delete mode 100644 sdk_nnbd/lib/io/bytes_builder.dart delete mode 100644 sdk_nnbd/lib/io/common.dart delete mode 100644 sdk_nnbd/lib/io/data_transformer.dart delete mode 100644 sdk_nnbd/lib/io/directory.dart delete mode 100644 sdk_nnbd/lib/io/directory_impl.dart delete mode 100644 sdk_nnbd/lib/io/embedder_config.dart delete mode 100644 sdk_nnbd/lib/io/eventhandler.dart delete mode 100644 sdk_nnbd/lib/io/file.dart delete mode 100644 sdk_nnbd/lib/io/file_impl.dart delete mode 100644 sdk_nnbd/lib/io/file_system_entity.dart delete mode 100644 sdk_nnbd/lib/io/io.dart delete mode 100644 sdk_nnbd/lib/io/io_resource_info.dart delete mode 100644 sdk_nnbd/lib/io/io_service.dart delete mode 100644 sdk_nnbd/lib/io/io_sink.dart delete mode 100644 sdk_nnbd/lib/io/io_sources.gni delete mode 100644 sdk_nnbd/lib/io/link.dart delete mode 100644 sdk_nnbd/lib/io/namespace_impl.dart delete mode 100644 sdk_nnbd/lib/io/network_profiling.dart delete mode 100644 sdk_nnbd/lib/io/overrides.dart delete mode 100644 sdk_nnbd/lib/io/platform.dart delete mode 100644 sdk_nnbd/lib/io/platform_impl.dart delete mode 100644 sdk_nnbd/lib/io/process.dart delete mode 100644 sdk_nnbd/lib/io/secure_server_socket.dart delete mode 100644 sdk_nnbd/lib/io/secure_socket.dart delete mode 100644 sdk_nnbd/lib/io/security_context.dart delete mode 100644 sdk_nnbd/lib/io/service_object.dart delete mode 100644 sdk_nnbd/lib/io/socket.dart delete mode 100644 sdk_nnbd/lib/io/stdio.dart delete mode 100644 sdk_nnbd/lib/io/string_transformer.dart delete mode 100644 sdk_nnbd/lib/io/sync_socket.dart delete mode 100644 sdk_nnbd/lib/isolate/capability.dart delete mode 100644 sdk_nnbd/lib/isolate/isolate.dart delete mode 100644 sdk_nnbd/lib/isolate/isolate_sources.gni delete mode 100644 sdk_nnbd/lib/js/_js.dart delete mode 100644 sdk_nnbd/lib/js/_js_annotations.dart delete mode 100644 sdk_nnbd/lib/js/_js_client.dart delete mode 100644 sdk_nnbd/lib/js/_js_server.dart delete mode 100644 sdk_nnbd/lib/js/js.dart delete mode 100644 sdk_nnbd/lib/js/js_sources.gni delete mode 100644 sdk_nnbd/lib/js_util/js_util.dart delete mode 100644 sdk_nnbd/lib/js_util/js_util_sources.gni delete mode 100644 sdk_nnbd/lib/libraries.json delete mode 100644 sdk_nnbd/lib/libraries.yaml delete mode 100644 sdk_nnbd/lib/math/jenkins_smi_hash.dart delete mode 100644 sdk_nnbd/lib/math/math.dart delete mode 100644 sdk_nnbd/lib/math/math_sources.gni delete mode 100644 sdk_nnbd/lib/math/point.dart delete mode 100644 sdk_nnbd/lib/math/random.dart delete mode 100644 sdk_nnbd/lib/math/rectangle.dart delete mode 100644 sdk_nnbd/lib/mirrors/mirrors.dart delete mode 100644 sdk_nnbd/lib/mirrors/mirrors_sources.gni delete mode 100644 sdk_nnbd/lib/svg/dart2js/svg_dart2js.dart delete mode 100644 sdk_nnbd/lib/typed_data/typed_data.dart delete mode 100644 sdk_nnbd/lib/typed_data/typed_data_sources.gni delete mode 100644 sdk_nnbd/lib/typed_data/unmodifiable_typed_data.dart delete mode 100644 sdk_nnbd/lib/vmservice/asset.dart delete mode 100644 sdk_nnbd/lib/vmservice/client.dart delete mode 100644 sdk_nnbd/lib/vmservice/constants.dart delete mode 100644 sdk_nnbd/lib/vmservice/devfs.dart delete mode 100644 sdk_nnbd/lib/vmservice/message.dart delete mode 100644 sdk_nnbd/lib/vmservice/message_router.dart delete mode 100644 sdk_nnbd/lib/vmservice/named_lookup.dart delete mode 100644 sdk_nnbd/lib/vmservice/running_isolate.dart delete mode 100644 sdk_nnbd/lib/vmservice/running_isolates.dart delete mode 100644 sdk_nnbd/lib/vmservice/vmservice.dart delete mode 100644 sdk_nnbd/lib/vmservice/vmservice_sources.gni delete mode 100644 sdk_nnbd/lib/vmservice_libraries.json delete mode 100644 sdk_nnbd/lib/vmservice_libraries.yaml delete mode 100644 sdk_nnbd/lib/wasm/wasm.dart delete mode 100644 sdk_nnbd/lib/wasm/wasm_sources.gni delete mode 100644 sdk_nnbd/lib/web_audio/dart2js/web_audio_dart2js.dart delete mode 100644 sdk_nnbd/lib/web_gl/dart2js/web_gl_dart2js.dart delete mode 100644 sdk_nnbd/lib/web_sql/dart2js/web_sql_dart2js.dart diff --git a/BUILD.gn b/BUILD.gn index 8e24f903581..c758c49815b 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -80,24 +80,12 @@ group("runtime_precompiled") { ] } -if (dont_use_nnbd) { - group("create_sdk") { - public_deps = [ "sdk:create_sdk" ] - } -} else { - group("create_sdk") { - public_deps = [ "sdk_nnbd:create_sdk" ] - } +group("create_sdk") { + public_deps = [ "sdk:create_sdk" ] } -if (dont_use_nnbd) { - group("create_platform_sdk") { - public_deps = [ "sdk:create_platform_sdk" ] - } -} else { - group("create_platform_sdk") { - public_deps = [ "sdk_nnbd:create_platform_sdk" ] - } +group("create_platform_sdk") { + public_deps = [ "sdk:create_platform_sdk" ] } group("dart2js") { diff --git a/PRESUBMIT.py b/PRESUBMIT.py index 5f27094c01a..bfaf1df881d 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py @@ -19,49 +19,6 @@ def is_cpp_file(path): return path.endswith('.cc') or path.endswith('.h') -def _CheckNnbdSdkSync(input_api, output_api): - files = [git_file.LocalPath() for git_file in input_api.AffectedTextFiles()] - unsynchronized_files = [] - for file in files: - if file.startswith('sdk/'): - nnbd_file = 'sdk_nnbd/' + file[4:] - if not nnbd_file in files: - unsynchronized_files.append(nnbd_file) - if unsynchronized_files: - return [ - output_api.PresubmitPromptWarning( - 'Changes were made to sdk/ that were not made to sdk_nnbd/\n' - 'Please update these files as well:\n' - '\n' - '%s' % ('\n'.join(unsynchronized_files))) - ] - return [] - - -def _CheckSdkDdcRuntimeSync(input_api, output_api): - files = [git_file.LocalPath() for git_file in input_api.AffectedTextFiles()] - unsynchronized_files = [] - runtime_lib = 'lib/_internal/js_dev_runtime/private/ddc_runtime/' - for nnbd_file in files: - if nnbd_file.startswith('sdk_nnbd/' + runtime_lib): - file = 'sdk/' + nnbd_file[9:] - if not file in files: - unsynchronized_files.append(file) - if unsynchronized_files: - return [ - output_api.PresubmitPromptWarning( - 'Changes were made to ' - 'sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/ ' - 'that were not made to ' - 'sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/ ' - 'Please copy those changes (without Null Safety syntax) to ' - 'these files as well:\n' - '\n' - '%s' % ('\n'.join(unsynchronized_files))) - ] - return [] - - def _CheckNnbdTestSync(input_api, output_api): """Make sure that any forked SDK tests are kept in sync. If a CL touches a test, the test's counterpart (if it exists at all) should be in the CL @@ -369,8 +326,6 @@ def _CheckTestMatrixValid(input_api, output_api): def _CommonChecks(input_api, output_api): results = [] - results.extend(_CheckNnbdSdkSync(input_api, output_api)) - results.extend(_CheckSdkDdcRuntimeSync(input_api, output_api)) results.extend(_CheckNnbdTestSync(input_api, output_api)) results.extend(_CheckValidHostsInDEPS(input_api, output_api)) results.extend(_CheckDartFormat(input_api, output_api)) diff --git a/WATCHLISTS b/WATCHLISTS index a0c46b6b9a2..c4e7dea4c8f 100644 --- a/WATCHLISTS +++ b/WATCHLISTS @@ -28,7 +28,6 @@ 'filepath': ( '^pkg/compiler|' '^sdk/lib/_internal/js_runtime|' - '^sdk_nnbd/lib/_internal/js_runtime|' '^tests/compiler/dart2js' ) }, @@ -36,7 +35,6 @@ 'filepath': ( '^pkg/dev_compiler|' '^sdk/lib/_internal/js_dev_runtime|' - '^sdk_nnbd/lib/_internal/js_dev_runtime|' '^tests/compiler/dartdevc_native' ) }, diff --git a/pkg/compiler/test/helpers/memory_compiler.dart b/pkg/compiler/test/helpers/memory_compiler.dart index b6dbd6363de..e688d5b566a 100644 --- a/pkg/compiler/test/helpers/memory_compiler.dart +++ b/pkg/compiler/test/helpers/memory_compiler.dart @@ -29,7 +29,7 @@ export 'diagnostic_helper.dart'; bool isDart2jsNnbd = !Platform.environment['DART_CONFIGURATION'].endsWith('Legacy'); -String sdkPath = isDart2jsNnbd ? 'sdk_nnbd/lib' : 'sdk/lib'; +String sdkPath = 'sdk/lib'; String sdkLibrariesSpecificationPath = '$sdkPath/libraries.json'; diff --git a/pkg/compiler/tool/modular_test_suite.dart b/pkg/compiler/tool/modular_test_suite.dart index 9f75ae87add..a318ff1a1de 100644 --- a/pkg/compiler/tool/modular_test_suite.dart +++ b/pkg/compiler/tool/modular_test_suite.dart @@ -132,10 +132,7 @@ class SourceToDillStep implements IOModularStep { return; } sources = ['dart:core']; - extraArgs = [ - '--libraries-file', - '$rootScheme:///sdk_nnbd/lib/libraries.json' - ]; + extraArgs = ['--libraries-file', '$rootScheme:///sdk/lib/libraries.json']; assert(transitiveDependencies.isEmpty); } else { sources = module.sources.map(sourceToImportUri).toList(); @@ -342,7 +339,7 @@ class RunD8 implements IOModularStep { if (_options.verbose) print("\nstep: d8 on $module"); List d8Args = [ sdkRoot - .resolve('sdk_nnbd/lib/_internal/js_runtime/lib/preambles/d8.js') + .resolve('sdk/lib/_internal/js_runtime/lib/preambles/d8.js') .toFilePath(), root.resolveUri(toUri(module, jsId)).toFilePath(), ]; diff --git a/pkg/dev_compiler/lib/src/compiler/shared_command.dart b/pkg/dev_compiler/lib/src/compiler/shared_command.dart index 2c6e4705c70..f1b8d93627b 100644 --- a/pkg/dev_compiler/lib/src/compiler/shared_command.dart +++ b/pkg/dev_compiler/lib/src/compiler/shared_command.dart @@ -339,9 +339,7 @@ Map placeSourceMap(Map sourceMap, String sourceMapPath, String multiRootScheme, // TODO(sigmund): extract all source-map normalization outside ddc. This // custom logic is BUILD specific and could be shared with other tools // like dart2js. - var shortPath = uri.path - .replaceAll('/sdk/', '/dart-sdk/') - .replaceAll('/sdk_nnbd/', '/dart-sdk/'); + var shortPath = uri.path.replaceAll('/sdk/', '/dart-sdk/'); var multiRootPath = "${multiRootOutputPath ?? ''}$shortPath"; multiRootPath = p.url.relative(multiRootPath, from: sourceMapDir); return multiRootPath; diff --git a/pkg/dev_compiler/test/modular_suite.dart b/pkg/dev_compiler/test/modular_suite.dart index 033d6824ec6..e368ee2c367 100644 --- a/pkg/dev_compiler/test/modular_suite.dart +++ b/pkg/dev_compiler/test/modular_suite.dart @@ -77,7 +77,7 @@ class SourceToSummaryDillStep implements IOModularStep { sources = ['dart:core']; extraArgs = [ '--libraries-file', - '$rootScheme:///sdk_nnbd/lib/libraries.json', + '$rootScheme:///sdk/lib/libraries.json', '--enable-experiment', 'non-nullable', ]; @@ -157,7 +157,7 @@ class DDCStep implements IOModularStep { extraArgs = [ '--compile-sdk', '--libraries-file', - '$rootScheme:///sdk_nnbd/lib/libraries.json', + '$rootScheme:///sdk/lib/libraries.json', '--enable-experiment', 'non-nullable', ]; diff --git a/pkg/dev_compiler/test/modular_suite_nnbd.dart b/pkg/dev_compiler/test/modular_suite_nnbd.dart index 9c52552ac4c..c1a624b33d0 100644 --- a/pkg/dev_compiler/test/modular_suite_nnbd.dart +++ b/pkg/dev_compiler/test/modular_suite_nnbd.dart @@ -77,7 +77,7 @@ class SourceToSummaryDillStep implements IOModularStep { sources = ['dart:core']; extraArgs = [ '--libraries-file', - '$rootScheme:///sdk_nnbd/lib/libraries.json', + '$rootScheme:///sdk/lib/libraries.json', ]; assert(transitiveDependencies.isEmpty); } else { @@ -159,7 +159,7 @@ class DDCStep implements IOModularStep { extraArgs = [ '--compile-sdk', '--libraries-file', - '$rootScheme:///sdk_nnbd/lib/libraries.json', + '$rootScheme:///sdk/lib/libraries.json', ]; assert(transitiveDependencies.isEmpty); } else { diff --git a/pkg/dev_compiler/tool/check_nnbd_sdk.dart b/pkg/dev_compiler/tool/check_nnbd_sdk.dart index 382535054b7..01eddae6533 100644 --- a/pkg/dev_compiler/tool/check_nnbd_sdk.dart +++ b/pkg/dev_compiler/tool/check_nnbd_sdk.dart @@ -37,7 +37,7 @@ void main(List argv) { var librariesJson = args['libraries'] != null ? resolveInputUri(args['libraries'] as String) - : Platform.script.resolve('../../../sdk_nnbd/lib/libraries.json'); + : Platform.script.resolve('../../../sdk/lib/libraries.json'); var target = args['target'] as String; patch.main([ '--libraries', @@ -115,8 +115,7 @@ main() {} var result = Process.runSync(dart.toFilePath(), [ // The NNBD dart binaries / snapshots require this flag to be enabled at // VM level. - if (analyzerSnapshot.contains('NNBD')) - '--enable-experiment=non-nullable', + if (analyzerSnapshot.contains('NNBD')) '--enable-experiment=non-nullable', analyzerSnapshot, '--dart-sdk=${sdkDir}', '--format', @@ -198,7 +197,7 @@ main() {} final _parser = ArgParser() ..addOption('libraries', help: 'Path to the nnbd libraries.json (defaults to the one under ' - 'sdk_nnbd/lib/libraries.json.') + 'sdk/lib/libraries.json.') ..addOption('out', help: 'Path to an output folder (defaults to a new tmp folder).') ..addOption('target', diff --git a/pkg/front_end/lib/src/api_prototype/experimental_flags.dart b/pkg/front_end/lib/src/api_prototype/experimental_flags.dart index 9a9da8ce18f..9f21e27e62a 100644 --- a/pkg/front_end/lib/src/api_prototype/experimental_flags.dart +++ b/pkg/front_end/lib/src/api_prototype/experimental_flags.dart @@ -9,7 +9,7 @@ part 'experimental_flags_generated.dart'; /// The set of experiments enabled for SDK and packages. /// /// This are derived from an `allowed_experiments.json` file whose default is -/// located in `sdk_nnbd/lib/_internal/allowed_experiments.json`. +/// located in `sdk/lib/_internal/allowed_experiments.json`. class AllowedExperimentalFlags { /// The set of experiments that are enabled for all SDK libraries other than /// for those which are specified in [sdkLibraryExperiments]. diff --git a/pkg/front_end/testcases/general/sdk_diagnostic.dart.outline.expect b/pkg/front_end/testcases/general/sdk_diagnostic.dart.outline.expect index 5e3f10783f3..6d17367da61 100644 --- a/pkg/front_end/testcases/general/sdk_diagnostic.dart.outline.expect +++ b/pkg/front_end/testcases/general/sdk_diagnostic.dart.outline.expect @@ -12,7 +12,7 @@ library; // // class C extends Iterable { // ^ -// org-dartlang-sdk:///sdk_nnbd/lib/core/iterable.dart:158:19: Context: 'Iterable.iterator' is defined here. +// sdk/lib/core/iterable.dart:158:19: Context: 'Iterable.iterator' is defined here. // Iterator get iterator; // ^^^^^^^^ // diff --git a/pkg/front_end/testcases/general/sdk_diagnostic.dart.strong.expect b/pkg/front_end/testcases/general/sdk_diagnostic.dart.strong.expect index f8573390f42..95ddfbef4a9 100644 --- a/pkg/front_end/testcases/general/sdk_diagnostic.dart.strong.expect +++ b/pkg/front_end/testcases/general/sdk_diagnostic.dart.strong.expect @@ -12,14 +12,14 @@ library; // // class C extends Iterable { // ^ -// org-dartlang-sdk:///sdk_nnbd/lib/core/iterable.dart:158:19: Context: 'Iterable.iterator' is defined here. +// sdk/lib/core/iterable.dart:158:19: Context: 'Iterable.iterator' is defined here. // Iterator get iterator; // ^^^^^^^^ // // pkg/front_end/testcases/general/sdk_diagnostic.dart:12:8: Error: Too few positional arguments: 1 required, 0 given. // print(incorrectArgument: "fisk"); // ^ -// org-dartlang-sdk:///sdk_nnbd/lib/core/print.dart:8:6: Context: Found this candidate, but the arguments don't match. +// sdk/lib/core/print.dart:8:6: Context: Found this candidate, but the arguments don't match. // void print(Object? object) { // ^^^^^ // diff --git a/pkg/front_end/testcases/general/sdk_diagnostic.dart.strong.transformed.expect b/pkg/front_end/testcases/general/sdk_diagnostic.dart.strong.transformed.expect index f8573390f42..95ddfbef4a9 100644 --- a/pkg/front_end/testcases/general/sdk_diagnostic.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/general/sdk_diagnostic.dart.strong.transformed.expect @@ -12,14 +12,14 @@ library; // // class C extends Iterable { // ^ -// org-dartlang-sdk:///sdk_nnbd/lib/core/iterable.dart:158:19: Context: 'Iterable.iterator' is defined here. +// sdk/lib/core/iterable.dart:158:19: Context: 'Iterable.iterator' is defined here. // Iterator get iterator; // ^^^^^^^^ // // pkg/front_end/testcases/general/sdk_diagnostic.dart:12:8: Error: Too few positional arguments: 1 required, 0 given. // print(incorrectArgument: "fisk"); // ^ -// org-dartlang-sdk:///sdk_nnbd/lib/core/print.dart:8:6: Context: Found this candidate, but the arguments don't match. +// sdk/lib/core/print.dart:8:6: Context: Found this candidate, but the arguments don't match. // void print(Object? object) { // ^^^^^ // diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart.outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart.outline.expect index 99ede4e4f8e..bca3a48f68b 100644 --- a/pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart.outline.expect +++ b/pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart.outline.expect @@ -12,7 +12,7 @@ library; // // class C extends Iterable { // ^ -// org-dartlang-sdk:///sdk_nnbd/lib/core/iterable.dart:158:19: Context: 'Iterable.iterator' is defined here. +// org-dartlang-sdk:///sdk/lib/core/iterable.dart:158:19: Context: 'Iterable.iterator' is defined here. // Iterator get iterator; // ^^^^^^^^ // diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart.strong.expect b/pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart.strong.expect index 38cadb668a0..2bde57cb21d 100644 --- a/pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart.strong.expect +++ b/pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart.strong.expect @@ -12,14 +12,14 @@ library; // // class C extends Iterable { // ^ -// org-dartlang-sdk:///sdk_nnbd/lib/core/iterable.dart:158:19: Context: 'Iterable.iterator' is defined here. +// org-dartlang-sdk:///sdk/lib/core/iterable.dart:158:19: Context: 'Iterable.iterator' is defined here. // Iterator get iterator; // ^^^^^^^^ // // pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart:14:8: Error: Too few positional arguments: 1 required, 0 given. // print(incorrectArgument: "fisk"); // ^ -// org-dartlang-sdk:///sdk_nnbd/lib/core/print.dart:8:6: Context: Found this candidate, but the arguments don't match. +// org-dartlang-sdk:///sdk/lib/core/print.dart:8:6: Context: Found this candidate, but the arguments don't match. // void print(Object? object) { // ^^^^^ // diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart.strong.transformed.expect index 38cadb668a0..2bde57cb21d 100644 --- a/pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart.strong.transformed.expect @@ -12,14 +12,14 @@ library; // // class C extends Iterable { // ^ -// org-dartlang-sdk:///sdk_nnbd/lib/core/iterable.dart:158:19: Context: 'Iterable.iterator' is defined here. +// org-dartlang-sdk:///sdk/lib/core/iterable.dart:158:19: Context: 'Iterable.iterator' is defined here. // Iterator get iterator; // ^^^^^^^^ // // pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart:14:8: Error: Too few positional arguments: 1 required, 0 given. // print(incorrectArgument: "fisk"); // ^ -// org-dartlang-sdk:///sdk_nnbd/lib/core/print.dart:8:6: Context: Found this candidate, but the arguments don't match. +// org-dartlang-sdk:///sdk/lib/core/print.dart:8:6: Context: Found this candidate, but the arguments don't match. // void print(Object? object) { // ^^^^^ // diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart.weak.expect b/pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart.weak.expect index 38cadb668a0..abfc065e5b0 100644 --- a/pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart.weak.expect +++ b/pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart.weak.expect @@ -12,14 +12,14 @@ library; // // class C extends Iterable { // ^ -// org-dartlang-sdk:///sdk_nnbd/lib/core/iterable.dart:158:19: Context: 'Iterable.iterator' is defined here. +// sdk/lib/core/iterable.dart:158:19: Context: 'Iterable.iterator' is defined here. // Iterator get iterator; // ^^^^^^^^ // // pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart:14:8: Error: Too few positional arguments: 1 required, 0 given. // print(incorrectArgument: "fisk"); // ^ -// org-dartlang-sdk:///sdk_nnbd/lib/core/print.dart:8:6: Context: Found this candidate, but the arguments don't match. +// sdk/lib/core/print.dart:8:6: Context: Found this candidate, but the arguments don't match. // void print(Object? object) { // ^^^^^ // diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart.weak.transformed.expect index 38cadb668a0..abfc065e5b0 100644 --- a/pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart.weak.transformed.expect +++ b/pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart.weak.transformed.expect @@ -12,14 +12,14 @@ library; // // class C extends Iterable { // ^ -// org-dartlang-sdk:///sdk_nnbd/lib/core/iterable.dart:158:19: Context: 'Iterable.iterator' is defined here. +// sdk/lib/core/iterable.dart:158:19: Context: 'Iterable.iterator' is defined here. // Iterator get iterator; // ^^^^^^^^ // // pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart:14:8: Error: Too few positional arguments: 1 required, 0 given. // print(incorrectArgument: "fisk"); // ^ -// org-dartlang-sdk:///sdk_nnbd/lib/core/print.dart:8:6: Context: Found this candidate, but the arguments don't match. +// sdk/lib/core/print.dart:8:6: Context: Found this candidate, but the arguments don't match. // void print(Object? object) { // ^^^^^ // diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.1.expect index 047b5159957..5ea6e5760a4 100644 --- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.1.expect +++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.1.expect @@ -10,13 +10,13 @@ library from "org-dartlang-test:///main.dart" as main { abstract member-signature get length() → dart.core::int*; abstract member-signature operator [](dart.core::int* index) → dart.core::int*; abstract member-signature operator []=(dart.core::int* index, generic-covariant-impl dart.core::int* value) → void; - get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ iterator() → dart.core::Iterator + get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ iterator() → dart.core::Iterator return new dart._internal::ListIterator::•(this); - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ elementAt(dart.core::int index) → dart.core::int* + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ elementAt(dart.core::int index) → dart.core::int* return this.{dart.core::List::[]}(index); - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ followedBy(generic-covariant-impl dart.core::Iterable other) → dart.core::Iterable + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ followedBy(generic-covariant-impl dart.core::Iterable other) → dart.core::Iterable return dart._internal::FollowedByIterable::firstEfficient(this, other); - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ forEach((dart.core::int*) → void action) → void { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ forEach((dart.core::int*) → void action) → void { dart.core::int length = this.{dart.core::List::length}; for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) { action.call(this.{dart.core::List::[]}(i)); @@ -26,11 +26,11 @@ library from "org-dartlang-test:///main.dart" as main { } } @#C3 - get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ isEmpty() → dart.core::bool + get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ isEmpty() → dart.core::bool return this.{dart.core::List::length}.{dart.core::num::==}(0); - get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ isNotEmpty() → dart.core::bool + get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ isNotEmpty() → dart.core::bool return !this.{dart.collection::ListMixin::isEmpty}; - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ contains(dart.core::Object? element) → dart.core::bool { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ contains(dart.core::Object? element) → dart.core::bool { dart.core::int length = this.{dart.core::List::length}; for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) { if(this.{dart.core::List::[]}(i).{dart.core::Object::==}(element)) @@ -41,7 +41,7 @@ library from "org-dartlang-test:///main.dart" as main { } return false; } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ every((dart.core::int*) → dart.core::bool test) → dart.core::bool { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ every((dart.core::int*) → dart.core::bool test) → dart.core::bool { dart.core::int length = this.{dart.core::List::length}; for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) { if(!test.call(this.{dart.core::List::[]}(i))) @@ -52,7 +52,7 @@ library from "org-dartlang-test:///main.dart" as main { } return true; } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ any((dart.core::int*) → dart.core::bool test) → dart.core::bool { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ any((dart.core::int*) → dart.core::bool test) → dart.core::bool { dart.core::int length = this.{dart.core::List::length}; for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) { if(test.call(this.{dart.core::List::[]}(i))) @@ -63,7 +63,7 @@ library from "org-dartlang-test:///main.dart" as main { } return false; } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ firstWhere((dart.core::int*) → dart.core::bool test, {generic-covariant-impl () →? dart.core::int* orElse = #C2}) → dart.core::int* { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ firstWhere((dart.core::int*) → dart.core::bool test, {generic-covariant-impl () →? dart.core::int* orElse = #C2}) → dart.core::int* { dart.core::int length = this.{dart.core::List::length}; for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) { dart.core::int* element = this.{dart.core::List::[]}(i); @@ -77,7 +77,7 @@ library from "org-dartlang-test:///main.dart" as main { return orElse{() → dart.core::int*}.call(); throw dart._internal::IterableElementError::noElement(); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ lastWhere((dart.core::int*) → dart.core::bool test, {generic-covariant-impl () →? dart.core::int* orElse = #C2}) → dart.core::int* { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ lastWhere((dart.core::int*) → dart.core::bool test, {generic-covariant-impl () →? dart.core::int* orElse = #C2}) → dart.core::int* { dart.core::int length = this.{dart.core::List::length}; for (dart.core::int i = length.{dart.core::num::-}(1); i.{dart.core::num::>=}(0); i = i.{dart.core::num::-}(1)) { dart.core::int* element = this.{dart.core::List::[]}(i); @@ -91,7 +91,7 @@ library from "org-dartlang-test:///main.dart" as main { return orElse{() → dart.core::int*}.call(); throw dart._internal::IterableElementError::noElement(); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ singleWhere((dart.core::int*) → dart.core::bool test, {generic-covariant-impl () →? dart.core::int* orElse = #C2}) → dart.core::int* { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ singleWhere((dart.core::int*) → dart.core::bool test, {generic-covariant-impl () →? dart.core::int* orElse = #C2}) → dart.core::int* { dart.core::int length = this.{dart.core::List::length}; late dart.core::int* match; dart.core::bool matchFound = false; @@ -114,7 +114,7 @@ library from "org-dartlang-test:///main.dart" as main { return orElse{() → dart.core::int*}.call(); throw dart._internal::IterableElementError::noElement(); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ join([dart.core::String separator = #C4]) → dart.core::String { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ join([dart.core::String separator = #C4]) → dart.core::String { if(this.{dart.core::List::length}.{dart.core::num::==}(0)) return ""; dart.core::StringBuffer buffer = let final dart.core::StringBuffer #t1 = new dart.core::StringBuffer::•() in block { @@ -122,15 +122,15 @@ library from "org-dartlang-test:///main.dart" as main { } =>#t1; return buffer.{dart.core::StringBuffer::toString}(); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ where((dart.core::int*) → dart.core::bool test) → dart.core::Iterable + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ where((dart.core::int*) → dart.core::bool test) → dart.core::Iterable return new dart._internal::WhereIterable::•(this, test); - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ whereType() → dart.core::Iterable + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ whereType() → dart.core::Iterable return new dart._internal::WhereTypeIterable::•(this); - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ map((dart.core::int*) → main::_WithListMixin&Object&ListMixin::map::T% f) → dart.core::Iterable + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ map((dart.core::int*) → main::_WithListMixin&Object&ListMixin::map::T% f) → dart.core::Iterable return new dart._internal::MappedListIterable::•(this, f); - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ expand((dart.core::int*) → dart.core::Iterable f) → dart.core::Iterable + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ expand((dart.core::int*) → dart.core::Iterable f) → dart.core::Iterable return new dart._internal::ExpandIterable::•(this, f); - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ reduce(generic-covariant-impl (dart.core::int*, dart.core::int*) → dart.core::int* combine) → dart.core::int* { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ reduce(generic-covariant-impl (dart.core::int*, dart.core::int*) → dart.core::int* combine) → dart.core::int* { dart.core::int length = this.{dart.core::List::length}; if(length.{dart.core::num::==}(0)) throw dart._internal::IterableElementError::noElement(); @@ -143,7 +143,7 @@ library from "org-dartlang-test:///main.dart" as main { } return value; } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ fold(main::_WithListMixin&Object&ListMixin::fold::T% initialValue, (main::_WithListMixin&Object&ListMixin::fold::T%, dart.core::int*) → main::_WithListMixin&Object&ListMixin::fold::T% combine) → main::_WithListMixin&Object&ListMixin::fold::T% { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ fold(main::_WithListMixin&Object&ListMixin::fold::T% initialValue, (main::_WithListMixin&Object&ListMixin::fold::T%, dart.core::int*) → main::_WithListMixin&Object&ListMixin::fold::T% combine) → main::_WithListMixin&Object&ListMixin::fold::T% { main::_WithListMixin&Object&ListMixin::fold::T% value = initialValue; dart.core::int length = this.{dart.core::List::length}; for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) { @@ -154,17 +154,17 @@ library from "org-dartlang-test:///main.dart" as main { } return value; } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ skip(dart.core::int count) → dart.core::Iterable + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ skip(dart.core::int count) → dart.core::Iterable return new dart._internal::SubListIterable::•(this, count, null); - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ skipWhile((dart.core::int*) → dart.core::bool test) → dart.core::Iterable { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ skipWhile((dart.core::int*) → dart.core::bool test) → dart.core::Iterable { return new dart._internal::SkipWhileIterable::•(this, test); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ take(dart.core::int count) → dart.core::Iterable + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ take(dart.core::int count) → dart.core::Iterable return new dart._internal::SubListIterable::•(this, 0, count); - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ takeWhile((dart.core::int*) → dart.core::bool test) → dart.core::Iterable { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ takeWhile((dart.core::int*) → dart.core::bool test) → dart.core::Iterable { return new dart._internal::TakeWhileIterable::•(this, test); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ toList({dart.core::bool growable = #C5}) → dart.core::List { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ toList({dart.core::bool growable = #C5}) → dart.core::List { if(this.{dart.collection::ListMixin::isEmpty}) return dart.core::List::empty(growable: growable); dart.core::int* first = this.{dart.core::List::[]}(0); @@ -174,14 +174,14 @@ library from "org-dartlang-test:///main.dart" as main { } return result; } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ toSet() → dart.core::Set { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ toSet() → dart.core::Set { dart.core::Set result = dart.collection::LinkedHashSet::•(); for (dart.core::int i = 0; i.{dart.core::num::<}(this.{dart.core::List::length}); i = i.{dart.core::num::+}(1)) { result.{dart.core::Set::add}(this.{dart.core::List::[]}(i)); } return result; } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ addAll(generic-covariant-impl dart.core::Iterable iterable) → void { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ addAll(generic-covariant-impl dart.core::Iterable iterable) → void { dart.core::int i = this.{dart.core::List::length}; { dart.core::Iterator :sync-for-iterator = iterable.{dart.core::Iterable::iterator}; @@ -195,7 +195,7 @@ library from "org-dartlang-test:///main.dart" as main { } } } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ remove(dart.core::Object? element) → dart.core::bool { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ remove(dart.core::Object? element) → dart.core::bool { for (dart.core::int i = 0; i.{dart.core::num::<}(this.{dart.core::List::length}); i = i.{dart.core::num::+}(1)) { if(this.{dart.core::List::[]}(i).{dart.core::Object::==}(element)) { this.{dart.collection::ListMixin::_closeGap}(i, i.{dart.core::num::+}(1)); @@ -204,7 +204,7 @@ library from "org-dartlang-test:///main.dart" as main { } return false; } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ _closeGap(dart.core::int start, dart.core::int end) → void { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ _closeGap(dart.core::int start, dart.core::int end) → void { dart.core::int length = this.{dart.core::List::length}; assert(0.{dart.core::num::<=}(start)); assert(start.{dart.core::num::<}(end)); @@ -215,13 +215,13 @@ library from "org-dartlang-test:///main.dart" as main { } this.{dart.core::List::length} = length.{dart.core::num::-}(size); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ removeWhere((dart.core::int*) → dart.core::bool test) → void { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ removeWhere((dart.core::int*) → dart.core::bool test) → void { this.{dart.collection::ListMixin::_filter}(test, false); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ retainWhere((dart.core::int*) → dart.core::bool test) → void { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ retainWhere((dart.core::int*) → dart.core::bool test) → void { this.{dart.collection::ListMixin::_filter}(test, true); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ _filter((dart.core::int*) → dart.core::bool test, dart.core::bool retainMatching) → void { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ _filter((dart.core::int*) → dart.core::bool test, dart.core::bool retainMatching) → void { dart.core::List retained = []; dart.core::int length = this.{dart.core::List::length}; for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) { @@ -238,12 +238,12 @@ library from "org-dartlang-test:///main.dart" as main { this.{dart.core::List::length} = retained.{dart.core::List::length}; } } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ cast() → dart.core::List + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ cast() → dart.core::List return dart.core::List::castFrom(this); - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ sort([(dart.core::int*, dart.core::int*) →? dart.core::int compare = #C2]) → void { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ sort([(dart.core::int*, dart.core::int*) →? dart.core::int compare = #C2]) → void { dart._internal::Sort::sort(this, let final (dart.core::int*, dart.core::int*) →? dart.core::int #t2 = compare in #t2.{dart.core::Object::==}(null) ?{(dart.core::int*, dart.core::int*) → dart.core::int} #C6 : #t2{(dart.core::int*, dart.core::int*) → dart.core::int}); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ shuffle([dart.math::Random? random = #C2]) → void { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ shuffle([dart.math::Random? random = #C2]) → void { random.{dart.core::Object::==}(null) ?{dart.math::Random} random = dart.math::Random::•() : null; if(random{dart.math::Random}.{dart.core::Object::==}(null)) throw "!"; @@ -256,10 +256,10 @@ library from "org-dartlang-test:///main.dart" as main { this.{dart.core::List::[]=}(pos, tmp); } } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ asMap() → dart.core::Map { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ asMap() → dart.core::Map { return new dart._internal::ListMapView::•(this); } - operator /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ +(generic-covariant-impl dart.core::List other) → dart.core::List + operator /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ +(generic-covariant-impl dart.core::List other) → dart.core::List return block { final dart.core::List #t3 = []; { @@ -277,7 +277,7 @@ library from "org-dartlang-test:///main.dart" as main { } } } =>#t3; - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ sublist(dart.core::int start, [dart.core::int? end = #C2]) → dart.core::List { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ sublist(dart.core::int start, [dart.core::int? end = #C2]) → dart.core::List { dart.core::int listLength = this.{dart.core::List::length}; end.{dart.core::num::==}(null) ?{dart.core::int} end = listLength : null; if(end{dart.core::int}.{dart.core::num::==}(null)) @@ -285,24 +285,24 @@ library from "org-dartlang-test:///main.dart" as main { dart.core::RangeError::checkValidRange(start, end{dart.core::int}, listLength); return dart.core::List::from(this.{dart.collection::ListMixin::getRange}(start, end{dart.core::int})); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ getRange(dart.core::int start, dart.core::int end) → dart.core::Iterable { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ getRange(dart.core::int start, dart.core::int end) → dart.core::Iterable { dart.core::RangeError::checkValidRange(start, end, this.{dart.core::List::length}); return new dart._internal::SubListIterable::•(this, start, end); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ removeRange(dart.core::int start, dart.core::int end) → void { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ removeRange(dart.core::int start, dart.core::int end) → void { dart.core::RangeError::checkValidRange(start, end, this.{dart.core::List::length}); if(end.{dart.core::num::>}(start)) { this.{dart.collection::ListMixin::_closeGap}(start, end); } } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ fillRange(dart.core::int start, dart.core::int end, [generic-covariant-impl dart.core::int? fill = #C2]) → void { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ fillRange(dart.core::int start, dart.core::int end, [generic-covariant-impl dart.core::int? fill = #C2]) → void { dart.core::int* value = let dart.core::int? #t6 = fill in #t6.==(null) ?{dart.core::int*} #t6 : #t6{dart.core::int*}; dart.core::RangeError::checkValidRange(start, end, this.{dart.core::List::length}); for (dart.core::int i = start; i.{dart.core::num::<}(end); i = i.{dart.core::num::+}(1)) { this.{dart.core::List::[]=}(i, value); } } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ setRange(dart.core::int start, dart.core::int end, generic-covariant-impl dart.core::Iterable iterable, [dart.core::int skipCount = #C7]) → void { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ setRange(dart.core::int start, dart.core::int end, generic-covariant-impl dart.core::Iterable iterable, [dart.core::int skipCount = #C7]) → void { dart.core::RangeError::checkValidRange(start, end, this.{dart.core::List::length}); dart.core::int length = end.{dart.core::num::-}(start); if(length.{dart.core::num::==}(0)) @@ -332,7 +332,7 @@ library from "org-dartlang-test:///main.dart" as main { } } } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ replaceRange(dart.core::int start, dart.core::int end, generic-covariant-impl dart.core::Iterable newContents) → void { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ replaceRange(dart.core::int start, dart.core::int end, generic-covariant-impl dart.core::Iterable newContents) → void { dart.core::RangeError::checkValidRange(start, end, this.{dart.core::List::length}); if(start.{dart.core::num::==}(this.{dart.core::List::length})) { this.{dart.collection::ListMixin::addAll}(newContents); @@ -382,7 +382,7 @@ library from "org-dartlang-test:///main.dart" as main { this.{dart.collection::ListMixin::setRange}(start, insertEnd, newContents); } } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ indexOf(generic-covariant-impl dart.core::Object? element, [dart.core::int start = #C7]) → dart.core::int { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ indexOf(generic-covariant-impl dart.core::Object? element, [dart.core::int start = #C7]) → dart.core::int { if(start.{dart.core::num::<}(0)) start = 0; for (dart.core::int i = start; i.{dart.core::num::<}(this.{dart.core::List::length}); i = i.{dart.core::num::+}(1)) { @@ -391,7 +391,7 @@ library from "org-dartlang-test:///main.dart" as main { } return 1.{dart.core::int::unary-}(); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ indexWhere((dart.core::int*) → dart.core::bool test, [dart.core::int start = #C7]) → dart.core::int { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ indexWhere((dart.core::int*) → dart.core::bool test, [dart.core::int start = #C7]) → dart.core::int { if(start.{dart.core::num::<}(0)) start = 0; for (dart.core::int i = start; i.{dart.core::num::<}(this.{dart.core::List::length}); i = i.{dart.core::num::+}(1)) { @@ -400,7 +400,7 @@ library from "org-dartlang-test:///main.dart" as main { } return 1.{dart.core::int::unary-}(); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ lastIndexOf(generic-covariant-impl dart.core::Object? element, [dart.core::int? start = #C2]) → dart.core::int { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ lastIndexOf(generic-covariant-impl dart.core::Object? element, [dart.core::int? start = #C2]) → dart.core::int { if(start.{dart.core::num::==}(null) || start{dart.core::int}.{dart.core::num::>=}(this.{dart.core::List::length})) start = this.{dart.core::List::length}.{dart.core::num::-}(1); if(start{dart.core::int}.{dart.core::num::==}(null)) @@ -411,7 +411,7 @@ library from "org-dartlang-test:///main.dart" as main { } return 1.{dart.core::int::unary-}(); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ lastIndexWhere((dart.core::int*) → dart.core::bool test, [dart.core::int? start = #C2]) → dart.core::int { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ lastIndexWhere((dart.core::int*) → dart.core::bool test, [dart.core::int? start = #C2]) → dart.core::int { if(start.{dart.core::num::==}(null) || start{dart.core::int}.{dart.core::num::>=}(this.{dart.core::List::length})) start = this.{dart.core::List::length}.{dart.core::num::-}(1); if(start{dart.core::int}.{dart.core::num::==}(null)) @@ -422,7 +422,7 @@ library from "org-dartlang-test:///main.dart" as main { } return 1.{dart.core::int::unary-}(); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ insert(dart.core::int index, generic-covariant-impl dart.core::int* element) → void { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ insert(dart.core::int index, generic-covariant-impl dart.core::int* element) → void { dart.core::ArgumentError::checkNotNull(index, "index"); dart.core::RangeError::checkValueInInterval(index, 0, this.{dart.core::List::length}, "index"); if(index.{dart.core::num::==}(this.{dart.core::List::length})) { @@ -433,12 +433,12 @@ library from "org-dartlang-test:///main.dart" as main { this.{dart.collection::ListMixin::setRange}(index.{dart.core::num::+}(1), this.{dart.core::List::length}, this, index); this.{dart.core::List::[]=}(index, element); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ removeAt(dart.core::int index) → dart.core::int* { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ removeAt(dart.core::int index) → dart.core::int* { dart.core::int* result = this.{dart.core::List::[]}(index); this.{dart.collection::ListMixin::_closeGap}(index, index.{dart.core::num::+}(1)); return result; } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ insertAll(dart.core::int index, generic-covariant-impl dart.core::Iterable iterable) → void { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ insertAll(dart.core::int index, generic-covariant-impl dart.core::Iterable iterable) → void { dart.core::RangeError::checkValueInInterval(index, 0, this.{dart.core::List::length}, "index"); if(index.{dart.core::num::==}(this.{dart.core::List::length})) { this.{dart.collection::ListMixin::addAll}(iterable); @@ -465,7 +465,7 @@ library from "org-dartlang-test:///main.dart" as main { } this.{dart.collection::ListMixin::setAll}(index, iterable); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ setAll(dart.core::int index, generic-covariant-impl dart.core::Iterable iterable) → void { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ setAll(dart.core::int index, generic-covariant-impl dart.core::Iterable iterable) → void { if(iterable is{ForNonNullableByDefault} dart.core::List) { this.{dart.collection::ListMixin::setRange}(index, index.{dart.core::num::+}(iterable.{dart.core::Iterable::length}), iterable); } @@ -481,9 +481,9 @@ library from "org-dartlang-test:///main.dart" as main { } } } - get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ reversed() → dart.core::Iterable + get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ reversed() → dart.core::Iterable return new dart._internal::ReversedListIterable::•(this); - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ toString() → dart.core::String + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ toString() → dart.core::String return dart.collection::IterableBase::iterableToFullString(this, "[", "]"); abstract member-signature get _identityHashCode() → dart.core::int*; abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → dart.core::bool*; @@ -495,40 +495,40 @@ library from "org-dartlang-test:///main.dart" as main { abstract member-signature method noSuchMethod(dart.core::Invocation* invocation) → dynamic; abstract member-signature get runtimeType() → dart.core::Type*; abstract member-signature set length(dart.core::int* newLength) → void; - get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ first() → dart.core::int* { + get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ first() → dart.core::int* { if(this.{dart.core::List::length}.{dart.core::num::==}(0)) throw dart._internal::IterableElementError::noElement(); return this.{dart.core::List::[]}(0); } - set /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ first(generic-covariant-impl dart.core::int* value) → void { + set /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ first(generic-covariant-impl dart.core::int* value) → void { if(this.{dart.core::List::length}.{dart.core::num::==}(0)) throw dart._internal::IterableElementError::noElement(); this.{dart.core::List::[]=}(0, value); } - get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ last() → dart.core::int* { + get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ last() → dart.core::int* { if(this.{dart.core::List::length}.{dart.core::num::==}(0)) throw dart._internal::IterableElementError::noElement(); return this.{dart.core::List::[]}(this.{dart.core::List::length}.{dart.core::num::-}(1)); } - set /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ last(generic-covariant-impl dart.core::int* value) → void { + set /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ last(generic-covariant-impl dart.core::int* value) → void { if(this.{dart.core::List::length}.{dart.core::num::==}(0)) throw dart._internal::IterableElementError::noElement(); this.{dart.core::List::[]=}(this.{dart.core::List::length}.{dart.core::num::-}(1), value); } - get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ single() → dart.core::int* { + get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ single() → dart.core::int* { if(this.{dart.core::List::length}.{dart.core::num::==}(0)) throw dart._internal::IterableElementError::noElement(); if(this.{dart.core::List::length}.{dart.core::num::>}(1)) throw dart._internal::IterableElementError::tooMany(); return this.{dart.core::List::[]}(0); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ add(generic-covariant-impl dart.core::int* element) → void { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ add(generic-covariant-impl dart.core::int* element) → void { this.{dart.core::List::[]=}(let final dart.core::int #t9 = this.{dart.core::List::length} in let final dart.core::int #t10 = this.{dart.core::List::length} = #t9.{dart.core::num::+}(1) in #t9, element); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ clear() → void { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ clear() → void { this.{dart.core::List::length} = 0; } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ removeLast() → dart.core::int* { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ removeLast() → dart.core::int* { if(this.{dart.core::List::length}.{dart.core::num::==}(0)) { throw dart._internal::IterableElementError::noElement(); } @@ -536,7 +536,7 @@ library from "org-dartlang-test:///main.dart" as main { this.{dart.core::List::length} = this.{dart.core::List::length}.{dart.core::num::-}(1); return result; } - static method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ _compareAny(dynamic a, dynamic b) → dart.core::int { + static method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ _compareAny(dynamic a, dynamic b) → dart.core::int { return dart.core::Comparable::compare(a as{ForNonNullableByDefault} dart.core::Comparable, b as{ForNonNullableByDefault} dart.core::Comparable); } } diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.2.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.2.expect index 047b5159957..5ea6e5760a4 100644 --- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.2.expect +++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.2.expect @@ -10,13 +10,13 @@ library from "org-dartlang-test:///main.dart" as main { abstract member-signature get length() → dart.core::int*; abstract member-signature operator [](dart.core::int* index) → dart.core::int*; abstract member-signature operator []=(dart.core::int* index, generic-covariant-impl dart.core::int* value) → void; - get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ iterator() → dart.core::Iterator + get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ iterator() → dart.core::Iterator return new dart._internal::ListIterator::•(this); - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ elementAt(dart.core::int index) → dart.core::int* + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ elementAt(dart.core::int index) → dart.core::int* return this.{dart.core::List::[]}(index); - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ followedBy(generic-covariant-impl dart.core::Iterable other) → dart.core::Iterable + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ followedBy(generic-covariant-impl dart.core::Iterable other) → dart.core::Iterable return dart._internal::FollowedByIterable::firstEfficient(this, other); - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ forEach((dart.core::int*) → void action) → void { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ forEach((dart.core::int*) → void action) → void { dart.core::int length = this.{dart.core::List::length}; for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) { action.call(this.{dart.core::List::[]}(i)); @@ -26,11 +26,11 @@ library from "org-dartlang-test:///main.dart" as main { } } @#C3 - get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ isEmpty() → dart.core::bool + get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ isEmpty() → dart.core::bool return this.{dart.core::List::length}.{dart.core::num::==}(0); - get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ isNotEmpty() → dart.core::bool + get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ isNotEmpty() → dart.core::bool return !this.{dart.collection::ListMixin::isEmpty}; - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ contains(dart.core::Object? element) → dart.core::bool { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ contains(dart.core::Object? element) → dart.core::bool { dart.core::int length = this.{dart.core::List::length}; for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) { if(this.{dart.core::List::[]}(i).{dart.core::Object::==}(element)) @@ -41,7 +41,7 @@ library from "org-dartlang-test:///main.dart" as main { } return false; } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ every((dart.core::int*) → dart.core::bool test) → dart.core::bool { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ every((dart.core::int*) → dart.core::bool test) → dart.core::bool { dart.core::int length = this.{dart.core::List::length}; for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) { if(!test.call(this.{dart.core::List::[]}(i))) @@ -52,7 +52,7 @@ library from "org-dartlang-test:///main.dart" as main { } return true; } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ any((dart.core::int*) → dart.core::bool test) → dart.core::bool { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ any((dart.core::int*) → dart.core::bool test) → dart.core::bool { dart.core::int length = this.{dart.core::List::length}; for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) { if(test.call(this.{dart.core::List::[]}(i))) @@ -63,7 +63,7 @@ library from "org-dartlang-test:///main.dart" as main { } return false; } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ firstWhere((dart.core::int*) → dart.core::bool test, {generic-covariant-impl () →? dart.core::int* orElse = #C2}) → dart.core::int* { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ firstWhere((dart.core::int*) → dart.core::bool test, {generic-covariant-impl () →? dart.core::int* orElse = #C2}) → dart.core::int* { dart.core::int length = this.{dart.core::List::length}; for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) { dart.core::int* element = this.{dart.core::List::[]}(i); @@ -77,7 +77,7 @@ library from "org-dartlang-test:///main.dart" as main { return orElse{() → dart.core::int*}.call(); throw dart._internal::IterableElementError::noElement(); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ lastWhere((dart.core::int*) → dart.core::bool test, {generic-covariant-impl () →? dart.core::int* orElse = #C2}) → dart.core::int* { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ lastWhere((dart.core::int*) → dart.core::bool test, {generic-covariant-impl () →? dart.core::int* orElse = #C2}) → dart.core::int* { dart.core::int length = this.{dart.core::List::length}; for (dart.core::int i = length.{dart.core::num::-}(1); i.{dart.core::num::>=}(0); i = i.{dart.core::num::-}(1)) { dart.core::int* element = this.{dart.core::List::[]}(i); @@ -91,7 +91,7 @@ library from "org-dartlang-test:///main.dart" as main { return orElse{() → dart.core::int*}.call(); throw dart._internal::IterableElementError::noElement(); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ singleWhere((dart.core::int*) → dart.core::bool test, {generic-covariant-impl () →? dart.core::int* orElse = #C2}) → dart.core::int* { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ singleWhere((dart.core::int*) → dart.core::bool test, {generic-covariant-impl () →? dart.core::int* orElse = #C2}) → dart.core::int* { dart.core::int length = this.{dart.core::List::length}; late dart.core::int* match; dart.core::bool matchFound = false; @@ -114,7 +114,7 @@ library from "org-dartlang-test:///main.dart" as main { return orElse{() → dart.core::int*}.call(); throw dart._internal::IterableElementError::noElement(); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ join([dart.core::String separator = #C4]) → dart.core::String { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ join([dart.core::String separator = #C4]) → dart.core::String { if(this.{dart.core::List::length}.{dart.core::num::==}(0)) return ""; dart.core::StringBuffer buffer = let final dart.core::StringBuffer #t1 = new dart.core::StringBuffer::•() in block { @@ -122,15 +122,15 @@ library from "org-dartlang-test:///main.dart" as main { } =>#t1; return buffer.{dart.core::StringBuffer::toString}(); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ where((dart.core::int*) → dart.core::bool test) → dart.core::Iterable + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ where((dart.core::int*) → dart.core::bool test) → dart.core::Iterable return new dart._internal::WhereIterable::•(this, test); - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ whereType() → dart.core::Iterable + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ whereType() → dart.core::Iterable return new dart._internal::WhereTypeIterable::•(this); - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ map((dart.core::int*) → main::_WithListMixin&Object&ListMixin::map::T% f) → dart.core::Iterable + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ map((dart.core::int*) → main::_WithListMixin&Object&ListMixin::map::T% f) → dart.core::Iterable return new dart._internal::MappedListIterable::•(this, f); - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ expand((dart.core::int*) → dart.core::Iterable f) → dart.core::Iterable + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ expand((dart.core::int*) → dart.core::Iterable f) → dart.core::Iterable return new dart._internal::ExpandIterable::•(this, f); - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ reduce(generic-covariant-impl (dart.core::int*, dart.core::int*) → dart.core::int* combine) → dart.core::int* { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ reduce(generic-covariant-impl (dart.core::int*, dart.core::int*) → dart.core::int* combine) → dart.core::int* { dart.core::int length = this.{dart.core::List::length}; if(length.{dart.core::num::==}(0)) throw dart._internal::IterableElementError::noElement(); @@ -143,7 +143,7 @@ library from "org-dartlang-test:///main.dart" as main { } return value; } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ fold(main::_WithListMixin&Object&ListMixin::fold::T% initialValue, (main::_WithListMixin&Object&ListMixin::fold::T%, dart.core::int*) → main::_WithListMixin&Object&ListMixin::fold::T% combine) → main::_WithListMixin&Object&ListMixin::fold::T% { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ fold(main::_WithListMixin&Object&ListMixin::fold::T% initialValue, (main::_WithListMixin&Object&ListMixin::fold::T%, dart.core::int*) → main::_WithListMixin&Object&ListMixin::fold::T% combine) → main::_WithListMixin&Object&ListMixin::fold::T% { main::_WithListMixin&Object&ListMixin::fold::T% value = initialValue; dart.core::int length = this.{dart.core::List::length}; for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) { @@ -154,17 +154,17 @@ library from "org-dartlang-test:///main.dart" as main { } return value; } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ skip(dart.core::int count) → dart.core::Iterable + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ skip(dart.core::int count) → dart.core::Iterable return new dart._internal::SubListIterable::•(this, count, null); - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ skipWhile((dart.core::int*) → dart.core::bool test) → dart.core::Iterable { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ skipWhile((dart.core::int*) → dart.core::bool test) → dart.core::Iterable { return new dart._internal::SkipWhileIterable::•(this, test); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ take(dart.core::int count) → dart.core::Iterable + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ take(dart.core::int count) → dart.core::Iterable return new dart._internal::SubListIterable::•(this, 0, count); - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ takeWhile((dart.core::int*) → dart.core::bool test) → dart.core::Iterable { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ takeWhile((dart.core::int*) → dart.core::bool test) → dart.core::Iterable { return new dart._internal::TakeWhileIterable::•(this, test); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ toList({dart.core::bool growable = #C5}) → dart.core::List { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ toList({dart.core::bool growable = #C5}) → dart.core::List { if(this.{dart.collection::ListMixin::isEmpty}) return dart.core::List::empty(growable: growable); dart.core::int* first = this.{dart.core::List::[]}(0); @@ -174,14 +174,14 @@ library from "org-dartlang-test:///main.dart" as main { } return result; } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ toSet() → dart.core::Set { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ toSet() → dart.core::Set { dart.core::Set result = dart.collection::LinkedHashSet::•(); for (dart.core::int i = 0; i.{dart.core::num::<}(this.{dart.core::List::length}); i = i.{dart.core::num::+}(1)) { result.{dart.core::Set::add}(this.{dart.core::List::[]}(i)); } return result; } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ addAll(generic-covariant-impl dart.core::Iterable iterable) → void { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ addAll(generic-covariant-impl dart.core::Iterable iterable) → void { dart.core::int i = this.{dart.core::List::length}; { dart.core::Iterator :sync-for-iterator = iterable.{dart.core::Iterable::iterator}; @@ -195,7 +195,7 @@ library from "org-dartlang-test:///main.dart" as main { } } } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ remove(dart.core::Object? element) → dart.core::bool { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ remove(dart.core::Object? element) → dart.core::bool { for (dart.core::int i = 0; i.{dart.core::num::<}(this.{dart.core::List::length}); i = i.{dart.core::num::+}(1)) { if(this.{dart.core::List::[]}(i).{dart.core::Object::==}(element)) { this.{dart.collection::ListMixin::_closeGap}(i, i.{dart.core::num::+}(1)); @@ -204,7 +204,7 @@ library from "org-dartlang-test:///main.dart" as main { } return false; } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ _closeGap(dart.core::int start, dart.core::int end) → void { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ _closeGap(dart.core::int start, dart.core::int end) → void { dart.core::int length = this.{dart.core::List::length}; assert(0.{dart.core::num::<=}(start)); assert(start.{dart.core::num::<}(end)); @@ -215,13 +215,13 @@ library from "org-dartlang-test:///main.dart" as main { } this.{dart.core::List::length} = length.{dart.core::num::-}(size); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ removeWhere((dart.core::int*) → dart.core::bool test) → void { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ removeWhere((dart.core::int*) → dart.core::bool test) → void { this.{dart.collection::ListMixin::_filter}(test, false); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ retainWhere((dart.core::int*) → dart.core::bool test) → void { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ retainWhere((dart.core::int*) → dart.core::bool test) → void { this.{dart.collection::ListMixin::_filter}(test, true); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ _filter((dart.core::int*) → dart.core::bool test, dart.core::bool retainMatching) → void { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ _filter((dart.core::int*) → dart.core::bool test, dart.core::bool retainMatching) → void { dart.core::List retained = []; dart.core::int length = this.{dart.core::List::length}; for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) { @@ -238,12 +238,12 @@ library from "org-dartlang-test:///main.dart" as main { this.{dart.core::List::length} = retained.{dart.core::List::length}; } } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ cast() → dart.core::List + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ cast() → dart.core::List return dart.core::List::castFrom(this); - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ sort([(dart.core::int*, dart.core::int*) →? dart.core::int compare = #C2]) → void { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ sort([(dart.core::int*, dart.core::int*) →? dart.core::int compare = #C2]) → void { dart._internal::Sort::sort(this, let final (dart.core::int*, dart.core::int*) →? dart.core::int #t2 = compare in #t2.{dart.core::Object::==}(null) ?{(dart.core::int*, dart.core::int*) → dart.core::int} #C6 : #t2{(dart.core::int*, dart.core::int*) → dart.core::int}); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ shuffle([dart.math::Random? random = #C2]) → void { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ shuffle([dart.math::Random? random = #C2]) → void { random.{dart.core::Object::==}(null) ?{dart.math::Random} random = dart.math::Random::•() : null; if(random{dart.math::Random}.{dart.core::Object::==}(null)) throw "!"; @@ -256,10 +256,10 @@ library from "org-dartlang-test:///main.dart" as main { this.{dart.core::List::[]=}(pos, tmp); } } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ asMap() → dart.core::Map { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ asMap() → dart.core::Map { return new dart._internal::ListMapView::•(this); } - operator /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ +(generic-covariant-impl dart.core::List other) → dart.core::List + operator /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ +(generic-covariant-impl dart.core::List other) → dart.core::List return block { final dart.core::List #t3 = []; { @@ -277,7 +277,7 @@ library from "org-dartlang-test:///main.dart" as main { } } } =>#t3; - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ sublist(dart.core::int start, [dart.core::int? end = #C2]) → dart.core::List { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ sublist(dart.core::int start, [dart.core::int? end = #C2]) → dart.core::List { dart.core::int listLength = this.{dart.core::List::length}; end.{dart.core::num::==}(null) ?{dart.core::int} end = listLength : null; if(end{dart.core::int}.{dart.core::num::==}(null)) @@ -285,24 +285,24 @@ library from "org-dartlang-test:///main.dart" as main { dart.core::RangeError::checkValidRange(start, end{dart.core::int}, listLength); return dart.core::List::from(this.{dart.collection::ListMixin::getRange}(start, end{dart.core::int})); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ getRange(dart.core::int start, dart.core::int end) → dart.core::Iterable { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ getRange(dart.core::int start, dart.core::int end) → dart.core::Iterable { dart.core::RangeError::checkValidRange(start, end, this.{dart.core::List::length}); return new dart._internal::SubListIterable::•(this, start, end); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ removeRange(dart.core::int start, dart.core::int end) → void { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ removeRange(dart.core::int start, dart.core::int end) → void { dart.core::RangeError::checkValidRange(start, end, this.{dart.core::List::length}); if(end.{dart.core::num::>}(start)) { this.{dart.collection::ListMixin::_closeGap}(start, end); } } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ fillRange(dart.core::int start, dart.core::int end, [generic-covariant-impl dart.core::int? fill = #C2]) → void { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ fillRange(dart.core::int start, dart.core::int end, [generic-covariant-impl dart.core::int? fill = #C2]) → void { dart.core::int* value = let dart.core::int? #t6 = fill in #t6.==(null) ?{dart.core::int*} #t6 : #t6{dart.core::int*}; dart.core::RangeError::checkValidRange(start, end, this.{dart.core::List::length}); for (dart.core::int i = start; i.{dart.core::num::<}(end); i = i.{dart.core::num::+}(1)) { this.{dart.core::List::[]=}(i, value); } } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ setRange(dart.core::int start, dart.core::int end, generic-covariant-impl dart.core::Iterable iterable, [dart.core::int skipCount = #C7]) → void { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ setRange(dart.core::int start, dart.core::int end, generic-covariant-impl dart.core::Iterable iterable, [dart.core::int skipCount = #C7]) → void { dart.core::RangeError::checkValidRange(start, end, this.{dart.core::List::length}); dart.core::int length = end.{dart.core::num::-}(start); if(length.{dart.core::num::==}(0)) @@ -332,7 +332,7 @@ library from "org-dartlang-test:///main.dart" as main { } } } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ replaceRange(dart.core::int start, dart.core::int end, generic-covariant-impl dart.core::Iterable newContents) → void { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ replaceRange(dart.core::int start, dart.core::int end, generic-covariant-impl dart.core::Iterable newContents) → void { dart.core::RangeError::checkValidRange(start, end, this.{dart.core::List::length}); if(start.{dart.core::num::==}(this.{dart.core::List::length})) { this.{dart.collection::ListMixin::addAll}(newContents); @@ -382,7 +382,7 @@ library from "org-dartlang-test:///main.dart" as main { this.{dart.collection::ListMixin::setRange}(start, insertEnd, newContents); } } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ indexOf(generic-covariant-impl dart.core::Object? element, [dart.core::int start = #C7]) → dart.core::int { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ indexOf(generic-covariant-impl dart.core::Object? element, [dart.core::int start = #C7]) → dart.core::int { if(start.{dart.core::num::<}(0)) start = 0; for (dart.core::int i = start; i.{dart.core::num::<}(this.{dart.core::List::length}); i = i.{dart.core::num::+}(1)) { @@ -391,7 +391,7 @@ library from "org-dartlang-test:///main.dart" as main { } return 1.{dart.core::int::unary-}(); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ indexWhere((dart.core::int*) → dart.core::bool test, [dart.core::int start = #C7]) → dart.core::int { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ indexWhere((dart.core::int*) → dart.core::bool test, [dart.core::int start = #C7]) → dart.core::int { if(start.{dart.core::num::<}(0)) start = 0; for (dart.core::int i = start; i.{dart.core::num::<}(this.{dart.core::List::length}); i = i.{dart.core::num::+}(1)) { @@ -400,7 +400,7 @@ library from "org-dartlang-test:///main.dart" as main { } return 1.{dart.core::int::unary-}(); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ lastIndexOf(generic-covariant-impl dart.core::Object? element, [dart.core::int? start = #C2]) → dart.core::int { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ lastIndexOf(generic-covariant-impl dart.core::Object? element, [dart.core::int? start = #C2]) → dart.core::int { if(start.{dart.core::num::==}(null) || start{dart.core::int}.{dart.core::num::>=}(this.{dart.core::List::length})) start = this.{dart.core::List::length}.{dart.core::num::-}(1); if(start{dart.core::int}.{dart.core::num::==}(null)) @@ -411,7 +411,7 @@ library from "org-dartlang-test:///main.dart" as main { } return 1.{dart.core::int::unary-}(); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ lastIndexWhere((dart.core::int*) → dart.core::bool test, [dart.core::int? start = #C2]) → dart.core::int { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ lastIndexWhere((dart.core::int*) → dart.core::bool test, [dart.core::int? start = #C2]) → dart.core::int { if(start.{dart.core::num::==}(null) || start{dart.core::int}.{dart.core::num::>=}(this.{dart.core::List::length})) start = this.{dart.core::List::length}.{dart.core::num::-}(1); if(start{dart.core::int}.{dart.core::num::==}(null)) @@ -422,7 +422,7 @@ library from "org-dartlang-test:///main.dart" as main { } return 1.{dart.core::int::unary-}(); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ insert(dart.core::int index, generic-covariant-impl dart.core::int* element) → void { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ insert(dart.core::int index, generic-covariant-impl dart.core::int* element) → void { dart.core::ArgumentError::checkNotNull(index, "index"); dart.core::RangeError::checkValueInInterval(index, 0, this.{dart.core::List::length}, "index"); if(index.{dart.core::num::==}(this.{dart.core::List::length})) { @@ -433,12 +433,12 @@ library from "org-dartlang-test:///main.dart" as main { this.{dart.collection::ListMixin::setRange}(index.{dart.core::num::+}(1), this.{dart.core::List::length}, this, index); this.{dart.core::List::[]=}(index, element); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ removeAt(dart.core::int index) → dart.core::int* { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ removeAt(dart.core::int index) → dart.core::int* { dart.core::int* result = this.{dart.core::List::[]}(index); this.{dart.collection::ListMixin::_closeGap}(index, index.{dart.core::num::+}(1)); return result; } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ insertAll(dart.core::int index, generic-covariant-impl dart.core::Iterable iterable) → void { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ insertAll(dart.core::int index, generic-covariant-impl dart.core::Iterable iterable) → void { dart.core::RangeError::checkValueInInterval(index, 0, this.{dart.core::List::length}, "index"); if(index.{dart.core::num::==}(this.{dart.core::List::length})) { this.{dart.collection::ListMixin::addAll}(iterable); @@ -465,7 +465,7 @@ library from "org-dartlang-test:///main.dart" as main { } this.{dart.collection::ListMixin::setAll}(index, iterable); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ setAll(dart.core::int index, generic-covariant-impl dart.core::Iterable iterable) → void { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ setAll(dart.core::int index, generic-covariant-impl dart.core::Iterable iterable) → void { if(iterable is{ForNonNullableByDefault} dart.core::List) { this.{dart.collection::ListMixin::setRange}(index, index.{dart.core::num::+}(iterable.{dart.core::Iterable::length}), iterable); } @@ -481,9 +481,9 @@ library from "org-dartlang-test:///main.dart" as main { } } } - get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ reversed() → dart.core::Iterable + get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ reversed() → dart.core::Iterable return new dart._internal::ReversedListIterable::•(this); - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ toString() → dart.core::String + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ toString() → dart.core::String return dart.collection::IterableBase::iterableToFullString(this, "[", "]"); abstract member-signature get _identityHashCode() → dart.core::int*; abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → dart.core::bool*; @@ -495,40 +495,40 @@ library from "org-dartlang-test:///main.dart" as main { abstract member-signature method noSuchMethod(dart.core::Invocation* invocation) → dynamic; abstract member-signature get runtimeType() → dart.core::Type*; abstract member-signature set length(dart.core::int* newLength) → void; - get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ first() → dart.core::int* { + get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ first() → dart.core::int* { if(this.{dart.core::List::length}.{dart.core::num::==}(0)) throw dart._internal::IterableElementError::noElement(); return this.{dart.core::List::[]}(0); } - set /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ first(generic-covariant-impl dart.core::int* value) → void { + set /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ first(generic-covariant-impl dart.core::int* value) → void { if(this.{dart.core::List::length}.{dart.core::num::==}(0)) throw dart._internal::IterableElementError::noElement(); this.{dart.core::List::[]=}(0, value); } - get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ last() → dart.core::int* { + get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ last() → dart.core::int* { if(this.{dart.core::List::length}.{dart.core::num::==}(0)) throw dart._internal::IterableElementError::noElement(); return this.{dart.core::List::[]}(this.{dart.core::List::length}.{dart.core::num::-}(1)); } - set /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ last(generic-covariant-impl dart.core::int* value) → void { + set /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ last(generic-covariant-impl dart.core::int* value) → void { if(this.{dart.core::List::length}.{dart.core::num::==}(0)) throw dart._internal::IterableElementError::noElement(); this.{dart.core::List::[]=}(this.{dart.core::List::length}.{dart.core::num::-}(1), value); } - get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ single() → dart.core::int* { + get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ single() → dart.core::int* { if(this.{dart.core::List::length}.{dart.core::num::==}(0)) throw dart._internal::IterableElementError::noElement(); if(this.{dart.core::List::length}.{dart.core::num::>}(1)) throw dart._internal::IterableElementError::tooMany(); return this.{dart.core::List::[]}(0); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ add(generic-covariant-impl dart.core::int* element) → void { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ add(generic-covariant-impl dart.core::int* element) → void { this.{dart.core::List::[]=}(let final dart.core::int #t9 = this.{dart.core::List::length} in let final dart.core::int #t10 = this.{dart.core::List::length} = #t9.{dart.core::num::+}(1) in #t9, element); } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ clear() → void { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ clear() → void { this.{dart.core::List::length} = 0; } - method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ removeLast() → dart.core::int* { + method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ removeLast() → dart.core::int* { if(this.{dart.core::List::length}.{dart.core::num::==}(0)) { throw dart._internal::IterableElementError::noElement(); } @@ -536,7 +536,7 @@ library from "org-dartlang-test:///main.dart" as main { this.{dart.core::List::length} = this.{dart.core::List::length}.{dart.core::num::-}(1); return result; } - static method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ _compareAny(dynamic a, dynamic b) → dart.core::int { + static method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ _compareAny(dynamic a, dynamic b) → dart.core::int { return dart.core::Comparable::compare(a as{ForNonNullableByDefault} dart.core::Comparable, b as{ForNonNullableByDefault} dart.core::Comparable); } } diff --git a/pkg/front_end/tool/_fasta/generate_experimental_flags.dart b/pkg/front_end/tool/_fasta/generate_experimental_flags.dart index 8978f14dd5a..35fee301d80 100644 --- a/pkg/front_end/tool/_fasta/generate_experimental_flags.dart +++ b/pkg/front_end/tool/_fasta/generate_experimental_flags.dart @@ -37,7 +37,7 @@ Uri computeYamlFile() { Uri computeAllowListFile() { return Platform.script - .resolve("../../../../sdk_nnbd/lib/_internal/allowed_experiments.json"); + .resolve("../../../../sdk/lib/_internal/allowed_experiments.json"); } String generateKernelFile() { diff --git a/pkg/modular_test/lib/src/loader.dart b/pkg/modular_test/lib/src/loader.dart index 4efd9e61904..65d5558084c 100644 --- a/pkg/modular_test/lib/src/loader.dart +++ b/pkg/modular_test/lib/src/loader.dart @@ -204,8 +204,6 @@ Future _addModulePerPackage( Future _createSdkModule(Uri root) async { List sources = [ Uri.parse('sdk/lib/libraries.json'), - // TODO(#38701) Cleanup after merging the forked SDK into mainline. - Uri.parse('sdk_nnbd/lib/libraries.json'), ]; // Include all dart2js, ddc, vm library sources and patch files. @@ -213,8 +211,6 @@ Future _createSdkModule(Uri root) async { // it doesn't list files that are transitively imported. var sdkLibrariesAndPatchesRoots = [ 'sdk/lib/', - // TODO(#38701) Cleanup after merging the forked SDK into mainline. - 'sdk_nnbd/lib/', 'runtime/lib/', 'runtime/bin/', ]; diff --git a/pkg/nnbd_migration/tool/src/package.dart b/pkg/nnbd_migration/tool/src/package.dart index 152b61f7677..6b67e50f300 100644 --- a/pkg/nnbd_migration/tool/src/package.dart +++ b/pkg/nnbd_migration/tool/src/package.dart @@ -217,15 +217,4 @@ class Sdk { Sdk(String sdkPath) { this.sdkPath = path.canonicalize(sdkPath); } - - /// Returns true if the SDK was built with --nnbd. - /// - /// May throw if [sdkPath] is invalid, or there is an error parsing - /// the libraries.json file. - bool get isNnbdSdk { - // TODO(jcollins-g): contact eng-prod for a more foolproof detection method - String libraries = path.join(sdkPath, 'lib', 'libraries.json'); - var decodedJson = JsonDecoder().convert(File(libraries).readAsStringSync()); - return ((decodedJson['comment:1'] as String).contains('sdk_nnbd')); - } } diff --git a/pkg/nnbd_migration/tool/trial_migration.dart b/pkg/nnbd_migration/tool/trial_migration.dart index 3203d1d181c..e7bc2b638fc 100644 --- a/pkg/nnbd_migration/tool/trial_migration.dart +++ b/pkg/nnbd_migration/tool/trial_migration.dart @@ -27,7 +27,6 @@ main(List args) async { Sdk sdk = Sdk(parsedArgs['sdk'] as String); warnOnNoAssertions(); - warnOnNoSdkNnbd(sdk); Playground playground = Playground(defaultPlaygroundPath, parsedArgs['clean'] as bool); @@ -218,17 +217,6 @@ void warnOnNoAssertions() { printWarning("You didn't --enable-asserts!"); } -void warnOnNoSdkNnbd(Sdk sdk) { - try { - if (sdk.isNnbdSdk) return; - } catch (e) { - printWarning('Unable to determine whether this SDK supports NNBD'); - return; - } - printWarning( - 'SDK at ${sdk.sdkPath} not compiled with --nnbd, use --sdk option'); -} - class ExceptionCategory { final String topOfStack; final List> exceptionCountPerPackage; diff --git a/pkg/test_runner/lib/src/compiler_configuration.dart b/pkg/test_runner/lib/src/compiler_configuration.dart index 97be6bd17fd..03ff4464284 100644 --- a/pkg/test_runner/lib/src/compiler_configuration.dart +++ b/pkg/test_runner/lib/src/compiler_configuration.dart @@ -367,9 +367,7 @@ class Dart2xCompilerConfiguration extends CompilerConfiguration { : super._subclass(configuration); String computeCompilerPath() { - var prefix = - // TODO(38701): Cleanup after merging the forked SDK into mainline. - _configuration.nnbdMode == NnbdMode.legacy ? 'sdk/bin' : 'sdk_nnbd/bin'; + var prefix = 'sdk/bin'; var suffix = shellScriptExtension; if (_isHostChecked) { @@ -461,9 +459,7 @@ class Dart2jsCompilerConfiguration extends Dart2xCompilerConfiguration { CommandArtifact artifact) { var sdk = _useSdk ? Uri.directory(_configuration.buildDirectory).resolve('dart-sdk/') - : Uri.directory(Repository.dir.toNativePath()).resolve( - // TODO(38701): Cleanup after merging the forked SDK into mainline. - _configuration.nnbdMode == NnbdMode.legacy ? 'sdk/' : 'sdk_nnbd/'); + : Uri.directory(Repository.dir.toNativePath()).resolve('sdk/'); var preambleDir = sdk.resolve('lib/_internal/js_runtime/lib/preambles/'); return runtimeConfiguration.dart2jsPreambles(preambleDir) ..add(artifact.filename); @@ -494,10 +490,7 @@ class DevCompilerConfiguration extends CompilerConfiguration { bool get useKernel => _configuration.compiler == Compiler.dartdevk; String computeCompilerPath() { - var dir = _useSdk - ? "${_configuration.buildDirectory}/dart-sdk" - // TODO(38701): Cleanup after merging the forked SDK into mainline. - : _configuration.nnbdMode == NnbdMode.legacy ? "sdk" : "sdk_nnbd"; + var dir = _useSdk ? "${_configuration.buildDirectory}/dart-sdk" : "sdk"; return "$dir/bin/dartdevc$shellScriptExtension"; } @@ -508,8 +501,7 @@ class DevCompilerConfiguration extends CompilerConfiguration { ..._configuration.sharedOptions, ..._experimentsArgument(_configuration, testFile), ...testFile.ddcOptions, - if (_configuration.nnbdMode == NnbdMode.strong) - '--sound-null-safety', + if (_configuration.nnbdMode == NnbdMode.strong) '--sound-null-safety', // The file being compiled is the last argument. args.last ]; @@ -712,14 +704,11 @@ class PrecompilerCompilerConfiguration extends CompilerConfiguration "--snapshot-kind=app-aot-assembly", "--assembly=$tempDir/out.S" ], - if (_isAndroid && _isArm) - '--no-sim-use-hardfp', - if (_configuration.isMinified) - '--obfuscate', + if (_isAndroid && _isArm) '--no-sim-use-hardfp', + if (_configuration.isMinified) '--obfuscate', // The SIMARM precompiler assumes support for integer division, but the // Qemu arm cpus do not support integer division. - if (_configuration.useQemu) - '--no-use-integer-division', + if (_configuration.useQemu) '--no-use-integer-division', ..._replaceDartFiles(arguments, tempKernelFile(tempDir)), ]; @@ -936,9 +925,7 @@ class AnalyzerCompilerConfiguration extends CompilerConfiguration { int get timeoutMultiplier => 4; String computeCompilerPath() { - var prefix = - // TODO(38701): Cleanup after merging the forked SDK into mainline. - _configuration.nnbdMode == NnbdMode.legacy ? 'sdk/bin' : 'sdk_nnbd/bin'; + var prefix = 'sdk/bin'; if (_isHostChecked) { if (_useSdk) { throw "--host-checked and --use-sdk cannot be used together"; diff --git a/pkg/test_runner/lib/src/configuration.dart b/pkg/test_runner/lib/src/configuration.dart index 26a9f912d1f..dfc966ec824 100644 --- a/pkg/test_runner/lib/src/configuration.dart +++ b/pkg/test_runner/lib/src/configuration.dart @@ -69,8 +69,7 @@ class TestConfiguration { this.reproducingArguments, this.fastTestsOnly, this.printPassingStdout}) - : _packages = packages, - isPreNNBD = configuration.name.split('-').contains('prennbd'); + : _packages = packages; final Map selectors; final Progress progress; @@ -99,7 +98,6 @@ class TestConfiguration { final bool writeResults; final bool writeLogs; final bool printPassingStdout; - final bool isPreNNBD; Architecture get architecture => configuration.architecture; Compiler get compiler => configuration.compiler; @@ -470,13 +468,6 @@ class TestConfiguration { var normal = '$result$arch'; var cross = '${result}X$arch'; - // TODO(sigmund): remove once all prennbd coverage is dropped. Currently - // only dart2js supports opting-out of using the nnbd sdk. - if (isPreNNBD) { - normal += 'Legacy'; - cross += 'Legacy'; - } - var outDir = system.outputDirectory; var normalDir = Directory(Path('$outDir$normal').toNativePath()); var crossDir = Directory(Path('$outDir$cross').toNativePath()); diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn index 3ec3471714a..50a155d7795 100644 --- a/runtime/bin/BUILD.gn +++ b/runtime/bin/BUILD.gn @@ -528,14 +528,9 @@ gen_snapshot_action("generate_snapshot_bin") { isolate_snapshot_data, isolate_snapshot_instructions, ] - args = [] - if (!dont_use_nnbd) { - args += [ - "--enable-experiment=non-nullable", - "--null-safety", - ] - } - args += [ + args = [ + "--enable-experiment=non-nullable", + "--null-safety", "--deterministic", "--snapshot_kind=" + dart_core_snapshot_kind, "--vm_snapshot_data=" + rebase_path(vm_snapshot_data, root_build_dir), diff --git a/runtime/vm/BUILD.gn b/runtime/vm/BUILD.gn index 395b15fbc3f..3888a2bc9f9 100644 --- a/runtime/vm/BUILD.gn +++ b/runtime/vm/BUILD.gn @@ -155,12 +155,7 @@ template("gen_vm_platform") { } single_root_scheme = "org-dartlang-sdk" single_root_base = rebase_path("../../") - if (!dont_use_nnbd) { - libraries_specification_uri = - "org-dartlang-sdk:///sdk_nnbd/lib/libraries.json" - } else { - libraries_specification_uri = "org-dartlang-sdk:///sdk/lib/libraries.json" - } + libraries_specification_uri = "org-dartlang-sdk:///sdk/lib/libraries.json" outputs = [ "$root_out_dir/vm_platform" + output_postfix + ".dill", "$root_out_dir/vm_outline" + output_postfix + ".dill", @@ -172,11 +167,9 @@ template("gen_vm_platform") { "-Ddart.vm.product=$is_product_flag", "-Ddart.developer.causal_async_stacks=$allow_causal_async_stacks", "-Ddart.isVM=true", + "--enable-experiment=non-nullable", + "--nnbd-agnostic", ] - if (!dont_use_nnbd) { - args += [ "--enable-experiment=non-nullable" ] - args += [ "--nnbd-agnostic" ] - } if (defined(invoker.exclude_source) && invoker.exclude_source) { args += [ "--exclude-source" ] } diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn index 812565a0373..5354079d5f6 100644 --- a/sdk/BUILD.gn +++ b/sdk/BUILD.gn @@ -618,11 +618,15 @@ copy("copy_dart2js_dill_files") { visibility = [ ":create_full_sdk" ] deps = [ ":copy_libraries", + "../utils/compiler:compile_dart2js_nnbd_strong_platform", "../utils/compiler:compile_dart2js_platform", + "../utils/compiler:compile_dart2js_server_nnbd_strong_platform", "../utils/compiler:compile_dart2js_server_platform", ] sources = [ + "$root_out_dir/dart2js_nnbd_strong_platform.dill", "$root_out_dir/dart2js_platform.dill", + "$root_out_dir/dart2js_server_nnbd_strong_platform.dill", "$root_out_dir/dart2js_server_platform.dill", ] outputs = [ "$root_out_dir/dart-sdk/lib/_internal/{{source_file_part}}" ] @@ -636,9 +640,22 @@ copy("copy_dev_compiler_outline") { "../utils/dartdevc:dartdevc_platform", ] sources = [ "$root_out_dir/ddc_outline.dill" ] + + # TODO(nshahan) Fix the name here to be consistent and merge with below. outputs = [ "$root_out_dir/dart-sdk/lib/_internal/ddc_sdk.dill" ] } +# Copies DDC's SDK outline .dill with sound null safety to lib/_internal +copy("copy_dev_compiler_outline_sound") { + visibility = [ "../utils/dartdevc:dartdevc_test" ] + deps = [ + ":copy_libraries", + "../utils/dartdevc:dartdevc_platform_sound", + ] + sources = [ "$root_out_dir/ddc_outline_sound.dill" ] + outputs = [ "$root_out_dir/dart-sdk/lib/_internal/{{source_file_part}}" ] +} + # This rule copies DDK's JS SDK and require.js to lib/dev_compiler/kernel/amd. copy("copy_dev_compiler_js_amd_kernel") { visibility = [ ":copy_dev_compiler_js" ] diff --git a/sdk/bin/dart2js b/sdk/bin/dart2js index cfc91b1d759..9c562ecfcee 100755 --- a/sdk/bin/dart2js +++ b/sdk/bin/dart2js @@ -52,4 +52,4 @@ DART_ROOT="$(cd "${SDK_DIR}/.." ; pwd -P)" DART2JS="package:compiler/src/dart2js.dart" -exec "$DART" "--packages=$DART_ROOT/.packages" "${EXTRA_VM_OPTIONS[@]}" "$DART2JS" "${EXTRA_OPTIONS[@]}" "$@" +exec "$DART" "--packages=$DART_ROOT/.packages" --enable-experiment=non-nullable "${EXTRA_VM_OPTIONS[@]}" "$DART2JS" "${EXTRA_OPTIONS[@]}" "$@" diff --git a/sdk/bin/dart2js_sdk b/sdk/bin/dart2js_sdk index e7999b47af8..03999f9d6c8 100755 --- a/sdk/bin/dart2js_sdk +++ b/sdk/bin/dart2js_sdk @@ -55,4 +55,4 @@ if [[ $DART_VM_OPTIONS ]]; then EXTRA_VM_OPTIONS+=("${OPTIONS[@]}") fi -exec "$DART" "${EXTRA_VM_OPTIONS[@]}" "$SNAPSHOT" "${EXTRA_OPTIONS[@]}" "$@" +exec "$DART" --enable-experiment=non-nullable "${EXTRA_VM_OPTIONS[@]}" "$SNAPSHOT" "${EXTRA_OPTIONS[@]}" "$@" diff --git a/sdk/bin/dartanalyzer b/sdk/bin/dartanalyzer index 7ea062cf3db..0574603a0b1 100755 --- a/sdk/bin/dartanalyzer +++ b/sdk/bin/dartanalyzer @@ -28,6 +28,7 @@ DART="$BIN_DIR/dart" unset EXTRA_VM_OPTIONS declare -a EXTRA_VM_OPTIONS +EXTRA_VM_OPTIONS+=("--enable_experiment=non-nullable") case $0 in *_developer) diff --git a/sdk/bin/dartanalyzer_sdk b/sdk/bin/dartanalyzer_sdk index 28f37ab3d7b..88f4deb0434 100755 --- a/sdk/bin/dartanalyzer_sdk +++ b/sdk/bin/dartanalyzer_sdk @@ -28,4 +28,4 @@ SNAPSHOT="$BIN_DIR/snapshots/dartanalyzer.dart.snapshot" # We are running the snapshot in the built SDK. DART="$BIN_DIR/dart" -exec "$DART" "$SNAPSHOT" "$SDK_ARG" "$@" +exec "$DART" --enable_experiment=non-nullable "$SNAPSHOT" "$SDK_ARG" "$@" diff --git a/sdk/bin/dartdevc b/sdk/bin/dartdevc index 5b75ad2fdec..c2c25d903ab 100755 --- a/sdk/bin/dartdevc +++ b/sdk/bin/dartdevc @@ -45,4 +45,4 @@ DART_ROOT="$(cd "${SDK_DIR}/.." ; pwd -P)" DEV_COMPILER="$DART_ROOT/pkg/dev_compiler/bin/dartdevc.dart" -exec "$DART" "--packages=$DART_ROOT/.packages" "${EXTRA_VM_OPTIONS[@]}" "$DEV_COMPILER" "$SDK_ARG" "$@" +exec "$DART" "--packages=$DART_ROOT/.packages" --enable_experiment=non-nullable "${EXTRA_VM_OPTIONS[@]}" "$DEV_COMPILER" "$SDK_ARG" "$@" diff --git a/sdk/bin/dartdevc_sdk b/sdk/bin/dartdevc_sdk index 6cba7d8a096..c687bdd9472 100755 --- a/sdk/bin/dartdevc_sdk +++ b/sdk/bin/dartdevc_sdk @@ -35,4 +35,4 @@ if [[ $DART_VM_OPTIONS ]]; then EXTRA_VM_OPTIONS+=("${OPTIONS[@]}") fi -exec "$DART" "${EXTRA_VM_OPTIONS[@]}" "$SNAPSHOT" "$@" +exec "$DART" --enable_experiment=non-nullable "${EXTRA_VM_OPTIONS[@]}" "$SNAPSHOT" "$@" diff --git a/sdk/lib/_http/crypto.dart b/sdk/lib/_http/crypto.dart index 73f3745f7d3..f29a15b6eb0 100644 --- a/sdk/lib/_http/crypto.dart +++ b/sdk/lib/_http/crypto.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart._http; class _CryptoUtils { @@ -68,7 +66,7 @@ class _CryptoUtils { } final String lookup = urlSafe ? _encodeTableUrlSafe : _encodeTable; // Size of 24 bit chunks. - final int remainderLength = len.remainder(3); + final int remainderLength = len.remainder(3) as int; final int chunkLength = len - remainderLength; // Size of base output. int outputLen = ((len ~/ 3) * 4) + ((remainderLength > 0) ? 4 : 0); @@ -76,7 +74,7 @@ class _CryptoUtils { if (addLineSeparator) { outputLen += ((outputLen - 1) ~/ LINE_LENGTH) << 1; } - List out = new List(outputLen); + List out = new List.filled(outputLen, 0); // Encode 24 bit chunks. int j = 0, i = 0, c = 0; @@ -120,7 +118,7 @@ class _CryptoUtils { [bool ignoreInvalidCharacters = true]) { int len = input.length; if (len == 0) { - return new List(0); + return new List.empty(); } // Count '\r', '\n' and illegal characters, For illegal characters, @@ -149,7 +147,7 @@ class _CryptoUtils { if (currentCodeUnit == PAD) padLength++; } int outputLen = (((len - extrasLen) * 6) >> 3) - padLength; - List out = new List(outputLen); + List out = new List.filled(outputLen, 0); for (int i = 0, o = 0; o < outputLen;) { // Accumulate 4 valid 6 bit Base 64 characters into an int. @@ -182,7 +180,6 @@ const _BYTES_PER_WORD = 4; abstract class _HashBase { // Hasher state. final int _chunkSizeInWords; - final int _digestSizeInWords; final bool _bigEndianWords; int _lengthInBytes = 0; List _pendingData; @@ -190,12 +187,10 @@ abstract class _HashBase { List _h; bool _digestCalled = false; - _HashBase( - this._chunkSizeInWords, this._digestSizeInWords, this._bigEndianWords) - : _pendingData = [] { - _currentChunk = new List(_chunkSizeInWords); - _h = new List(_digestSizeInWords); - } + _HashBase(this._chunkSizeInWords, int digestSizeInWords, this._bigEndianWords) + : _pendingData = [], + _currentChunk = new List.filled(_chunkSizeInWords, 0), + _h = new List.filled(digestSizeInWords, 0); // Update the hasher with more data. add(List data) { @@ -271,7 +266,7 @@ abstract class _HashBase { // Convert a 32-bit word to four bytes. List _wordToBytes(int word) { - List bytes = new List(_BYTES_PER_WORD); + List bytes = new List.filled(_BYTES_PER_WORD, 0); bytes[0] = (word >> (_bigEndianWords ? 24 : 0)) & _MASK_8; bytes[1] = (word >> (_bigEndianWords ? 16 : 8)) & _MASK_8; bytes[2] = (word >> (_bigEndianWords ? 8 : 16)) & _MASK_8; @@ -397,9 +392,11 @@ class _MD5 extends _HashBase { // The SHA1 hasher is used to compute an SHA1 message digest. class _SHA1 extends _HashBase { + List _w; + // Construct a SHA1 hasher object. _SHA1() - : _w = new List(80), + : _w = List.filled(80, 0), super(16, 5, true) { _h[0] = 0x67452301; _h[1] = 0xEFCDAB89; @@ -455,6 +452,4 @@ class _SHA1 extends _HashBase { _h[3] = _add32(d, _h[3]); _h[4] = _add32(e, _h[4]); } - - List _w; } diff --git a/sdk/lib/_http/embedder_config.dart b/sdk/lib/_http/embedder_config.dart index fb13beabd24..730bc2ddb61 100644 --- a/sdk/lib/_http/embedder_config.dart +++ b/sdk/lib/_http/embedder_config.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart._http; /// Embedder-specific `dart:_http` configuration. diff --git a/sdk/lib/_http/http.dart b/sdk/lib/_http/http.dart index e80369c1b1e..6db8524ad46 100644 --- a/sdk/lib/_http/http.dart +++ b/sdk/lib/_http/http.dart @@ -2,8 +2,6 @@ // 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.6 - library dart._http; import 'dart:async'; @@ -18,7 +16,8 @@ import 'dart:collection' UnmodifiableMapView; import 'dart:convert'; import 'dart:developer' hide log; -import 'dart:_internal' show Since, HttpStatus; +import 'dart:_internal' + show Since, valueOfNonNullableParamWithDefault, HttpStatus; import 'dart:math'; import 'dart:io'; import 'dart:typed_data'; @@ -144,7 +143,7 @@ abstract class HttpServer implements Stream { * * The default value is `null`. */ - String serverHeader; + String? serverHeader; /** * Default set of headers added to all response objects. @@ -171,7 +170,7 @@ abstract class HttpServer implements Stream { * The default value is `false` (compression disabled). * To enable, set `autoCompress` to `true`. */ - bool autoCompress; + bool autoCompress = false; /** * Gets or sets the timeout used for idle keep-alive connections. If no @@ -185,7 +184,7 @@ abstract class HttpServer implements Stream { * * To disable, set [idleTimeout] to `null`. */ - Duration idleTimeout; + Duration? idleTimeout = const Duration(seconds: 120); /** * Starts listening for HTTP requests on the specified [address] and @@ -209,13 +208,13 @@ abstract class HttpServer implements Stream { * [InternetAddress.loopbackIPv6], only IP version 6 (IPv6) connections * will be accepted. * - * If [port] has the value [:0:] an ephemeral port will be chosen by + * If [port] has the value 0 an ephemeral port will be chosen by * the system. The actual port used can be retrieved using the * [port] getter. * * The optional argument [backlog] can be used to specify the listen * backlog for the underlying OS listen setup. If [backlog] has the - * value of [:0:] (the default) a reasonable value will be chosen by + * value of 0 (the default) a reasonable value will be chosen by * the system. * * The optional argument [shared] specifies whether additional HttpServer @@ -226,7 +225,7 @@ abstract class HttpServer implements Stream { * distributed over multiple isolates this way. */ static Future bind(address, int port, - {int backlog: 0, bool v6Only: false, bool shared: false}) => + {int backlog = 0, bool v6Only = false, bool shared = false}) => _HttpServer.bind(address, port, backlog, v6Only, shared); /** @@ -246,13 +245,13 @@ abstract class HttpServer implements Stream { * restrict this to version 6 (IPv6) only, use [v6Only] to set * version 6 only. * - * If [port] has the value [:0:] an ephemeral port will be chosen by + * If [port] has the value 0 an ephemeral port will be chosen by * the system. The actual port used can be retrieved using the * [port] getter. * * The optional argument [backlog] can be used to specify the listen * backlog for the underlying OS listen setup. If [backlog] has the - * value of [:0:] (the default) a reasonable value will be chosen by + * value of 0 (the default) a reasonable value will be chosen by * the system. * * If [requestClientCertificate] is true, the server will @@ -271,10 +270,10 @@ abstract class HttpServer implements Stream { static Future bindSecure( address, int port, SecurityContext context, - {int backlog: 0, - bool v6Only: false, - bool requestClientCertificate: false, - bool shared: false}) => + {int backlog = 0, + bool v6Only = false, + bool requestClientCertificate = false, + bool shared = false}) => _HttpServer.bindSecure(address, port, context, backlog, v6Only, requestClientCertificate, shared); @@ -295,30 +294,33 @@ abstract class HttpServer implements Stream { * * If [force] is `true`, active connections will be closed immediately. */ - Future close({bool force: false}); + Future close({bool force = false}); /** - * Returns the port that the server is listening on. This can be - * used to get the actual port used when a value of 0 for [:port:] is + * The port that the server is listening on. + * + * This is the actual port used when a port of zero is * specified in the [bind] or [bindSecure] call. */ int get port; /** - * Returns the address that the server is listening on. This can be - * used to get the actual address used, when the address is fetched by - * a lookup from a hostname. + * The address that the server is listening on. + * + * This is the actual address used when the original address + * was specified as a hostname. */ InternetAddress get address; /** * Sets the timeout, in seconds, for sessions of this [HttpServer]. + * * The default timeout is 20 minutes. */ set sessionTimeout(int timeout); /** - * Returns an [HttpConnectionsInfo] object summarizing the number of + * A [HttpConnectionsInfo] object summarizing the number of * current connections handled by the server. */ HttpConnectionsInfo connectionsInfo(); @@ -345,8 +347,9 @@ class HttpConnectionsInfo { int idle = 0; /** - * Number of connections which are preparing to close. Note: These - * connections are also part of the [:active:] count as they might + * Number of connections which are preparing to close. + * + * Note: These connections are also part of the [active] count as they might * still be sending data to the client before finally closing. */ int closing = 0; @@ -357,9 +360,9 @@ class HttpConnectionsInfo { * * In some situations, headers are immutable: * - * * HttpRequest and HttpClientResponse always have immutable headers. + * * [HttpRequest] and [HttpClientResponse] always have immutable headers. * - * * HttpResponse and HttpClientRequest have immutable headers + * * [HttpResponse] and [HttpClientRequest] have immutable headers * from the moment the body is written to. * * In these situations, the mutating methods throw exceptions. @@ -376,7 +379,7 @@ class HttpConnectionsInfo { * * print(request.headers.value(HttpHeaders.userAgentHeader)); * - * An HttpHeaders object holds a list of values for each name + * An `HttpHeaders` object holds a list of values for each name * as the standard allows. In most cases a name holds only a single value, * The most common mode of operation is to use `set()` for setting a value, * and `value()` for retrieving a value. @@ -534,6 +537,7 @@ abstract class HttpHeaders { @Deprecated("Use setCookieHeader instead") static const SET_COOKIE = setCookieHeader; + // TODO(39783): Document this. static const generalHeaders = const [ cacheControlHeader, connectionHeader, @@ -606,71 +610,71 @@ abstract class HttpHeaders { static const REQUEST_HEADERS = requestHeaders; /** - * Gets and sets the date. The value of this property will - * reflect the 'date' header. + * The date specified by the [dateHeader] header, if any. */ - DateTime date; + DateTime? date; /** - * Gets and sets the expiry date. The value of this property will - * reflect the 'expires' header. + * The date and time specified by the [expiresHeader] header, if any. */ - DateTime expires; + DateTime? expires; /** - * Gets and sets the "if-modified-since" date. The value of this property will - * reflect the "if-modified-since" header. + * The date and time specified by the [ifModifiedSinceHeader] header, if any. */ - DateTime ifModifiedSince; + DateTime? ifModifiedSince; /** - * Gets and sets the host part of the 'host' header for the - * connection. + * The value of the [hostHeader] header, if any. */ - String host; + String? host; /** - * Gets and sets the port part of the 'host' header for the - * connection. + * The value of the port part of the [hostHeader] header, if any. */ - int port; + int? port; /** - * Gets and sets the content type. Note that the content type in the - * header will only be updated if this field is set - * directly. Mutating the returned current value will have no - * effect. + * The [ContentType] of the [contentTypeHeader] header, if any. */ - ContentType contentType; + ContentType? contentType; /** - * Gets and sets the content length header value. + * The value of the [contentLengthHeader] header, if any. + * + * The value is negative if there is no content length set. */ - int contentLength; + int contentLength = -1; /** - * Gets and sets the persistent connection header value. + * Whether the connection is persistent (keep-alive). */ - bool persistentConnection; + late bool persistentConnection; /** - * Gets and sets the chunked transfer encoding header value. + * Whether the connection uses chunked transfer encoding. + * + * Reflects and modifies the value of the [transferEncodingHeader] header. */ - bool chunkedTransferEncoding; + late bool chunkedTransferEncoding; /** - * Returns the list of values for the header named [name]. If there - * is no header with the provided name, [:null:] will be returned. + * The values for the header named [name]. + * + * Returns null if there is no header with the provided name, + * otherwise returns a new list containing the current values. + * Not that modifying the list does not change the header. */ - List operator [](String name); + List? operator [](String name); /** - * Convenience method for the value for a single valued header. If - * there is no header with the provided name, [:null:] will be - * returned. If the header has more than one value an exception is - * thrown. + * Convenience method for the value for a single valued header. + * + * The value must not have more than one value. + * + * Returns `null` if there is no header with the provided name. */ - String value(String name); + String? value(String name); /** * Adds a header value. @@ -705,17 +709,24 @@ abstract class HttpHeaders { {@Since("2.8") bool preserveHeaderCase = false}); /** - * Removes a specific value for a header name. Some headers have - * system supplied values and for these the system supplied values - * will still be added to the collection of values for the header. + * Removes a specific value for a header name. + * + * Some headers have system supplied values which cannot be removed. + * For all other headers and values, the [value] is converted to a string + * in the same way as for [add], then that string value is removed from the + * current values of [name]. + * If there are no remaining values for [name], the header is no longer + * considered present. */ void remove(String name, Object value); /** - * Removes all values for the specified header name. Some headers - * have system supplied values and for these the system supplied - * values will still be added to the collection of values for the - * header. + * Removes all values for the specified header name. + * + * Some headers have system supplied values which cannot be removed. + * All other values for [name] are removed. + * If there are no remaining values for [name], the header is no longer + * considered present. */ void removeAll(String name); @@ -731,25 +742,30 @@ abstract class HttpHeaders { void forEach(void action(String name, List values)); /** - * Disables folding for the header named [name] when sending the HTTP - * header. By default, multiple header values are folded into a - * single header line by separating the values with commas. The - * 'set-cookie' header has folding disabled by default. + * Disables folding for the header named [name] when sending the HTTP header. + * + * By default, multiple header values are folded into a + * single header line by separating the values with commas. + * + * The 'set-cookie' header has folding disabled by default. */ void noFolding(String name); /** - * Remove all headers. Some headers have system supplied values and - * for these the system supplied values will still be added to the - * collection of values for the header. + * Removes all headers. + * + * Some headers have system supplied values which cannot be removed. + * All other header values are removed, and header names with not + * remaining values are no longer considered present. */ void clear(); } /** * Representation of a header value in the form: - * - * [:value; parameter1=value1; parameter2=value2:] + * ```dart + * value; parameter1=value1; parameter2=value2 + * ``` * * [HeaderValue] can be used to conveniently build and parse header * values on this form. @@ -759,7 +775,7 @@ abstract class HttpHeaders { * token characters and backslash sequences can be used to represent the double * quote and backslash characters themselves. * - * To build an [:accepts:] header with the value + * To build an "accepts" header with the value * * text/plain; q=0.3, text/html * @@ -770,7 +786,7 @@ abstract class HttpHeaders { * request.headers.add(HttpHeaders.acceptHeader, v); * request.headers.add(HttpHeaders.acceptHeader, "text/html"); * - * To parse the header values use the [:parse:] static method. + * To parse the header values use the [parse] static method. * * HttpRequest request = ...; * List values = request.headers[HttpHeaders.acceptHeader]; @@ -786,7 +802,7 @@ abstract class HeaderValue { * Creates a new header value object setting the value and parameters. */ factory HeaderValue( - [String value = "", Map parameters = const {}]) { + [String value = "", Map parameters = const {}]) { return new _HeaderValue(value, parameters); } @@ -795,9 +811,9 @@ abstract class HeaderValue { * string with both value and optional parameters. */ static HeaderValue parse(String value, - {String parameterSeparator: ";", - String valueSeparator: null, - bool preserveBackslash: false}) { + {String parameterSeparator = ";", + String? valueSeparator, + bool preserveBackslash = false}) { return _HeaderValue.parse(value, parameterSeparator: parameterSeparator, valueSeparator: valueSeparator, @@ -805,52 +821,57 @@ abstract class HeaderValue { } /** - * Gets the header value. + * The value of the header. */ String get value; /** - * Gets the map of parameters. + * A map of parameters. * - * This map cannot be modified. Invoking any operation which would - * modify the map will throw [UnsupportedError]. + * This map cannot be modified. */ - Map get parameters; + Map get parameters; /** * Returns the formatted string representation in the form: - * - * value; parameter1=value1; parameter2=value2 + * ``` + * value; parameter1=value1; parameter2=value2 + * ``` */ String toString(); } abstract class HttpSession implements Map { /** - * Gets the id for the current session. + * The id of the current session. */ String get id; /** - * Destroys the session. This will terminate the session and any further + * Destroys the session. + * + * This terminates the session and any further * connections with this id will be given a new id and session. */ void destroy(); /** * Sets a callback that will be called when the session is timed out. + * + * Calling this again will overwrite the previous value. */ void set onTimeout(void callback()); /** - * Is true if the session has not been sent to the client yet. + * Whether the session has not yet been sent to the client. */ bool get isNew; } /** - * Representation of a content type. An instance of [ContentType] is - * immutable. + * A MIME/IANA media type used as the value of the [contentTypeHeader] header. + * + * A [ContentType] is immutable. */ abstract class ContentType implements HeaderValue { /** @@ -899,7 +920,7 @@ abstract class ContentType implements HeaderValue { * or in `parameters`, will have its value converted to lower-case. */ factory ContentType(String primaryType, String subType, - {String charset, Map parameters = const {}}) { + {String? charset, Map parameters = const {}}) { return new _ContentType(primaryType, subType, charset, parameters); } @@ -911,32 +932,47 @@ abstract class ContentType implements HeaderValue { * * text/html; charset=utf-8 * - * will create a content type object with primary type [:text:], sub - * type [:html:] and parameter [:charset:] with value [:utf-8:]. + * will create a content type object with primary type "text", + * subtype "html" and parameter "charset" with value "utf-8". + * There may be more parameters supplied, but they are not recognized + * by this class. */ static ContentType parse(String value) { return _ContentType.parse(value); } /** - * Gets the mime-type, without any parameters. + * Gets the MIME type and subtype, without any parameters. + * + * For the full content type `text/html;charset=utf-8`, + * the [mimeType] value is the string `text/html`. */ String get mimeType; /** * Gets the primary type. + * + * For the full content type `text/html;charset=utf-8`, + * the [primaryType] value is the string `text`. */ String get primaryType; /** - * Gets the sub type. + * Gets the subtype. + * + * For the full content type `text/html;charset=utf-8`, + * the [subType] value is the string `html`. + * May be the empty string. */ String get subType; /** - * Gets the character set. + * Gets the character set, if any. + * + * For the full content type `text/html;charset=utf-8`, + * the [charset] value is the string `utf-8`. */ - String get charset; + String? get charset; } /** @@ -956,7 +992,7 @@ abstract class Cookie { * `(`, `)`, `<`, `>`, `@`, `,`, `;`, `:`, `\`, `"`, `/`, `[`, `]`, `?`, `=`, * `{`, and `}`. */ - String name; + late String name; /** * The value of the cookie. @@ -969,39 +1005,39 @@ abstract class Cookie { * Cookie values may be wrapped in a single pair of double quotes * (U+0022, `"`). */ - String value; + late String value; /** * The time at which the cookie expires. */ - DateTime expires; + DateTime? expires; /** * The number of seconds until the cookie expires. A zero or negative value * means the cookie has expired. */ - int maxAge; + int? maxAge; /** - * The domain the cookie applies to. + * The domain that the cookie applies to. */ - String domain; + String? domain; /** - * The path within the [domain] the cookie applies to. + * The path within the [domain] that the cookie applies to. */ - String path; + String? path; /** * Whether to only send this cookie on secure connections. */ - bool secure; + bool secure = false; /** * Whether the cookie is only sent in the HTTP request and is not made * available to client side scripts. */ - bool httpOnly; + bool httpOnly = false; /** * Creates a new cookie setting the name and value. @@ -1123,7 +1159,7 @@ abstract class HttpRequest implements Stream { HttpHeaders get headers; /** - * The cookies in the request, from the Cookie headers. + * The cookies in the request, from the "Cookie" headers. */ List get cookies; @@ -1139,14 +1175,13 @@ abstract class HttpRequest implements Stream { * or if the server does not request a client certificate, or if the client * does not provide one. */ - X509Certificate get certificate; + X509Certificate? get certificate; /** * The session for the given request. * - * If the session is - * being initialized by this call, [:isNew:] is true for the returned - * session. + * If the session is being initialized by this call, + * [HttpSession.isNew] is true for the returned session. * See [HttpServer.sessionTimeout] on how to change default timeout. */ HttpSession get session; @@ -1160,9 +1195,9 @@ abstract class HttpRequest implements Stream { /** * Information about the client connection. * - * Returns [:null:] if the socket is not available. + * Returns `null` if the socket is not available. */ - HttpConnectionInfo get connectionInfo; + HttpConnectionInfo? get connectionInfo; /** * The [HttpResponse] object, used for sending back the response to the @@ -1231,10 +1266,12 @@ abstract class HttpResponse implements IOSink { * the response is not known in advance set the content length to * -1, which is also the default if not set. */ - int contentLength; + int contentLength = -1; /** - * Gets and sets the status code. Any integer value is accepted. For + * The status code of the response. + * + * Any integer value is accepted. For * the official HTTP status codes use the fields from * [HttpStatus]. If no status code is explicitly set the default * value [HttpStatus.ok] is used. @@ -1243,24 +1280,25 @@ abstract class HttpResponse implements IOSink { * to. Setting the status code after writing to the response body or * closing the response will throw a `StateError`. */ - int statusCode; + int statusCode = HttpStatus.ok; /** - * Gets and sets the reason phrase. If no reason phrase is explicitly - * set a default reason phrase is provided. + * The reason phrase for the response. + * + * If no reason phrase is explicitly set, a default reason phrase is provided. * * The reason phrase must be set before the body is written * to. Setting the reason phrase after writing to the response body - * or closing the response will throw a `StateError`. + * or closing the response will throw a [StateError]. */ - String reasonPhrase; + late String reasonPhrase; /** * Gets and sets the persistent connection state. The initial value * of this property is the persistent connection state from the * request. */ - bool persistentConnection; + late bool persistentConnection; /** * Set and get the [deadline] for the response. The deadline is timed from the @@ -1272,7 +1310,7 @@ abstract class HttpResponse implements IOSink { * * The [deadline] is `null` by default. */ - Duration deadline; + Duration? deadline; /** * Gets or sets if the [HttpResponse] should buffer output. @@ -1282,7 +1320,7 @@ abstract class HttpResponse implements IOSink { * __Note__: Disabling buffering of the output can result in very poor * performance, when writing many small chunks. */ - bool bufferOutput; + bool bufferOutput = true; /** * Returns the response headers. @@ -1310,7 +1348,7 @@ abstract class HttpResponse implements IOSink { * This method will also call `close`, and the returned future is * the future returned by `close`. */ - Future redirect(Uri location, {int status: HttpStatus.movedTemporarily}); + Future redirect(Uri location, {int status = HttpStatus.movedTemporarily}); /** * Detaches the underlying socket from the HTTP server. When the @@ -1324,13 +1362,13 @@ abstract class HttpResponse implements IOSink { * to the socket before it's detached. If `false`, the socket is detached * immediately, without any data written to the socket. Default is `true`. */ - Future detachSocket({bool writeHeaders: true}); + Future detachSocket({bool writeHeaders = true}); /** - * Gets information about the client connection. Returns [:null:] if the + * Gets information about the client connection. Returns `null` if the * socket is not available. */ - HttpConnectionInfo get connectionInfo; + HttpConnectionInfo? get connectionInfo; } /** @@ -1416,7 +1454,7 @@ abstract class HttpResponse implements IOSink { * By default the HttpClient uses the proxy configuration available * from the environment, see [findProxyFromEnvironment]. To turn off * the use of proxies set the [findProxy] property to - * [:null:]. + * `null`. * * HttpClient client = new HttpClient(); * client.findProxy = null; @@ -1435,7 +1473,8 @@ abstract class HttpClient { /// /// Default is `false`. static set enableTimelineLogging(bool value) { - _enableTimelineLogging = value ?? false; + _enableTimelineLogging = + valueOfNonNullableParamWithDefault(value, false); } /// Current state of HTTP request logging from all [HttpClient]s to the @@ -1450,7 +1489,7 @@ abstract class HttpClient { /// connections. /// /// The default value is 15 seconds. - Duration idleTimeout; + Duration idleTimeout = const Duration(seconds: 15); /// Gets and sets the connection timeout. /// @@ -1460,7 +1499,7 @@ abstract class HttpClient { /// /// When this is `null`, the OS default timeout is used. The default is /// `null`. - Duration connectionTimeout; + Duration? connectionTimeout; /** * Gets and sets the maximum number of live connections, to a single host. @@ -1472,7 +1511,7 @@ abstract class HttpClient { * * Default is `null`. */ - int maxConnectionsPerHost; + int? maxConnectionsPerHost; /** * Gets and sets whether the body of a response will be automatically @@ -1500,7 +1539,7 @@ abstract class HttpClient { * * Default is `true`. */ - bool autoUncompress; + bool autoUncompress = true; /// Gets and sets the default value of the `User-Agent` header for all requests /// generated by this [HttpClient]. @@ -1509,10 +1548,10 @@ abstract class HttpClient { /// /// If the userAgent is set to `null`, no default `User-Agent` header will be /// added to each request. - String userAgent; + String? userAgent; - factory HttpClient({SecurityContext context}) { - HttpOverrides overrides = HttpOverrides.current; + factory HttpClient({SecurityContext? context}) { + HttpOverrides? overrides = HttpOverrides.current; if (overrides == null) { return new _HttpClient(context); } @@ -1679,12 +1718,12 @@ abstract class HttpClient { * * The function returns a [Future] which should complete when the * authentication has been resolved. If credentials cannot be - * provided the [Future] should complete with [:false:]. If + * provided the [Future] should complete with `false`. If * credentials are available the function should add these using * [addCredentials] before completing the [Future] with the value - * [:true:]. + * `true`. * - * If the [Future] completes with [:true:] the request will be retried + * If the [Future] completes with `true` the request will be retried * using the updated credentials, however, the retried request will not * carry the original request payload. Otherwise response processing will * continue normally. @@ -1695,7 +1734,7 @@ abstract class HttpClient { * of a failed request, or issues due to missing request payload on retried * request. */ - set authenticate(Future f(Uri url, String scheme, String realm)); + void set authenticate(Future f(Uri url, String scheme, String realm)?); /** * Add credentials to be used for authorizing HTTP requests. @@ -1716,7 +1755,7 @@ abstract class HttpClient { * * "PROXY host:port" * - * for using the proxy server [:host:] on port [:port:]. + * for using the proxy server `host` on port `port`. * * A configuration can contain several configuration elements * separated by semicolons, e.g. @@ -1727,7 +1766,7 @@ abstract class HttpClient { * be used to implement proxy server resolving based on environment * variables. */ - set findProxy(String f(Uri url)); + void set findProxy(String f(Uri url)?); /** * Function for resolving the proxy server to be used for a HTTP @@ -1781,8 +1820,8 @@ abstract class HttpClient { * to set credentials for proxies which require authentication. */ static String findProxyFromEnvironment(Uri url, - {Map environment}) { - HttpOverrides overrides = HttpOverrides.current; + {Map? environment}) { + HttpOverrides? overrides = HttpOverrides.current; if (overrides == null) { return _HttpClient._findProxyFromEnvironment(url, environment); } @@ -1797,17 +1836,17 @@ abstract class HttpClient { * * The function returns a [Future] which should complete when the * authentication has been resolved. If credentials cannot be - * provided the [Future] should complete with [:false:]. If + * provided the [Future] should complete with `false`. If * credentials are available the function should add these using * [addProxyCredentials] before completing the [Future] with the value - * [:true:]. + * `true`. * - * If the [Future] completes with [:true:] the request will be retried + * If the [Future] completes with `true` the request will be retried * using the updated credentials. Otherwise response processing will * continue normally. */ - set authenticateProxy( - Future f(String host, int port, String scheme, String realm)); + void set authenticateProxy( + Future f(String host, int port, String scheme, String realm)?); /** * Add credentials to be used for authorizing HTTP proxies. @@ -1824,8 +1863,8 @@ abstract class HttpClient { * server returns a server certificate that cannot be authenticated, the * callback is called asynchronously with the [X509Certificate] object and * the server's hostname and port. If the value of [badCertificateCallback] - * is [:null:], the bad certificate is rejected, as if the callback - * returned [:false:] + * is `null`, the bad certificate is rejected, as if the callback + * returned `false` * * If the callback returns true, the secure connection is accepted and the * [:Future:] that was returned from the call making the @@ -1837,8 +1876,8 @@ abstract class HttpClient { * the request is made, even if the value of badCertificateCallback * has changed since then. */ - set badCertificateCallback( - bool callback(X509Certificate cert, String host, int port)); + void set badCertificateCallback( + bool callback(X509Certificate cert, String host, int port)?); /// Shuts down the HTTP client. /// @@ -1848,7 +1887,7 @@ abstract class HttpClient { /// closed connections will receive an error event to indicate that the client /// was shut down. In both cases trying to establish a new connection after /// calling [close] will throw an exception. - void close({bool force: false}); + void close({bool force = false}); } /** @@ -1883,23 +1922,25 @@ abstract class HttpClient { */ abstract class HttpClientRequest implements IOSink { /** - * Gets and sets the requested persistent connection state. + * The requested persistent connection state. * - * The default value is [:true:]. + * The default value is `true`. */ - bool persistentConnection; + bool persistentConnection = true; /** - * Set this property to [:true:] if this request should - * automatically follow redirects. The default is [:true:]. + * Whether to follow redirects automatically. + * + * Set this property to `false` if this request should not + * automatically follow redirects. The default is `true`. * * Automatic redirect will only happen for "GET" and "HEAD" requests - * and only for the status codes [:HttpStatus.movedPermanently:] - * (301), [:HttpStatus.found:] (302), - * [:HttpStatus.movedTemporarily:] (302, alias for - * [:HttpStatus.found:]), [:HttpStatus.seeOther:] (303) and - * [:HttpStatus.temporaryRedirect:] (307). For - * [:HttpStatus.seeOther:] (303) automatic redirect will also happen + * and only for the status codes [HttpStatus.movedPermanently] + * (301), [HttpStatus.found] (302), + * [HttpStatus.movedTemporarily] (302, alias for + * [HttpStatus.found]), [HttpStatus.seeOther] (303) and + * [HttpStatus.temporaryRedirect] (307). For + * [HttpStatus.seeOther] (303) automatic redirect will also happen * for "POST" requests with the method changed to "GET" when * following the redirect. * @@ -1907,7 +1948,7 @@ abstract class HttpClientRequest implements IOSink { * request(s). However, any body send with the request will not be * part of the redirection request(s). */ - bool followRedirects; + bool followRedirects = true; /** * Set this property to the maximum number of redirects to follow @@ -1916,7 +1957,7 @@ abstract class HttpClientRequest implements IOSink { * * The default value is 5. */ - int maxRedirects; + int maxRedirects = 5; /** * The method of the request. @@ -1932,7 +1973,7 @@ abstract class HttpClientRequest implements IOSink { /// /// If the size of the request is not known in advance set content length to /// -1, which is also the default. - int contentLength; + int contentLength = -1; /** * Gets or sets if the [HttpClientRequest] should buffer output. @@ -1942,7 +1983,7 @@ abstract class HttpClientRequest implements IOSink { * __Note__: Disabling buffering of the output can result in very poor * performance, when writing many small chunks. */ - bool bufferOutput; + bool bufferOutput = true; /** * Returns the client request headers. @@ -1972,8 +2013,8 @@ abstract class HttpClientRequest implements IOSink { /// Gets information about the client connection. /// - /// Returns [:null:] if the socket is not available. - HttpConnectionInfo get connectionInfo; + /// Returns `null` if the socket is not available. + HttpConnectionInfo? get connectionInfo; } /** @@ -2063,14 +2104,14 @@ abstract class HttpClientResponse implements Stream> { * request. However, any body sent with the request will not be * part of the redirection request. * - * If [followLoops] is set to [:true:], redirect will follow the redirect, - * even if the URL was already visited. The default value is [:false:]. + * If [followLoops] is set to `true`, redirect will follow the redirect, + * even if the URL was already visited. The default value is `false`. * * The method will ignore [HttpClientRequest.maxRedirects] * and will always perform the redirect. */ Future redirect( - [String method, Uri url, bool followLoops]); + [String? method, Uri? url, bool? followLoops]); /** * Returns the client response headers. @@ -2098,13 +2139,13 @@ abstract class HttpClientResponse implements Stream> { * Returns the certificate of the HTTPS server providing the response. * Returns null if the connection is not a secure TLS or SSL connection. */ - X509Certificate get certificate; + X509Certificate? get certificate; /** - * Gets information about the client connection. Returns [:null:] if the socket + * Gets information about the client connection. Returns `null` if the socket * is not available. */ - HttpConnectionInfo get connectionInfo; + HttpConnectionInfo? get connectionInfo; } /// Enum that specifies the compression state of the byte stream of an @@ -2215,12 +2256,13 @@ abstract class DetachedSocket { class HttpException implements IOException { final String message; - final Uri uri; + final Uri? uri; const HttpException(this.message, {this.uri}); String toString() { var b = new StringBuffer()..write('HttpException: ')..write(message); + var uri = this.uri; if (uri != null) { b.write(', uri = $uri'); } diff --git a/sdk/lib/_http/http_date.dart b/sdk/lib/_http/http_date.dart index ab24b876be7..5fd2f345d8d 100644 --- a/sdk/lib/_http/http_date.dart +++ b/sdk/lib/_http/http_date.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart._http; /** @@ -123,7 +121,6 @@ class HttpDate { int index = 0; String tmp; - int format; void expect(String s) { if (date.length - index < s.length) { @@ -147,21 +144,18 @@ class HttpDate { index = pos + 1; weekday = wkdays.indexOf(tmp); if (weekday != -1) { - format = formatAsctime; - return weekday; + return formatAsctime; } } else { tmp = date.substring(index, pos); index = pos + 1; weekday = wkdays.indexOf(tmp); if (weekday != -1) { - format = formatRfc1123; - return weekday; + return formatRfc1123; } weekday = weekdays.indexOf(tmp); if (weekday != -1) { - format = formatRfc850; - return weekday; + return formatRfc850; } } throw new HttpException("Invalid HTTP date $date"); @@ -200,10 +194,10 @@ class HttpDate { } } - int weekday = expectWeekday(); - int day; - int month; + int format = expectWeekday(); int year; + int month; + int day; int hours; int minutes; int seconds; @@ -248,7 +242,7 @@ class HttpDate { int position = 0; - void error() { + Never error() { throw new HttpException("Invalid cookie date $date"); } @@ -302,10 +296,10 @@ class HttpDate { while (!isEnd() && isDelimiter(date[position])) position++; } - String timeStr; - String dayOfMonthStr; - String monthStr; - String yearStr; + String? timeStr; + String? dayOfMonthStr; + String? monthStr; + String? yearStr; for (var token in tokens) { if (token.length < 1) continue; diff --git a/sdk/lib/_http/http_headers.dart b/sdk/lib/_http/http_headers.dart index ad887b92c8c..ae8b4829bdb 100644 --- a/sdk/lib/_http/http_headers.dart +++ b/sdk/lib/_http/http_headers.dart @@ -2,30 +2,28 @@ // 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.6 - part of dart._http; class _HttpHeaders implements HttpHeaders { final Map> _headers; // The original header names keyed by the lowercase header names. - Map _originalHeaderNames; + Map? _originalHeaderNames; final String protocolVersion; bool _mutable = true; // Are the headers currently mutable? - List _noFoldingHeaders; + List? _noFoldingHeaders; int _contentLength = -1; bool _persistentConnection = true; bool _chunkedTransferEncoding = false; - String _host; - int _port; + String? _host; + int? _port; final int _defaultPortForScheme; _HttpHeaders(this.protocolVersion, - {int defaultPortForScheme: HttpClient.defaultHttpPort, - _HttpHeaders initialHeaders}) + {int defaultPortForScheme = HttpClient.defaultHttpPort, + _HttpHeaders? initialHeaders}) : _headers = new HashMap>(), _defaultPortForScheme = defaultPortForScheme { if (initialHeaders != null) { @@ -42,12 +40,13 @@ class _HttpHeaders implements HttpHeaders { } } - List operator [](String name) => _headers[_validateField(name)]; + List? operator [](String name) => _headers[_validateField(name)]; - String value(String name) { + String? value(String name) { name = _validateField(name); - List values = _headers[name]; + List? values = _headers[name]; if (values == null) return null; + assert(values.isNotEmpty); if (values.length > 1) { throw new HttpException("More than one value for header $name"); } @@ -86,8 +85,6 @@ class _HttpHeaders implements HttpHeaders { } if (preserveHeaderCase && name != lowercaseName) { (_originalHeaderNames ??= {})[lowercaseName] = name; - } else { - _originalHeaderNames?.remove(lowercaseName); } _addAll(lowercaseName, value); } @@ -96,12 +93,9 @@ class _HttpHeaders implements HttpHeaders { _checkMutable(); name = _validateField(name); value = _validateValue(value); - List values = _headers[name]; + List? values = _headers[name]; if (values != null) { - int index = values.indexOf(value); - if (index != -1) { - values.removeRange(index, index + 1); - } + values.remove(_valueToString(value)); if (values.length == 0) { _headers.remove(name); _originalHeaderNames?.remove(name); @@ -128,8 +122,7 @@ class _HttpHeaders implements HttpHeaders { void noFolding(String name) { name = _validateField(name); - if (_noFoldingHeaders == null) _noFoldingHeaders = new List(); - _noFoldingHeaders.add(name); + (_noFoldingHeaders ??= []).add(name); } bool get persistentConnection => _persistentConnection; @@ -142,7 +135,7 @@ class _HttpHeaders implements HttpHeaders { if (protocolVersion == "1.1") { remove(HttpHeaders.connectionHeader, "close"); } else { - if (_contentLength == -1) { + if (_contentLength < 0) { throw new HttpException( "Trying to set 'Connection: Keep-Alive' on HTTP 1.0 headers with " "no ContentLength"); @@ -176,7 +169,7 @@ class _HttpHeaders implements HttpHeaders { if (chunkedTransferEncoding) chunkedTransferEncoding = false; _set(HttpHeaders.contentLengthHeader, contentLength.toString()); } else { - removeAll(HttpHeaders.contentLengthHeader); + _headers.remove(HttpHeaders.contentLengthHeader); if (protocolVersion == "1.1") { chunkedTransferEncoding = true; } @@ -193,8 +186,8 @@ class _HttpHeaders implements HttpHeaders { } if (chunkedTransferEncoding == _chunkedTransferEncoding) return; if (chunkedTransferEncoding) { - List values = _headers[HttpHeaders.transferEncodingHeader]; - if ((values == null || !values.contains("chunked"))) { + List? values = _headers[HttpHeaders.transferEncodingHeader]; + if (values == null || !values.contains("chunked")) { // Headers does not specify chunked encoding - add it if set. _addValue(HttpHeaders.transferEncodingHeader, "chunked"); } @@ -206,25 +199,26 @@ class _HttpHeaders implements HttpHeaders { _chunkedTransferEncoding = chunkedTransferEncoding; } - String get host => _host; + String? get host => _host; - void set host(String host) { + void set host(String? host) { _checkMutable(); _host = host; _updateHostHeader(); } - int get port => _port; + int? get port => _port; - void set port(int port) { + void set port(int? port) { _checkMutable(); _port = port; _updateHostHeader(); } - DateTime get ifModifiedSince { - List values = _headers[HttpHeaders.ifModifiedSinceHeader]; + DateTime? get ifModifiedSince { + List? values = _headers[HttpHeaders.ifModifiedSinceHeader]; if (values != null) { + assert(values.isNotEmpty); try { return HttpDate.parse(values[0]); } on Exception { @@ -234,16 +228,21 @@ class _HttpHeaders implements HttpHeaders { return null; } - void set ifModifiedSince(DateTime ifModifiedSince) { + void set ifModifiedSince(DateTime? ifModifiedSince) { _checkMutable(); - // Format "ifModifiedSince" header with date in Greenwich Mean Time (GMT). - String formatted = HttpDate.format(ifModifiedSince.toUtc()); - _set(HttpHeaders.ifModifiedSinceHeader, formatted); + if (ifModifiedSince == null) { + _headers.remove(HttpHeaders.ifModifiedSinceHeader); + } else { + // Format "ifModifiedSince" header with date in Greenwich Mean Time (GMT). + String formatted = HttpDate.format(ifModifiedSince.toUtc()); + _set(HttpHeaders.ifModifiedSinceHeader, formatted); + } } - DateTime get date { - List values = _headers[HttpHeaders.dateHeader]; + DateTime? get date { + List? values = _headers[HttpHeaders.dateHeader]; if (values != null) { + assert(values.isNotEmpty); try { return HttpDate.parse(values[0]); } on Exception { @@ -253,16 +252,21 @@ class _HttpHeaders implements HttpHeaders { return null; } - void set date(DateTime date) { + void set date(DateTime? date) { _checkMutable(); - // Format "DateTime" header with date in Greenwich Mean Time (GMT). - String formatted = HttpDate.format(date.toUtc()); - _set("date", formatted); + if (date == null) { + _headers.remove(HttpHeaders.dateHeader); + } else { + // Format "DateTime" header with date in Greenwich Mean Time (GMT). + String formatted = HttpDate.format(date.toUtc()); + _set(HttpHeaders.dateHeader, formatted); + } } - DateTime get expires { - List values = _headers[HttpHeaders.expiresHeader]; + DateTime? get expires { + List? values = _headers[HttpHeaders.expiresHeader]; if (values != null) { + assert(values.isNotEmpty); try { return HttpDate.parse(values[0]); } on Exception { @@ -272,14 +276,18 @@ class _HttpHeaders implements HttpHeaders { return null; } - void set expires(DateTime expires) { + void set expires(DateTime? expires) { _checkMutable(); - // Format "Expires" header with date in Greenwich Mean Time (GMT). - String formatted = HttpDate.format(expires.toUtc()); - _set(HttpHeaders.expiresHeader, formatted); + if (expires == null) { + _headers.remove(HttpHeaders.expiresHeader); + } else { + // Format "Expires" header with date in Greenwich Mean Time (GMT). + String formatted = HttpDate.format(expires.toUtc()); + _set(HttpHeaders.expiresHeader, formatted); + } } - ContentType get contentType { + ContentType? get contentType { var values = _headers[HttpHeaders.contentTypeHeader]; if (values != null) { return ContentType.parse(values[0]); @@ -288,9 +296,13 @@ class _HttpHeaders implements HttpHeaders { } } - void set contentType(ContentType contentType) { + void set contentType(ContentType? contentType) { _checkMutable(); - _set(HttpHeaders.contentTypeHeader, contentType.toString()); + if (contentType == null) { + _headers.remove(HttpHeaders.contentTypeHeader); + } else { + _set(HttpHeaders.contentTypeHeader, contentType.toString()); + } } void clear() { @@ -447,42 +459,41 @@ class _HttpHeaders implements HttpHeaders { } void _addValue(String name, Object value) { - List values = _headers[name]; - if (values == null) { - values = new List(); - _headers[name] = values; - } + List values = (_headers[name] ??= []); + values.add(_valueToString(value)); + } + + String _valueToString(Object value) { if (value is DateTime) { - values.add(HttpDate.format(value)); + return HttpDate.format(value); } else if (value is String) { - values.add(value); + return value; // TODO(39784): no _validateValue? } else { - values.add(_validateValue(value.toString())); + return _validateValue(value.toString()) as String; } } void _set(String name, String value) { assert(name == _validateField(name)); - List values = new List(); - _headers[name] = values; - values.add(value); + _headers[name] = [value]; } - _checkMutable() { + void _checkMutable() { if (!_mutable) throw new HttpException("HTTP headers are not mutable"); } - _updateHostHeader() { - bool defaultPort = _port == null || _port == _defaultPortForScheme; - _set("host", defaultPort ? host : "$host:$_port"); + void _updateHostHeader() { + var host = _host; + if (host != null) { + bool defaultPort = _port == null || _port == _defaultPortForScheme; + _set("host", defaultPort ? host : "$host:$_port"); + } } - _foldHeader(String name) { - if (name == HttpHeaders.setCookieHeader || - (_noFoldingHeaders != null && _noFoldingHeaders.indexOf(name) != -1)) { - return false; - } - return true; + bool _foldHeader(String name) { + if (name == HttpHeaders.setCookieHeader) return false; + var noFoldingHeaders = _noFoldingHeaders; + return noFoldingHeaders == null || !noFoldingHeaders.contains(name); } void _finalize() { @@ -540,7 +551,7 @@ class _HttpHeaders implements HttpHeaders { List _parseCookies() { // Parse a Cookie header value according to the rules in RFC 6265. - var cookies = new List(); + var cookies = []; void parseCookieString(String s) { int index = 0; @@ -603,7 +614,7 @@ class _HttpHeaders implements HttpHeaders { } } - List values = _headers[HttpHeaders.cookieHeader]; + List? values = _headers[HttpHeaders.cookieHeader]; if (values != null) { values.forEach((headerValue) => parseCookieString(headerValue)); } @@ -632,26 +643,28 @@ class _HttpHeaders implements HttpHeaders { } String _originalHeaderName(String name) { - return (_originalHeaderNames == null ? null : _originalHeaderNames[name]) ?? - name; + // TODO: Update syntax to_originalHeaderNames?[name]. + return _originalHeaderNames?.[name] ?? name; } } class _HeaderValue implements HeaderValue { String _value; - Map _parameters; - Map _unmodifiableParameters; + Map? _parameters; + Map? _unmodifiableParameters; - _HeaderValue([this._value = "", Map parameters = const {}]) { - if (parameters != null && parameters.isNotEmpty) { - _parameters = new HashMap.from(parameters); + _HeaderValue([this._value = "", Map parameters = const {}]) { + // TODO(40614): Remove once non-nullability is sound. + Map? nullableParameters = parameters; + if (nullableParameters != null && nullableParameters.isNotEmpty) { + _parameters = new HashMap.from(nullableParameters); } } static _HeaderValue parse(String value, - {parameterSeparator: ";", - valueSeparator: null, - preserveBackslash: false}) { + {String parameterSeparator = ";", + String? valueSeparator, + bool preserveBackslash = false}) { // Parse the string. var result = new _HeaderValue(); result._parse(value, parameterSeparator, valueSeparator, preserveBackslash); @@ -660,9 +673,10 @@ class _HeaderValue implements HeaderValue { String get value => _value; - Map _ensureParameters() => _parameters ??= {}; + Map _ensureParameters() => + _parameters ??= {}; - Map get parameters => + Map get parameters => _unmodifiableParameters ??= UnmodifiableMapView(_ensureParameters()); static bool _isToken(String token) { @@ -684,8 +698,9 @@ class _HeaderValue implements HeaderValue { String toString() { StringBuffer sb = new StringBuffer(); sb.write(_value); + var parameters = this._parameters; if (parameters != null && parameters.length > 0) { - _parameters.forEach((String name, String value) { + parameters.forEach((String name, String? value) { sb..write("; ")..write(name); if (value != null) { sb.write("="); @@ -712,7 +727,7 @@ class _HeaderValue implements HeaderValue { return sb.toString(); } - void _parse(String s, String parameterSeparator, String valueSeparator, + void _parse(String s, String parameterSeparator, String? valueSeparator, bool preserveBackslash) { int index = 0; @@ -728,10 +743,11 @@ class _HeaderValue implements HeaderValue { String parseValue() { int start = index; while (!done()) { - if (s[index] == " " || - s[index] == "\t" || - s[index] == valueSeparator || - s[index] == parameterSeparator) break; + var char = s[index]; + if (char == " " || + char == "\t" || + char == valueSeparator || + char == parameterSeparator) break; index++; } return s.substring(start, index); @@ -753,17 +769,17 @@ class _HeaderValue implements HeaderValue { } void parseParameters() { - var parameters = new HashMap(); - _parameters = new UnmodifiableMapView(parameters); + var parameters = _ensureParameters(); String parseParameterName() { int start = index; while (!done()) { - if (s[index] == " " || - s[index] == "\t" || - s[index] == "=" || - s[index] == parameterSeparator || - s[index] == valueSeparator) break; + var char = s[index]; + if (char == " " || + char == "\t" || + char == "=" || + char == parameterSeparator || + char == valueSeparator) break; index++; } return s.substring(start, index).toLowerCase(); @@ -775,19 +791,21 @@ class _HeaderValue implements HeaderValue { StringBuffer sb = new StringBuffer(); index++; while (!done()) { - if (s[index] == "\\") { + var char = s[index]; + if (char == "\\") { if (index + 1 == s.length) { throw new HttpException("Failed to parse header value"); } if (preserveBackslash && s[index + 1] != "\"") { - sb.write(s[index]); + sb.write(char); } index++; - } else if (s[index] == "\"") { + } else if (char == "\"") { index++; return sb.toString(); } - sb.write(s[index]); + char = s[index]; + sb.write(char); index++; } throw new HttpException("Failed to parse header value"); @@ -835,27 +853,30 @@ class _ContentType extends _HeaderValue implements ContentType { String _primaryType = ""; String _subType = ""; - _ContentType(String primaryType, String subType, String charset, - Map parameters) + _ContentType(String primaryType, String subType, String? charset, + Map parameters) : _primaryType = primaryType, _subType = subType, super("") { - if (_primaryType == null) _primaryType = ""; - if (_subType == null) _subType = ""; + // TODO(40614): Remove once non-nullability is sound. + String emptyIfNull(String? string) => string ?? ""; + _primaryType = emptyIfNull(_primaryType); + _subType = emptyIfNull(_subType); _value = "$_primaryType/$_subType"; - if (parameters != null) { - _ensureParameters(); - parameters.forEach((String key, String value) { + // TODO(40614): Remove once non-nullability is sound. + Map? nullableParameters = parameters; + if (nullableParameters != null) { + var parameterMap = _ensureParameters(); + nullableParameters.forEach((String key, String? value) { String lowerCaseKey = key.toLowerCase(); if (lowerCaseKey == "charset") { value = value?.toLowerCase(); } - this._parameters[lowerCaseKey] = value; + parameterMap[lowerCaseKey] = value; }); } if (charset != null) { - _ensureParameters(); - this._parameters["charset"] = charset.toLowerCase(); + _ensureParameters()["charset"] = charset.toLowerCase(); } } @@ -867,7 +888,6 @@ class _ContentType extends _HeaderValue implements ContentType { int index = result._value.indexOf("/"); if (index == -1 || index == (result._value.length - 1)) { result._primaryType = result._value.trim().toLowerCase(); - result._subType = ""; } else { result._primaryType = result._value.substring(0, index).trim().toLowerCase(); @@ -882,16 +902,16 @@ class _ContentType extends _HeaderValue implements ContentType { String get subType => _subType; - String get charset => parameters["charset"]; + String? get charset => parameters["charset"]; } class _Cookie implements Cookie { String _name; String _value; - DateTime expires; - int maxAge; - String domain; - String path; + DateTime? expires; + int? maxAge; + String? domain; + String? path; bool httpOnly = false; bool secure = false; @@ -913,7 +933,9 @@ class _Cookie implements Cookie { _value = newValue; } - _Cookie.fromSetCookieValue(String value) { + _Cookie.fromSetCookieValue(String value) + : _name = "", + _value = "" { // Parse the 'set-cookie' header value. _parseSetCookieValue(value); } @@ -999,6 +1021,7 @@ class _Cookie implements Cookie { String toString() { StringBuffer sb = new StringBuffer(); sb..write(_name)..write("=")..write(_value); + var expires = this.expires; if (expires != null) { sb..write("; Expires=")..write(HttpDate.format(expires)); } @@ -1038,7 +1061,7 @@ class _Cookie implements Cookie { ]; if (newName == null) throw new ArgumentError.notNull("name"); for (int i = 0; i < newName.length; i++) { - int codeUnit = newName.codeUnits[i]; + int codeUnit = newName.codeUnitAt(i); if (codeUnit <= 32 || codeUnit >= 127 || separators.indexOf(newName[i]) >= 0) { diff --git a/sdk/lib/_http/http_impl.dart b/sdk/lib/_http/http_impl.dart index b300a6354f9..766b567316f 100644 --- a/sdk/lib/_http/http_impl.dart +++ b/sdk/lib/_http/http_impl.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart._http; int _nextServiceId = 1; @@ -140,12 +138,12 @@ class _HttpIncoming extends Stream { bool upgraded = false; // ClientResponse properties. - int statusCode; - String reasonPhrase; + int? statusCode; + String? reasonPhrase; // Request properties. - String method; - Uri uri; + String? method; + Uri? uri; bool hasSubscriber = false; @@ -157,8 +155,8 @@ class _HttpIncoming extends Stream { _HttpIncoming(this.headers, this._transferLength, this._stream); - StreamSubscription listen(void onData(Uint8List event), - {Function onError, void onDone(), bool cancelOnError}) { + StreamSubscription listen(void onData(Uint8List event)?, + {Function? onError, void onDone()?, bool? cancelOnError}) { hasSubscriber = true; return _stream.handleError((error) { throw new HttpException(error.message, uri: uri); @@ -178,14 +176,11 @@ class _HttpIncoming extends Stream { abstract class _HttpInboundMessageListInt extends Stream> { final _HttpIncoming _incoming; - List _cookies; + List? _cookies; _HttpInboundMessageListInt(this._incoming); - List get cookies { - if (_cookies != null) return _cookies; - return _cookies = headers._parseCookies(); - } + List get cookies => _cookies ??= headers._parseCookies(); _HttpHeaders get headers => _incoming.headers; String get protocolVersion => headers.protocolVersion; @@ -195,14 +190,11 @@ abstract class _HttpInboundMessageListInt extends Stream> { abstract class _HttpInboundMessage extends Stream { final _HttpIncoming _incoming; - List _cookies; + List? _cookies; _HttpInboundMessage(this._incoming); - List get cookies { - if (_cookies != null) return _cookies; - return _cookies = headers._parseCookies(); - } + List get cookies => _cookies ??= headers._parseCookies(); _HttpHeaders get headers => _incoming.headers; String get protocolVersion => headers.protocolVersion; @@ -217,9 +209,9 @@ class _HttpRequest extends _HttpInboundMessage implements HttpRequest { final _HttpConnection _httpConnection; - _HttpSession _session; + _HttpSession? _session; - Uri _requestedUri; + Uri? _requestedUri; _HttpRequest(this.response, _HttpIncoming _incoming, this._httpServer, this._httpConnection) @@ -234,68 +226,62 @@ class _HttpRequest extends _HttpInboundMessage implements HttpRequest { // Map to session if exists. var sessionIds = cookies .where((cookie) => cookie.name.toUpperCase() == _DART_SESSION_ID) - .map((cookie) => cookie.value); + .map((cookie) => cookie.value); for (var sessionId in sessionIds) { - _session = _httpServer._sessionManager.getSession(sessionId); - if (_session != null) { - _session._markSeen(); + var session = _httpServer._sessionManager.getSession(sessionId); + _session = session; + if (session != null) { + session._markSeen(); break; } } } } - StreamSubscription listen(void onData(Uint8List event), - {Function onError, void onDone(), bool cancelOnError}) { + StreamSubscription listen(void onData(Uint8List event)?, + {Function? onError, void onDone()?, bool? cancelOnError}) { return _incoming.listen(onData, onError: onError, onDone: onDone, cancelOnError: cancelOnError); } - Uri get uri => _incoming.uri; + Uri get uri => _incoming.uri!; Uri get requestedUri { - if (_requestedUri == null) { - var proto = headers['x-forwarded-proto']; - var scheme = proto != null - ? proto.first - : _httpConnection._socket is SecureSocket ? "https" : "http"; - var hostList = headers['x-forwarded-host']; - String host; + var requestedUri = _requestedUri; + if (requestedUri != null) return requestedUri; + var proto = headers['x-forwarded-proto']; + var scheme = proto != null + ? proto.first + : _httpConnection._socket is SecureSocket ? "https" : "http"; + var hostList = headers['x-forwarded-host']; + String host; + if (hostList != null) { + host = hostList.first; + } else { + hostList = headers[HttpHeaders.hostHeader]; if (hostList != null) { host = hostList.first; } else { - hostList = headers[HttpHeaders.hostHeader]; - if (hostList != null) { - host = hostList.first; - } else { - host = "${_httpServer.address.host}:${_httpServer.port}"; - } + host = "${_httpServer.address.host}:${_httpServer.port}"; } - _requestedUri = Uri.parse("$scheme://$host$uri"); } - return _requestedUri; + return _requestedUri = Uri.parse("$scheme://$host$uri"); } - String get method => _incoming.method; + String get method => _incoming.method!; HttpSession get session { - if (_session != null) { - if (_session._destroyed) { - // It's destroyed, clear it. - _session = null; - // Create new session object by calling recursive. - return session; - } - // It's already mapped, use it. - return _session; + var session = _session; + if (session != null && !session._destroyed) { + return session; } // Create session, store it in connection, and return. return _session = _httpServer._sessionManager.createSession(); } - HttpConnectionInfo get connectionInfo => _httpConnection.connectionInfo; + HttpConnectionInfo? get connectionInfo => _httpConnection.connectionInfo; - X509Certificate get certificate { + X509Certificate? get certificate { var socket = _httpConnection._socket; if (socket is SecureSocket) return socket.peerCertificate; return null; @@ -334,25 +320,27 @@ class _HttpClientResponse extends _HttpInboundMessageListInt } } - int get statusCode => _incoming.statusCode; - String get reasonPhrase => _incoming.reasonPhrase; + int get statusCode => _incoming.statusCode!; + String get reasonPhrase => _incoming.reasonPhrase!; - X509Certificate get certificate { + X509Certificate? get certificate { var socket = _httpRequest._httpClientConnection._socket; if (socket is SecureSocket) return socket.peerCertificate; return null; } List get cookies { - if (_cookies != null) return _cookies; - _cookies = new List(); - List values = headers[HttpHeaders.setCookieHeader]; + var cookies = _cookies; + if (cookies != null) return cookies; + cookies = []; + List? values = headers[HttpHeaders.setCookieHeader]; if (values != null) { - values.forEach((value) { - _cookies.add(new Cookie.fromSetCookieValue(value)); - }); + for (var value in values) { + cookies.add(new Cookie.fromSetCookieValue(value)); + } } - return _cookies; + _cookies = cookies; + return cookies; } bool get isRedirect { @@ -368,7 +356,7 @@ class _HttpClientResponse extends _HttpInboundMessageListInt } Future redirect( - [String method, Uri url, bool followLoops]) { + [String? method, Uri? url, bool? followLoops]) { if (method == null) { // Set method as defined by RFC 2616 section 10.3.4. if (statusCode == HttpStatus.seeOther && _httpRequest.method == "POST") { @@ -378,7 +366,7 @@ class _HttpClientResponse extends _HttpInboundMessageListInt } } if (url == null) { - String location = headers.value(HttpHeaders.locationHeader); + String? location = headers.value(HttpHeaders.locationHeader); if (location == null) { throw new StateError("Response has no Location header for redirect"); } @@ -397,13 +385,13 @@ class _HttpClientResponse extends _HttpInboundMessageListInt .then((request) { request._responseRedirects ..addAll(this.redirects) - ..add(new _RedirectInfo(statusCode, method, url)); + ..add(new _RedirectInfo(statusCode, method!, url!)); return request.close(); }); } - StreamSubscription listen(void onData(Uint8List event), - {Function onError, void onDone(), bool cancelOnError}) { + StreamSubscription listen(void onData(Uint8List event)?, + {Function? onError, void onDone()?, bool? cancelOnError}) { if (_incoming.upgraded) { // If upgraded, the connection is already 'removed' form the client. // Since listening to upgraded data is 'bogus', simply close and @@ -427,11 +415,11 @@ class _HttpClientResponse extends _HttpInboundMessageListInt return _httpRequest._httpClientConnection.detachSocket(); } - HttpConnectionInfo get connectionInfo => _httpRequest.connectionInfo; + HttpConnectionInfo? get connectionInfo => _httpRequest.connectionInfo; bool get _shouldAuthenticateProxy { // Only try to authenticate if there is a challenge in the response. - List challenge = headers[HttpHeaders.proxyAuthenticateHeader]; + List? challenge = headers[HttpHeaders.proxyAuthenticateHeader]; return statusCode == HttpStatus.proxyAuthenticationRequired && challenge != null && challenge.length == 1; @@ -439,7 +427,7 @@ class _HttpClientResponse extends _HttpInboundMessageListInt bool get _shouldAuthenticate { // Only try to authenticate if there is a challenge in the response. - List challenge = headers[HttpHeaders.wwwAuthenticateHeader]; + List? challenge = headers[HttpHeaders.wwwAuthenticateHeader]; return statusCode == HttpStatus.unauthorized && challenge != null && challenge.length == 1; @@ -458,13 +446,13 @@ class _HttpClientResponse extends _HttpInboundMessageListInt }); } - List authChallenge() { + List? authChallenge() { return proxyAuth ? headers[HttpHeaders.proxyAuthenticateHeader] : headers[HttpHeaders.wwwAuthenticateHeader]; } - _Credentials findCredentials(_AuthenticationScheme scheme) { + _Credentials? findCredentials(_AuthenticationScheme scheme) { return proxyAuth ? _httpClient._findProxyCredentials(_httpRequest._proxy, scheme) : _httpClient._findCredentials(_httpRequest.uri, scheme); @@ -478,64 +466,70 @@ class _HttpClientResponse extends _HttpInboundMessageListInt } } - Future requestAuthentication(_AuthenticationScheme scheme, String realm) { + Future requestAuthentication( + _AuthenticationScheme scheme, String? realm) { if (proxyAuth) { - if (_httpClient._authenticateProxy == null) { + var authenticateProxy = _httpClient._authenticateProxy; + if (authenticateProxy == null) { return new Future.value(false); } var proxy = _httpRequest._proxy; - return _httpClient._authenticateProxy( + return authenticateProxy( proxy.host, proxy.port, scheme.toString(), realm); } else { - if (_httpClient._authenticate == null) { + var authenticate = _httpClient._authenticate; + if (authenticate == null) { return new Future.value(false); } - return _httpClient._authenticate( - _httpRequest.uri, scheme.toString(), realm); + return authenticate(_httpRequest.uri, scheme.toString(), realm); } } - List challenge = authChallenge(); - assert(challenge != null || challenge.length == 1); + List challenge = authChallenge()!; + assert(challenge.length == 1); _HeaderValue header = _HeaderValue.parse(challenge[0], parameterSeparator: ","); _AuthenticationScheme scheme = new _AuthenticationScheme.fromString(header.value); - String realm = header.parameters["realm"]; + String? realm = header.parameters["realm"]; // See if any matching credentials are available. - _Credentials cr = findCredentials(scheme); + var cr = findCredentials(scheme); if (cr != null) { // For basic authentication don't retry already used credentials // as they must have already been added to the request causing // this authenticate response. if (cr.scheme == _AuthenticationScheme.BASIC && !cr.used) { - // Credentials where found, prepare for retrying the request. + // Credentials were found, prepare for retrying the request. return retry(); } // Digest authentication only supports the MD5 algorithm. - if (cr.scheme == _AuthenticationScheme.DIGEST && - (header.parameters["algorithm"] == null || - header.parameters["algorithm"].toLowerCase() == "md5")) { - if (cr.nonce == null || cr.nonce == header.parameters["nonce"]) { - // If the nonce is not set then this is the first authenticate - // response for these credentials. Set up authentication state. - if (cr.nonce == null) { - cr - ..nonce = header.parameters["nonce"] - ..algorithm = "MD5" - ..qop = header.parameters["qop"] - ..nonceCount = 0; + if (cr.scheme == _AuthenticationScheme.DIGEST) { + var algorithm = header.parameters["algorithm"]; + if (algorithm == null || algorithm.toLowerCase() == "md5") { + var nonce = cr.nonce; + if (nonce == null || nonce == header.parameters["nonce"]) { + // If the nonce is not set then this is the first authenticate + // response for these credentials. Set up authentication state. + if (nonce == null) { + cr + ..nonce = header.parameters["nonce"] + ..algorithm = "MD5" + ..qop = header.parameters["qop"] + ..nonceCount = 0; + } + // Credentials were found, prepare for retrying the request. + return retry(); + } else { + var staleHeader = header.parameters["stale"]; + if (staleHeader != null && staleHeader.toLowerCase() == "true") { + // If stale is true retry with new nonce. + cr.nonce = header.parameters["nonce"]; + // Credentials were found, prepare for retrying the request. + return retry(); + } } - // Credentials where found, prepare for retrying the request. - return retry(); - } else if (header.parameters["stale"] != null && - header.parameters["stale"].toLowerCase() == "true") { - // If stale is true retry with new nonce. - cr.nonce = header.parameters["nonce"]; - // Credentials where found, prepare for retrying the request. - return retry(); } } } @@ -585,9 +579,9 @@ class _Uint8ListConversionSink implements Sink> { class _StreamSinkImpl implements StreamSink { final StreamConsumer _target; - final Completer _doneCompleter = new Completer(); - StreamController _controllerInstance; - Completer _controllerCompleter; + final _doneCompleter = new Completer(); + StreamController? _controllerInstance; + Completer? _controllerCompleter; bool _isClosed = false; bool _isBound = false; bool _hasError = false; @@ -601,7 +595,7 @@ class _StreamSinkImpl implements StreamSink { _controller.add(data); } - void addError(error, [StackTrace stackTrace]) { + void addError(Object error, [StackTrace? stackTrace]) { if (_isClosed) { throw StateError("StreamSink is closed"); } @@ -621,9 +615,10 @@ class _StreamSinkImpl implements StreamSink { }); } - if (_controllerInstance == null) return targetAddStream(); - var future = _controllerCompleter.future; - _controllerInstance.close(); + var controller = _controllerInstance; + if (controller == null) return targetAddStream(); + var future = _controllerCompleter!.future; + controller.close(); return future.then((_) => targetAddStream()); } @@ -631,12 +626,13 @@ class _StreamSinkImpl implements StreamSink { if (_isBound) { throw new StateError("StreamSink is bound to a stream"); } - if (_controllerInstance == null) return new Future.value(this); + var controller = _controllerInstance; + if (controller == null) return new Future.value(this); // Adding an empty stream-controller will return a future that will complete // when all data is done. _isBound = true; - var future = _controllerCompleter.future; - _controllerInstance.close(); + var future = _controllerCompleter!.future; + controller.close(); return future.whenComplete(() { _isBound = false; }); @@ -648,8 +644,9 @@ class _StreamSinkImpl implements StreamSink { } if (!_isClosed) { _isClosed = true; - if (_controllerInstance != null) { - _controllerInstance.close(); + var controller = _controllerInstance; + if (controller != null) { + controller.close(); } else { _closeTarget(); } @@ -669,7 +666,7 @@ class _StreamSinkImpl implements StreamSink { } } - void _completeDoneError(error, StackTrace stackTrace) { + void _completeDoneError(Object error, StackTrace stackTrace) { if (!_doneCompleter.isCompleted) { _hasError = true; _doneCompleter.completeError(error, stackTrace); @@ -689,17 +686,17 @@ class _StreamSinkImpl implements StreamSink { _target.addStream(_controller.stream).then((_) { if (_isBound) { // A new stream takes over - forward values to that stream. - _controllerCompleter.complete(this); + _controllerCompleter!.complete(this); _controllerCompleter = null; _controllerInstance = null; } else { // No new stream, .close was called. Close _target. _closeTarget(); } - }, onError: (error, stackTrace) { + }, onError: (Object error, StackTrace stackTrace) { if (_isBound) { // A new stream takes over - forward errors to that stream. - _controllerCompleter.completeError(error, stackTrace); + _controllerCompleter!.completeError(error, stackTrace); _controllerCompleter = null; _controllerInstance = null; } else { @@ -709,7 +706,7 @@ class _StreamSinkImpl implements StreamSink { } }); } - return _controllerInstance; + return _controllerInstance!; } } @@ -728,7 +725,7 @@ class _IOSinkImpl extends _StreamSinkImpl> implements IOSink { _encoding = value; } - void write(Object obj) { + void write(Object? obj) { String string = '$obj'; if (string.isEmpty) return; add(_encoding.encode(string)); @@ -750,7 +747,7 @@ class _IOSinkImpl extends _StreamSinkImpl> implements IOSink { } } - void writeln([Object object = ""]) { + void writeln([Object? object = ""]) { write(object); write("\n"); } @@ -773,7 +770,7 @@ abstract class _HttpOutboundMessage extends _IOSinkImpl { final _HttpHeaders headers; _HttpOutboundMessage(Uri uri, String protocolVersion, _HttpOutgoing outgoing, - {_HttpHeaders initialHeaders}) + {_HttpHeaders? initialHeaders}) : _uri = uri, headers = new _HttpHeaders(protocolVersion, defaultPortForScheme: uri.scheme == 'https' @@ -781,7 +778,7 @@ abstract class _HttpOutboundMessage extends _IOSinkImpl { : HttpClient.defaultHttpPort, initialHeaders: initialHeaders), _outgoing = outgoing, - super(outgoing, null) { + super(outgoing, latin1) { _outgoing.outbound = this; _encodingMutable = false; } @@ -806,13 +803,14 @@ abstract class _HttpOutboundMessage extends _IOSinkImpl { if (_encodingSet && _outgoing.headersWritten) { return _encoding; } - var charset; - if (headers.contentType != null && headers.contentType.charset != null) { - charset = headers.contentType.charset; + String charset; + var contentType = headers.contentType; + if (contentType != null && contentType.charset != null) { + charset = contentType.charset!; } else { charset = "iso-8859-1"; } - return Encoding.getByName(charset); + return Encoding.getByName(charset) ?? latin1; } void add(List data) { @@ -820,7 +818,7 @@ abstract class _HttpOutboundMessage extends _IOSinkImpl { super.add(data); } - void write(Object obj) { + void write(Object? obj) { if (!_encodingSet) { _encoding = encoding; _encodingSet = true; @@ -836,26 +834,24 @@ abstract class _HttpOutboundMessage extends _IOSinkImpl { class _HttpResponse extends _HttpOutboundMessage implements HttpResponse { int _statusCode = 200; - String _reasonPhrase; - List _cookies; - _HttpRequest _httpRequest; - Duration _deadline; - Timer _deadlineTimer; + String? _reasonPhrase; + List? _cookies; + _HttpRequest? _httpRequest; + Duration? _deadline; + Timer? _deadlineTimer; _HttpResponse(Uri uri, String protocolVersion, _HttpOutgoing outgoing, - HttpHeaders defaultHeaders, String serverHeader) - : super(uri, protocolVersion, outgoing, initialHeaders: defaultHeaders) { + HttpHeaders defaultHeaders, String? serverHeader) + : super(uri, protocolVersion, outgoing, + initialHeaders: defaultHeaders as _HttpHeaders) { if (serverHeader != null) { headers.set(HttpHeaders.serverHeader, serverHeader); } } - bool get _isConnectionClosed => _httpRequest._httpConnection._isClosing; + bool get _isConnectionClosed => _httpRequest!._httpConnection._isClosing; - List get cookies { - if (_cookies == null) _cookies = new List(); - return _cookies; - } + List get cookies => _cookies ??= []; int get statusCode => _statusCode; void set statusCode(int statusCode) { @@ -869,17 +865,17 @@ class _HttpResponse extends _HttpOutboundMessage _reasonPhrase = reasonPhrase; } - Future redirect(Uri location, {int status: HttpStatus.movedTemporarily}) { + Future redirect(Uri location, {int status = HttpStatus.movedTemporarily}) { if (_outgoing.headersWritten) throw new StateError("Header already sent"); statusCode = status; headers.set(HttpHeaders.locationHeader, location.toString()); return close(); } - Future detachSocket({bool writeHeaders: true}) { + Future detachSocket({bool writeHeaders = true}) { if (_outgoing.headersWritten) throw new StateError("Headers already sent"); deadline = null; // Be sure to stop any deadline. - var future = _httpRequest._httpConnection.detachSocket(); + var future = _httpRequest!._httpConnection.detachSocket(); if (writeHeaders) { var headersFuture = _outgoing.writeHeaders(drainRequest: false, setOutgoing: false); @@ -897,17 +893,17 @@ class _HttpResponse extends _HttpOutboundMessage return future; } - HttpConnectionInfo get connectionInfo => _httpRequest.connectionInfo; + HttpConnectionInfo? get connectionInfo => _httpRequest!.connectionInfo; - Duration get deadline => _deadline; + Duration? get deadline => _deadline; - void set deadline(Duration d) { - if (_deadlineTimer != null) _deadlineTimer.cancel(); + void set deadline(Duration? d) { + _deadlineTimer?.cancel(); _deadline = d; - if (_deadline == null) return; - _deadlineTimer = new Timer(_deadline, () { - _httpRequest._httpConnection.destroy(); + if (d == null) return; + _deadlineTimer = new Timer(d, () { + _httpRequest!._httpConnection.destroy(); }); } @@ -927,7 +923,7 @@ class _HttpResponse extends _HttpOutboundMessage buffer.addByte(_CharCode.CR); buffer.addByte(_CharCode.LF); - var session = _httpRequest._session; + var session = _httpRequest!._session; if (session != null && !session._destroyed) { // Mark as not new. session._isNew = false; @@ -950,11 +946,9 @@ class _HttpResponse extends _HttpOutboundMessage } } // Add all the cookies set to the headers. - if (_cookies != null) { - _cookies.forEach((cookie) { - headers.add(HttpHeaders.setCookieHeader, cookie); - }); - } + _cookies?.forEach((cookie) { + headers.add(HttpHeaders.setCookieHeader, cookie); + }); headers._finalize(); @@ -967,8 +961,9 @@ class _HttpResponse extends _HttpOutboundMessage } String _findReasonPhrase(int statusCode) { - if (_reasonPhrase != null) { - return _reasonPhrase; + var reasonPhrase = _reasonPhrase; + if (reasonPhrase != null) { + return reasonPhrase; } switch (statusCode) { @@ -1062,19 +1057,19 @@ class _HttpClientRequest extends _HttpOutboundMessage implements HttpClientRequest { final String method; final Uri uri; - final List cookies = new List(); + final List cookies = []; // The HttpClient this request belongs to. final _HttpClient _httpClient; final _HttpClientConnection _httpClientConnection; - final TimelineTask _timeline; + final TimelineTask? _timeline; final Completer _responseCompleter = new Completer(); final _Proxy _proxy; - Future _response; + Future? _response; // TODO(ajohnsen): Get default value from client? bool _followRedirects = true; @@ -1099,7 +1094,7 @@ class _HttpClientRequest extends _HttpOutboundMessage _timeline?.instant('Response receieved'); Map formatConnectionInfo() => { 'localPort': response.connectionInfo?.localPort, - 'remoteAddress': response.connectionInfo?.remoteAddress?.address, + 'remoteAddress': response.connectionInfo?.remoteAddress.address, 'remotePort': response.connectionInfo?.remotePort, }; @@ -1126,7 +1121,7 @@ class _HttpClientRequest extends _HttpOutboundMessage _timeline?.finish(arguments: { // TODO(bkonyi): consider exposing certificate information? // 'certificate': response.certificate, - 'requestHeaders': outgoing.outbound.headers._headers, + 'requestHeaders': outgoing.outbound!.headers._headers, 'compressionState': response.compressionState.toString(), 'connectionInfo': formatConnectionInfo(), 'contentLength': response.contentLength, @@ -1141,14 +1136,9 @@ class _HttpClientRequest extends _HttpOutboundMessage }, onError: (e) {}); } - Future get done { - if (_response == null) { - _response = - Future.wait([_responseCompleter.future, super.done], eagerError: true) - .then((list) => list[0]); - } - return _response; - } + Future get done => _response ??= + Future.wait([_responseCompleter.future, super.done], eagerError: true) + .then((list) => list[0]); Future close() { super.close(); @@ -1167,7 +1157,8 @@ class _HttpClientRequest extends _HttpOutboundMessage _followRedirects = followRedirects; } - HttpConnectionInfo get connectionInfo => _httpClientConnection.connectionInfo; + HttpConnectionInfo? get connectionInfo => + _httpClientConnection.connectionInfo; void _onIncoming(_HttpIncoming incoming) { var response = new _HttpClientResponse(incoming, this, _httpClient); @@ -1320,67 +1311,68 @@ class _HttpOutgoing implements StreamConsumer> { bool ignoreBody = false; bool headersWritten = false; - Uint8List _buffer; + Uint8List? _buffer; int _length = 0; - Future _closeFuture; + Future? _closeFuture; bool chunked = false; int _pendingChunkedFooter = 0; - int contentLength; + int? contentLength; int _bytesWritten = 0; bool _gzip = false; - ByteConversionSink _gzipSink; + ByteConversionSink? _gzipSink; // _gzipAdd is set iff the sink is being added to. It's used to specify where // gzipped data should be taken (sometimes a controller, sometimes a socket). - _BytesConsumer _gzipAdd; - Uint8List _gzipBuffer; + _BytesConsumer? _gzipAdd; + Uint8List? _gzipBuffer; int _gzipBufferLength = 0; bool _socketError = false; - _HttpOutboundMessage outbound; + _HttpOutboundMessage? outbound; _HttpOutgoing(this.socket); // Returns either a future or 'null', if it was able to write headers // immediately. - Future writeHeaders({bool drainRequest: true, bool setOutgoing: true}) { + Future? writeHeaders( + {bool drainRequest = true, bool setOutgoing = true}) { if (headersWritten) return null; headersWritten = true; - Future drainFuture; + Future? drainFuture; bool gzip = false; - if (outbound is _HttpResponse) { + var response = outbound!; + if (response is _HttpResponse) { // Server side. - _HttpResponse response = outbound; - if (response._httpRequest._httpServer.autoCompress && - outbound.bufferOutput && - outbound.headers.chunkedTransferEncoding) { - List acceptEncodings = - response._httpRequest.headers[HttpHeaders.acceptEncodingHeader]; - List contentEncoding = - outbound.headers[HttpHeaders.contentEncodingHeader]; + if (response._httpRequest!._httpServer.autoCompress && + response.bufferOutput && + response.headers.chunkedTransferEncoding) { + List? acceptEncodings = + response._httpRequest!.headers[HttpHeaders.acceptEncodingHeader]; + List? contentEncoding = + response.headers[HttpHeaders.contentEncodingHeader]; if (acceptEncodings != null && + contentEncoding == null && acceptEncodings .expand((list) => list.split(",")) - .any((encoding) => encoding.trim().toLowerCase() == "gzip") && - contentEncoding == null) { - outbound.headers.set(HttpHeaders.contentEncodingHeader, "gzip"); + .any((encoding) => encoding.trim().toLowerCase() == "gzip")) { + response.headers.set(HttpHeaders.contentEncodingHeader, "gzip"); gzip = true; } } - if (drainRequest && !response._httpRequest._incoming.hasSubscriber) { - drainFuture = response._httpRequest.drain().catchError((_) {}); + if (drainRequest && !response._httpRequest!._incoming.hasSubscriber) { + drainFuture = response._httpRequest!.drain().catchError((_) {}); } } else { drainRequest = false; } if (!ignoreBody) { if (setOutgoing) { - int contentLength = outbound.headers.contentLength; - if (outbound.headers.chunkedTransferEncoding) { + int contentLength = response.headers.contentLength; + if (response.headers.chunkedTransferEncoding) { chunked = true; if (gzip) this.gzip = true; } else if (contentLength >= 0) { @@ -1388,10 +1380,10 @@ class _HttpOutgoing implements StreamConsumer> { } } if (drainFuture != null) { - return drainFuture.then((_) => outbound._writeHeader()); + return drainFuture.then((_) => response._writeHeader()); } } - outbound._writeHeader(); + response._writeHeader(); return null; } @@ -1408,12 +1400,10 @@ class _HttpOutgoing implements StreamConsumer> { } return close(); } - StreamSubscription> sub; // Use new stream so we are able to pause (see below listen). The // alternative is to use stream.extand, but that won't give us a way of // pausing. - var controller = new StreamController>( - onPause: () => sub.pause(), onResume: () => sub.resume(), sync: true); + var controller = new StreamController>(sync: true); void onData(List data) { if (_socketError) return; @@ -1421,13 +1411,14 @@ class _HttpOutgoing implements StreamConsumer> { if (chunked) { if (_gzip) { _gzipAdd = controller.add; - _addGZipChunk(data, _gzipSink.add); + _addGZipChunk(data, _gzipSink!.add); _gzipAdd = null; return; } _addChunk(_chunkHeader(data.length), controller.add); _pendingChunkedFooter = 2; } else { + var contentLength = this.contentLength; if (contentLength != null) { _bytesWritten += data.length; if (_bytesWritten > contentLength) { @@ -1443,10 +1434,12 @@ class _HttpOutgoing implements StreamConsumer> { _addChunk(data, controller.add); } - sub = stream.listen(onData, + var sub = stream.listen(onData, onError: controller.addError, onDone: controller.close, cancelOnError: true); + controller.onPause = sub.pause; + controller.onResume = sub.resume; // Write headers now that we are listening to the stream. if (!headersWritten) { var future = writeHeaders(); @@ -1460,7 +1453,7 @@ class _HttpOutgoing implements StreamConsumer> { return outbound; }, onError: (error, stackTrace) { // Be sure to close it in case of an error. - if (_gzip) _gzipSink.close(); + if (_gzip) _gzipSink!.close(); _socketError = true; _doneCompleter.completeError(error, stackTrace); if (_ignoreError(error)) { @@ -1473,7 +1466,10 @@ class _HttpOutgoing implements StreamConsumer> { Future close() { // If we are already closed, return that future. - if (_closeFuture != null) return _closeFuture; + var closeFuture = _closeFuture; + if (closeFuture != null) return closeFuture; + + var outbound = this.outbound!; // If we earlier saw an error, return immediate. The notification to // _Http*Connection is already done. if (_socketError) return new Future.value(outbound); @@ -1495,6 +1491,7 @@ class _HttpOutgoing implements StreamConsumer> { } } // If contentLength was specified, validate it. + var contentLength = this.contentLength; if (contentLength != null) { if (_bytesWritten < contentLength) { var error = new HttpException( @@ -1514,19 +1511,19 @@ class _HttpOutgoing implements StreamConsumer> { if (_gzip) { _gzipAdd = socket.add; if (_gzipBufferLength > 0) { - _gzipSink.add(new Uint8List.view(_gzipBuffer.buffer, - _gzipBuffer.offsetInBytes, _gzipBufferLength)); + _gzipSink!.add(new Uint8List.view(_gzipBuffer!.buffer, + _gzipBuffer!.offsetInBytes, _gzipBufferLength)); } _gzipBuffer = null; - _gzipSink.close(); + _gzipSink!.close(); _gzipAdd = null; } _addChunk(_chunkHeader(0), socket.add); } // Add any remaining data in the buffer. if (_length > 0) { - socket.add( - new Uint8List.view(_buffer.buffer, _buffer.offsetInBytes, _length)); + socket.add(new Uint8List.view( + _buffer!.buffer, _buffer!.offsetInBytes, _length)); } // Clear references, for better GC. _buffer = null; @@ -1557,22 +1554,22 @@ class _HttpOutgoing implements StreamConsumer> { void setHeader(List data, int length) { assert(_length == 0); - _buffer = data; + _buffer = data as Uint8List; _length = length; } void set gzip(bool value) { _gzip = value; - if (_gzip) { + if (value) { _gzipBuffer = new Uint8List(_OUTGOING_BUFFER_SIZE); assert(_gzipSink == null); _gzipSink = new ZLibEncoder(gzip: true) .startChunkedConversion(new _HttpGZipSink((data) { // We are closing down prematurely, due to an error. Discard. if (_gzipAdd == null) return; - _addChunk(_chunkHeader(data.length), _gzipAdd); + _addChunk(_chunkHeader(data.length), _gzipAdd!); _pendingChunkedFooter = 2; - _addChunk(data, _gzipAdd); + _addChunk(data, _gzipAdd!); })); } } @@ -1582,46 +1579,51 @@ class _HttpOutgoing implements StreamConsumer> { outbound is HttpResponse; void _addGZipChunk(List chunk, void add(List data)) { - if (!outbound.bufferOutput) { + var bufferOutput = outbound!.bufferOutput; + if (!bufferOutput) { add(chunk); return; } - if (chunk.length > _gzipBuffer.length - _gzipBufferLength) { + var gzipBuffer = _gzipBuffer!; + if (chunk.length > gzipBuffer.length - _gzipBufferLength) { add(new Uint8List.view( - _gzipBuffer.buffer, _gzipBuffer.offsetInBytes, _gzipBufferLength)); + gzipBuffer.buffer, gzipBuffer.offsetInBytes, _gzipBufferLength)); _gzipBuffer = new Uint8List(_OUTGOING_BUFFER_SIZE); _gzipBufferLength = 0; } if (chunk.length > _OUTGOING_BUFFER_SIZE) { add(chunk); } else { - _gzipBuffer.setRange( - _gzipBufferLength, _gzipBufferLength + chunk.length, chunk); - _gzipBufferLength += chunk.length; + var currentLength = _gzipBufferLength; + var newLength = currentLength + chunk.length; + _gzipBuffer!.setRange(currentLength, newLength, chunk); + _gzipBufferLength = newLength; } } void _addChunk(List chunk, void add(List data)) { - if (!outbound.bufferOutput) { + var bufferOutput = outbound!.bufferOutput; + if (!bufferOutput) { if (_buffer != null) { // If _buffer is not null, we have not written the header yet. Write // it now. - add(new Uint8List.view(_buffer.buffer, _buffer.offsetInBytes, _length)); + add(new Uint8List.view( + _buffer!.buffer, _buffer!.offsetInBytes, _length)); _buffer = null; _length = 0; } add(chunk); return; } - if (chunk.length > _buffer.length - _length) { - add(new Uint8List.view(_buffer.buffer, _buffer.offsetInBytes, _length)); + if (chunk.length > _buffer!.length - _length) { + add(new Uint8List.view(_buffer!.buffer, _buffer!.offsetInBytes, _length)); _buffer = new Uint8List(_OUTGOING_BUFFER_SIZE); _length = 0; } if (chunk.length > _OUTGOING_BUFFER_SIZE) { add(chunk); } else { - _buffer.setRange(_length, _length + chunk.length, chunk); + _buffer!.setRange(_length, _length + chunk.length, chunk); _length += chunk.length; } } @@ -1676,17 +1678,17 @@ class _HttpClientConnection { final String key; final Socket _socket; final bool _proxyTunnel; - final SecurityContext _context; + final SecurityContext? _context; final _HttpParser _httpParser; - StreamSubscription _subscription; + StreamSubscription? _subscription; final _HttpClient _httpClient; bool _dispose = false; - Timer _idleTimer; + Timer? _idleTimer; bool closed = false; - Uri _currentUri; + Uri? _currentUri; - Completer<_HttpIncoming> _nextResponseCompleter; - Future _streamFuture; + Completer<_HttpIncoming>? _nextResponseCompleter; + Future? _streamFuture; _HttpClientConnection(this.key, this._socket, this._httpClient, [this._proxyTunnel = false, this._context]) @@ -1698,7 +1700,7 @@ class _HttpClientConnection { _subscription = _httpParser.listen((incoming) { // Only handle one incoming response at the time. Keep the // stream paused until the response have been processed. - _subscription.pause(); + _subscription!.pause(); // We assume the response is not here, until we have send the request. if (_nextResponseCompleter == null) { throw new HttpException( @@ -1712,48 +1714,44 @@ class _HttpClientConnection { // the '100 Continue' response. if (incoming.statusCode == 100) { incoming.drain().then((_) { - _subscription.resume(); - }).catchError((error, [StackTrace stackTrace]) { - _nextResponseCompleter.completeError( + _subscription!.resume(); + }).catchError((dynamic error, StackTrace stackTrace) { + _nextResponseCompleter!.completeError( new HttpException(error.message, uri: _currentUri), stackTrace); _nextResponseCompleter = null; }); } else { - _nextResponseCompleter.complete(incoming); - _nextResponseCompleter = null; - } - }, onError: (error, [StackTrace stackTrace]) { - if (_nextResponseCompleter != null) { - _nextResponseCompleter.completeError( - new HttpException(error.message, uri: _currentUri), stackTrace); + _nextResponseCompleter!.complete(incoming); _nextResponseCompleter = null; } + }, onError: (dynamic error, StackTrace stackTrace) { + _nextResponseCompleter?.completeError( + new HttpException(error.message, uri: _currentUri), stackTrace); + _nextResponseCompleter = null; }, onDone: () { - if (_nextResponseCompleter != null) { - _nextResponseCompleter.completeError(new HttpException( - "Connection closed before response was received", - uri: _currentUri)); - _nextResponseCompleter = null; - } + _nextResponseCompleter?.completeError(new HttpException( + "Connection closed before response was received", + uri: _currentUri)); + _nextResponseCompleter = null; close(); }); } _HttpClientRequest send( - Uri uri, int port, String method, _Proxy proxy, TimelineTask timeline) { + Uri uri, int port, String method, _Proxy proxy, TimelineTask? timeline) { if (closed) { throw new HttpException("Socket closed before request was sent", uri: uri); } _currentUri = uri; // Start with pausing the parser. - _subscription.pause(); + _subscription!.pause(); if (method == "CONNECT") { // Parser will ignore Content-Length or Transfer-Encoding header _httpParser.connectMethod = true; } - _ProxyCredentials proxyCreds; // Credentials used to authorize proxy. - _SiteCredentials creds; // Credentials used to authorize this request. + _ProxyCredentials? proxyCreds; // Credentials used to authorize proxy. + _SiteCredentials? creds; // Credentials used to authorize this request. var outgoing = new _HttpOutgoing(_socket); // Create new request object, wrapping the outgoing connection. var request = new _HttpClientRequest( @@ -1766,7 +1764,7 @@ class _HttpClientConnection { ..port = port ..add(HttpHeaders.acceptEncodingHeader, "gzip"); if (_httpClient.userAgent != null) { - request.headers.add(HttpHeaders.userAgentHeader, _httpClient.userAgent); + request.headers.add(HttpHeaders.userAgentHeader, _httpClient.userAgent!); } if (proxy.isAuthenticated) { // If the proxy configuration contains user information use that @@ -1798,10 +1796,11 @@ class _HttpClientConnection { _httpParser.isHead = method == "HEAD"; _streamFuture = outgoing.done.then((Socket s) { // Request sent, set up response completer. - _nextResponseCompleter = new Completer<_HttpIncoming>(); + var nextResponseCompleter = new Completer<_HttpIncoming>(); + _nextResponseCompleter = nextResponseCompleter; // Listen for response. - _nextResponseCompleter.future.then((incoming) { + nextResponseCompleter.future.then((incoming) { _currentUri = null; incoming.dataDone.then((closing) { if (incoming.upgraded) { @@ -1816,7 +1815,7 @@ class _HttpClientConnection { request.persistentConnection) { // Return connection, now we are done. _httpClient._returnConnection(this); - _subscription.resume(); + _subscription!.resume(); } else { destroy(); } @@ -1859,16 +1858,17 @@ class _HttpClientConnection { }); // Resume the parser now we have a handler. - _subscription.resume(); + _subscription!.resume(); return s; - }, onError: (e) { + }); + Future.value(_streamFuture).catchError((e) { destroy(); }); return request; } Future detachSocket() { - return _streamFuture.then( + return _streamFuture!.then( (_) => new _DetachedSocket(_socket, _httpParser.detachIncoming())); } @@ -1881,7 +1881,7 @@ class _HttpClientConnection { void close() { closed = true; _httpClient._connectionClosed(this); - _streamFuture + _streamFuture! .timeout(_httpClient.idleTimeout) .then((_) => _socket.destroy()); } @@ -1891,7 +1891,7 @@ class _HttpClientConnection { int port, _Proxy proxy, bool callback(X509Certificate certificate), - TimelineTask timeline) { + TimelineTask? timeline) { timeline?.instant('Establishing proxy tunnel', arguments: { 'proxyInfo': { if (proxy.host != null) 'host': proxy.host, @@ -1939,17 +1939,15 @@ class _HttpClientConnection { }); } - HttpConnectionInfo get connectionInfo => _HttpConnectionInfo.create(_socket); + HttpConnectionInfo? get connectionInfo => _HttpConnectionInfo.create(_socket); static makeKey(bool isSecure, String host, int port) { return isSecure ? "ssh:$host:$port" : "$host:$port"; } void stopTimer() { - if (_idleTimer != null) { - _idleTimer.cancel(); - _idleTimer = null; - } + _idleTimer?.cancel(); + _idleTimer = null; } void startTimer() { @@ -1974,7 +1972,7 @@ class _ConnectionTarget { final String host; final int port; final bool isSecure; - final SecurityContext context; + final SecurityContext? context; final Set<_HttpClientConnection> _idle = new HashSet(); final Set<_HttpClientConnection> _active = new HashSet(); final Set _socketTasks = new HashSet(); @@ -2048,14 +2046,15 @@ class _ConnectionTarget { } Future<_ConnectionInfo> connect(String uriHost, int uriPort, _Proxy proxy, - _HttpClient client, TimelineTask timeline) { + _HttpClient client, TimelineTask? timeline) { if (hasIdle) { var connection = takeIdle(); client._connectionsChanged(); return new Future.value(new _ConnectionInfo(connection, proxy)); } - if (client.maxConnectionsPerHost != null && - _active.length + _connecting >= client.maxConnectionsPerHost) { + var maxConnectionsPerHost = client.maxConnectionsPerHost; + if (maxConnectionsPerHost != null && + _active.length + _connecting >= maxConnectionsPerHost) { var completer = new Completer<_ConnectionInfo>(); _pending.add(() { completer.complete(connect(uriHost, uriPort, proxy, client, timeline)); @@ -2077,7 +2076,7 @@ class _ConnectionTarget { return connectionTask.then((ConnectionTask task) { _socketTasks.add(task); Future socketFuture = task.socket; - final Duration connectionTimeout = client.connectionTimeout; + final Duration? connectionTimeout = client.connectionTimeout; if (connectionTimeout != null) { socketFuture = socketFuture.timeout(connectionTimeout, onTimeout: () { _socketTasks.remove(task); @@ -2138,22 +2137,22 @@ class _HttpClient implements HttpClient { new HashMap(); final List<_Credentials> _credentials = []; final List<_ProxyCredentials> _proxyCredentials = []; - final SecurityContext _context; - Function _authenticate; - Function _authenticateProxy; - Function _findProxy = HttpClient.findProxyFromEnvironment; + final SecurityContext? _context; + Function? _authenticate; + Function? _authenticateProxy; + Function? _findProxy = HttpClient.findProxyFromEnvironment; Duration _idleTimeout = const Duration(seconds: 15); - BadCertificateCallback _badCertificateCallback; + BadCertificateCallback? _badCertificateCallback; Duration get idleTimeout => _idleTimeout; - Duration connectionTimeout; + Duration? connectionTimeout; - int maxConnectionsPerHost; + int? maxConnectionsPerHost; bool autoUncompress = true; - String userAgent = _getHttpVersion(); + String? userAgent = _getHttpVersion(); _HttpClient(this._context); @@ -2169,7 +2168,7 @@ class _HttpClient implements HttpClient { } set badCertificateCallback( - bool callback(X509Certificate cert, String host, int port)) { + bool callback(X509Certificate cert, String host, int port)?) { _badCertificateCallback = callback; } @@ -2188,7 +2187,7 @@ class _HttpClient implements HttpClient { queryStart = i; } } - String query = null; + String? query; if (queryStart < fragmentStart) { query = path.substring(queryStart + 1, fragmentStart); path = path.substring(0, queryStart); @@ -2231,7 +2230,7 @@ class _HttpClient implements HttpClient { Future patchUrl(Uri url) => _openUrl("patch", url); - void close({bool force: false}) { + void close({bool force = false}) { _closing = true; _closingForcefully = force; _closeConnections(_closingForcefully); @@ -2240,28 +2239,30 @@ class _HttpClient implements HttpClient { !force || !_connectionTargets.values.any((s) => s._active.isNotEmpty)); } - set authenticate(Future f(Uri url, String scheme, String realm)) { + set authenticate(Future f(Uri url, String scheme, String realm)?) { _authenticate = f; } void addCredentials(Uri url, String realm, HttpClientCredentials cr) { - _credentials.add(new _SiteCredentials(url, realm, cr)); + _credentials + .add(new _SiteCredentials(url, realm, cr as _HttpClientCredentials)); } set authenticateProxy( - Future f(String host, int port, String scheme, String realm)) { + Future f(String host, int port, String scheme, String realm)?) { _authenticateProxy = f; } void addProxyCredentials( String host, int port, String realm, HttpClientCredentials cr) { - _proxyCredentials.add(new _ProxyCredentials(host, port, realm, cr)); + _proxyCredentials.add( + new _ProxyCredentials(host, port, realm, cr as _HttpClientCredentials)); } - set findProxy(String f(Uri uri)) => _findProxy = f; + set findProxy(String f(Uri uri)?) => _findProxy = f; static void _startRequestTimelineEvent( - TimelineTask timeline, String method, Uri uri) { + TimelineTask? timeline, String method, Uri uri) { timeline?.start('HTTP CLIENT ${method.toUpperCase()}', arguments: { 'method': method.toUpperCase(), 'uri': uri.toString(), @@ -2275,7 +2276,7 @@ class _HttpClient implements HttpClient { /// is set to any other non-null value, HTTP is not allowed. /// Otherwise, if the `dart.library.io.allow_http` environment flag /// is set to `false`, HTTP is not allowed. - /// Otherwise, [_embedderAllowsHTTP] determines the result. + /// Otherwise, [_embedderAllowsHttp] determines the result. bool get _isHttpAllowed { final zoneOverride = Zone.current[#dart.library.io.allow_http]; if (zoneOverride != null) return true == zoneOverride; @@ -2327,16 +2328,17 @@ class _HttpClient implements HttpClient { } // Check to see if a proxy server should be used for this connection. var proxyConf = const _ProxyConfiguration.direct(); - if (_findProxy != null) { + var findProxy = _findProxy; + if (findProxy != null) { // TODO(sgjesse): Keep a map of these as normally only a few // configuration strings will be used. try { - proxyConf = new _ProxyConfiguration(_findProxy(uri)); + proxyConf = new _ProxyConfiguration(findProxy(uri)); } catch (error, stackTrace) { return new Future.error(error, stackTrace); } } - TimelineTask timeline; + TimelineTask? timeline; // TODO(bkonyi): do we want this to be opt-in? if (HttpClient.enableTimelineLogging) { timeline = TimelineTask(filterKey: 'HTTP/client'); @@ -2379,7 +2381,7 @@ class _HttpClient implements HttpClient { // Copy headers. for (var header in previous.headers._headers.keys) { if (request.headers[header] == null) { - request.headers.set(header, previous.headers[header]); + request.headers.set(header, previous.headers[header]!); } } return request @@ -2390,7 +2392,7 @@ class _HttpClient implements HttpClient { // Return a live connection to the idle pool. void _returnConnection(_HttpClientConnection connection) { - _connectionTargets[connection.key].returnConnection(connection); + _connectionTargets[connection.key]!.returnConnection(connection); _connectionsChanged(); } @@ -2428,14 +2430,14 @@ class _HttpClient implements HttpClient { // Get a new _HttpClientConnection, from the matching _ConnectionTarget. Future<_ConnectionInfo> _getConnection(String uriHost, int uriPort, - _ProxyConfiguration proxyConf, bool isSecure, TimelineTask timeline) { + _ProxyConfiguration proxyConf, bool isSecure, TimelineTask? timeline) { Iterator<_Proxy> proxies = proxyConf.proxies.iterator; Future<_ConnectionInfo> connect(error) { if (!proxies.moveNext()) return new Future.error(error); _Proxy proxy = proxies.current; - String host = proxy.isDirect ? uriHost : proxy.host; - int port = proxy.isDirect ? uriPort : proxy.port; + String host = proxy.isDirect ? uriHost : proxy.host!; + int port = proxy.isDirect ? uriPort : proxy.port!; return _getConnectionTarget(host, port, isSecure) .connect(uriHost, uriPort, proxy, this, timeline) // On error, continue with next proxy. @@ -2445,10 +2447,10 @@ class _HttpClient implements HttpClient { return connect(new HttpException("No proxies given")); } - _SiteCredentials _findCredentials(Uri url, [_AuthenticationScheme scheme]) { + _SiteCredentials? _findCredentials(Uri url, [_AuthenticationScheme? scheme]) { // Look for credentials. - _SiteCredentials cr = - _credentials.fold(null, (_SiteCredentials prev, value) { + _SiteCredentials? cr = + _credentials.fold(null, (_SiteCredentials? prev, value) { var siteCredentials = value as _SiteCredentials; if (siteCredentials.applies(url, scheme)) { if (prev == null) return value; @@ -2462,13 +2464,12 @@ class _HttpClient implements HttpClient { return cr; } - _ProxyCredentials _findProxyCredentials(_Proxy proxy, - [_AuthenticationScheme scheme]) { + _ProxyCredentials? _findProxyCredentials(_Proxy proxy, + [_AuthenticationScheme? scheme]) { // Look for credentials. - var it = _proxyCredentials.iterator; - while (it.moveNext()) { - if (it.current.applies(proxy, scheme)) { - return it.current; + for (var current in _proxyCredentials) { + if (current.applies(proxy, scheme)) { + return current; } } return null; @@ -2482,15 +2483,12 @@ class _HttpClient implements HttpClient { } void _removeProxyCredentials(_Credentials cr) { - int index = _proxyCredentials.indexOf(cr); - if (index != -1) { - _proxyCredentials.removeAt(index); - } + _proxyCredentials.remove(cr); } static String _findProxyFromEnvironment( - Uri url, Map environment) { - checkNoProxy(String option) { + Uri url, Map? environment) { + String? checkNoProxy(String? option) { if (option == null) return null; Iterator names = option.split(",").map((s) => s.trim()).iterator; while (names.moveNext()) { @@ -2505,7 +2503,7 @@ class _HttpClient implements HttpClient { return null; } - checkProxy(String option) { + String? checkProxy(String? option) { if (option == null) return null; option = option.trim(); if (option.isEmpty) return null; @@ -2530,24 +2528,24 @@ class _HttpClient implements HttpClient { // Default to using the process current environment. if (environment == null) environment = _platformEnvironmentCache; - String proxyCfg; + String? proxyCfg; - String noProxy = environment["no_proxy"]; - if (noProxy == null) noProxy = environment["NO_PROXY"]; - if ((proxyCfg = checkNoProxy(noProxy)) != null) { + String? noProxy = environment["no_proxy"] ?? environment["NO_PROXY"]; + proxyCfg = checkNoProxy(noProxy); + if (proxyCfg != null) { return proxyCfg; } if (url.scheme == "http") { - String proxy = environment["http_proxy"]; - if (proxy == null) proxy = environment["HTTP_PROXY"]; - if ((proxyCfg = checkProxy(proxy)) != null) { + String? proxy = environment["http_proxy"] ?? environment["HTTP_PROXY"]; + proxyCfg = checkProxy(proxy); + if (proxyCfg != null) { return proxyCfg; } } else if (url.scheme == "https") { - String proxy = environment["https_proxy"]; - if (proxy == null) proxy = environment["HTTPS_PROXY"]; - if ((proxyCfg = checkProxy(proxy)) != null) { + String? proxy = environment["https_proxy"] ?? environment["HTTPS_PROXY"]; + proxyCfg = checkProxy(proxy); + if (proxyCfg != null) { return proxyCfg; } } @@ -2572,9 +2570,9 @@ class _HttpConnection extends LinkedListEntry<_HttpConnection> final _HttpServer _httpServer; final _HttpParser _httpParser; int _state = _IDLE; - StreamSubscription _subscription; + StreamSubscription? _subscription; bool _idleMark = false; - Future _streamFuture; + Future? _streamFuture; _HttpConnection(this._socket, this._httpServer) : _httpParser = new _HttpParser.requestParser() { @@ -2588,11 +2586,11 @@ class _HttpConnection extends LinkedListEntry<_HttpConnection> }); // Only handle one incoming request at the time. Keep the // stream paused until the request has been send. - _subscription.pause(); + _subscription!.pause(); _state = _ACTIVE; var outgoing = new _HttpOutgoing(_socket); var response = new _HttpResponse( - incoming.uri, + incoming.uri!, incoming.headers.protocolVersion, outgoing, _httpServer.defaultResponseHeaders, @@ -2615,7 +2613,7 @@ class _HttpConnection extends LinkedListEntry<_HttpConnection> _httpServer._markIdle(this); // Resume the subscription for incoming requests as the // request is now processed. - _subscription.resume(); + _subscription!.resume(); } else { // Close socket, keep-alive not used or body sent before // received data was handled. @@ -2656,17 +2654,18 @@ class _HttpConnection extends LinkedListEntry<_HttpConnection> _HttpDetachedIncoming detachedIncoming = _httpParser.detachIncoming(); - return _streamFuture.then((_) { + return _streamFuture!.then((_) { _connections.remove(_serviceId); return new _DetachedSocket(_socket, detachedIncoming); }); } - HttpConnectionInfo get connectionInfo => _HttpConnectionInfo.create(_socket); + HttpConnectionInfo? get connectionInfo => _HttpConnectionInfo.create(_socket); bool get _isActive => _state == _ACTIVE; bool get _isIdle => _state == _IDLE; bool get _isClosing => _state == _CLOSING; + bool get _isDetached => _state == _DETACHED; String get _serviceTypePath => 'io/http/serverconnections'; String get _serviceTypeName => 'HttpServerConnection'; @@ -2722,12 +2721,12 @@ class _HttpServer extends Stream // Use default Map so we keep order. static Map _servers = new Map(); - String serverHeader; + String? serverHeader; final HttpHeaders defaultResponseHeaders = _initDefaultResponseHeaders(); bool autoCompress = false; - Duration _idleTimeout; - Timer _idleTimer; + Duration? _idleTimeout; + Timer? _idleTimer; static Future bind( address, int port, int backlog, bool v6Only, bool shared) { @@ -2741,7 +2740,7 @@ class _HttpServer extends Stream static Future bindSecure( address, int port, - SecurityContext context, + SecurityContext? context, int backlog, bool v6Only, bool requestClientCertificate, @@ -2756,16 +2755,17 @@ class _HttpServer extends Stream }); } - _HttpServer._(this._serverSocket, this._closeServer) { - _controller = - new StreamController(sync: true, onCancel: close); + _HttpServer._(this._serverSocket, this._closeServer) + : _controller = new StreamController(sync: true) { + _controller.onCancel = close; idleTimeout = const Duration(seconds: 120); _servers[_serviceId] = this; } - _HttpServer.listenOn(this._serverSocket) : _closeServer = false { - _controller = - new StreamController(sync: true, onCancel: close); + _HttpServer.listenOn(this._serverSocket) + : _closeServer = false, + _controller = new StreamController(sync: true) { + _controller.onCancel = close; idleTimeout = const Duration(seconds: 120); _servers[_serviceId] = this; } @@ -2779,16 +2779,17 @@ class _HttpServer extends Stream return defaultResponseHeaders; } - Duration get idleTimeout => _idleTimeout; + Duration? get idleTimeout => _idleTimeout; - void set idleTimeout(Duration duration) { - if (_idleTimer != null) { - _idleTimer.cancel(); + void set idleTimeout(Duration? duration) { + var idleTimer = _idleTimer; + if (idleTimer != null) { + idleTimer.cancel(); _idleTimer = null; } _idleTimeout = duration; - if (_idleTimeout != null) { - _idleTimer = new Timer.periodic(_idleTimeout, (_) { + if (duration != null) { + _idleTimer = new Timer.periodic(duration, (_) { for (var idle in _idleConnections.toList()) { if (idle.isMarkedIdle) { idle.destroy(); @@ -2800,8 +2801,8 @@ class _HttpServer extends Stream } } - StreamSubscription listen(void onData(HttpRequest event), - {Function onError, void onDone(), bool cancelOnError}) { + StreamSubscription listen(void onData(HttpRequest event)?, + {Function? onError, void onDone()?, bool? cancelOnError}) { _serverSocket.listen((Socket socket) { socket.setOption(SocketOption.tcpNoDelay, true); // Accept the client connection. @@ -2818,7 +2819,7 @@ class _HttpServer extends Stream onError: onError, onDone: onDone, cancelOnError: cancelOnError); } - Future close({bool force: false}) { + Future close({bool force = false}) { closed = true; Future result; if (_serverSocket != null && _closeServer) { @@ -2841,11 +2842,12 @@ class _HttpServer extends Stream } void _maybePerformCleanup() { + var sessionManager = _sessionManagerInstance; if (closed && _idleConnections.isEmpty && _activeConnections.isEmpty && - _sessionManagerInstance != null) { - _sessionManagerInstance.close(); + sessionManager != null) { + sessionManager.close(); _sessionManagerInstance = null; _servers.remove(_serviceId); } @@ -2889,13 +2891,9 @@ class _HttpServer extends Stream _activeConnections.add(connection); } - _HttpSessionManager get _sessionManager { - // Lazy init. - if (_sessionManagerInstance == null) { - _sessionManagerInstance = new _HttpSessionManager(); - } - return _sessionManagerInstance; - } + // Lazy init. + _HttpSessionManager get _sessionManager => + _sessionManagerInstance ??= _HttpSessionManager(); HttpConnectionsInfo connectionsInfo() { HttpConnectionsInfo result = new HttpConnectionsInfo(); @@ -2946,7 +2944,7 @@ class _HttpServer extends Stream return r; } - _HttpSessionManager _sessionManagerInstance; + _HttpSessionManager? _sessionManagerInstance; // Indicated if the http server has been closed. bool closed = false; @@ -2968,7 +2966,7 @@ class _ProxyConfiguration { static const String PROXY_PREFIX = "PROXY "; static const String DIRECT_PREFIX = "DIRECT"; - _ProxyConfiguration(String configuration) : proxies = new List<_Proxy>() { + _ProxyConfiguration(String configuration) : proxies = <_Proxy>[] { if (configuration == null) { throw new HttpException("Invalid proxy configuration $configuration"); } @@ -2977,8 +2975,8 @@ class _ProxyConfiguration { proxy = proxy.trim(); if (!proxy.isEmpty) { if (proxy.startsWith(PROXY_PREFIX)) { - String username; - String password; + String? username; + String? password; // Skip the "PROXY " prefix. proxy = proxy.substring(PROXY_PREFIX.length).trim(); // Look for proxy authentication. @@ -3008,7 +3006,7 @@ class _ProxyConfiguration { int port; try { port = int.parse(portString); - } on FormatException { + } on FormatException catch (e) { throw new HttpException( "Invalid proxy configuration $configuration, " "invalid port '$portString'"); @@ -3029,13 +3027,13 @@ class _ProxyConfiguration { } class _Proxy { - final String host; - final int port; - final String username; - final String password; + final String? host; + final int? port; + final String? username; + final String? password; final bool isDirect; - const _Proxy(this.host, this.port, this.username, this.password) + const _Proxy(String this.host, int this.port, this.username, this.password) : isDirect = false; const _Proxy.direct() : host = null, @@ -3052,14 +3050,13 @@ class _HttpConnectionInfo implements HttpConnectionInfo { int remotePort; int localPort; - static _HttpConnectionInfo create(Socket socket) { + _HttpConnectionInfo(this.remoteAddress, this.remotePort, this.localPort); + + static _HttpConnectionInfo? create(Socket socket) { if (socket == null) return null; try { - _HttpConnectionInfo info = new _HttpConnectionInfo(); - return info - ..remoteAddress = socket.remoteAddress - ..remotePort = socket.remotePort - ..localPort = socket.port; + return _HttpConnectionInfo( + socket.remoteAddress, socket.remotePort, socket.port); } catch (e) {} return null; } @@ -3071,8 +3068,8 @@ class _DetachedSocket extends Stream implements Socket { _DetachedSocket(this._socket, this._incoming); - StreamSubscription listen(void onData(Uint8List event), - {Function onError, void onDone(), bool cancelOnError}) { + StreamSubscription listen(void onData(Uint8List event)?, + {Function? onError, void onDone()?, bool? cancelOnError}) { return _incoming.listen(onData, onError: onError, onDone: onDone, cancelOnError: cancelOnError); } @@ -3083,11 +3080,11 @@ class _DetachedSocket extends Stream implements Socket { _socket.encoding = value; } - void write(Object obj) { + void write(Object? obj) { _socket.write(obj); } - void writeln([Object obj = ""]) { + void writeln([Object? obj = ""]) { _socket.writeln(obj); } @@ -3103,7 +3100,7 @@ class _DetachedSocket extends Stream implements Socket { _socket.add(bytes); } - void addError(error, [StackTrace stackTrace]) => + void addError(Object error, [StackTrace? stackTrace]) => _socket.addError(error, stackTrace); Future addStream(Stream> stream) { @@ -3173,11 +3170,11 @@ abstract class _Credentials { bool used = false; // Digest specific fields. - String ha1; - String nonce; - String algorithm; - String qop; - int nonceCount; + String? ha1; + String? nonce; + String? algorithm; + String? qop; + int? nonceCount; _Credentials(this.credentials, this.realm) { if (credentials.scheme == _AuthenticationScheme.DIGEST) { @@ -3187,7 +3184,7 @@ abstract class _Credentials { // the WWW-Authenticate and Proxy-Authenticate headers, see // http://tools.ietf.org/html/draft-reschke-basicauth-enc-06. For // now always use UTF-8 encoding. - _HttpClientDigestCredentials creds = credentials; + var creds = credentials as _HttpClientDigestCredentials; var hasher = new _MD5() ..add(utf8.encode(creds.username)) ..add([_CharCode.COLON]) @@ -3209,7 +3206,7 @@ class _SiteCredentials extends _Credentials { _SiteCredentials(this.uri, realm, _HttpClientCredentials creds) : super(creds, realm); - bool applies(Uri uri, _AuthenticationScheme scheme) { + bool applies(Uri uri, _AuthenticationScheme? scheme) { if (scheme != null && credentials.scheme != scheme) return false; if (uri.host != this.uri.host) return false; int thisPort = @@ -3225,7 +3222,7 @@ class _SiteCredentials extends _Credentials { if (credentials.scheme == _AuthenticationScheme.DIGEST && nonce == null) { return; } - credentials.authorize(this, request); + credentials.authorize(this, request as _HttpClientRequest); used = true; } } @@ -3237,7 +3234,7 @@ class _ProxyCredentials extends _Credentials { _ProxyCredentials(this.host, this.port, realm, _HttpClientCredentials creds) : super(creds, realm); - bool applies(_Proxy proxy, _AuthenticationScheme scheme) { + bool applies(_Proxy proxy, _AuthenticationScheme? scheme) { if (scheme != null && credentials.scheme != scheme) return false; return proxy.host == host && proxy.port == port; } @@ -3248,13 +3245,13 @@ class _ProxyCredentials extends _Credentials { if (credentials.scheme == _AuthenticationScheme.DIGEST && nonce == null) { return; } - credentials.authorizeProxy(this, request); + credentials.authorizeProxy(this, request as _HttpClientRequest); } } abstract class _HttpClientCredentials implements HttpClientCredentials { _AuthenticationScheme get scheme; - void authorize(_Credentials credentials, HttpClientRequest request); + void authorize(_Credentials credentials, _HttpClientRequest request); void authorizeProxy(_ProxyCredentials credentials, HttpClientRequest request); } @@ -3305,29 +3302,31 @@ class _HttpClientDigestCredentials extends _HttpClientCredentials ..add(requestUri.codeUnits); var ha2 = _CryptoUtils.bytesToHex(hasher.close()); - String qop; - String cnonce; - String nc; - hasher = new _MD5()..add(credentials.ha1.codeUnits)..add([_CharCode.COLON]); + bool isAuth = false; + String cnonce = ""; + String nc = ""; + hasher = new _MD5() + ..add(credentials.ha1!.codeUnits) + ..add([_CharCode.COLON]); if (credentials.qop == "auth") { - qop = credentials.qop; + isAuth = true; cnonce = _CryptoUtils.bytesToHex(_CryptoUtils.getRandomBytes(4)); - ++credentials.nonceCount; - nc = credentials.nonceCount.toRadixString(16); - nc = "00000000".substring(0, 8 - nc.length + 1) + nc; + var nonceCount = credentials.nonceCount! + 1; + credentials.nonceCount = nonceCount; + nc = nonceCount.toRadixString(16).padLeft(9, "0"); hasher - ..add(credentials.nonce.codeUnits) + ..add(credentials.nonce!.codeUnits) ..add([_CharCode.COLON]) ..add(nc.codeUnits) ..add([_CharCode.COLON]) ..add(cnonce.codeUnits) ..add([_CharCode.COLON]) - ..add(credentials.qop.codeUnits) + ..add("auth".codeUnits) ..add([_CharCode.COLON]) ..add(ha2.codeUnits); } else { hasher - ..add(credentials.nonce.codeUnits) + ..add(credentials.nonce!.codeUnits) ..add([_CharCode.COLON]) ..add(ha2.codeUnits); } @@ -3340,9 +3339,9 @@ class _HttpClientDigestCredentials extends _HttpClientCredentials ..write(', nonce="${credentials.nonce}"') ..write(', uri="$requestUri"') ..write(', algorithm="${credentials.algorithm}"'); - if (qop == "auth") { + if (isAuth) { buffer - ..write(', qop="$qop"') + ..write(', qop="auth"') ..write(', cnonce="$cnonce"') ..write(', nc="$nc"'); } @@ -3351,14 +3350,14 @@ class _HttpClientDigestCredentials extends _HttpClientCredentials } void authorize(_Credentials credentials, HttpClientRequest request) { - request.headers.set( - HttpHeaders.authorizationHeader, authorization(credentials, request)); + request.headers.set(HttpHeaders.authorizationHeader, + authorization(credentials, request as _HttpClientRequest)); } void authorizeProxy( _ProxyCredentials credentials, HttpClientRequest request) { request.headers.set(HttpHeaders.proxyAuthorizationHeader, - authorization(credentials, request)); + authorization(credentials, request as _HttpClientRequest)); } } diff --git a/sdk/lib/_http/http_parser.dart b/sdk/lib/_http/http_parser.dart index a67011e33a4..94597897490 100644 --- a/sdk/lib/_http/http_parser.dart +++ b/sdk/lib/_http/http_parser.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart._http; // Global constants. @@ -112,19 +110,19 @@ class _MessageType { */ class _HttpDetachedStreamSubscription implements StreamSubscription { StreamSubscription _subscription; - Uint8List _injectData; + Uint8List? _injectData; + Function? _userOnData; bool _isCanceled = false; - int _pauseCount = 1; - Function _userOnData; bool _scheduled = false; + int _pauseCount = 1; _HttpDetachedStreamSubscription( this._subscription, this._injectData, this._userOnData); bool get isPaused => _subscription.isPaused; - Future asFuture([T futureValue]) => - _subscription.asFuture(futureValue); + Future asFuture([T? futureValue]) => + _subscription.asFuture(futureValue as T); Future cancel() { _isCanceled = true; @@ -132,20 +130,20 @@ class _HttpDetachedStreamSubscription implements StreamSubscription { return _subscription.cancel(); } - void onData(void handleData(Uint8List data)) { + void onData(void handleData(Uint8List data)?) { _userOnData = handleData; _subscription.onData(handleData); } - void onDone(void handleDone()) { + void onDone(void handleDone()?) { _subscription.onDone(handleDone); } - void onError(Function handleError) { + void onError(Function? handleError) { _subscription.onError(handleError); } - void pause([Future resumeSignal]) { + void pause([Future? resumeSignal]) { if (_injectData == null) { _subscription.pause(resumeSignal); } else { @@ -177,21 +175,20 @@ class _HttpDetachedStreamSubscription implements StreamSubscription { // To ensure that 'subscription.isPaused' is false, we resume the // subscription here. This is fine as potential events are delayed. _subscription.resume(); - if (_userOnData != null) { - _userOnData(data); - } + _userOnData?.call(data); }); } } class _HttpDetachedIncoming extends Stream { - final StreamSubscription subscription; - final Uint8List bufferedData; + final StreamSubscription? subscription; + final Uint8List? bufferedData; _HttpDetachedIncoming(this.subscription, this.bufferedData); - StreamSubscription listen(void onData(Uint8List event), - {Function onError, void onDone(), bool cancelOnError}) { + StreamSubscription listen(void onData(Uint8List event)?, + {Function? onError, void onDone()?, bool? cancelOnError}) { + var subscription = this.subscription; if (subscription != null) { subscription ..onData(onData) @@ -205,7 +202,7 @@ class _HttpDetachedIncoming extends Stream { ..resume(); } else { // TODO(26379): add test for this branch. - return new Stream.fromIterable([bufferedData]).listen(onData, + return new Stream.fromIterable([bufferedData!]).listen(onData, onError: onError, onDone: onDone, cancelOnError: cancelOnError); } } @@ -236,13 +233,13 @@ class _HttpParser extends Stream<_HttpIncoming> { bool _parserCalled = false; // The data that is currently being parsed. - Uint8List _buffer; - int _index; + Uint8List? _buffer; + int _index = -1; final bool _requestParser; - int _state; - int _httpVersionIndex; - int _messageType; + int _state = _State.START; + int? _httpVersionIndex; + int _messageType = _MessageType.UNDETERMINED; int _statusCode = 0; int _statusCodeLength = 0; final List _method = []; @@ -252,11 +249,11 @@ class _HttpParser extends Stream<_HttpIncoming> { // The limit for method, uriOrReasonPhrase, header field and value int _headerSizeLimit = 8 * 1024; - int _httpVersion; + int _httpVersion = _HttpVersion.UNDETERMINED; int _transferLength = -1; - bool _persistentConnection; - bool _connectionUpgrade; - bool _chunked; + bool _persistentConnection = false; + bool _connectionUpgrade = false; + bool _chunked = false; bool _noMessageBody = false; int _remainingContent = -1; @@ -264,18 +261,18 @@ class _HttpParser extends Stream<_HttpIncoming> { bool _transferEncoding = false; bool connectMethod = false; - _HttpHeaders _headers; + _HttpHeaders? _headers; // The limit for parsing chunk size int _chunkSizeLimit = 0x7FFFFFFF; // The current incoming connection. - _HttpIncoming _incoming; - StreamSubscription _socketSubscription; + _HttpIncoming? _incoming; + StreamSubscription? _socketSubscription; bool _paused = true; bool _bodyPaused = false; - StreamController<_HttpIncoming> _controller; - StreamController _bodyController; + final StreamController<_HttpIncoming> _controller; + StreamController? _bodyController; factory _HttpParser.requestParser() { return new _HttpParser._(true); @@ -285,30 +282,28 @@ class _HttpParser extends Stream<_HttpIncoming> { return new _HttpParser._(false); } - _HttpParser._(this._requestParser) { - _controller = new StreamController<_HttpIncoming>( - sync: true, - onListen: () { - _paused = false; - }, - onPause: () { - _paused = true; - _pauseStateChanged(); - }, - onResume: () { - _paused = false; - _pauseStateChanged(); - }, - onCancel: () { - if (_socketSubscription != null) { - _socketSubscription.cancel(); - } - }); + _HttpParser._(this._requestParser) + : _controller = new StreamController<_HttpIncoming>(sync: true) { + _controller + ..onListen = () { + _paused = false; + } + ..onPause = () { + _paused = true; + _pauseStateChanged(); + } + ..onResume = () { + _paused = false; + _pauseStateChanged(); + } + ..onCancel = () { + _socketSubscription?.cancel(); + }; _reset(); } - StreamSubscription<_HttpIncoming> listen(void onData(_HttpIncoming event), - {Function onError, void onDone(), bool cancelOnError}) { + StreamSubscription<_HttpIncoming> listen(void onData(_HttpIncoming event)?, + {Function? onError, void onDone()?, bool? cancelOnError}) { return _controller.stream.listen(onData, onError: onError, onDone: onDone, cancelOnError: cancelOnError); } @@ -341,6 +336,7 @@ class _HttpParser extends Stream<_HttpIncoming> { // parsing and return. This will be in case of either an upgrade // request or a request or response with an empty body. bool _headersEnd() { + var headers = _headers!; // If method is CONNECT, response parser should ignore any Content-Length or // Transfer-Encoding header fields in a successful response. // [RFC 7231](https://tools.ietf.org/html/rfc7231#section-4.3.6) @@ -349,14 +345,14 @@ class _HttpParser extends Stream<_HttpIncoming> { _statusCode < 300 && connectMethod) { _transferLength = -1; - _headers.chunkedTransferEncoding = false; + headers.chunkedTransferEncoding = false; _chunked = false; - _headers.removeAll(HttpHeaders.contentLengthHeader); - _headers.removeAll(HttpHeaders.transferEncodingHeader); + headers.removeAll(HttpHeaders.contentLengthHeader); + headers.removeAll(HttpHeaders.transferEncodingHeader); } - _headers._mutable = false; + headers._mutable = false; - _transferLength = _headers.contentLength; + _transferLength = headers.contentLength; // Ignore the Content-Length header if Transfer-Encoding // is chunked (RFC 2616 section 4.4) if (_chunked) _transferLength = -1; @@ -373,30 +369,28 @@ class _HttpParser extends Stream<_HttpIncoming> { _state = _State.UPGRADED; _transferLength = 0; } - _createIncoming(_transferLength); + var incoming = _createIncoming(_transferLength); if (_requestParser) { - _incoming.method = new String.fromCharCodes(_method); - _incoming.uri = Uri.parse(new String.fromCharCodes(_uriOrReasonPhrase)); + incoming.method = new String.fromCharCodes(_method); + incoming.uri = Uri.parse(new String.fromCharCodes(_uriOrReasonPhrase)); } else { - _incoming.statusCode = _statusCode; - _incoming.reasonPhrase = new String.fromCharCodes(_uriOrReasonPhrase); + incoming.statusCode = _statusCode; + incoming.reasonPhrase = new String.fromCharCodes(_uriOrReasonPhrase); } _method.clear(); _uriOrReasonPhrase.clear(); if (_connectionUpgrade) { - _incoming.upgraded = true; + incoming.upgraded = true; _parserCalled = false; - var tmp = _incoming; _closeIncoming(); - _controller.add(tmp); + _controller.add(incoming); return true; } if (_transferLength == 0 || (_messageType == _MessageType.RESPONSE && _noMessageBody)) { _reset(); - var tmp = _incoming; _closeIncoming(); - _controller.add(tmp); + _controller.add(incoming); return false; } else if (_chunked) { _state = _State.CHUNK_SIZE; @@ -410,7 +404,7 @@ class _HttpParser extends Stream<_HttpIncoming> { _state = _State.BODY; } _parserCalled = false; - _controller.add(_incoming); + _controller.add(incoming); return true; } @@ -433,7 +427,7 @@ class _HttpParser extends Stream<_HttpIncoming> { throw HttpException("Data on failed connection"); } while (_buffer != null && - _index < _buffer.length && + _index < _buffer!.length && _state != _State.FAILURE && _state != _State.UPGRADED) { // Depending on _incoming, we either break on _bodyPaused or _paused. @@ -442,7 +436,9 @@ class _HttpParser extends Stream<_HttpIncoming> { _parserCalled = false; return; } - int byte = _buffer[_index++]; + int index = _index; + int byte = _buffer![index]; + _index = index + 1; switch (_state) { case _State.START: if (byte == _Const.HTTP[0]) { @@ -463,22 +459,23 @@ class _HttpParser extends Stream<_HttpIncoming> { break; case _State.METHOD_OR_RESPONSE_HTTP_VERSION: - if (_httpVersionIndex < _Const.HTTP.length && - byte == _Const.HTTP[_httpVersionIndex]) { + var httpVersionIndex = _httpVersionIndex!; + if (httpVersionIndex < _Const.HTTP.length && + byte == _Const.HTTP[httpVersionIndex]) { // Continue parsing HTTP version. - _httpVersionIndex++; - } else if (_httpVersionIndex == _Const.HTTP.length && + _httpVersionIndex = httpVersionIndex + 1; + } else if (httpVersionIndex == _Const.HTTP.length && byte == _CharCode.SLASH) { // HTTP/ parsed. As method is a token this cannot be a // method anymore. - _httpVersionIndex++; + _httpVersionIndex = httpVersionIndex + 1; if (_requestParser) { throw HttpException("Invalid request line"); } _state = _State.RESPONSE_HTTP_VERSION; } else { // Did not parse HTTP version. Expect method instead. - for (int i = 0; i < _httpVersionIndex; i++) { + for (int i = 0; i < httpVersionIndex; i++) { _addWithValidation(_method, _Const.HTTP[i]); } if (byte == _CharCode.SP) { @@ -495,23 +492,24 @@ class _HttpParser extends Stream<_HttpIncoming> { break; case _State.RESPONSE_HTTP_VERSION: - if (_httpVersionIndex < _Const.HTTP1DOT.length) { + var httpVersionIndex = _httpVersionIndex!; + if (httpVersionIndex < _Const.HTTP1DOT.length) { // Continue parsing HTTP version. - _expect(byte, _Const.HTTP1DOT[_httpVersionIndex]); - _httpVersionIndex++; - } else if (_httpVersionIndex == _Const.HTTP1DOT.length && + _expect(byte, _Const.HTTP1DOT[httpVersionIndex]); + _httpVersionIndex = httpVersionIndex + 1; + } else if (httpVersionIndex == _Const.HTTP1DOT.length && byte == _CharCode.ONE) { // HTTP/1.1 parsed. _httpVersion = _HttpVersion.HTTP11; _persistentConnection = true; - _httpVersionIndex++; - } else if (_httpVersionIndex == _Const.HTTP1DOT.length && + _httpVersionIndex = httpVersionIndex + 1; + } else if (httpVersionIndex == _Const.HTTP1DOT.length && byte == _CharCode.ZERO) { // HTTP/1.0 parsed. _httpVersion = _HttpVersion.HTTP10; _persistentConnection = false; - _httpVersionIndex++; - } else if (_httpVersionIndex == _Const.HTTP1DOT.length + 1) { + _httpVersionIndex = httpVersionIndex + 1; + } else if (httpVersionIndex == _Const.HTTP1DOT.length + 1) { _expect(byte, _CharCode.SP); // HTTP version parsed. _state = _State.RESPONSE_LINE_STATUS_CODE; @@ -550,20 +548,21 @@ class _HttpParser extends Stream<_HttpIncoming> { break; case _State.REQUEST_LINE_HTTP_VERSION: - if (_httpVersionIndex < _Const.HTTP1DOT.length) { - _expect(byte, _Const.HTTP11[_httpVersionIndex]); - _httpVersionIndex++; + var httpVersionIndex = _httpVersionIndex!; + if (httpVersionIndex < _Const.HTTP1DOT.length) { + _expect(byte, _Const.HTTP11[httpVersionIndex]); + _httpVersionIndex = httpVersionIndex + 1; } else if (_httpVersionIndex == _Const.HTTP1DOT.length) { if (byte == _CharCode.ONE) { // HTTP/1.1 parsed. _httpVersion = _HttpVersion.HTTP11; _persistentConnection = true; - _httpVersionIndex++; + _httpVersionIndex = httpVersionIndex + 1; } else if (byte == _CharCode.ZERO) { // HTTP/1.0 parsed. _httpVersion = _HttpVersion.HTTP10; _persistentConnection = false; - _httpVersionIndex++; + _httpVersionIndex = httpVersionIndex + 1; } else { throw HttpException("Invalid response, invalid HTTP version"); } @@ -627,12 +626,12 @@ class _HttpParser extends Stream<_HttpIncoming> { break; case _State.HEADER_START: - _headers = new _HttpHeaders(version); + _headers = new _HttpHeaders(version!); if (byte == _CharCode.CR) { _state = _State.HEADER_ENDING; } else if (byte == _CharCode.LF) { _state = _State.HEADER_ENDING; - _index--; // Make the new state see the LF again. + _index = _index - 1; // Make the new state see the LF again. } else { // Start of new header field. _addWithValidation(_headerField, _toLowerCaseByte(byte)); @@ -700,6 +699,7 @@ class _HttpParser extends Stream<_HttpIncoming> { _statusCode = HttpStatus.badRequest; } } + var headers = _headers!; if (headerField == HttpHeaders.connectionHeader) { List tokens = _tokenizeFieldValue(headerValue); final bool isResponse = _messageType == _MessageType.RESPONSE; @@ -713,10 +713,10 @@ class _HttpParser extends Stream<_HttpIncoming> { (isUpgrade && isResponse && isUpgradeCode)) { _connectionUpgrade = true; } - _headers._add(headerField, tokens[i]); + headers._add(headerField, tokens[i]); } } else { - _headers._add(headerField, headerValue); + headers._add(headerField, headerValue); } _headerField.clear(); _headerValue.clear(); @@ -725,7 +725,7 @@ class _HttpParser extends Stream<_HttpIncoming> { _state = _State.HEADER_ENDING; } else if (byte == _CharCode.LF) { _state = _State.HEADER_ENDING; - _index--; // Make the new state see the LF again. + _index = _index - 1; // Make the new state see the LF again. } else { // Start of new header field. _state = _State.HEADER_FIELD; @@ -794,8 +794,9 @@ class _HttpParser extends Stream<_HttpIncoming> { case _State.BODY: // The body is not handled one byte at a time but in blocks. - _index--; - int dataAvailable = _buffer.length - _index; + _index = _index - 1; + var buffer = _buffer!; + int dataAvailable = buffer.length - _index; if (_remainingContent >= 0 && dataAvailable > _remainingContent) { dataAvailable = _remainingContent; } @@ -803,12 +804,12 @@ class _HttpParser extends Stream<_HttpIncoming> { // cases like this, and the user will not experience different data // typed (which could lead to polymorphic user code). Uint8List data = new Uint8List.view( - _buffer.buffer, _buffer.offsetInBytes + _index, dataAvailable); - _bodyController.add(data); + buffer.buffer, buffer.offsetInBytes + _index, dataAvailable); + _bodyController!.add(data); if (_remainingContent != -1) { _remainingContent -= data.length; } - _index += data.length; + _index = _index + data.length; if (_remainingContent == 0) { if (!_chunked) { _reset(); @@ -832,18 +833,19 @@ class _HttpParser extends Stream<_HttpIncoming> { } _parserCalled = false; - if (_buffer != null && _index == _buffer.length) { + var buffer = _buffer; + if (buffer != null && _index == buffer.length) { // If all data is parsed release the buffer and resume receiving // data. _releaseBuffer(); if (_state != _State.UPGRADED && _state != _State.FAILURE) { - _socketSubscription.resume(); + _socketSubscription!.resume(); } } } void _onData(Uint8List buffer) { - _socketSubscription.pause(); + _socketSubscription!.pause(); assert(_buffer == null); _buffer = buffer; _index = 0; @@ -903,7 +905,7 @@ class _HttpParser extends Stream<_HttpIncoming> { _controller.close(); } - String get version { + String? get version { switch (_httpVersion) { case _HttpVersion.HTTP10: return "1.0"; @@ -918,7 +920,9 @@ class _HttpParser extends Stream<_HttpIncoming> { bool get upgrade => _connectionUpgrade && _state == _State.UPGRADED; bool get persistentConnection => _persistentConnection; - void set isHead(bool value) => _noMessageBody = value ?? false; + void set isHead(bool value) { + _noMessageBody = valueOfNonNullableParamWithDefault(value, false); + } _HttpDetachedIncoming detachIncoming() { // Simulate detached by marking as upgraded. @@ -926,10 +930,12 @@ class _HttpParser extends Stream<_HttpIncoming> { return new _HttpDetachedIncoming(_socketSubscription, readUnparsedData()); } - Uint8List readUnparsedData() { - if (_buffer == null) return null; - if (_index == _buffer.length) return null; - var result = _buffer.sublist(_index); + Uint8List? readUnparsedData() { + var buffer = _buffer; + if (buffer == null) return null; + var index = _index; + if (index == buffer.length) return null; + var result = buffer.sublist(index); _releaseBuffer(); return result; } @@ -963,7 +969,7 @@ class _HttpParser extends Stream<_HttpIncoming> { void _releaseBuffer() { _buffer = null; - _index = null; + _index = -1; } static bool _isTokenChar(int byte) { @@ -977,7 +983,7 @@ class _HttpParser extends Stream<_HttpIncoming> { } static List _tokenizeFieldValue(String headerValue) { - List tokens = new List(); + List tokens = []; int start = 0; int index = 0; while (index < headerValue.length) { @@ -1072,53 +1078,53 @@ class _HttpParser extends Stream<_HttpIncoming> { throw HttpException("$method exceeds the $_headerSizeLimit size limit"); } - void _createIncoming(int transferLength) { + _HttpIncoming _createIncoming(int transferLength) { assert(_incoming == null); assert(_bodyController == null); assert(!_bodyPaused); - var incoming; - _bodyController = new StreamController( - sync: true, - onListen: () { - if (incoming != _incoming) return; - assert(_bodyPaused); - _bodyPaused = false; - _pauseStateChanged(); - }, - onPause: () { - if (incoming != _incoming) return; - assert(!_bodyPaused); - _bodyPaused = true; - _pauseStateChanged(); - }, - onResume: () { - if (incoming != _incoming) return; - assert(_bodyPaused); - _bodyPaused = false; - _pauseStateChanged(); - }, - onCancel: () { - if (incoming != _incoming) return; - if (_socketSubscription != null) { - _socketSubscription.cancel(); - } - _closeIncoming(true); - _controller.close(); - }); - incoming = _incoming = - new _HttpIncoming(_headers, transferLength, _bodyController.stream); + var controller = + _bodyController = new StreamController(sync: true); + var incoming = _incoming = + new _HttpIncoming(_headers!, transferLength, controller.stream); + controller + ..onListen = () { + if (incoming != _incoming) return; + assert(_bodyPaused); + _bodyPaused = false; + _pauseStateChanged(); + } + ..onPause = () { + if (incoming != _incoming) return; + assert(!_bodyPaused); + _bodyPaused = true; + _pauseStateChanged(); + } + ..onResume = () { + if (incoming != _incoming) return; + assert(_bodyPaused); + _bodyPaused = false; + _pauseStateChanged(); + } + ..onCancel = () { + if (incoming != _incoming) return; + _socketSubscription?.cancel(); + _closeIncoming(true); + _controller.close(); + }; _bodyPaused = true; _pauseStateChanged(); + return incoming; } void _closeIncoming([bool closing = false]) { // Ignore multiple close (can happen in re-entrance). - if (_incoming == null) return; var tmp = _incoming; + if (tmp == null) return; tmp.close(closing); _incoming = null; - if (_bodyController != null) { - _bodyController.close(); + var controller = _bodyController; + if (controller != null) { + controller.close(); _bodyController = null; } _bodyPaused = false; @@ -1138,19 +1144,17 @@ class _HttpParser extends Stream<_HttpIncoming> { } void _reportHttpError(error, [stackTrace]) { - if (_socketSubscription != null) _socketSubscription.cancel(); + _socketSubscription?.cancel(); _state = _State.FAILURE; _controller.addError(error, stackTrace); _controller.close(); } void _reportBodyError(error, [stackTrace]) { - if (_socketSubscription != null) _socketSubscription.cancel(); + _socketSubscription?.cancel(); _state = _State.FAILURE; - _bodyController.addError(error, stackTrace); + _bodyController?.addError(error, stackTrace); // In case of drain(), error event will close the stream. - if (_bodyController != null) { - _bodyController.close(); - } + _bodyController?.close(); } } diff --git a/sdk/lib/_http/http_session.dart b/sdk/lib/_http/http_session.dart index 30b65af5bfd..407192a8620 100644 --- a/sdk/lib/_http/http_session.dart +++ b/sdk/lib/_http/http_session.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart._http; const String _DART_SESSION_ID = "DARTSESSID"; @@ -15,11 +13,11 @@ class _HttpSession implements HttpSession { bool _destroyed = false; bool _isNew = true; DateTime _lastSeen; - Function _timeoutCallback; + Function? _timeoutCallback; _HttpSessionManager _sessionManager; // Pointers in timeout queue. - _HttpSession _prev; - _HttpSession _next; + _HttpSession? _prev; + _HttpSession? _next; final String id; final Map _data = new HashMap(); @@ -27,6 +25,7 @@ class _HttpSession implements HttpSession { _HttpSession(this._sessionManager, this.id) : _lastSeen = new DateTime.now(); void destroy() { + assert(!_destroyed); _destroyed = true; _sessionManager._removeFromTimeoutQueue(this); _sessionManager._sessions.remove(id); @@ -43,7 +42,7 @@ class _HttpSession implements HttpSession { bool get isNew => _isNew; - void set onTimeout(void callback()) { + void set onTimeout(void callback()?) { _timeoutCallback = callback; } @@ -80,7 +79,7 @@ class _HttpSession implements HttpSession { } Map cast() => _data.cast(); - update(key, update(value), {ifAbsent()}) => + update(key, update(value), {ifAbsent()?}) => _data.update(key, update, ifAbsent: ifAbsent); void updateAll(update(key, value)) { @@ -104,9 +103,9 @@ class _HttpSession implements HttpSession { class _HttpSessionManager { Map _sessions; int _sessionTimeout = 20 * 60; // 20 mins. - _HttpSession _head; - _HttpSession _tail; - Timer _timer; + _HttpSession? _head; + _HttpSession? _tail; + Timer? _timer; _HttpSessionManager() : _sessions = {}; @@ -116,7 +115,7 @@ class _HttpSessionManager { return _CryptoUtils.bytesToHex(data); } - _HttpSession getSession(String id) => _sessions[id]; + _HttpSession? getSession(String id) => _sessions[id]; _HttpSession createSession() { var id = createSessionId(); @@ -152,55 +151,52 @@ class _HttpSessionManager { _startTimer(); } else { assert(_timer != null); - assert(_tail != null); + var tail = _tail!; // Add to end. - _tail._next = session; - session._prev = _tail; + tail._next = session; + session._prev = tail; _tail = session; } } void _removeFromTimeoutQueue(_HttpSession session) { - if (session._next != null) { - session._next._prev = session._prev; - } - if (session._prev != null) { - session._prev._next = session._next; + var next = session._next; + var prev = session._prev; + session._next = session._prev = null; + next?._prev = prev; + prev?._next = next; + if (_tail == session) { + _tail = prev; } if (_head == session) { + _head = next; // We removed the head element, start new timer. - _head = session._next; _stopTimer(); _startTimer(); } - if (_tail == session) { - _tail = session._prev; - } - session._next = session._prev = null; } void _timerTimeout() { _stopTimer(); // Clear timer. - assert(_head != null); - var session = _head; + var session = _head!; session.destroy(); // Will remove the session from timeout queue and map. - if (session._timeoutCallback != null) { - session._timeoutCallback(); - } + session._timeoutCallback?.call(); } void _startTimer() { assert(_timer == null); - if (_head != null) { - int seconds = new DateTime.now().difference(_head.lastSeen).inSeconds; + var head = _head; + if (head != null) { + int seconds = new DateTime.now().difference(head.lastSeen).inSeconds; _timer = new Timer( new Duration(seconds: _sessionTimeout - seconds), _timerTimeout); } } void _stopTimer() { - if (_timer != null) { - _timer.cancel(); + var timer = _timer; + if (timer != null) { + timer.cancel(); _timer = null; } } diff --git a/sdk/lib/_http/overrides.dart b/sdk/lib/_http/overrides.dart index 8b63209c8a1..bbd21eef792 100644 --- a/sdk/lib/_http/overrides.dart +++ b/sdk/lib/_http/overrides.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart._http; final _httpOverridesToken = new Object(); @@ -32,9 +30,9 @@ const _asyncRunZoned = runZoned; /// } /// ``` abstract class HttpOverrides { - static HttpOverrides _global; + static HttpOverrides? _global; - static HttpOverrides get current { + static HttpOverrides? get current { return Zone.current[_httpOverridesToken] ?? _global; } @@ -43,14 +41,14 @@ abstract class HttpOverrides { /// These are the [HttpOverrides] that will be used in the root Zone, and in /// Zone's that do not set [HttpOverrides] and whose ancestors up to the root /// Zone do not set [HttpOverrides]. - static set global(HttpOverrides overrides) { + static set global(HttpOverrides? overrides) { _global = overrides; } /// Runs [body] in a fresh [Zone] using the provided overrides. static R runZoned(R body(), - {HttpClient Function(SecurityContext) createHttpClient, - String Function(Uri uri, Map environment) + {HttpClient Function(SecurityContext?)? createHttpClient, + String Function(Uri uri, Map? environment)? findProxyFromEnvironment}) { HttpOverrides overrides = new _HttpOverridesScope(createHttpClient, findProxyFromEnvironment); @@ -71,7 +69,7 @@ abstract class HttpOverrides { /// /// When this override is installed, this function overrides the behavior of /// `new HttpClient`. - HttpClient createHttpClient(SecurityContext context) { + HttpClient createHttpClient(SecurityContext? context) { return new _HttpClient(context); } @@ -79,34 +77,37 @@ abstract class HttpOverrides { /// /// When this override is installed, this function overrides the behavior of /// `HttpClient.findProxyFromEnvironment`. - String findProxyFromEnvironment(Uri url, Map environment) { + String findProxyFromEnvironment(Uri url, Map? environment) { return _HttpClient._findProxyFromEnvironment(url, environment); } } class _HttpOverridesScope extends HttpOverrides { - final HttpOverrides _previous = HttpOverrides.current; - - final HttpClient Function(SecurityContext) _createHttpClient; - final String Function(Uri uri, Map environment) + final HttpOverrides? _previous = HttpOverrides.current; + final HttpClient Function(SecurityContext?)? _createHttpClient; + final String Function(Uri uri, Map? environment)? _findProxyFromEnvironment; _HttpOverridesScope(this._createHttpClient, this._findProxyFromEnvironment); @override - HttpClient createHttpClient(SecurityContext context) { - if (_createHttpClient != null) return _createHttpClient(context); - if (_previous != null) return _previous.createHttpClient(context); + HttpClient createHttpClient(SecurityContext? context) { + var createHttpClient = _createHttpClient; + if (createHttpClient != null) return createHttpClient(context); + var previous = _previous; + if (previous != null) return previous.createHttpClient(context); return super.createHttpClient(context); } @override - String findProxyFromEnvironment(Uri url, Map environment) { - if (_findProxyFromEnvironment != null) { - return _findProxyFromEnvironment(url, environment); + String findProxyFromEnvironment(Uri url, Map? environment) { + var findProxyFromEnvironment = _findProxyFromEnvironment; + if (findProxyFromEnvironment != null) { + return findProxyFromEnvironment(url, environment); } - if (_previous != null) { - return _previous.findProxyFromEnvironment(url, environment); + var previous = _previous; + if (previous != null) { + return previous.findProxyFromEnvironment(url, environment); } return super.findProxyFromEnvironment(url, environment); } diff --git a/sdk/lib/_http/websocket.dart b/sdk/lib/_http/websocket.dart index 45cc51173b3..c9c6246c094 100644 --- a/sdk/lib/_http/websocket.dart +++ b/sdk/lib/_http/websocket.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart._http; /** @@ -99,7 +97,7 @@ class CompressionOptions { /// If set to `null`, the client has no preference, and the compression can /// use up to its default maximum window size of 15 bits depending on the /// server's preference. - final int clientMaxWindowBits; + final int? clientMaxWindowBits; /// The maximal window size bit count requested by the server. /// @@ -109,7 +107,7 @@ class CompressionOptions { /// If set to `null`, the server has no preference, and the compression can /// use up to its default maximum window size of 15 bits depending on the /// client's preference. - final int serverMaxWindowBits; + final int? serverMaxWindowBits; /// Whether WebSocket compression is enabled. /// @@ -132,21 +130,18 @@ class CompressionOptions { /// value from headers. Defaults to [WebSocket.DEFAULT_WINDOW_BITS]. Returns a /// [_CompressionMaxWindowBits] object which contains the response headers and /// negotiated max window bits. - _CompressionMaxWindowBits _createServerResponseHeader(HeaderValue requested) { - var info = new _CompressionMaxWindowBits(); + _CompressionMaxWindowBits _createServerResponseHeader( + HeaderValue? requested) { + var info = new _CompressionMaxWindowBits("", 0); - int mwb; - String part; - if (requested?.parameters != null) { - part = requested.parameters[_serverMaxWindowBits]; - } + String? part = requested?.parameters[_serverMaxWindowBits]; if (part != null) { if (part.length >= 2 && part.startsWith('0')) { throw new ArgumentError("Illegal 0 padding on value."); } else { - mwb = serverMaxWindowBits == null - ? int.tryParse(part) ?? _WebSocketImpl.DEFAULT_WINDOW_BITS - : serverMaxWindowBits; + int mwb = serverMaxWindowBits ?? + int.tryParse(part) ?? + _WebSocketImpl.DEFAULT_WINDOW_BITS; info.headerValue = "; server_max_window_bits=${mwb}"; info.maxWindowBits = mwb; } @@ -158,7 +153,7 @@ class CompressionOptions { } /// Returns default values for client compression request headers. - String _createClientRequestHeader(HeaderValue requested, int size) { + String _createClientRequestHeader(HeaderValue? requested, int size) { var info = ""; // If responding to a valid request, specify size @@ -189,7 +184,7 @@ class CompressionOptions { /// `server_max_window_bits` value. This method returns a /// [_CompressionMaxWindowBits] object with the response headers and /// negotiated `maxWindowBits` value. - _CompressionMaxWindowBits _createHeader([HeaderValue requested]) { + _CompressionMaxWindowBits _createHeader([HeaderValue? requested]) { var info = new _CompressionMaxWindowBits("", 0); if (!enabled) { return info; @@ -266,8 +261,8 @@ abstract class WebSocketTransformer * then the [WebSocket] will be created with the default [CompressionOptions]. */ factory WebSocketTransformer( - {/*String|Future*/ protocolSelector(List protocols), - CompressionOptions compression: CompressionOptions.compressionDefault}) { + {/*String|Future*/ protocolSelector(List protocols)?, + CompressionOptions compression = CompressionOptions.compressionDefault}) { return new _WebSocketTransformerImpl(protocolSelector, compression); } @@ -289,8 +284,8 @@ abstract class WebSocketTransformer * then the [WebSocket] will be created with the default [CompressionOptions]. */ static Future upgrade(HttpRequest request, - {protocolSelector(List protocols), - CompressionOptions compression: CompressionOptions.compressionDefault}) { + {protocolSelector(List protocols)?, + CompressionOptions compression = CompressionOptions.compressionDefault}) { return _WebSocketTransformerImpl._upgrade( request, protocolSelector, compression); } @@ -347,7 +342,7 @@ abstract class WebSocket * * The default value is `null`. */ - Duration pingInterval; + Duration? pingInterval; /** * Create a new WebSocket connection. The URL supplied in [url] @@ -377,9 +372,9 @@ abstract class WebSocket * authentication when setting up the connection. */ static Future connect(String url, - {Iterable protocols, - Map headers, - CompressionOptions compression: + {Iterable? protocols, + Map? headers, + CompressionOptions compression = CompressionOptions.compressionDefault}) => _WebSocketImpl.connect(url, protocols, headers, compression: compression); @@ -407,9 +402,9 @@ abstract class WebSocket * then the [WebSocket] will be created with the default [CompressionOptions]. */ factory WebSocket.fromUpgradedSocket(Socket socket, - {String protocol, - bool serverSide, - CompressionOptions compression: CompressionOptions.compressionDefault}) { + {String? protocol, + bool? serverSide, + CompressionOptions compression = CompressionOptions.compressionDefault}) { if (serverSide == null) { throw new ArgumentError("The serverSide argument must be passed " "explicitly to WebSocket.fromUpgradedSocket."); @@ -436,19 +431,19 @@ abstract class WebSocket * selected by the server. If no subprotocol is negotiated the * value will remain [:null:]. */ - String get protocol; + String? get protocol; /** * The close code set when the WebSocket connection is closed. If * there is no close code available this property will be [:null:] */ - int get closeCode; + int? get closeCode; /** * The close reason set when the WebSocket connection is closed. If * there is no close reason available this property will be [:null:] */ - String get closeReason; + String? get closeReason; /** * Closes the WebSocket connection. Set the optional [code] and [reason] @@ -456,7 +451,7 @@ abstract class WebSocket * omitted, the peer will see [WebSocketStatus.noStatusReceived] code * with no reason. */ - Future close([int code, String reason]); + Future close([int? code, String? reason]); /** * Sends data on the WebSocket connection. The data in [data] must @@ -482,12 +477,12 @@ abstract class WebSocket /** * Gets the user agent used for WebSocket connections. */ - static String get userAgent => _WebSocketImpl.userAgent; + static String? get userAgent => _WebSocketImpl.userAgent; /** * Sets the user agent to use for WebSocket connections. */ - static set userAgent(String userAgent) { + static set userAgent(String? userAgent) { _WebSocketImpl.userAgent = userAgent; } } diff --git a/sdk/lib/_http/websocket_impl.dart b/sdk/lib/_http/websocket_impl.dart index 820dd694e08..68d0f2950cf 100644 --- a/sdk/lib/_http/websocket_impl.dart +++ b/sdk/lib/_http/websocket_impl.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart._http; const String _webSocketGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; @@ -51,7 +49,7 @@ class _EncodedString { class _CompressionMaxWindowBits { String headerValue; int maxWindowBits; - _CompressionMaxWindowBits([this.headerValue, this.maxWindowBits]); + _CompressionMaxWindowBits(this.headerValue, this.maxWindowBits); String toString() => headerValue; } @@ -91,16 +89,16 @@ class _WebSocketProtocolTransformer extends StreamTransformerBase, int _remainingPayloadBytes = -1; int _unmaskingIndex = 0; int _currentMessageType = _WebSocketMessageType.NONE; - int closeCode = WebSocketStatus.noStatusReceived; + int closeCode = WebSocketStatus.NO_STATUS_RECEIVED; String closeReason = ""; - EventSink|_WebSocketPing|_WebSocketPong*/ > _eventSink; + EventSink|_WebSocketPing|_WebSocketPong*/ >? _eventSink; final bool _serverSide; - final List _maskingBytes = new List(4); + final Uint8List _maskingBytes = Uint8List(4); final BytesBuilder _payload = new BytesBuilder(copy: false); - _WebSocketPerMessageDeflate _deflate; + _WebSocketPerMessageDeflate? _deflate; _WebSocketProtocolTransformer([this._serverSide = false, this._deflate]); Stream|_WebSocketPing|_WebSocketPong*/ > bind( @@ -114,13 +112,14 @@ class _WebSocketProtocolTransformer extends StreamTransformerBase, }); } - void addError(Object error, [StackTrace stackTrace]) { + void addError(Object error, [StackTrace? stackTrace]) { + // TODO(40614): Remove once non-nullability is sound. ArgumentError.checkNotNull(error, "error"); - _eventSink.addError(error, stackTrace); + _eventSink!.addError(error, stackTrace); } void close() { - _eventSink.close(); + _eventSink!.close(); } /** @@ -308,13 +307,13 @@ class _WebSocketProtocolTransformer extends StreamTransformerBase, switch (_opcode) { case _WebSocketOpcode.CLOSE: _state = CLOSED; - _eventSink.close(); + _eventSink!.close(); break; case _WebSocketOpcode.PING: - _eventSink.add(new _WebSocketPing()); + _eventSink!.add(new _WebSocketPing()); break; case _WebSocketOpcode.PONG: - _eventSink.add(new _WebSocketPong()); + _eventSink!.add(new _WebSocketPong()); break; } _prepareForNextFrame(); @@ -329,16 +328,17 @@ class _WebSocketProtocolTransformer extends StreamTransformerBase, void _messageFrameEnd() { if (_fin) { var bytes = _payload.takeBytes(); - if (_deflate != null && _compressed) { - bytes = _deflate.processIncomingMessage(bytes); + var deflate = _deflate; + if (deflate != null && _compressed) { + bytes = deflate.processIncomingMessage(bytes); } switch (_currentMessageType) { case _WebSocketMessageType.TEXT: - _eventSink.add(utf8.decode(bytes)); + _eventSink!.add(utf8.decode(bytes)); break; case _WebSocketMessageType.BINARY: - _eventSink.add(bytes); + _eventSink!.add(bytes); break; } _currentMessageType = _WebSocketMessageType.NONE; @@ -364,15 +364,15 @@ class _WebSocketProtocolTransformer extends StreamTransformerBase, } } _state = CLOSED; - _eventSink.close(); + _eventSink!.close(); break; case _WebSocketOpcode.PING: - _eventSink.add(new _WebSocketPing(_payload.takeBytes())); + _eventSink!.add(new _WebSocketPing(_payload.takeBytes())); break; case _WebSocketOpcode.PONG: - _eventSink.add(new _WebSocketPong(_payload.takeBytes())); + _eventSink!.add(new _WebSocketPong(_payload.takeBytes())); break; } _prepareForNextFrame(); @@ -397,12 +397,12 @@ class _WebSocketProtocolTransformer extends StreamTransformerBase, } class _WebSocketPing { - final List payload; + final List? payload; _WebSocketPing([this.payload = null]); } class _WebSocketPong { - final List payload; + final List? payload; _WebSocketPong([this.payload = null]); } @@ -413,7 +413,7 @@ class _WebSocketTransformerImpl implements WebSocketTransformer { final StreamController _controller = new StreamController(sync: true); - final _ProtocolSelector _protocolSelector; + final _ProtocolSelector? _protocolSelector; final CompressionOptions _compression; _WebSocketTransformerImpl(this._protocolSelector, this._compression); @@ -431,7 +431,7 @@ class _WebSocketTransformerImpl } static List _tokenizeFieldValue(String headerValue) { - List tokens = new List(); + List tokens = []; int start = 0; int index = 0; while (index < headerValue.length) { @@ -448,7 +448,7 @@ class _WebSocketTransformerImpl } static Future _upgrade(HttpRequest request, - _ProtocolSelector _protocolSelector, CompressionOptions compression) { + _ProtocolSelector? protocolSelector, CompressionOptions compression) { var response = request.response; if (!_isUpgradeRequest(request)) { // Send error response. @@ -459,13 +459,13 @@ class _WebSocketTransformerImpl new WebSocketException("Invalid WebSocket upgrade request")); } - Future upgrade(String protocol) { + Future upgrade(String? protocol) { // Send the upgrade response. response ..statusCode = HttpStatus.switchingProtocols ..headers.add(HttpHeaders.connectionHeader, "Upgrade") ..headers.add(HttpHeaders.upgradeHeader, "websocket"); - String key = request.headers.value("Sec-WebSocket-Key"); + String key = request.headers.value("Sec-WebSocket-Key")!; _SHA1 sha1 = new _SHA1(); sha1.add("$key$_webSocketGUID".codeUnits); String accept = _CryptoUtils.bytesToBase64(sha1.close()); @@ -483,14 +483,14 @@ class _WebSocketTransformerImpl } var protocols = request.headers['Sec-WebSocket-Protocol']; - if (protocols != null && _protocolSelector != null) { + if (protocols != null && protocolSelector != null) { // The suggested protocols can be spread over multiple lines, each // consisting of multiple protocols. To unify all of them, first join // the lists with ', ' and then tokenize. - protocols = _tokenizeFieldValue(protocols.join(', ')); - return new Future(() => _protocolSelector(protocols)) + var tokenizedProtocols = _tokenizeFieldValue(protocols.join(', ')); + return new Future(() => protocolSelector(tokenizedProtocols)) .then((protocol) { - if (protocols.indexOf(protocol) < 0) { + if (tokenizedProtocols.indexOf(protocol) < 0) { throw new WebSocketException( "Selected protocol is not in the list of available protocols"); } @@ -506,7 +506,7 @@ class _WebSocketTransformerImpl } } - static _WebSocketPerMessageDeflate _negotiateCompression(HttpRequest request, + static _WebSocketPerMessageDeflate? _negotiateCompression(HttpRequest request, HttpResponse response, CompressionOptions compression) { var extensionHeader = request.headers.value("Sec-WebSocket-Extensions"); @@ -540,23 +540,27 @@ class _WebSocketTransformerImpl if (request.method != "GET") { return false; } - if (request.headers[HttpHeaders.connectionHeader] == null) { + var connectionHeader = request.headers[HttpHeaders.connectionHeader]; + if (connectionHeader == null) { return false; } bool isUpgrade = false; - request.headers[HttpHeaders.connectionHeader].forEach((String value) { - if (value.toLowerCase() == "upgrade") isUpgrade = true; - }); + for (var value in connectionHeader) { + if (value.toLowerCase() == "upgrade") { + isUpgrade = true; + break; + } + } if (!isUpgrade) return false; - String upgrade = request.headers.value(HttpHeaders.upgradeHeader); + String? upgrade = request.headers.value(HttpHeaders.upgradeHeader); if (upgrade == null || upgrade.toLowerCase() != "websocket") { return false; } - String version = request.headers.value("Sec-WebSocket-Version"); + String? version = request.headers.value("Sec-WebSocket-Version"); if (version == null || version != "13") { return false; } - String key = request.headers.value("Sec-WebSocket-Key"); + String? key = request.headers.value("Sec-WebSocket-Key"); if (key == null) { return false; } @@ -571,34 +575,26 @@ class _WebSocketPerMessageDeflate { int serverMaxWindowBits; bool serverSide; - RawZLibFilter decoder; - RawZLibFilter encoder; + RawZLibFilter? decoder; + RawZLibFilter? encoder; _WebSocketPerMessageDeflate( - {this.clientMaxWindowBits: _WebSocketImpl.DEFAULT_WINDOW_BITS, - this.serverMaxWindowBits: _WebSocketImpl.DEFAULT_WINDOW_BITS, - this.serverNoContextTakeover: false, - this.clientNoContextTakeover: false, - this.serverSide: false}); + {this.clientMaxWindowBits = _WebSocketImpl.DEFAULT_WINDOW_BITS, + this.serverMaxWindowBits = _WebSocketImpl.DEFAULT_WINDOW_BITS, + this.serverNoContextTakeover = false, + this.clientNoContextTakeover = false, + this.serverSide = false}); - void _ensureDecoder() { - if (decoder == null) { - decoder = new RawZLibFilter.inflateFilter( - windowBits: serverSide ? clientMaxWindowBits : serverMaxWindowBits, - raw: true); - } - } + RawZLibFilter _ensureDecoder() => decoder ??= new RawZLibFilter.inflateFilter( + windowBits: serverSide ? clientMaxWindowBits : serverMaxWindowBits, + raw: true); - void _ensureEncoder() { - if (encoder == null) { - encoder = new RawZLibFilter.deflateFilter( - windowBits: serverSide ? serverMaxWindowBits : clientMaxWindowBits, - raw: true); - } - } + RawZLibFilter _ensureEncoder() => encoder ??= new RawZLibFilter.deflateFilter( + windowBits: serverSide ? serverMaxWindowBits : clientMaxWindowBits, + raw: true); Uint8List processIncomingMessage(List msg) { - _ensureDecoder(); + var decoder = _ensureDecoder(); var data = []; data.addAll(msg); @@ -608,20 +604,22 @@ class _WebSocketPerMessageDeflate { final result = new BytesBuilder(); List out; - while ((out = decoder.processed()) != null) { + while (true) { + final out = decoder.processed(); + if (out == null) break; result.add(out); } if ((serverSide && clientNoContextTakeover) || (!serverSide && serverNoContextTakeover)) { - decoder = null; + this.decoder = null; } return result.takeBytes(); } List processOutgoingMessage(List msg) { - _ensureEncoder(); + var encoder = _ensureEncoder(); var result = []; Uint8List buffer; @@ -639,14 +637,15 @@ class _WebSocketPerMessageDeflate { encoder.process(buffer, 0, buffer.length); - List out; - while ((out = encoder.processed()) != null) { + while (true) { + final out = encoder.processed(); + if (out == null) break; result.addAll(out); } if ((!serverSide && clientNoContextTakeover) || (serverSide && serverNoContextTakeover)) { - encoder = null; + this.encoder = null; } if (result.length > 4) { @@ -670,13 +669,12 @@ class _WebSocketPerMessageDeflate { class _WebSocketOutgoingTransformer extends StreamTransformerBase> implements EventSink { final _WebSocketImpl webSocket; - EventSink> _eventSink; + EventSink>? _eventSink; - _WebSocketPerMessageDeflate _deflateHelper; + _WebSocketPerMessageDeflate? _deflateHelper; - _WebSocketOutgoingTransformer(this.webSocket) { - _deflateHelper = webSocket._deflate; - } + _WebSocketOutgoingTransformer(this.webSocket) + : _deflateHelper = webSocket._deflate; Stream> bind(Stream stream) { return new Stream>.eventTransformed(stream, @@ -698,53 +696,55 @@ class _WebSocketOutgoingTransformer addFrame(_WebSocketOpcode.PING, message.payload); return; } - List data; + List? data; int opcode; if (message != null) { + List messageData; if (message is String) { opcode = _WebSocketOpcode.TEXT; - data = utf8.encode(message); + messageData = utf8.encode(message); } else if (message is List) { opcode = _WebSocketOpcode.BINARY; - data = message; + messageData = message; } else if (message is _EncodedString) { opcode = _WebSocketOpcode.TEXT; - data = message.bytes; + messageData = message.bytes; } else { throw new ArgumentError(message); } - - if (_deflateHelper != null) { - data = _deflateHelper.processOutgoingMessage(data); + var deflateHelper = _deflateHelper; + if (deflateHelper != null) { + messageData = deflateHelper.processOutgoingMessage(messageData); } + data = messageData; } else { opcode = _WebSocketOpcode.TEXT; } addFrame(opcode, data); } - void addError(Object error, [StackTrace stackTrace]) { + void addError(Object error, [StackTrace? stackTrace]) { + // TODO(40614): Remove once non-nullability is sound. ArgumentError.checkNotNull(error, "error"); - _eventSink.addError(error, stackTrace); + _eventSink!.addError(error, stackTrace); } void close() { - int code = webSocket._outCloseCode; - String reason = webSocket._outCloseReason; - List data; + int? code = webSocket._outCloseCode; + String? reason = webSocket._outCloseReason; + List? data; if (code != null) { - data = new List(); - data.add((code >> 8) & 0xFF); - data.add(code & 0xFF); - if (reason != null) { - data.addAll(utf8.encode(reason)); - } + data = [ + (code >> 8) & 0xFF, + code & 0xFF, + if (reason != null) ...utf8.encode(reason) + ]; } addFrame(_WebSocketOpcode.CLOSE, data); - _eventSink.close(); + _eventSink!.close(); } - void addFrame(int opcode, List data) { + void addFrame(int opcode, List? data) { createFrame( opcode, data, @@ -753,12 +753,12 @@ class _WebSocketOutgoingTransformer (opcode == _WebSocketOpcode.TEXT || opcode == _WebSocketOpcode.BINARY)) .forEach((e) { - _eventSink.add(e); + _eventSink!.add(e); }); } static Iterable> createFrame( - int opcode, List data, bool serverSide, bool compressed) { + int opcode, List? data, bool serverSide, bool compressed) { bool mask = !serverSide; // Masking not implemented for server. int dataLength = data == null ? 0 : data.length; // Determine the header size. @@ -849,58 +849,59 @@ class _WebSocketOutgoingTransformer class _WebSocketConsumer implements StreamConsumer { final _WebSocketImpl webSocket; final Socket socket; - StreamController _controller; - StreamSubscription _subscription; + StreamController? _controller; + StreamSubscription? _subscription; bool _issuedPause = false; bool _closed = false; Completer _closeCompleter = new Completer(); - Completer _completer; + Completer? _completer; _WebSocketConsumer(this.webSocket, this.socket); void _onListen() { - if (_subscription != null) { - _subscription.cancel(); - } + _subscription?.cancel(); } void _onPause() { - if (_subscription != null) { - _subscription.pause(); + var subscription = _subscription; + if (subscription != null) { + subscription.pause(); } else { _issuedPause = true; } } void _onResume() { - if (_subscription != null) { - _subscription.resume(); + var subscription = _subscription; + if (subscription != null) { + subscription.resume(); } else { _issuedPause = false; } } void _cancel() { - if (_subscription != null) { - var subscription = _subscription; + var subscription = _subscription; + if (subscription != null) { _subscription = null; subscription.cancel(); } } - _ensureController() { - if (_controller != null) return; - _controller = new StreamController( + StreamController _ensureController() { + var controller = _controller; + if (controller != null) return controller; + controller = _controller = new StreamController( sync: true, onPause: _onPause, onResume: _onResume, onCancel: _onListen); - var stream = _controller.stream + var stream = controller.stream .transform(new _WebSocketOutgoingTransformer(webSocket)); socket.addStream(stream).then((_) { _done(); _closeCompleter.complete(webSocket); - }, onError: (error, StackTrace stackTrace) { + }, onError: (Object error, StackTrace stackTrace) { _closed = true; _cancel(); if (error is ArgumentError) { @@ -912,53 +913,52 @@ class _WebSocketConsumer implements StreamConsumer { _closeCompleter.complete(webSocket); } }); + return controller; } - bool _done([error, StackTrace stackTrace]) { - if (_completer == null) return false; + bool _done([Object? error, StackTrace? stackTrace]) { + var completer = _completer; + if (completer == null) return false; if (error != null) { - _completer.completeError(error, stackTrace); + completer.completeError(error, stackTrace); } else { - _completer.complete(webSocket); + completer.complete(webSocket); } _completer = null; return true; } - Future addStream(var stream) { + Future addStream(Stream stream) { if (_closed) { stream.listen(null).cancel(); return new Future.value(webSocket); } _ensureController(); - _completer = new Completer(); - _subscription = stream.listen((data) { - _controller.add(data); + var completer = _completer = new Completer(); + var subscription = _subscription = stream.listen((data) { + _controller!.add(data); }, onDone: _done, onError: _done, cancelOnError: true); if (_issuedPause) { - _subscription.pause(); + subscription.pause(); _issuedPause = false; } - return _completer.future; + return completer.future; } Future close() { - _ensureController(); - Future closeSocket() { - return socket.close().catchError((_) {}).then((_) => webSocket); - } + _ensureController().close(); - _controller.close(); - return _closeCompleter.future.then((_) => closeSocket()); + return _closeCompleter.future + .then((_) => socket.close().catchError((_) {}).then((_) => webSocket)); } void add(data) { if (_closed) return; - _ensureController(); + var controller = _ensureController(); // Stop sending message if _controller has been closed. // https://github.com/dart-lang/sdk/issues/37441 - if (_controller.isClosed) return; - _controller.add(data); + if (controller.isClosed) return; + controller.add(data); } void closeSocket() { @@ -974,32 +974,33 @@ class _WebSocketImpl extends Stream with _ServiceObject implements WebSocket { static const int DEFAULT_WINDOW_BITS = 15; static const String PER_MESSAGE_DEFLATE = "permessage-deflate"; - final String protocol; + final String? protocol; - StreamController _controller; - StreamSubscription _subscription; - StreamSink _sink; + final StreamController _controller; + StreamSubscription? _subscription; + late StreamSink _sink; - final _socket; + final Socket _socket; final bool _serverSide; int _readyState = WebSocket.connecting; bool _writeClosed = false; - int _closeCode; - String _closeReason; - Duration _pingInterval; - Timer _pingTimer; - _WebSocketConsumer _consumer; + int? _closeCode; + String? _closeReason; + Duration? _pingInterval; + Timer? _pingTimer; + late _WebSocketConsumer _consumer; - int _outCloseCode; - String _outCloseReason; - Timer _closeTimer; - _WebSocketPerMessageDeflate _deflate; + int? _outCloseCode; + String? _outCloseReason; + Timer? _closeTimer; + _WebSocketPerMessageDeflate? _deflate; static final HttpClient _httpClient = new HttpClient(); static Future connect( - String url, Iterable protocols, Map headers, - {CompressionOptions compression: CompressionOptions.compressionDefault}) { + String url, Iterable? protocols, Map? headers, + {CompressionOptions compression = + CompressionOptions.compressionDefault}) { Uri uri = Uri.parse(url); if (uri.scheme != "ws" && uri.scheme != "wss") { throw new WebSocketException("Unsupported URL scheme '${uri.scheme}'"); @@ -1049,7 +1050,7 @@ class _WebSocketImpl extends Stream with _ServiceObject implements WebSocket { return request.close(); }).then((response) { - void error(String message) { + Never error(String message) { // Flush data. response.detachSocket().then((socket) { socket.destroy(); @@ -1057,15 +1058,15 @@ class _WebSocketImpl extends Stream with _ServiceObject implements WebSocket { throw new WebSocketException(message); } + var connectionHeader = response.headers[HttpHeaders.connectionHeader]; if (response.statusCode != HttpStatus.switchingProtocols || - response.headers[HttpHeaders.connectionHeader] == null || - !response.headers[HttpHeaders.connectionHeader] - .any((value) => value.toLowerCase() == "upgrade") || - response.headers.value(HttpHeaders.upgradeHeader).toLowerCase() != + connectionHeader == null || + !connectionHeader.any((value) => value.toLowerCase() == "upgrade") || + response.headers.value(HttpHeaders.upgradeHeader)!.toLowerCase() != "websocket") { error("Connection to '$uri' was not upgraded to websocket"); } - String accept = response.headers.value("Sec-WebSocket-Accept"); + String? accept = response.headers.value("Sec-WebSocket-Accept"); if (accept == null) { error("Response did not contain a 'Sec-WebSocket-Accept' header"); } @@ -1083,7 +1084,7 @@ class _WebSocketImpl extends Stream with _ServiceObject implements WebSocket { } var protocol = response.headers.value('Sec-WebSocket-Protocol'); - _WebSocketPerMessageDeflate deflate = + _WebSocketPerMessageDeflate? deflate = negotiateClientCompression(response, compression); return response.detachSocket().then((socket) => @@ -1092,13 +1093,10 @@ class _WebSocketImpl extends Stream with _ServiceObject implements WebSocket { }); } - static _WebSocketPerMessageDeflate negotiateClientCompression( + static _WebSocketPerMessageDeflate? negotiateClientCompression( HttpClientResponse response, CompressionOptions compression) { - String extensionHeader = response.headers.value('Sec-WebSocket-Extensions'); - - if (extensionHeader == null) { - extensionHeader = ""; - } + String extensionHeader = + response.headers.value('Sec-WebSocket-Extensions') ?? ""; var hv = HeaderValue.parse(extensionHeader, valueSeparator: ','); @@ -1129,14 +1127,15 @@ class _WebSocketImpl extends Stream with _ServiceObject implements WebSocket { _WebSocketImpl._fromSocket( this._socket, this.protocol, CompressionOptions compression, - [this._serverSide = false, _WebSocketPerMessageDeflate deflate]) { + [this._serverSide = false, _WebSocketPerMessageDeflate? deflate]) + : _controller = new StreamController(sync: true) { _consumer = new _WebSocketConsumer(this, _socket); _sink = new _StreamSinkImpl(_consumer); _readyState = WebSocket.open; _deflate = deflate; - var transformer = new _WebSocketProtocolTransformer(_serverSide, _deflate); - _subscription = transformer.bind(_socket).listen((data) { + var transformer = new _WebSocketProtocolTransformer(_serverSide, deflate); + var subscription = _subscription = transformer.bind(_socket).listen((data) { if (data is _WebSocketPing) { if (!_writeClosed) _consumer.add(new _WebSocketPong(data.payload)); } else if (data is _WebSocketPong) { @@ -1145,8 +1144,8 @@ class _WebSocketImpl extends Stream with _ServiceObject implements WebSocket { } else { _controller.add(data); } - }, onError: (error, stackTrace) { - if (_closeTimer != null) _closeTimer.cancel(); + }, onError: (Object error, StackTrace stackTrace) { + _closeTimer?.cancel(); if (error is FormatException) { _close(WebSocketStatus.invalidFramePayloadData); } else { @@ -1157,7 +1156,7 @@ class _WebSocketImpl extends Stream with _ServiceObject implements WebSocket { _closeReason = _outCloseReason; _controller.close(); }, onDone: () { - if (_closeTimer != null) _closeTimer.cancel(); + _closeTimer?.cancel(); if (_readyState == WebSocket.open) { _readyState = WebSocket.closing; if (!_isReservedStatusCode(transformer.closeCode)) { @@ -1172,39 +1171,38 @@ class _WebSocketImpl extends Stream with _ServiceObject implements WebSocket { _closeReason = transformer.closeReason; _controller.close(); }, cancelOnError: true); - _subscription.pause(); - _controller = new StreamController( - sync: true, - onListen: _subscription.resume, - onCancel: () { - _subscription.cancel(); - _subscription = null; - }, - onPause: _subscription.pause, - onResume: _subscription.resume); + subscription.pause(); + _controller + ..onListen = subscription.resume + ..onCancel = () { + _subscription!.cancel(); + _subscription = null; + } + ..onPause = subscription.pause + ..onResume = subscription.resume; _webSockets[_serviceId] = this; } - StreamSubscription listen(void onData(message), - {Function onError, void onDone(), bool cancelOnError}) { + StreamSubscription listen(void onData(message)?, + {Function? onError, void onDone()?, bool? cancelOnError}) { return _controller.stream.listen(onData, onError: onError, onDone: onDone, cancelOnError: cancelOnError); } - Duration get pingInterval => _pingInterval; + Duration? get pingInterval => _pingInterval; - void set pingInterval(Duration interval) { + void set pingInterval(Duration? interval) { if (_writeClosed) return; - if (_pingTimer != null) _pingTimer.cancel(); + _pingTimer?.cancel(); _pingInterval = interval; - if (_pingInterval == null) return; + if (interval == null) return; - _pingTimer = new Timer(_pingInterval, () { + _pingTimer = new Timer(interval, () { if (_writeClosed) return; _consumer.add(new _WebSocketPing()); - _pingTimer = new Timer(_pingInterval, () { + _pingTimer = new Timer(interval, () { _closeTimer?.cancel(); // No pong received. _close(WebSocketStatus.goingAway); @@ -1217,27 +1215,28 @@ class _WebSocketImpl extends Stream with _ServiceObject implements WebSocket { int get readyState => _readyState; - String get extensions => null; - int get closeCode => _closeCode; - String get closeReason => _closeReason; + String get extensions => ""; + int? get closeCode => _closeCode; + String? get closeReason => _closeReason; void add(data) { _sink.add(data); } void addUtf8Text(List bytes) { + // TODO(40614): Remove once non-nullability is sound. ArgumentError.checkNotNull(bytes, "bytes"); _sink.add(new _EncodedString(bytes)); } - void addError(error, [StackTrace stackTrace]) { + void addError(Object error, [StackTrace? stackTrace]) { _sink.addError(error, stackTrace); } Future addStream(Stream stream) => _sink.addStream(stream); Future get done => _sink.done; - Future close([int code, String reason]) { + Future close([int? code, String? reason]) { if (_isReservedStatusCode(code)) { throw new WebSocketException("Reserved status code $code"); } @@ -1260,7 +1259,7 @@ class _WebSocketImpl extends Stream with _ServiceObject implements WebSocket { // Reuse code and reason from the local close. _closeCode = _outCloseCode; _closeReason = _outCloseReason; - if (_subscription != null) _subscription.cancel(); + _subscription?.cancel(); _controller.close(); _webSockets.remove(_serviceId); }); @@ -1269,13 +1268,13 @@ class _WebSocketImpl extends Stream with _ServiceObject implements WebSocket { return _sink.close(); } - static String get userAgent => _httpClient.userAgent; + static String? get userAgent => _httpClient.userAgent; - static set userAgent(String userAgent) { + static set userAgent(String? userAgent) { _httpClient.userAgent = userAgent; } - void _close([int code, String reason]) { + void _close([int? code, String? reason]) { if (_writeClosed) return; if (_outCloseCode == null) { _outCloseCode = code; @@ -1301,7 +1300,7 @@ class _WebSocketImpl extends Stream with _ServiceObject implements WebSocket { return r; } try { - r['socket'] = _socket._toJSON(true); + r['socket'] = (_socket as dynamic)._toJSON(true); } catch (_) { r['socket'] = { 'id': _servicePath, @@ -1313,7 +1312,7 @@ class _WebSocketImpl extends Stream with _ServiceObject implements WebSocket { return r; } - static bool _isReservedStatusCode(int code) { + static bool _isReservedStatusCode(int? code) { return code != null && (code < WebSocketStatus.normalClosure || code == WebSocketStatus.reserved1004 || diff --git a/sdk_nnbd/lib/_internal/allowed_experiments.json b/sdk/lib/_internal/allowed_experiments.json similarity index 100% rename from sdk_nnbd/lib/_internal/allowed_experiments.json rename to sdk/lib/_internal/allowed_experiments.json diff --git a/sdk/lib/_internal/js_dev_runtime/libraries.dart b/sdk/lib/_internal/js_dev_runtime/libraries.dart deleted file mode 100644 index 88b2efae1a9..00000000000 --- a/sdk/lib/_internal/js_dev_runtime/libraries.dart +++ /dev/null @@ -1,313 +0,0 @@ -// Copyright (c) 2012, 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.6 - -library libraries; - -/** - * A bit flag used by [LibraryInfo] indicating that a library is used by dart2js - */ -const int DART2JS_PLATFORM = 1; - -/** - * A bit flag used by [LibraryInfo] indicating that a library is used by the VM - */ -const int VM_PLATFORM = 2; - -/// The contexts that a library can be used from. -enum Category { - /// Indicates that a library can be used in a browser context. - client, - - /// Indicates that a library can be used in a command line context. - server, - - /// Indicates that a library can be used from embedded devices. - embedded -} - -Category parseCategory(String name) { - switch (name) { - case "Client": - return Category.client; - case "Server": - return Category.server; - case "Embedded": - return Category.embedded; - } - return null; -} - -/// Mapping of "dart:" library name (e.g. "core") to information about that -/// library. -const Map libraries = const { - "async": const LibraryInfo("async/async.dart", - categories: "Client,Server", - maturity: Maturity.STABLE, - dart2jsPatchPath: "_internal/js_runtime/lib/async_patch.dart"), - "collection": const LibraryInfo("collection/collection.dart", - categories: "Client,Server,Embedded", - maturity: Maturity.STABLE, - dart2jsPatchPath: "_internal/js_runtime/lib/collection_patch.dart"), - "convert": const LibraryInfo("convert/convert.dart", - categories: "Client,Server", - maturity: Maturity.STABLE, - dart2jsPatchPath: "_internal/js_runtime/lib/convert_patch.dart"), - "core": const LibraryInfo("core/core.dart", - categories: "Client,Server,Embedded", - maturity: Maturity.STABLE, - dart2jsPatchPath: "_internal/js_runtime/lib/core_patch.dart"), - "developer": const LibraryInfo("developer/developer.dart", - categories: "Client,Server,Embedded", - maturity: Maturity.UNSTABLE, - dart2jsPatchPath: "_internal/js_runtime/lib/developer_patch.dart"), - "html": const LibraryInfo("html/dart2js/html_dart2js.dart", - categories: "Client", - maturity: Maturity.WEB_STABLE, - platforms: DART2JS_PLATFORM), - "html_common": const LibraryInfo("html/html_common/html_common.dart", - categories: "Client", - maturity: Maturity.WEB_STABLE, - dart2jsPath: "html/html_common/html_common_dart2js.dart", - documented: false, - implementation: true), - "indexed_db": const LibraryInfo("indexed_db/dart2js/indexed_db_dart2js.dart", - categories: "Client", - maturity: Maturity.WEB_STABLE, - platforms: DART2JS_PLATFORM), - "_http": - const LibraryInfo("_http/http.dart", categories: "", documented: false), - "io": const LibraryInfo("io/io.dart", - categories: "Server", - dart2jsPatchPath: "_internal/js_runtime/lib/io_patch.dart"), - "isolate": const LibraryInfo("isolate/isolate.dart", - categories: "Client,Server", - maturity: Maturity.STABLE, - dart2jsPatchPath: "_internal/js_runtime/lib/isolate_patch.dart"), - "js": const LibraryInfo("js/js.dart", - categories: "Client", - maturity: Maturity.STABLE, - platforms: DART2JS_PLATFORM, - dart2jsPatchPath: "_internal/js_runtime/lib/js_patch.dart"), - "js_util": const LibraryInfo("js_util/js_util.dart", - categories: "Client", - maturity: Maturity.STABLE, - platforms: DART2JS_PLATFORM), - "math": const LibraryInfo("math/math.dart", - categories: "Client,Server,Embedded", - maturity: Maturity.STABLE, - dart2jsPatchPath: "_internal/js_runtime/lib/math_patch.dart"), - "mirrors": const LibraryInfo("mirrors/mirrors.dart", - categories: "Client,Server", - maturity: Maturity.UNSTABLE, - dart2jsPatchPath: "_internal/js_runtime/lib/mirrors_patch.dart"), - "nativewrappers": const LibraryInfo("html/dartium/nativewrappers.dart", - categories: "Client", - implementation: true, - documented: false, - platforms: DART2JS_PLATFORM), - "typed_data": const LibraryInfo("typed_data/typed_data.dart", - categories: "Client,Server,Embedded", - maturity: Maturity.STABLE, - dart2jsPatchPath: "_internal/js_runtime/lib/typed_data_patch.dart"), - "_native_typed_data": const LibraryInfo( - "_internal/js_runtime/lib/native_typed_data.dart", - categories: "", - implementation: true, - documented: false, - platforms: DART2JS_PLATFORM), - "cli": const LibraryInfo("cli/cli.dart", - categories: "Server", - dart2jsPatchPath: "_internal/js_runtime/lib/cli_patch.dart"), - "svg": const LibraryInfo("svg/dart2js/svg_dart2js.dart", - categories: "Client", - maturity: Maturity.WEB_STABLE, - platforms: DART2JS_PLATFORM), - "web_audio": const LibraryInfo("web_audio/dart2js/web_audio_dart2js.dart", - categories: "Client", - maturity: Maturity.WEB_STABLE, - platforms: DART2JS_PLATFORM), - "web_gl": const LibraryInfo("web_gl/dart2js/web_gl_dart2js.dart", - categories: "Client", - maturity: Maturity.WEB_STABLE, - platforms: DART2JS_PLATFORM), - "web_sql": const LibraryInfo("web_sql/dart2js/web_sql_dart2js.dart", - categories: "Client", - maturity: Maturity.WEB_STABLE, - platforms: DART2JS_PLATFORM), - "_internal": const LibraryInfo("internal/internal.dart", - categories: "", - documented: false, - dart2jsPatchPath: "_internal/js_runtime/lib/internal_patch.dart"), - "_js_helper": const LibraryInfo("_internal/js_runtime/lib/js_helper.dart", - categories: "", documented: false, platforms: DART2JS_PLATFORM), - "_interceptors": const LibraryInfo( - "_internal/js_runtime/lib/interceptors.dart", - categories: "", - documented: false, - platforms: DART2JS_PLATFORM), - "_foreign_helper": const LibraryInfo( - "_internal/js_runtime/lib/foreign_helper.dart", - categories: "", - documented: false, - platforms: DART2JS_PLATFORM), - "_isolate_helper": const LibraryInfo( - "_internal/js_runtime/lib/isolate_helper.dart", - categories: "", - documented: false, - platforms: DART2JS_PLATFORM), - "_js_mirrors": const LibraryInfo("_internal/js_runtime/lib/js_mirrors.dart", - categories: "", documented: false, platforms: DART2JS_PLATFORM), - "_js_primitives": const LibraryInfo( - "_internal/js_runtime/lib/js_primitives.dart", - categories: "", - documented: false, - platforms: DART2JS_PLATFORM), - "_metadata": const LibraryInfo("html/html_common/metadata.dart", - categories: "", documented: false, platforms: DART2JS_PLATFORM), - "_debugger": const LibraryInfo("_internal/js_runtime/lib/debugger.dart", - category: "", documented: false, platforms: DART2JS_PLATFORM), - "_runtime": const LibraryInfo( - "_internal/js_runtime/lib/ddc_runtime/runtime.dart", - category: "", - documented: false, - platforms: DART2JS_PLATFORM), -}; - -/** - * Information about a "dart:" library. - */ -class LibraryInfo { - /** - * Path to the library's *.dart file relative to this file. - */ - final String path; - - /** - * The categories in which the library can be used encoded as a - * comma-separated String. - */ - final String _categories; - - /** - * Path to the dart2js library's *.dart file relative to this file - * or null if dart2js uses the common library path defined above. - * Access using the [#getDart2JsPath()] method. - */ - final String dart2jsPath; - - /** - * Path to the dart2js library's patch file relative to this file - * or null if no dart2js patch file associated with this library. - * Access using the [#getDart2JsPatchPath()] method. - */ - final String dart2jsPatchPath; - - /** - * True if this library is documented and should be shown to the user. - */ - final bool documented; - - /** - * Bit flags indicating which platforms consume this library. - * See [DART2JS_LIBRARY] and [VM_LIBRARY]. - */ - final int platforms; - - /** - * True if the library contains implementation details for another library. - * The implication is that these libraries are less commonly used - * and that tools like Dart Editor should not show these libraries - * in a list of all libraries unless the user specifically asks the tool to - * do so. - */ - final bool implementation; - - /** - * States the current maturity of this library. - */ - final Maturity maturity; - - const LibraryInfo(this.path, - {String categories: "", - this.dart2jsPath, - this.dart2jsPatchPath, - this.implementation: false, - this.documented: true, - this.maturity: Maturity.UNSPECIFIED, - this.platforms: DART2JS_PLATFORM | VM_PLATFORM}) - : _categories = categories; - - bool get isDart2jsLibrary => (platforms & DART2JS_PLATFORM) != 0; - bool get isVmLibrary => (platforms & VM_PLATFORM) != 0; - - /** - * The categories in which the library can be used. - * - * If no categories are specified, the library is internal and can not be - * loaded by user code. - */ - List get categories { - // `"".split(,)` returns [""] not [], so we handle that case separately. - if (_categories == "") return const []; - return _categories.split(",").map(parseCategory).toList(); - } - - bool get isInternal => categories.isEmpty; - - /// The original "categories" String that was passed to the constructor. - /// - /// Can be used to construct a slightly modified copy of this LibraryInfo. - String get categoriesString { - return _categories; - } -} - -/** - * Abstraction to capture the maturity of a library. - */ -class Maturity { - final int level; - final String name; - final String description; - - const Maturity(this.level, this.name, this.description); - - String toString() => "$name: $level\n$description\n"; - - static const Maturity DEPRECATED = const Maturity(0, "Deprecated", - "This library will be remove before next major release."); - - static const Maturity EXPERIMENTAL = const Maturity( - 1, - "Experimental", - "This library is experimental and will likely change or be removed\n" - "in future versions."); - - static const Maturity UNSTABLE = const Maturity( - 2, - "Unstable", - "This library is in still changing and have not yet endured\n" - "sufficient real-world testing.\n" - "Backwards-compatibility is NOT guaranteed."); - - static const Maturity WEB_STABLE = const Maturity( - 3, - "Web Stable", - "This library is tracking the DOM evolution as defined by WC3.\n" - "Backwards-compatibility is NOT guaranteed."); - - static const Maturity STABLE = const Maturity( - 4, - "Stable", - "The library is stable. API backwards-compatibility is guaranteed.\n" - "However implementation details might change."); - - static const Maturity LOCKED = const Maturity(5, "Locked", - "This library will not change except when serious bugs are encountered."); - - static const Maturity UNSPECIFIED = const Maturity(-1, "Unspecified", - "The maturity for this library has not been specified."); -} diff --git a/sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart b/sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart index ab5022325f3..b80c74e8975 100644 --- a/sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart +++ b/sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // Patch file for the dart:async library. import 'dart:_js_helper' show notNull, patch, ReifyFunctionTypes; @@ -26,11 +24,11 @@ import 'dart:_runtime' as dart; @ReifyFunctionTypes(false) _async(Function() initGenerator) { var iter; - Object Function(Object) onValue; - Object Function(Object, StackTrace) onError; + late Object? Function(Object?) onValue; + late Object Function(Object, StackTrace?) onError; - onAwait(Object value) { - _Future f; + onAwait(Object? value) { + _Future f; if (value is _Future) { f = value; } else if (value is Future) { @@ -161,7 +159,7 @@ class _AsyncRun { } @ReifyFunctionTypes(false) - static Object _scheduleImmediateWithPromise(void Function() callback) { + static void _scheduleImmediateWithPromise(void Function() callback) { dart.addAsyncCallback(); JS('', '#.Promise.resolve(null).then(#)', dart.global_, () { dart.removeAsyncCallback(); @@ -182,7 +180,7 @@ class DeferredLibrary { @patch class Timer { @patch - static Timer _createTimer(Duration duration, void callback()) { + static Timer _createTimer(Duration duration, void Function() callback) { int milliseconds = duration.inMilliseconds; if (milliseconds < 0) milliseconds = 0; return TimerImpl(milliseconds, callback); @@ -228,7 +226,7 @@ void _rethrow(Object error, StackTrace stackTrace) { /// } /// class _AsyncStarImpl { - StreamController controller; + late StreamController controller; Object Function(_AsyncStarImpl) initGenerator; @notNull bool isSuspendedAtYieldStar = false; @@ -243,11 +241,11 @@ class _AsyncStarImpl { @notNull bool isSuspendedAtAwait = false; - Completer cancellationCompleter; - Object jsIterator; + Completer? cancellationCompleter; + late Object jsIterator; - Null Function(Object, StackTrace) _handleErrorCallback; - void Function([Object]) _runBodyCallback; + Null Function(Object, StackTrace)? _handleErrorCallback; + void Function([Object?])? _runBodyCallback; _AsyncStarImpl(this.initGenerator) { controller = StreamController( @@ -293,10 +291,10 @@ class _AsyncStarImpl { }; var zone = Zone.current; if (!identical(zone, Zone.root)) { - _handleErrorCallback = zone.bindBinaryCallback(_handleErrorCallback); + _handleErrorCallback = zone.bindBinaryCallback(_handleErrorCallback!); } } - return _handleErrorCallback; + return _handleErrorCallback!; } void scheduleGenerator() { @@ -315,11 +313,11 @@ class _AsyncStarImpl { if (_runBodyCallback == null) { _runBodyCallback = JS('!', '#.bind(this)', runBody); if (!identical(zone, Zone.root)) { - var registered = zone.registerUnaryCallback(_runBodyCallback); + var registered = zone.registerUnaryCallback(_runBodyCallback!); _runBodyCallback = ([arg]) => zone.runUnaryGuarded(registered, arg); } } - zone.scheduleMicrotask(_runBodyCallback); + zone.scheduleMicrotask(_runBodyCallback!); } void runBody(awaitValue) { @@ -332,16 +330,16 @@ class _AsyncStarImpl { iterResult = JS('', '#.next(#)', jsIterator, awaitValue); } catch (e, s) { addError(e, s); - return null; + return; } if (JS('!', '#.done', iterResult)) { close(); - return null; + return; } // If we're suspended at a yield/yield*, we're done for now. - if (isSuspendedAtYield || isSuspendedAtYieldStar) return null; + if (isSuspendedAtYield || isSuspendedAtYieldStar) return; // Handle `await`: if we get a value passed to `yield` it means we are // waiting on this Future. Make sure to prevent scheduling, and pass the @@ -350,10 +348,10 @@ class _AsyncStarImpl { // TODO(jmesserly): is the timing here correct? The assumption here is // that we should schedule `await` in `async*` the same as in `async`. isSuspendedAtAwait = true; - FutureOr value = JS('', '#.value', iterResult); + FutureOr value = JS('', '#.value', iterResult); // TODO(jmesserly): this logic was copied from `async` function impl. - _Future f; + _Future f; if (value is _Future) { f = value; } else if (value is Future) { @@ -362,7 +360,7 @@ class _AsyncStarImpl { } else { f = _Future.value(value); } - f._thenAwait(_runBodyCallback, handleError); + f._thenAwait(_runBodyCallback!, handleError); } /// Adds element to [stream] and returns true if the caller should terminate @@ -417,10 +415,11 @@ class _AsyncStarImpl { void addError(Object error, StackTrace stackTrace) { ArgumentError.checkNotNull(error, "error"); - if (cancellationCompleter != null && !cancellationCompleter.isCompleted) { + var completer = cancellationCompleter; + if (completer != null && !completer.isCompleted) { // If the stream has been cancelled, complete the cancellation future // with the error. - cancellationCompleter.completeError(error, stackTrace); + completer.completeError(error, stackTrace); } else if (controller.hasListener) { controller.addError(error, stackTrace); } @@ -432,10 +431,11 @@ class _AsyncStarImpl { } void close() { - if (cancellationCompleter != null && !cancellationCompleter.isCompleted) { + var completer = cancellationCompleter; + if (completer != null && !completer.isCompleted) { // If the stream has been cancelled, complete the cancellation future // with the error. - cancellationCompleter.complete(); + completer.complete(); } controller.close(); } @@ -465,7 +465,7 @@ class _AsyncStarImpl { scheduleGenerator(); } } - return cancellationCompleter.future; + return cancellationCompleter!.future; } _fatal(String message) => throw StateError(message); diff --git a/sdk/lib/_internal/js_dev_runtime/patch/collection_patch.dart b/sdk/lib/_internal/js_dev_runtime/patch/collection_patch.dart index f0f7c9b6cbe..d9709b9ee59 100644 --- a/sdk/lib/_internal/js_dev_runtime/patch/collection_patch.dart +++ b/sdk/lib/_internal/js_dev_runtime/patch/collection_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // Patch file for dart:collection classes. import 'dart:_foreign_helper' show JS, JSExportName; import 'dart:_runtime' as dart; @@ -26,9 +24,9 @@ import 'dart:_js_helper' class HashMap { @patch factory HashMap( - {bool equals(K key1, K key2), - int hashCode(K key), - bool isValidKey(Object potentialKey)}) { + {bool Function(K, K)? equals, + int Function(K)? hashCode, + bool Function(dynamic)? isValidKey}) { if (isValidKey == null) { if (hashCode == null) { if (equals == null) { @@ -56,9 +54,9 @@ class HashMap { class LinkedHashMap { @patch factory LinkedHashMap( - {bool equals(K key1, K key2), - int hashCode(K key), - bool isValidKey(Object potentialKey)}) { + {bool Function(K, K)? equals, + int Function(K)? hashCode, + bool Function(dynamic)? isValidKey}) { if (isValidKey == null) { if (hashCode == null) { if (equals == null) { @@ -86,9 +84,9 @@ class LinkedHashMap { class HashSet { @patch factory HashSet( - {bool equals(E e1, E e2), - int hashCode(E e), - bool isValidKey(Object potentialKey)}) { + {bool Function(E, E)? equals, + int Function(E)? hashCode, + bool Function(dynamic)? isValidKey}) { if (isValidKey == null) { if (hashCode == null) { if (equals == null) { @@ -97,7 +95,6 @@ class HashSet { } return _HashSet(); } - hashCode = dart.hashCode; } else if (identical(identityHashCode, hashCode) && identical(identical, equals)) { return _IdentityHashSet(); @@ -117,9 +114,9 @@ class HashSet { class LinkedHashSet { @patch factory LinkedHashSet( - {bool equals(E e1, E e2), - int hashCode(E e), - bool isValidKey(Object potentialKey)}) { + {bool Function(E, E)? equals, + int Function(E)? hashCode, + bool Function(dynamic)? isValidKey}) { if (isValidKey == null) { if (hashCode == null) { if (equals == null) { @@ -133,8 +130,7 @@ class LinkedHashSet { identical(identical, equals)) { return _IdentityHashSet(); } - return _CustomHashSet( - equals ?? dart.equals, hashCode ?? dart.hashCode); + return _CustomHashSet(equals ?? dart.equals, hashCode); } return _CustomKeyHashSet( equals ?? dart.equals, hashCode ?? dart.hashCode, isValidKey); @@ -180,13 +176,14 @@ class _HashSet extends _InternalSet Set _newSimilarSet() => _HashSet(); - bool contains(Object key) { + bool contains(Object? key) { if (key == null) { + // Convert undefined to null, if needed. key = null; } else if (JS('!', '#[#] !== #', key, dart.extensionSymbol('_equals'), dart.identityEquals)) { @notNull - var k = key; + Object? k = key; var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, k.hashCode); if (buckets != null) { for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) { @@ -199,12 +196,12 @@ class _HashSet extends _InternalSet return JS('!', '#.has(#)', _map, key); } - E lookup(Object key) { + E? lookup(Object? key) { if (key == null) return null; if (JS('!', '#[#] !== #', key, dart.extensionSymbol('_equals'), dart.identityEquals)) { @notNull - var k = key; + Object? k = key; var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, k.hashCode); if (buckets != null) { for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) { @@ -221,7 +218,8 @@ class _HashSet extends _InternalSet var map = _map; if (key == null) { if (JS('', '#.has(null)', map)) return false; - key = null; + // Convert undefined to null, if needed. + JS('', '# = null', key); } else if (JS('!', '#[#] !== #', key, dart.extensionSymbol('_equals'), dart.identityEquals)) { var keyMap = _keyMap; @@ -251,7 +249,8 @@ class _HashSet extends _InternalSet int length = JS('', '#.size', map); for (E key in objects) { if (key == null) { - key = null; // converts undefined to null, if needed. + // Convert undefined to null, if needed. + JS('', '# = null', key); } else if (JS('!', '#[#] !== #', key, dart.extensionSymbol('_equals'), dart.identityEquals)) { key = putLinkedMapKey(key, _keyMap); @@ -263,13 +262,14 @@ class _HashSet extends _InternalSet } } - bool remove(Object key) { + bool remove(Object? key) { if (key == null) { + // Convert undefined to null, if needed. key = null; } else if (JS('!', '#[#] !== #', key, dart.extensionSymbol('_equals'), dart.identityEquals)) { @notNull - var k = key; + Object? k = key; int hash = JS('!', '# & 0x3ffffff', k.hashCode); var buckets = JS('', '#.get(#)', _keyMap, hash); if (buckets == null) return false; // not found @@ -311,7 +311,8 @@ class _ImmutableSet extends _HashSet { var map = _map; for (Object key in entries) { if (key == null) { - key = null; // converts undefined to null, if needed. + // Convert undefined to null, if needed. + JS('', '# = null', key); } else if (JS('!', '#[#] !== #', key, dart.extensionSymbol('_equals'), dart.identityEquals)) { key = putLinkedMapKey(key, _keyMap); @@ -320,10 +321,10 @@ class _ImmutableSet extends _HashSet { } } - bool add(Object other) => throw _unsupported(); - void addAll(Object other) => throw _unsupported(); + bool add(E value) => throw _unsupported(); + void addAll(Iterable elements) => throw _unsupported(); void clear() => throw _unsupported(); - bool remove(Object key) => throw _unsupported(); + bool remove(Object? value) => throw _unsupported(); static Error _unsupported() => UnsupportedError("Cannot modify unmodifiable set"); @@ -344,12 +345,14 @@ class _IdentityHashSet extends _InternalSet Set _newSimilarSet() => _IdentityHashSet(); - bool contains(Object element) { - return JS('', '#.has(#)', _map, element); + bool contains(Object? element) { + return JS('!', '#.has(#)', _map, element); } - E lookup(Object element) { - return JS('', '#.has(#)', _map, element) ? element : null; + E? lookup(Object? element) { + return element is E && JS('!', '#.has(#)', _map, element) + ? element + : null; } bool add(E element) { @@ -371,7 +374,7 @@ class _IdentityHashSet extends _InternalSet } } - bool remove(Object element) { + bool remove(Object? element) { if (JS('!', '#.delete(#)', _map, element)) { _modifications = (_modifications + 1) & 0x3ffffff; return true; @@ -389,7 +392,7 @@ class _IdentityHashSet extends _InternalSet } class _CustomKeyHashSet extends _CustomHashSet { - _Predicate _validKey; + _Predicate _validKey; _CustomKeyHashSet(_Equality equals, _Hasher hashCode, this._validKey) : super(equals, hashCode); @@ -397,7 +400,7 @@ class _CustomKeyHashSet extends _CustomHashSet { Set _newSimilarSet() => _HashSet(); - bool contains(Object element) { + bool contains(Object? element) { // TODO(jmesserly): there is a subtle difference here compared to Dart 1. // See the comment on CustomKeyHashMap.containsKey for more information. // Treatment of `null` is different due to strong mode's requirement to @@ -406,12 +409,12 @@ class _CustomKeyHashSet extends _CustomHashSet { return super.contains(element); } - E lookup(Object element) { + E? lookup(Object? element) { if (!_validKey(element)) return null; return super.lookup(element); } - bool remove(Object element) { + bool remove(Object? element) { if (!_validKey(element)) return false; return super.remove(element); } @@ -447,7 +450,7 @@ class _CustomHashSet extends _InternalSet Set _newSet() => _CustomHashSet(_equals, _hashCode); Set _newSimilarSet() => _HashSet(); - bool contains(Object key) { + bool contains(Object? key) { if (key is E) { var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, _hashCode(key)); if (buckets != null) { @@ -461,7 +464,7 @@ class _CustomHashSet extends _InternalSet return false; } - E lookup(Object key) { + E? lookup(Object? key) { if (key is E) { var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, _hashCode(key)); if (buckets != null) { @@ -499,7 +502,7 @@ class _CustomHashSet extends _InternalSet for (E element in objects) add(element); } - bool remove(Object key) { + bool remove(Object? key) { if (key is E) { var hash = JS('!', '# & 0x3ffffff', _hashCode(key)); var keyMap = _keyMap; @@ -575,30 +578,3 @@ abstract class _InternalSet extends _SetBase { iterator); } } - -@patch -abstract class _SplayTree> { - @patch - Node _splayMin(Node node) { - Node current = node; - while (current.left != null) { - Node left = current.left; - current.left = left.right; - left.right = current; - current = left; - } - return current; - } - - @patch - Node _splayMax(Node node) { - Node current = node; - while (current.right != null) { - Node right = current.right; - current.right = right.left; - right.left = current; - current = right; - } - return current; - } -} diff --git a/sdk/lib/_internal/js_dev_runtime/patch/convert_patch.dart b/sdk/lib/_internal/js_dev_runtime/patch/convert_patch.dart index ad45663924f..c86dab00de1 100644 --- a/sdk/lib/_internal/js_dev_runtime/patch/convert_patch.dart +++ b/sdk/lib/_internal/js_dev_runtime/patch/convert_patch.dart @@ -2,15 +2,13 @@ // 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.6 - // Patch file for dart:convert library. import 'dart:_js_helper' show argumentErrorValue, patch; import 'dart:_foreign_helper' show JS; import 'dart:_interceptors' show JSExtendableArray; import 'dart:_internal' show MappedIterable, ListIterable; -import 'dart:collection' show Maps, LinkedHashMap, MapBase; +import 'dart:collection' show LinkedHashMap, MapBase; import 'dart:_native_typed_data' show NativeUint8List; /** @@ -30,7 +28,7 @@ import 'dart:_native_typed_data' show NativeUint8List; * Throws [FormatException] if the input is not valid JSON text. */ @patch -_parseJson(String source, reviver(Object key, Object value)) { +_parseJson(String source, reviver(key, value)?) { if (source is! String) throw argumentErrorValue(source); var parsed; @@ -53,8 +51,7 @@ _parseJson(String source, reviver(Object key, Object value)) { * Maps. [json] is expected to be freshly allocated so elements can be replaced * in-place. */ -_convertJsonToDart(json, reviver(Object key, Object value)) { - assert(reviver != null); +_convertJsonToDart(json, reviver(Object? key, Object? value)) { walk(e) { // JavaScript null, string, number, bool are in the correct representation. if (JS('!', '# == null', e) || @@ -214,7 +211,7 @@ class _JsonMap extends MapBase { return value; } - remove(Object key) { + remove(Object? key) { if (!_isUpgraded && !containsKey(key)) return null; return _upgrade().remove(key); } @@ -275,7 +272,7 @@ class _JsonMap extends MapBase { List _computeKeys() { assert(!_isUpgraded); - List keys = _data; + List? keys = _data; if (keys == null) { keys = _data = _getPropertyNames(_original); } @@ -298,7 +295,7 @@ class _JsonMap extends MapBase { // safely force a concurrent modification error in case // someone is iterating over the map here. if (keys.isEmpty) { - keys.add(null); + keys.add(""); } else { keys.clear(); } @@ -357,13 +354,13 @@ class _JsonMapKeyIterable extends ListIterable { /// Delegate to [parent.containsKey] to ensure the performance expected /// from [Map.keys.containsKey]. - bool contains(Object key) => _parent.containsKey(key); + bool contains(Object? key) => _parent.containsKey(key); } @patch class JsonDecoder { @patch - StringConversionSink startChunkedConversion(Sink sink) { + StringConversionSink startChunkedConversion(Sink sink) { return _JsonDecoderSink(_reviver, sink); } } @@ -375,18 +372,17 @@ class JsonDecoder { * The sink only creates one object, but its input can be chunked. */ // TODO(floitsch): don't accumulate everything before starting to decode. -class _JsonDecoderSink extends _StringSinkConversionSink { - final Function(Object key, Object value) _reviver; - final Sink _sink; +class _JsonDecoderSink extends _StringSinkConversionSink { + final Object? Function(Object? key, Object? value)? _reviver; + final Sink _sink; _JsonDecoderSink(this._reviver, this._sink) : super(StringBuffer('')); void close() { super.close(); - StringBuffer buffer = _stringSink; - String accumulated = buffer.toString(); - buffer.clear(); - Object decoded = _parseJson(accumulated, _reviver); + String accumulated = _stringSink.toString(); + _stringSink.clear(); + Object? decoded = _parseJson(accumulated, _reviver); _sink.add(decoded); _sink.close(); } @@ -405,8 +401,8 @@ class Utf8Decoder { // Currently not intercepting UTF8 decoding. @patch - static String _convertIntercepted( - bool allowMalformed, List codeUnits, int start, int end) { + static String? _convertIntercepted( + bool allowMalformed, List codeUnits, int start, int? end) { // Test `codeUnits is NativeUint8List`. Dart's NativeUint8List is // implemented by JavaScript's Uint8Array. if (JS('!', '# instanceof Uint8Array', codeUnits)) { @@ -417,7 +413,7 @@ class Utf8Decoder { if (end - start < _shortInputThreshold) { return null; } - String result = + String? result = _convertInterceptedUint8List(allowMalformed, casted, start, end); if (result != null && allowMalformed) { // In principle, TextDecoder should have provided the correct result @@ -433,7 +429,7 @@ class Utf8Decoder { return null; // This call was not intercepted. } - static String _convertInterceptedUint8List( + static String? _convertInterceptedUint8List( bool allowMalformed, NativeUint8List codeUnits, int start, int end) { final decoder = allowMalformed ? _decoderNonfatal : _decoder; if (decoder == null) return null; @@ -448,7 +444,7 @@ class Utf8Decoder { JS('!', '#.subarray(#, #)', codeUnits, start, end)); } - static String _useTextDecoder(decoder, NativeUint8List codeUnits) { + static String? _useTextDecoder(decoder, NativeUint8List codeUnits) { // If the input is malformed, catch the exception and return `null` to fall // back on unintercepted decoder. The fallback will either succeed in // decoding, or report the problem better than TextDecoder. @@ -480,12 +476,12 @@ class _Utf8Decoder { _Utf8Decoder(this.allowMalformed) : _state = beforeBom; @patch - String convertSingle(List codeUnits, int start, int maybeEnd) { + String convertSingle(List codeUnits, int start, int? maybeEnd) { return convertGeneral(codeUnits, start, maybeEnd, true); } @patch - String convertChunked(List codeUnits, int start, int maybeEnd) { + String convertChunked(List codeUnits, int start, int? maybeEnd) { return convertGeneral(codeUnits, start, maybeEnd, false); } } diff --git a/sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart b/sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart index 76ff54278bc..2171a9f1e7e 100644 --- a/sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart +++ b/sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // Patch file for dart:core classes. import "dart:_internal" as _symbol_dev; import 'dart:_interceptors'; @@ -30,14 +28,14 @@ import 'dart:typed_data' show Endian, Uint8List, Uint16List; String _symbolToString(Symbol symbol) => symbol is PrivateSymbol ? PrivateSymbol.getName(symbol) - : _symbol_dev.Symbol.getName(symbol); + : _symbol_dev.Symbol.getName(symbol as _symbol_dev.Symbol); @patch -int identityHashCode(Object object) { +int identityHashCode(Object? object) { if (object == null) return 0; // Note: this works for primitives because we define the `identityHashCode` // for them to be equivalent to their computed hashCode function. - int hash = JS('int|Null', r'#[#]', object, dart.identityHashCode_); + int? hash = JS('int|Null', r'#[#]', object, dart.identityHashCode_); if (hash == null) { hash = JS('!', '(Math.random() * 0x3fffffff) | 0'); JS('void', r'#[#] = #', object, dart.identityHashCode_, hash); @@ -49,7 +47,7 @@ int identityHashCode(Object object) { @patch class Object { @patch - bool operator ==(other) => identical(this, other); + bool operator ==(Object other) => identical(this, other); @patch int get hashCode => identityHashCode(this); @@ -59,7 +57,7 @@ class Object { "Instance of '${dart.typeName(dart.getReifiedType(this))}'"; @patch - noSuchMethod(Invocation invocation) { + dynamic noSuchMethod(Invocation invocation) { return dart.defaultNoSuchMethod(this, invocation); } @@ -68,10 +66,11 @@ class Object { // Everything is an Object. @JSExportName('is') - static bool _is_Object(Object o) => true; + static bool _is_Object(Object? o) => o != null; @JSExportName('as') - static Object _as_Object(Object o) => o; + static Object? _as_Object(Object? o) => + o == null ? dart.cast(o, dart.unwrapType(Object)) : o; } @patch @@ -80,10 +79,10 @@ class Null { int get hashCode => super.hashCode; @JSExportName('is') - static bool _is_Null(Object o) => o == null; + static bool _is_Null(Object? o) => o == null; @JSExportName('as') - static Object _as_Null(Object o) { + static Object? _as_Null(Object? o) { // Avoid extra function call to core.Null.is() by manually inlining. if (o == null) return o; return dart.cast(o, dart.unwrapType(Null)); @@ -94,8 +93,8 @@ class Null { @patch class Function { @patch - static apply(Function f, List positionalArguments, - [Map namedArguments]) { + static apply(Function function, List? positionalArguments, + [Map? namedArguments]) { positionalArguments ??= []; // dcall expects the namedArguments as a JS map in the last slot. if (namedArguments != null && namedArguments.isNotEmpty) { @@ -103,9 +102,9 @@ class Function { namedArguments.forEach((symbol, arg) { JS('', '#[#] = #', map, _symbolToString(symbol), arg); }); - return dart.dcall(f, positionalArguments, map); + return dart.dcall(function, positionalArguments, map); } - return dart.dcall(f, positionalArguments); + return dart.dcall(function, positionalArguments); } static Map _toMangledNames( @@ -118,13 +117,13 @@ class Function { } @JSExportName('is') - static bool _is_Function(Object o) => + static bool _is_Function(Object? o) => JS('!', 'typeof $o == "function"'); @JSExportName('as') - static Object _as_Function(Object o) { + static Object? _as_Function(Object? o) { // Avoid extra function call to core.Function.is() by manually inlining. - if (JS('!', 'typeof $o == "function"') || o == null) return o; + if (JS('!', 'typeof $o == "function"')) return o; return dart.cast(o, dart.unwrapType(Function)); } } @@ -132,18 +131,20 @@ class Function { // TODO(jmesserly): switch to WeakMap // Patch for Expando implementation. @patch -class Expando { +class Expando { @patch - Expando([String name]) : this.name = name; + Expando([String? name]) : this.name = name; @patch - T operator [](Object object) { + T? operator [](Object object) { var values = Primitives.getProperty(object, _EXPANDO_PROPERTY_NAME); - return (values == null) ? null : Primitives.getProperty(values, _getKey()); + return (values == null) + ? null + : Primitives.getProperty(values, _getKey()) as T?; } @patch - void operator []=(Object object, T value) { + void operator []=(Object object, T? value) { var values = Primitives.getProperty(object, _EXPANDO_PROPERTY_NAME); if (values == null) { values = Object(); @@ -153,7 +154,7 @@ class Expando { } String _getKey() { - String key = Primitives.getProperty(this, _KEY_PROPERTY_NAME); + var key = Primitives.getProperty(this, _KEY_PROPERTY_NAME) as String?; if (key == null) { key = "expando\$key\$${_keyCount++}"; Primitives.setProperty(this, _KEY_PROPERTY_NAME, key); @@ -170,7 +171,7 @@ class Expando { class int { @patch static int parse(String source, - {int radix, @deprecated int onError(String source)}) { + {int? radix, @deprecated int onError(String source)?}) { var value = tryParse(source, radix: radix); if (value != null) return value; if (onError != null) return onError(source); @@ -178,7 +179,7 @@ class int { } @patch - static int tryParse(String source, {int radix}) { + static int? tryParse(String source, {int? radix}) { return Primitives.parseInt(source, radix); } @@ -190,15 +191,14 @@ class int { } @JSExportName('is') - static bool _is_int(Object o) { + static bool _is_int(Object? o) { return JS('!', 'typeof $o == "number" && Math.floor($o) == $o'); } @JSExportName('as') - static Object _as_int(Object o) { + static Object? _as_int(Object? o) { // Avoid extra function call to core.int.is() by manually inlining. - if (JS('!', '(typeof $o == "number" && Math.floor($o) == $o)') || - o == null) { + if (JS('!', '(typeof $o == "number" && Math.floor($o) == $o)')) { return o; } return dart.cast(o, dart.unwrapType(int)); @@ -209,7 +209,7 @@ class int { class double { @patch static double parse(String source, - [@deprecated double onError(String source)]) { + [@deprecated double onError(String source)?]) { var value = tryParse(source); if (value != null) return value; if (onError != null) return onError(source); @@ -217,19 +217,19 @@ class double { } @patch - static double tryParse(String source) { + static double? tryParse(String source) { return Primitives.parseDouble(source); } @JSExportName('is') - static bool _is_double(o) { + static bool _is_double(Object? o) { return JS('!', 'typeof $o == "number"'); } @JSExportName('as') - static Object _as_double(o) { + static Object? _as_double(Object? o) { // Avoid extra function call to core.double.is() by manually inlining. - if (JS('!', 'typeof $o == "number"') || o == null) return o; + if (JS('!', 'typeof $o == "number"')) return o; return dart.cast(o, dart.unwrapType(double)); } } @@ -237,14 +237,14 @@ class double { @patch abstract class num implements Comparable { @JSExportName('is') - static bool _is_num(o) { + static bool _is_num(Object? o) { return JS('!', 'typeof $o == "number"'); } @JSExportName('as') - static Object _as_num(o) { + static Object? _as_num(Object? o) { // Avoid extra function call to core.num.is() by manually inlining. - if (JS('!', 'typeof $o == "number"') || o == null) return o; + if (JS('!', 'typeof $o == "number"')) return o; return dart.cast(o, dart.unwrapType(num)); } } @@ -259,11 +259,11 @@ class BigInt implements Comparable { static BigInt get two => _BigIntImpl.two; @patch - static BigInt parse(String source, {int radix}) => + static BigInt parse(String source, {int? radix}) => _BigIntImpl.parse(source, radix: radix); @patch - static BigInt tryParse(String source, {int radix}) => + static BigInt? tryParse(String source, {int? radix}) => _BigIntImpl._tryParse(source, radix: radix); @patch @@ -283,7 +283,7 @@ class Error { } @patch - StackTrace get stackTrace => dart.stackTraceForError(this); + StackTrace? get stackTrace => dart.stackTraceForError(this); } @patch @@ -319,10 +319,7 @@ class DateTime { @patch DateTime._internal(int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond, bool isUtc) - // checkBool is manually inlined here because dart2js doesn't inline it - // and [isUtc] is usually a constant. - : this.isUtc = - isUtc is bool ? isUtc : throw ArgumentError.value(isUtc, 'isUtc'), + : isUtc = isUtc, _value = checkInt(Primitives.valueFromDecomposedDate( year, month, @@ -346,7 +343,7 @@ class DateTime { } @patch - static int _brokenDownDateToValue(int year, int month, int day, int hour, + static int? _brokenDownDateToValue(int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond, bool isUtc) { return Primitives.valueFromDecomposedDate( year, @@ -367,7 +364,7 @@ class DateTime { @patch Duration get timeZoneOffset { - if (isUtc) return Duration(); + if (isUtc) return Duration.zero; return Duration(minutes: Primitives.getTimeZoneOffsetInMinutes(this)); } @@ -420,7 +417,7 @@ class DateTime { int get weekday => Primitives.getWeekday(this); @patch - bool operator ==(dynamic other) => + bool operator ==(Object other) => other is DateTime && _value == other.millisecondsSinceEpoch && isUtc == other.isUtc; @@ -444,9 +441,9 @@ class DateTime { @patch class Stopwatch { @patch - static void _initTicker() { + static int _initTicker() { Primitives.initTicker(); - _frequency = Primitives.timerFrequency; + return Primitives.timerFrequency; } @patch @@ -473,22 +470,29 @@ class Stopwatch { @patch class List { @patch - factory List([@undefined int _length]) { + factory List([@undefined int? length]) { dynamic list; - if (JS('!', '# === void 0', _length)) { + if (JS('!', '# === void 0', length)) { list = JS('', '[]'); } else { - int length = JS('!', '#', _length); - if (_length == null || length < 0) { + int _length = JS('!', '#', length); + if (length == null || _length < 0) { throw ArgumentError("Length must be a non-negative integer: $_length"); } - list = JS('', 'new Array(#)', length); + list = JS('', 'new Array(#)', _length); JS('', '#.fill(null)', list); JSArray.markFixedList(list); } return JSArray.of(list); } + @patch + factory List.empty({bool growable = false}) { + var list = JSArray.of(JS('', 'new Array()')); + if (!growable) JSArray.markFixedList(list); + return list; + } + @patch factory List.filled(@nullCheck int length, E fill, {bool growable = false}) { var list = JSArray.of(JS('', 'new Array(#)', length)); @@ -521,6 +525,17 @@ class List { return List.from(elements, growable: growable); } + @patch + factory List.generate(int length, E generator(int index), + {bool growable = true}) { + final result = JSArray.of(JS('', 'new Array(#)', length)); + if (!growable) JSArray.markFixedList(result); + for (int i = 0; i < length; i++) { + result[i] = generator(i); + } + return result; + } + @patch factory List.unmodifiable(Iterable elements) { var list = List.from(elements); @@ -532,7 +547,7 @@ class List { @patch class Map { @patch - factory Map.unmodifiable(Map other) { + factory Map.unmodifiable(Map other) { return UnmodifiableMapView(Map.from(other)); } @@ -544,7 +559,7 @@ class Map { class String { @patch factory String.fromCharCodes(Iterable charCodes, - [int start = 0, int end]) { + [int start = 0, int? end]) { if (charCodes is JSArray) { return _stringFromJSArray(charCodes, start, end); } @@ -569,7 +584,7 @@ class String { static String _stringFromJSArray( /*=JSArray*/ list, int start, - int endOrNull) { + int? endOrNull) { int len = list.length; int end = RangeError.checkValidRange(start, endOrNull, len); if (start > 0 || end < len) { @@ -579,14 +594,14 @@ class String { } static String _stringFromUint8List( - NativeUint8List charCodes, int start, int endOrNull) { + NativeUint8List charCodes, int start, int? endOrNull) { int len = charCodes.length; int end = RangeError.checkValidRange(start, endOrNull, len); return Primitives.stringFromNativeUint8List(charCodes, start, end); } static String _stringFromIterable( - Iterable charCodes, int start, int end) { + Iterable charCodes, int start, int? end) { if (start < 0) throw RangeError.range(start, 0, charCodes.length); if (end != null && end < start) { throw RangeError.range(end, start, charCodes.length); @@ -597,7 +612,7 @@ class String { throw RangeError.range(start, 0, i); } } - var list = []; + var list = JSArray.of(JS('', 'new Array()')); if (end == null) { while (it.moveNext()) list.add(it.current); } else { @@ -612,14 +627,14 @@ class String { } @JSExportName('is') - static bool _is_String(Object o) { + static bool _is_String(Object? o) { return JS('!', 'typeof $o == "string"'); } @JSExportName('as') - static Object _as_String(Object o) { + static Object? _as_String(Object? o) { // Avoid extra function call to core.String.is() by manually inlining. - if (JS('!', 'typeof $o == "string"') || o == null) return o; + if (JS('!', 'typeof $o == "string"')) return o; return dart.cast(o, dart.unwrapType(String)); } } @@ -644,13 +659,13 @@ class bool { int get hashCode => super.hashCode; @JSExportName('is') - static bool _is_bool(Object o) => + static bool _is_bool(Object? o) => JS('!', '$o === true || $o === false'); @JSExportName('as') - static Object _as_bool(Object o) { + static Object? _as_bool(Object? o) { // Avoid extra function call to core.bool.is() by manually inlining. - if (JS("!", '$o === true || $o === false') || o == null) return o; + if (JS("!", '$o === true || $o === false')) return o; return dart.cast(o, dart.unwrapType(bool)); } } @@ -675,7 +690,7 @@ class RegExp { // Patch for 'identical' function. @patch -bool identical(Object a, Object b) { +bool identical(Object? a, Object? b) { return JS('!', '(# == null ? # == null : # === #)', a, b, a, b); } @@ -690,7 +705,7 @@ class StringBuffer { int get length => _contents.length; @patch - void write(Object obj) { + void write(Object? obj) { _writeString('$obj'); } @@ -700,12 +715,12 @@ class StringBuffer { } @patch - void writeAll(Iterable objects, [String separator = ""]) { + void writeAll(Iterable objects, [String separator = ""]) { _contents = _writeAll(_contents, objects, separator); } @patch - void writeln([Object obj = ""]) { + void writeln([Object? obj = ""]) { _writeString('$obj\n'); } @@ -717,7 +732,7 @@ class StringBuffer { @patch String toString() => Primitives.flattenString(_contents); - void _writeString(str) { + void _writeString(String str) { _contents = Primitives.stringConcatUnchecked(_contents, str); } @@ -738,7 +753,7 @@ class StringBuffer { return string; } - static String _writeOne(String string, Object obj) { + static String _writeOne(String string, Object? obj) { return Primitives.stringConcatUnchecked(string, '$obj'); } } @@ -752,46 +767,44 @@ class _CompileTimeError extends Error { @patch class NoSuchMethodError { - final Object _receiver; + final Object? _receiver; final Symbol _memberName; - final List _arguments; - final Map _namedArguments; - final List _existingArgumentNames; - final Invocation _invocation; + final List? _arguments; + final Map? _namedArguments; + final Invocation? _invocation; @patch - NoSuchMethodError(Object receiver, Symbol memberName, - List positionalArguments, Map namedArguments, - [List existingArgumentNames = null]) + NoSuchMethodError(Object? receiver, Symbol memberName, + List? positionalArguments, Map? namedArguments) : _receiver = receiver, _memberName = memberName, _arguments = positionalArguments, _namedArguments = namedArguments, - _existingArgumentNames = existingArgumentNames, _invocation = null; @patch - NoSuchMethodError.withInvocation(Object receiver, Invocation invocation) + NoSuchMethodError.withInvocation(Object? receiver, Invocation invocation) : _receiver = receiver, _memberName = invocation.memberName, _arguments = invocation.positionalArguments, _namedArguments = invocation.namedArguments, - _existingArgumentNames = null, _invocation = invocation; @patch String toString() { StringBuffer sb = StringBuffer(''); String comma = ''; - if (_arguments != null) { - for (var argument in _arguments) { + var arguments = _arguments; + if (arguments != null) { + for (var argument in arguments) { sb.write(comma); sb.write(Error.safeToString(argument)); comma = ', '; } } - if (_namedArguments != null) { - _namedArguments.forEach((Symbol key, var value) { + var namedArguments = _namedArguments; + if (namedArguments != null) { + namedArguments.forEach((Symbol key, var value) { sb.write(comma); sb.write(_symbolToString(key)); sb.write(": "); @@ -802,22 +815,14 @@ class NoSuchMethodError { String memberName = _symbolToString(_memberName); String receiverText = Error.safeToString(_receiver); String actualParameters = '$sb'; - var failureMessage = (_invocation is dart.InvocationImpl) - ? (_invocation as dart.InvocationImpl).failureMessage + var invocation = _invocation; + var failureMessage = (invocation is dart.InvocationImpl) + ? invocation.failureMessage : 'method not found'; - if (_existingArgumentNames == null) { - return "NoSuchMethodError: '$memberName'\n" - "$failureMessage\n" - "Receiver: ${receiverText}\n" - "Arguments: [$actualParameters]"; - } else { - String formalParameters = _existingArgumentNames.join(', '); - return "NoSuchMethodError: incorrect number of arguments passed to " - "method named '$memberName'\n" - "Receiver: ${receiverText}\n" - "Tried calling: $memberName($actualParameters)\n" - "Found: $memberName($formalParameters)"; - } + return "NoSuchMethodError: '$memberName'\n" + "$failureMessage\n" + "Receiver: ${receiverText}\n" + "Arguments: [$actualParameters]"; } } @@ -973,14 +978,14 @@ class _BigIntImpl implements BigInt { // Result cache for last _divRem call. // Result cache for last _divRem call. - static Uint16List _lastDividendDigits; - static int _lastDividendUsed; - static Uint16List _lastDivisorDigits; - static int _lastDivisorUsed; - static Uint16List _lastQuoRemDigits; - static int _lastQuoRemUsed; - static int _lastRemUsed; - static int _lastRem_nsh; + static Uint16List? _lastDividendDigits; + static int? _lastDividendUsed; + static Uint16List? _lastDivisorDigits; + static int? _lastDivisorUsed; + static Uint16List? _lastQuoRemDigits; + static int? _lastQuoRemUsed; + static int? _lastRemUsed; + static int? _lastRem_nsh; /// Whether this bigint is negative. final bool _isNegative; @@ -1021,7 +1026,7 @@ class _BigIntImpl implements BigInt { * Throws a [FormatException] if the [source] is not a valid integer literal, * optionally prefixed by a sign. */ - static _BigIntImpl parse(String source, {int radix}) { + static _BigIntImpl parse(String source, {int? radix}) { var result = _tryParse(source, radix: radix); if (result == null) { throw FormatException("Could not parse BigInt", source); @@ -1040,7 +1045,7 @@ class _BigIntImpl implements BigInt { // Read in the source 4 digits at a time. // The first part may have a few leading virtual '0's to make the remaining // parts all have exactly 4 digits. - int digitInPartCount = 4 - source.length.remainder(4); + var digitInPartCount = 4 - source.length.remainder(4); if (digitInPartCount == 4) digitInPartCount = 0; for (int i = 0; i < source.length; i++) { part = part * 10 + source.codeUnitAt(i) - _0; @@ -1082,7 +1087,7 @@ class _BigIntImpl implements BigInt { /// If [isNegative] is true, negates the result before returning it. /// /// The [source] (substring) must be a valid hex literal. - static _BigIntImpl _parseHex(String source, int startPos, bool isNegative) { + static _BigIntImpl? _parseHex(String source, int startPos, bool isNegative) { int hexDigitsPerChunk = _digitBits ~/ 4; int sourceLength = source.length - startPos; int chunkCount = (sourceLength / hexDigitsPerChunk).ceil(); @@ -1116,7 +1121,7 @@ class _BigIntImpl implements BigInt { /// /// The [source] will be checked for invalid characters. If it is invalid, /// this function returns `null`. - static _BigIntImpl _parseRadix(String source, int radix, bool isNegative) { + static _BigIntImpl? _parseRadix(String source, int radix, bool isNegative) { var result = zero; var base = _BigIntImpl._fromInt(radix); for (int i = 0; i < source.length; i++) { @@ -1133,7 +1138,7 @@ class _BigIntImpl implements BigInt { /// Returns the parsed big integer, or `null` if it failed. /// /// If the [radix] is `null` accepts decimal literals or `0x` hex literals. - static _BigIntImpl _tryParse(String source, {int radix}) { + static _BigIntImpl? _tryParse(String source, {int? radix}) { if (source == "") return null; var match = _parseRE.firstMatch(source); @@ -1145,9 +1150,9 @@ class _BigIntImpl implements BigInt { bool isNegative = match[signIndex] == "-"; - String decimalMatch = match[decimalIndex]; - String hexMatch = match[hexIndex]; - String nonDecimalMatch = match[nonDecimalHexIndex]; + String? decimalMatch = match[decimalIndex]; + String? hexMatch = match[hexIndex]; + String? nonDecimalMatch = match[nonDecimalHexIndex]; if (radix == null) { if (decimalMatch != null) { @@ -1168,11 +1173,11 @@ class _BigIntImpl implements BigInt { return _parseDecimal(decimalMatch, isNegative); } if (radix == 16 && (decimalMatch != null || nonDecimalMatch != null)) { - return _parseHex(decimalMatch ?? nonDecimalMatch, 0, isNegative); + return _parseHex(decimalMatch ?? nonDecimalMatch!, 0, isNegative); } return _parseRadix( - decimalMatch ?? nonDecimalMatch ?? hexMatch, radix, isNegative); + decimalMatch ?? nonDecimalMatch ?? hexMatch!, radix, isNegative); } static RegExp _parseRE = RegExp( @@ -1220,7 +1225,7 @@ class _BigIntImpl implements BigInt { // then use the bit-manipulating `_fromDouble` for all other values. if (value.abs() < 0x100000000) return _BigIntImpl._fromInt(value.toInt()); if (value is double) return _BigIntImpl._fromDouble(value); - return _BigIntImpl._fromInt(value); + return _BigIntImpl._fromInt(value as int); } factory _BigIntImpl._fromInt(int value) { @@ -1984,9 +1989,9 @@ class _BigIntImpl implements BigInt { _divRem(other); // Return quotient, i.e. // _lastQuoRem_digits[_lastRem_used.._lastQuoRem_used-1] with proper sign. - var lastQuo_used = _lastQuoRemUsed - _lastRemUsed; + var lastQuo_used = _lastQuoRemUsed! - _lastRemUsed!; var quo_digits = _cloneDigits( - _lastQuoRemDigits, _lastRemUsed, _lastQuoRemUsed, lastQuo_used); + _lastQuoRemDigits!, _lastRemUsed!, _lastQuoRemUsed!, lastQuo_used); var quo = _BigIntImpl._(false, lastQuo_used, quo_digits); if ((_isNegative != other._isNegative) && (quo._used > 0)) { quo = -quo; @@ -2004,10 +2009,10 @@ class _BigIntImpl implements BigInt { // Return remainder, i.e. // denormalized _lastQuoRem_digits[0.._lastRem_used-1] with proper sign. var remDigits = - _cloneDigits(_lastQuoRemDigits, 0, _lastRemUsed, _lastRemUsed); - var rem = _BigIntImpl._(false, _lastRemUsed, remDigits); - if (_lastRem_nsh > 0) { - rem = rem >> _lastRem_nsh; // Denormalize remainder. + _cloneDigits(_lastQuoRemDigits!, 0, _lastRemUsed!, _lastRemUsed!); + var rem = _BigIntImpl._(false, _lastRemUsed!, remDigits); + if (_lastRem_nsh! > 0) { + rem = rem >> _lastRem_nsh!; // Denormalize remainder. } if (_isNegative && (rem._used > 0)) { rem = -rem; diff --git a/sdk/lib/_internal/js_dev_runtime/patch/developer_patch.dart b/sdk/lib/_internal/js_dev_runtime/patch/developer_patch.dart index c6e8905b1c9..d67b6c8265a 100644 --- a/sdk/lib/_internal/js_dev_runtime/patch/developer_patch.dart +++ b/sdk/lib/_internal/js_dev_runtime/patch/developer_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // Patch file for dart:developer library. import 'dart:_js_helper' show patch, ForceInline, ReifyFunctionTypes; @@ -15,7 +13,7 @@ import 'dart:isolate'; @patch @ForceInline() -bool debugger({bool when = true, String message}) { +bool debugger({bool when = true, String? message}) { if (when) { JS('', 'debugger'); } @@ -23,7 +21,7 @@ bool debugger({bool when = true, String message}) { } @patch -Object inspect(Object object) { +Object? inspect(Object? object) { // Note: this log level does not show up by default in Chrome. // This is used for communication with the debugger service. JS('', 'console.debug("dart.developer.inspect", #)', object); @@ -32,13 +30,13 @@ Object inspect(Object object) { @patch void log(String message, - {DateTime time, - int sequenceNumber, + {DateTime? time, + int? sequenceNumber, int level = 0, String name = '', - Zone zone, - Object error, - StackTrace stackTrace}) { + Zone? zone, + Object? error, + StackTrace? stackTrace}) { Object items = JS('!', '{ message: #, name: #, level: # }', message, name, level); if (time != null) JS('', '#.time = #', items, time); @@ -52,10 +50,10 @@ void log(String message, JS('', 'console.debug("dart.developer.log", #)', items); } -final _extensions = Map(); +final _extensions = {}; @patch -ServiceExtensionHandler _lookupExtension(String method) { +ServiceExtensionHandler? _lookupExtension(String method) { return _extensions[method]; } @@ -81,7 +79,7 @@ _invokeExtension(String methodName, String encodedJson) { return JS('', 'new #.Promise(#)', dart.global_, (Function(Object) resolve, Function(Object) reject) async { try { - var method = _lookupExtension(methodName); + var method = _lookupExtension(methodName)!; var parameters = (json.decode(encodedJson) as Map).cast(); var result = await method(methodName, parameters); resolve(result._toString()); @@ -154,7 +152,7 @@ void _webServerControl(SendPort sendPort, bool enable) { } @patch -String _getIsolateIDFromSendPort(SendPort sendPort) { +String? _getIsolateIDFromSendPort(SendPort sendPort) { return null; } @@ -168,7 +166,7 @@ class UserTag { } class _FakeUserTag implements UserTag { - static Map _instances = {}; + static final _instances = {}; _FakeUserTag.real(this.label); @@ -183,10 +181,7 @@ class _FakeUserTag implements UserTag { throw UnsupportedError( 'UserTag instance limit (${UserTag.MAX_USER_TAGS}) reached.'); } - // Create a new instance and add it to the instance map. - var instance = _FakeUserTag.real(label); - _instances[label] = instance; - return instance; + return _instances[label] = _FakeUserTag.real(label); } final String label; diff --git a/sdk/lib/_internal/js_dev_runtime/patch/internal_patch.dart b/sdk/lib/_internal/js_dev_runtime/patch/internal_patch.dart index 6ab2349f6b3..2e605a291b8 100644 --- a/sdk/lib/_internal/js_dev_runtime/patch/internal_patch.dart +++ b/sdk/lib/_internal/js_dev_runtime/patch/internal_patch.dart @@ -2,8 +2,6 @@ // 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.6 - import 'dart:core' hide Symbol; import 'dart:core' as core show Symbol; import 'dart:_js_primitives' show printString; @@ -12,6 +10,9 @@ import 'dart:_interceptors' show JSArray; import 'dart:_foreign_helper' show JS; import 'dart:_runtime' as dart; +@patch +bool typeAcceptsNull() => !dart.strictNullSafety || null is T; + @patch class Symbol implements core.Symbol { @patch @@ -19,7 +20,7 @@ class Symbol implements core.Symbol { @patch int get hashCode { - int hash = JS('int|Null', '#._hashCode', this); + int? hash = JS('int|Null', '#._hashCode', this); if (hash != null) return hash; const arbitraryPrime = 664597; hash = 0x1fffffff & (arbitraryPrime * _name.hashCode); @@ -40,17 +41,17 @@ void printToConsole(String line) { } @patch -List makeListFixedLength(List growableList) { +List makeListFixedLength(List growableList) { JSArray.markFixedList(growableList); return growableList; } @patch -List makeFixedListUnmodifiable(List fixedLengthList) { +List makeFixedListUnmodifiable(List fixedLengthList) { JSArray.markUnmodifiableList(fixedLengthList); return fixedLengthList; } @patch -Object extractTypeArguments(T instance, Function extract) => +Object? extractTypeArguments(T instance, Function extract) => dart.extractTypeArguments(instance, extract); diff --git a/sdk/lib/_internal/js_dev_runtime/patch/io_patch.dart b/sdk/lib/_internal/js_dev_runtime/patch/io_patch.dart index 2f6852753b1..041dfd54c18 100644 --- a/sdk/lib/_internal/js_dev_runtime/patch/io_patch.dart +++ b/sdk/lib/_internal/js_dev_runtime/patch/io_patch.dart @@ -2,8 +2,6 @@ // 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.6 - import 'dart:_js_helper' show patch; import 'dart:async'; import 'dart:convert'; @@ -75,7 +73,7 @@ class _AsyncDirectoryListerOps { @patch class _EventHandler { @patch - static void _sendData(Object sender, SendPort sendPort, int data) { + static void _sendData(Object? sender, SendPort sendPort, int data) { throw UnsupportedError("EventHandler._sendData"); } } @@ -305,7 +303,7 @@ class _Platform { @patch class _ProcessUtils { @patch - static void _exit(int status) { + static Never _exit(int status) { throw UnsupportedError("ProcessUtils._exit"); } @@ -325,7 +323,7 @@ class _ProcessUtils { } @patch - static int _pid(Process process) { + static int _pid(Process? process) { throw UnsupportedError("ProcessUtils._pid"); } @@ -352,8 +350,8 @@ class ProcessInfo { class Process { @patch static Future start(String executable, List arguments, - {String workingDirectory, - Map environment, + {String? workingDirectory, + Map? environment, bool includeParentEnvironment = true, bool runInShell = false, ProcessStartMode mode = ProcessStartMode.normal}) { @@ -362,8 +360,8 @@ class Process { @patch static Future run(String executable, List arguments, - {String workingDirectory, - Map environment, + {String? workingDirectory, + Map? environment, bool includeParentEnvironment = true, bool runInShell = false, Encoding stdoutEncoding = systemEncoding, @@ -373,8 +371,8 @@ class Process { @patch static ProcessResult runSync(String executable, List arguments, - {String workingDirectory, - Map environment, + {String? workingDirectory, + Map? environment, bool includeParentEnvironment = true, bool runInShell = false, Encoding stdoutEncoding = systemEncoding, @@ -411,13 +409,13 @@ class InternetAddress { } @patch - factory InternetAddress(String address, {InternetAddressType type}) { + factory InternetAddress(String address, {InternetAddressType? type}) { throw UnsupportedError("InternetAddress"); } @patch factory InternetAddress.fromRawAddress(Uint8List rawAddress, - {InternetAddressType type}) { + {InternetAddressType? type}) { throw new UnsupportedError("InternetAddress.fromRawAddress"); } @@ -434,7 +432,7 @@ class InternetAddress { } @patch - static InternetAddress tryParse(String address) { + static InternetAddress? tryParse(String address) { throw UnsupportedError("InternetAddress.tryParse"); } } @@ -476,14 +474,14 @@ class ServerSocket { @patch class RawSocket { @patch - static Future connect(host, int port, - {sourceAddress, Duration timeout}) { + static Future connect(dynamic host, int port, + {dynamic sourceAddress, Duration? timeout}) { throw UnsupportedError("RawSocket constructor"); } @patch - static Future> startConnect(host, int port, - {sourceAddress}) { + static Future> startConnect(dynamic host, int port, + {dynamic sourceAddress}) { throw UnsupportedError("RawSocket constructor"); } } @@ -491,14 +489,14 @@ class RawSocket { @patch class Socket { @patch - static Future _connect(host, int port, - {sourceAddress, Duration timeout}) { + static Future _connect(dynamic host, int port, + {dynamic sourceAddress, Duration? timeout}) { throw UnsupportedError("Socket constructor"); } @patch - static Future> _startConnect(host, int port, - {sourceAddress}) { + static Future> _startConnect(dynamic host, int port, + {dynamic sourceAddress}) { throw UnsupportedError("Socket constructor"); } } @@ -514,7 +512,7 @@ class SecureSocket { @patch class RawSynchronousSocket { @patch - static RawSynchronousSocket connectSync(host, int port) { + static RawSynchronousSocket connectSync(dynamic host, int port) { throw UnsupportedError("RawSynchronousSocket.connectSync"); } } @@ -556,7 +554,7 @@ class X509Certificate { @patch class RawDatagramSocket { @patch - static Future bind(host, int port, + static Future bind(dynamic host, int port, {bool reuseAddress = true, bool reusePort = false, int ttl = 1}) { throw UnsupportedError("RawDatagramSocket.bind"); } @@ -618,14 +616,14 @@ class RawZLibFilter { int windowBits, int memLevel, int strategy, - List dictionary, + List? dictionary, bool raw) { throw UnsupportedError("_newZLibDeflateFilter"); } @patch static RawZLibFilter _makeZLibInflateFilter( - int windowBits, List dictionary, bool raw) { + int windowBits, List? dictionary, bool raw) { throw UnsupportedError("_newZLibInflateFilter"); } } diff --git a/sdk/lib/_internal/js_dev_runtime/patch/isolate_patch.dart b/sdk/lib/_internal/js_dev_runtime/patch/isolate_patch.dart index 93e41658c92..9b45b66e681 100644 --- a/sdk/lib/_internal/js_dev_runtime/patch/isolate_patch.dart +++ b/sdk/lib/_internal/js_dev_runtime/patch/isolate_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // Patch file for the dart:isolate library. import 'dart:_js_helper' show patch, NoReifyGeneric; @@ -18,36 +16,37 @@ class Isolate { static Isolate get current => _unsupported(); @patch - String get debugName => _unsupported(); + String? get debugName => _unsupported(); @patch - static Future get packageRoot => _unsupported(); + static Future get packageRoot => _unsupported(); @patch - static Future get packageConfig => _unsupported(); + static Future get packageConfig => _unsupported(); @patch - static Future resolvePackageUri(Uri packageUri) => _unsupported(); + static Future resolvePackageUri(Uri packageUri) => _unsupported(); @patch static Future spawn(void entryPoint(T message), T message, {bool paused = false, - bool errorsAreFatal, - SendPort onExit, - SendPort onError}) => + bool errorsAreFatal = true, + SendPort? onExit, + SendPort? onError}) => _unsupported(); @patch static Future spawnUri(Uri uri, List args, var message, {bool paused = false, - SendPort onExit, - SendPort onError, - bool errorsAreFatal, - bool checked, - Map environment, - Uri packageRoot, - Uri packageConfig, - bool automaticPackageResolution = false}) => + SendPort? onExit, + SendPort? onError, + bool errorsAreFatal = true, + bool? checked, + Map? environment, + Uri? packageRoot, + Uri? packageConfig, + bool automaticPackageResolution = false, + String? debugName}) => _unsupported(); @patch @@ -57,7 +56,7 @@ class Isolate { void resume(Capability resumeCapability) => _unsupported(); @patch - void addOnExitListener(SendPort responsePort, {Object response}) => + void addOnExitListener(SendPort responsePort, {Object? response}) => _unsupported(); @patch @@ -70,7 +69,7 @@ class Isolate { void kill({int priority = beforeNextEvent}) => _unsupported(); @patch void ping(SendPort responsePort, - {Object response, int priority = immediate}) => + {Object? response, int priority = immediate}) => _unsupported(); @patch @@ -99,13 +98,17 @@ class _ReceivePort extends Stream implements ReceivePort { get sendPort => _unsupported(); - listen(onData, {onError, onDone, cancelOnError}) => _unsupported(); + StreamSubscription listen(void Function(dynamic)? onData, + {Function? onError, + void Function()? onDone, + bool? cancelOnError = true}) => + _unsupported(); } @patch class RawReceivePort { @patch - factory RawReceivePort([void handler(event)]) => _unsupported(); + factory RawReceivePort([Function? handler]) => _unsupported(); } @patch diff --git a/sdk/lib/_internal/js_dev_runtime/patch/js_patch.dart b/sdk/lib/_internal/js_dev_runtime/patch/js_patch.dart index ab61378581e..feb5ef1b186 100644 --- a/sdk/lib/_internal/js_dev_runtime/patch/js_patch.dart +++ b/sdk/lib/_internal/js_dev_runtime/patch/js_patch.dart @@ -2,14 +2,12 @@ // 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.6 - // Patch file for dart:js library. library dart.js; import 'dart:collection' show HashMap, ListMixin; -import 'dart:_js_helper' show patch, Primitives; +import 'dart:_js_helper' show patch, NoReifyGeneric, Primitives; import 'dart:_foreign_helper' show JS; import 'dart:_runtime' as dart; @@ -21,7 +19,7 @@ final JsObject _context = _wrapToDart(dart.global_); @patch class JsObject { // The wrapped JS object. - final dynamic _jsObject; + final Object _jsObject; // This should only be called from _wrapToDart JsObject._fromJs(this._jsObject) { @@ -29,7 +27,7 @@ class JsObject { } @patch - factory JsObject(JsFunction constructor, [List arguments]) { + factory JsObject(JsFunction constructor, [List? arguments]) { var ctor = constructor._jsObject; if (arguments == null) { return _wrapToDart(JS('', 'new #()', ctor)); @@ -39,25 +37,25 @@ class JsObject { } @patch - factory JsObject.fromBrowserObject(object) { + factory JsObject.fromBrowserObject(Object object) { if (object is num || object is String || object is bool || object == null) { throw ArgumentError("object cannot be a num, string, bool, or null"); } - return _wrapToDart(_convertToJS(object)); + return _wrapToDart(_convertToJS(object)!); } @patch - factory JsObject.jsify(object) { + factory JsObject.jsify(Object object) { if ((object is! Map) && (object is! Iterable)) { throw ArgumentError("object must be a Map or Iterable"); } return _wrapToDart(_convertDataTree(object)); } - static _convertDataTree(data) { + static _convertDataTree(Object data) { var _convertedObjects = HashMap.identity(); - _convert(o) { + _convert(Object? o) { if (_convertedObjects.containsKey(o)) { return _convertedObjects[o]; } @@ -90,7 +88,7 @@ class JsObject { } @patch - void operator []=(Object property, value) { + void operator []=(Object property, Object? value) { if (property is! String && property is! num) { throw ArgumentError("property is not a String or num"); } @@ -98,11 +96,11 @@ class JsObject { } @patch - bool operator ==(other) => + bool operator ==(Object other) => other is JsObject && JS('!', '# === #', _jsObject, other._jsObject); @patch - bool hasProperty(property) { + bool hasProperty(Object property) { if (property is! String && property is! num) { throw ArgumentError("property is not a String or num"); } @@ -110,7 +108,7 @@ class JsObject { } @patch - void deleteProperty(property) { + void deleteProperty(Object property) { if (property is! String && property is! num) { throw ArgumentError("property is not a String or num"); } @@ -132,14 +130,14 @@ class JsObject { } @patch - dynamic callMethod(method, [List args]) { + dynamic callMethod(Object method, [List? args]) { if (method is! String && method is! num) { throw ArgumentError("method is not a String or num"); } if (args != null) args = List.from(args.map(_convertToJS)); var fn = JS('', '#[#]', _jsObject, method); if (JS('!', 'typeof(#) !== "function"', fn)) { - throw NoSuchMethodError(_jsObject, Symbol(method), args, {}); + throw NoSuchMethodError(_jsObject, Symbol('$method'), args, {}); } return _convertToDart(JS('', '#.apply(#, #)', fn, _jsObject, args)); } @@ -164,7 +162,7 @@ class JsFunction extends JsObject { f)); } - JsFunction._fromJs(jsObject) : super._fromJs(jsObject); + JsFunction._fromJs(Object jsObject) : super._fromJs(jsObject); @patch dynamic apply(List args, {thisArg}) => _convertToDart(JS( @@ -185,16 +183,16 @@ class JsArray extends JsObject with ListMixin { factory JsArray.from(Iterable other) => JsArray._fromJs([]..addAll(other.map(_convertToJS))); - JsArray._fromJs(jsObject) : super._fromJs(jsObject); + JsArray._fromJs(Object jsObject) : super._fromJs(jsObject); _checkIndex(int index) { - if (index is int && (index < 0 || index >= length)) { + if (index < 0 || index >= length) { throw RangeError.range(index, 0, length); } } _checkInsertIndex(int index) { - if (index is int && (index < 0 || index >= length + 1)) { + if (index < 0 || index >= length + 1) { throw RangeError.range(index, 0, length); } } @@ -210,9 +208,7 @@ class JsArray extends JsObject with ListMixin { @patch E operator [](Object index) { - // TODO(justinfagnani): fix the semantics for non-ints - // dartbug.com/14605 - if (index is num && index == index.toInt()) { + if (index is int) { _checkIndex(index); } return super[index] as E; @@ -220,9 +216,7 @@ class JsArray extends JsObject with ListMixin { @patch void operator []=(Object index, value) { - // TODO(justinfagnani): fix the semantics for non-ints - // dartbug.com/14605 - if (index is num && index == index.toInt()) { + if (index is int) { _checkIndex(index); } super[index] = value; @@ -253,7 +247,7 @@ class JsArray extends JsObject with ListMixin { @patch void addAll(Iterable iterable) { var list = (JS('!', '# instanceof Array', iterable)) - ? iterable + ? JS('', '#', iterable) : List.from(iterable); callMethod('push', list); } @@ -288,13 +282,13 @@ class JsArray extends JsObject with ListMixin { int length = end - start; if (length == 0) return; if (skipCount < 0) throw ArgumentError(skipCount); - var args = [start, length] + var args = [start, length] ..addAll(iterable.skip(skipCount).take(length)); callMethod('splice', args); } @patch - void sort([int compare(E a, E b)]) { + void sort([int compare(E a, E b)?]) { // Note: arr.sort(null) is a type error in FF callMethod('sort', compare == null ? [] : [compare]); } @@ -304,7 +298,7 @@ class JsArray extends JsObject with ListMixin { // We include the instanceof Object test to filter out cross frame objects // on FireFox. Surprisingly on FireFox the instanceof Window test succeeds for // cross frame windows while the instanceof Object test fails. -bool _isBrowserType(o) => JS( +bool _isBrowserType(Object o) => JS( 'bool', '# instanceof Object && (' '# instanceof Blob || ' @@ -329,11 +323,11 @@ bool _isBrowserType(o) => JS( o); class _DartObject { - final _dartObj; + final Object _dartObj; _DartObject(this._dartObj); } -dynamic _convertToJS(dynamic o) { +Object? _convertToJS(Object? o) { if (o == null || o is String || o is num || o is bool || _isBrowserType(o)) { return o; } else if (o is DateTime) { @@ -349,8 +343,8 @@ dynamic _convertToJS(dynamic o) { } } -dynamic _wrapDartFunction(f) { - var wrapper = JS( +Object _wrapDartFunction(Object f) { + var wrapper = JS( '', 'function(/*...arguments*/) {' ' let args = Array.prototype.map.call(arguments, #);' @@ -366,11 +360,11 @@ dynamic _wrapDartFunction(f) { // converts a Dart object to a reference to a native JS object // which might be a DartObject JS->Dart proxy -Object _convertToDart(o) { +Object? _convertToDart(Object? o) { if (o == null || o is String || o is num || o is bool || _isBrowserType(o)) { return o; } else if (JS('!', '# instanceof Date', o)) { - num ms = JS('!', '#.getTime()', o); + int ms = JS('!', '#.getTime()', o); return DateTime.fromMillisecondsSinceEpoch(ms); } else if (o is _DartObject && !identical(dart.getReifiedType(o), dart.jsobject)) { @@ -380,9 +374,10 @@ Object _convertToDart(o) { } } -Object _wrapToDart(o) => _putIfAbsent(_dartProxies, o, _wrapToDartHelper); +JsObject _wrapToDart(Object o) => + _putIfAbsent(_dartProxies, o, _wrapToDartHelper); -Object _wrapToDartHelper(o) { +JsObject _wrapToDartHelper(Object o) { if (JS('!', 'typeof # == "function"', o)) { return JsFunction._fromJs(o); } @@ -392,16 +387,18 @@ Object _wrapToDartHelper(o) { return JsObject._fromJs(o); } -final _dartProxies = JS('', 'new WeakMap()'); -final _jsProxies = JS('', 'new WeakMap()'); +final Object _dartProxies = JS('', 'new WeakMap()'); +final Object _jsProxies = JS('', 'new WeakMap()'); -Object _putIfAbsent(weakMap, o, getValue(o)) { - var value = JS('', '#.get(#)', weakMap, o); +@NoReifyGeneric() +T _putIfAbsent(Object weakMap, Object o, T getValue(Object o)) { + T? value = JS('', '#.get(#)', weakMap, o); if (value == null) { value = getValue(o); JS('', '#.set(#, #)', weakMap, o, value); } - return value; + // TODO(vsm): Static cast. Unnecessary? + return JS('', '#', value); } Expando _interopExpando = Expando(); @@ -409,9 +406,9 @@ Expando _interopExpando = Expando(); @patch F allowInterop(F f) { if (!dart.isDartFunction(f)) return f; - var ret = _interopExpando[f]; + var ret = _interopExpando[f] as F?; if (ret == null) { - ret = JS( + ret = JS( '', 'function (...args) {' ' return #(#, args);' @@ -430,7 +427,7 @@ Function allowInteropCaptureThis(Function f) { if (!dart.isDartFunction(f)) return f; var ret = _interopCaptureThisExpando[f]; if (ret == null) { - ret = JS( + ret = JS( '', 'function(...arguments) {' ' let args = [this];' diff --git a/sdk/lib/_internal/js_dev_runtime/patch/math_patch.dart b/sdk/lib/_internal/js_dev_runtime/patch/math_patch.dart index c2363f7b414..288f66e838d 100644 --- a/sdk/lib/_internal/js_dev_runtime/patch/math_patch.dart +++ b/sdk/lib/_internal/js_dev_runtime/patch/math_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // Patch file for dart:math library. import 'dart:_foreign_helper' show JS; import 'dart:_js_helper' show patch, nullCheck, notNull; @@ -12,53 +10,53 @@ import 'dart:typed_data' show ByteData; @patch @notNull T min(@nullCheck T a, @nullCheck T b) => - JS('-dynamic', r'Math.min(#, #)', a, b); + JS('-dynamic', r'Math.min(#, #)', a, b); @patch @notNull T max(@nullCheck T a, @nullCheck T b) => - JS('-dynamic', r'Math.max(#, #)', a, b); + JS('-dynamic', r'Math.max(#, #)', a, b); @patch @notNull -double sqrt(@nullCheck num x) => JS('!', r'Math.sqrt(#)', x); +double sqrt(@nullCheck num x) => JS('!', r'Math.sqrt(#)', x); @patch @notNull -double sin(@nullCheck num radians) => JS('!', r'Math.sin(#)', radians); +double sin(@nullCheck num radians) => JS('!', r'Math.sin(#)', radians); @patch @notNull -double cos(@nullCheck num radians) => JS('!', r'Math.cos(#)', radians); +double cos(@nullCheck num radians) => JS('!', r'Math.cos(#)', radians); @patch @notNull -double tan(@nullCheck num radians) => JS('!', r'Math.tan(#)', radians); +double tan(@nullCheck num radians) => JS('!', r'Math.tan(#)', radians); @patch @notNull -double acos(@nullCheck num x) => JS('!', r'Math.acos(#)', x); +double acos(@nullCheck num x) => JS('!', r'Math.acos(#)', x); @patch @notNull -double asin(@nullCheck num x) => JS('!', r'Math.asin(#)', x); +double asin(@nullCheck num x) => JS('!', r'Math.asin(#)', x); @patch @notNull -double atan(@nullCheck num x) => JS('!', r'Math.atan(#)', x); +double atan(@nullCheck num x) => JS('!', r'Math.atan(#)', x); @patch @notNull double atan2(@nullCheck num a, @nullCheck num b) => - JS('!', r'Math.atan2(#, #)', a, b); + JS('!', r'Math.atan2(#, #)', a, b); @patch @notNull -double exp(@nullCheck num x) => JS('!', r'Math.exp(#)', x); +double exp(@nullCheck num x) => JS('!', r'Math.exp(#)', x); @patch @notNull -double log(@nullCheck num x) => JS('!', r'Math.log(#)', x); +double log(@nullCheck num x) => JS('!', r'Math.log(#)', x); @patch @notNull @@ -69,10 +67,10 @@ const int _POW2_32 = 0x100000000; @patch class Random { - static Random _secureRandom; + static Random? _secureRandom; @patch - factory Random([int seed]) => + factory Random([int? seed]) => (seed == null) ? const _JSRandom() : _Random(seed); @patch @@ -88,7 +86,7 @@ class _JSRandom implements Random { if (max <= 0 || max > _POW2_32) { throw RangeError("max must be in range 0 < max ≤ 2^32, was $max"); } - return JS("int", "(Math.random() * #) >>> 0", max); + return JS("int", "(Math.random() * #) >>> 0", max); } /** @@ -96,13 +94,13 @@ class _JSRandom implements Random { * the range from 0.0, inclusive, to 1.0, exclusive. */ @notNull - double nextDouble() => JS("double", "Math.random()"); + double nextDouble() => JS("double", "Math.random()"); /** * Generates a random boolean value. */ @notNull - bool nextBool() => JS("bool", "Math.random() < 0.5"); + bool nextBool() => JS("bool", "Math.random() < 0.5"); } class _Random implements Random { @@ -240,7 +238,7 @@ class _Random implements Random { do { _nextState(); rnd32 = _lo; - result = rnd32.remainder(max); // % max; + result = rnd32.remainder(max).toInt(); // % max; } while ((rnd32 - result + max) >= _POW2_32); return result; } @@ -327,7 +325,7 @@ class _JSSecureRandom implements Random { } _buffer.setUint32(0, 0); int start = 4 - byteCount; - int randomLimit = pow(256, byteCount); + int randomLimit = pow(256, byteCount).toInt(); while (true) { _getRandomBytes(start, byteCount); // The getUint32 method is big-endian as default. @@ -336,7 +334,7 @@ class _JSSecureRandom implements Random { // Max is power of 2. return random & (max - 1); } - int result = random.remainder(max); + int result = random.remainder(max).toInt(); // Ensure results have equal probability by rejecting values in the // last range of k*max .. 256**byteCount. // TODO: Consider picking a higher byte count if the last range is a diff --git a/sdk/lib/_internal/js_dev_runtime/patch/typed_data_patch.dart b/sdk/lib/_internal/js_dev_runtime/patch/typed_data_patch.dart index 9cf539b7944..d1c6a1a19f3 100644 --- a/sdk/lib/_internal/js_dev_runtime/patch/typed_data_patch.dart +++ b/sdk/lib/_internal/js_dev_runtime/patch/typed_data_patch.dart @@ -2,8 +2,6 @@ // 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.6 - import 'dart:_js_helper' show patch; import 'dart:_native_typed_data'; diff --git a/sdk/lib/_internal/js_dev_runtime/private/annotations.dart b/sdk/lib/_internal/js_dev_runtime/private/annotations.dart index feac26e4eb7..9062f3170e6 100644 --- a/sdk/lib/_internal/js_dev_runtime/private/annotations.dart +++ b/sdk/lib/_internal/js_dev_runtime/private/annotations.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart._js_helper; /// Tells the optimizing compiler to always inline the annotated method. @@ -83,7 +81,7 @@ class JsPeerInterface { /// Used for classes where Dart subclasses should be callable from JavaScript /// matching the JavaScript calling conventions. final String name; - const JsPeerInterface({this.name}); + const JsPeerInterface({required this.name}); } /// A Dart interface may only be implemented by a native JavaScript object diff --git a/sdk/lib/_internal/js_dev_runtime/private/custom_hash_map.dart b/sdk/lib/_internal/js_dev_runtime/private/custom_hash_map.dart index c387062688c..14444e32ff6 100644 --- a/sdk/lib/_internal/js_dev_runtime/private/custom_hash_map.dart +++ b/sdk/lib/_internal/js_dev_runtime/private/custom_hash_map.dart @@ -2,30 +2,28 @@ // 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.6 - part of dart._js_helper; class CustomKeyHashMap extends CustomHashMap { - final _Predicate _validKey; + final _Predicate _validKey; CustomKeyHashMap(_Equality equals, _Hasher hashCode, this._validKey) : super(equals, hashCode); @override @notNull - bool containsKey(Object key) { + bool containsKey(Object? key) { if (!_validKey(key)) return false; return super.containsKey(key); } @override - V operator [](Object key) { + V? operator [](Object? key) { if (!_validKey(key)) return null; return super[key]; } @override - V remove(Object key) { + V? remove(Object? key) { if (!_validKey(key)) return null; return super.remove(key); } @@ -69,7 +67,7 @@ class CustomHashMap extends InternalMap { Iterable get values => _JSMapIterable(this, false); @notNull - bool containsKey(Object key) { + bool containsKey(Object? key) { if (key is K) { var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, _hashCode(key)); if (buckets != null) { @@ -83,7 +81,7 @@ class CustomHashMap extends InternalMap { return false; } - bool containsValue(Object value) { + bool containsValue(Object? value) { for (var v in JS('', '#.values()', _map)) { if (value == v) return true; } @@ -96,7 +94,7 @@ class CustomHashMap extends InternalMap { }); } - V operator [](Object key) { + V? operator [](Object? key) { if (key is K) { var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, _hashCode(key)); if (buckets != null) { @@ -152,13 +150,13 @@ class CustomHashMap extends InternalMap { JS('', '#.push(#)', buckets, key); } V value = ifAbsent(); - if (value == null) value = null; // coerce undefined to null. + if (value == null) JS('', '# = null', value); // coerce undefined to null. JS('', '#.set(#, #)', _map, key, value); _modifications = (_modifications + 1) & 0x3ffffff; return value; } - V remove(Object key) { + V? remove(Object? key) { if (key is K) { int hash = JS('!', '# & 0x3ffffff', _hashCode(key)); var keyMap = _keyMap; diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/classes.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/classes.dart index 15922180c4d..bb580634fd9 100644 --- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/classes.dart +++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/classes.dart @@ -2,8 +2,6 @@ // 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.6 - /// This library defines the operations that define and manipulate Dart /// classes. Included in this are: /// - Generics @@ -109,7 +107,7 @@ final mixinOn = JS('', 'Symbol("mixinOn")'); @JSExportName('implements') final implements_ = JS('', 'Symbol("implements")'); -List Function() getImplements(clazz) => JS( +List? Function() getImplements(clazz) => JS( '', 'Object.hasOwnProperty.call(#, #) ? #[#] : null', clazz, @@ -229,11 +227,11 @@ getGenericClass(type) => safeGetOwnProperty(type, _originalDeclaration); // TODO(markzipan): Make this non-nullable if we can ensure this returns // an empty list or if null and the empty list are semantically the same. -List getGenericArgs(type) => +List? getGenericArgs(type) => JS('', '#', safeGetOwnProperty(type, _typeArguments)); -List getGenericArgVariances(type) => - JS('', '#', safeGetOwnProperty(type, _variances)); +List? getGenericArgVariances(type) => + JS('', '#', safeGetOwnProperty(type, _variances)); void setGenericArgVariances(f, variances) => JS('', '#[#] = #', f, _variances, variances); diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart index 7d695998bcc..ba418a46805 100644 --- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart +++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart._runtime; // We need to set these properties while the sdk is only partially initialized @@ -21,15 +19,15 @@ throwUnimplementedError(String message) { // TODO(nshahan) Cleanup embeded strings and extract file location at runtime // from the stacktrace. -assertFailed(String message, - [String fileUri, int line, int column, String conditionSource]) { +assertFailed(String? message, + [String? fileUri, int? line, int? column, String? conditionSource]) { throw AssertionErrorImpl(message, fileUri, line, column, conditionSource); } final _nullFailedSet = JS('!', 'new Set()'); // Run-time null safety assertion per: // https://github.com/dart-lang/language/blob/master/accepted/future-releases/nnbd/feature-specification.md#automatic-debug-assertion-insertion -nullFailed(String fileUri, int line, int column, String variable) { +nullFailed(String? fileUri, int? line, int? column, String? variable) { if (strictNullSafety) { throw AssertionErrorImpl( 'A null value was passed into a non-nullable parameter $variable', @@ -47,7 +45,7 @@ nullFailed(String fileUri, int line, int column, String variable) { } } -throwCyclicInitializationError([String field]) { +throwCyclicInitializationError([String? field]) { throw CyclicInitializationError(field); } @@ -101,7 +99,7 @@ final Object _jsError = JS('', 'Symbol("_jsError")'); /// /// If the throw originated in JavaScript, then there is not a corresponding /// Dart value, so we just return the error object. -Object getThrown(Object error) { +Object? getThrown(Object? error) { if (error != null) { // Get the Dart thrown value, if any. var value = JS('', '#[#]', error, _thrownValue); @@ -123,7 +121,7 @@ final _stackTrace = JS('', 'Symbol("_stackTrace")'); /// the corresponding stack trace the same way we do for Dart throws. If the /// throw object was not an Error, then we don't have a JS trace, so we create /// one here. -StackTrace stackTrace(Object error) { +StackTrace stackTrace(Object? error) { if (JS('!', '!(# instanceof Error)', error)) { // We caught something that isn't a JS Error. // @@ -133,7 +131,7 @@ StackTrace stackTrace(Object error) { } // If we've already created the Dart stack trace object, return it. - StackTrace trace = JS('', '#[#]', error, _stackTrace); + StackTrace? trace = JS('', '#[#]', error, _stackTrace); if (trace != null) return trace; // Otherwise create the Dart stack trace (by parsing the JS stack), and @@ -210,7 +208,7 @@ final Object RethrownDartError = JS( /// Implements `throw` of [exception], allowing for throw in an expression /// context, and capturing the current stack trace. @JSExportName('throw') -void throw_(Object exception) { +void throw_(Object? exception) { /// Wrap the object so we capture a new stack trace, and so it will print /// nicely from JS, as if it were a normal JS error. JS('', 'throw new #(#)', DartError, exception); @@ -233,7 +231,7 @@ void throw_(Object exception) { /// If the stack trace is null, this will preserve the original stack trace /// on the exception, if available, otherwise it will capture the current stack /// trace. -Object createErrorWithStack(Object exception, StackTrace trace) { +Object? createErrorWithStack(Object exception, StackTrace? trace) { if (trace == null) { var error = JS('', '#[#]', exception, _jsError); return error != null ? error : JS('', 'new #(#)', DartError, exception); @@ -257,18 +255,18 @@ void stackPrint(Object error) { } class _StackTrace implements StackTrace { - final Object _jsError; - final Object _jsObjectMissingTrace; - String _trace; + final Object? _jsError; + final Object? _jsObjectMissingTrace; + String? _trace; _StackTrace(this._jsError) : _jsObjectMissingTrace = null; - _StackTrace.missing(Object caughtObj) + _StackTrace.missing(Object? caughtObj) : _jsObjectMissingTrace = caughtObj != null ? caughtObj : 'null', _jsError = JS('', 'Error()'); String toString() { - if (_trace != null) return _trace; + if (_trace != null) return _trace!; var e = _jsError; String trace = ''; diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart index 313bdc3100e..fd9a7d40ecf 100644 --- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart +++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart @@ -2,8 +2,6 @@ // 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.6 - /// This library defines runtime operations on objects used by the code /// generator. part of dart._runtime; @@ -19,7 +17,7 @@ class InvocationImpl extends Invocation { final bool isSetter; final String failureMessage; - InvocationImpl(memberName, List positionalArguments, + InvocationImpl(memberName, List positionalArguments, {namedArguments, List typeArguments = const [], this.isMethod = false, @@ -146,7 +144,7 @@ dput(obj, field, value) { /// [actuals] and [namedActuals]. /// /// Returns `null` if all checks pass. -String _argumentErrors(FunctionType type, List actuals, namedActuals) { +String? _argumentErrors(FunctionType type, List actuals, namedActuals) { // Check for too few required arguments. int actualsCount = JS('!', '#.length', actuals); var required = type.args; @@ -165,7 +163,7 @@ String _argumentErrors(FunctionType type, List actuals, namedActuals) { } // Check if we have invalid named arguments. - Iterable names; + Iterable? names; var named = type.named; var requiredNamed = type.requiredNamed; if (namedActuals != null) { @@ -444,7 +442,7 @@ cast(obj, type) { return castError(obj, type); } -bool test(bool obj) { +bool test(bool? obj) { if (obj == null) throw BooleanConversionAssertionError(); return obj; } @@ -513,11 +511,11 @@ final constantMaps = JS('!', 'new Map()'); // Keeping the paths is probably expensive. It would probably // be more space efficient to just use a direct hash table with // an appropriately defined structural equality function. -Object _lookupNonTerminal(Object map, Object key) { +Object _lookupNonTerminal(Object map, Object? key) { var result = JS('', '#.get(#)', map, key); if (result != null) return result; JS('', '#.set(#, # = new Map())', map, key, result); - return result; + return result!; } Map constMap(JSArray elements) { @@ -527,7 +525,7 @@ Map constMap(JSArray elements) { map = _lookupNonTerminal(map, JS('', '#[#]', elements, i)); } map = _lookupNonTerminal(map, K); - Map result = JS('', '#.get(#)', map, V); + Map? result = JS('', '#.get(#)', map, V); if (result != null) return result; result = ImmutableMap.from(elements); JS('', '#.set(#, #)', map, V, result); @@ -550,7 +548,7 @@ Set constSet(JSArray elements) { for (var i = 0; i < count; i++) { map = _lookupNonTerminal(map, JS('', '#[#]', elements, i)); } - Set result = JS('', '#.get(#)', map, E); + Set? result = JS('', '#.get(#)', map, E); if (result != null) return result; result = _createImmutableSet(elements); JS('', '#.set(#, #)', map, E, result); diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/rtti.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/rtti.dart index 4d731ced596..1f362a8cab1 100644 --- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/rtti.dart +++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/rtti.dart @@ -2,8 +2,6 @@ // 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.6 - /// This library defines the association between runtime objects and /// runtime types. part of dart._runtime; @@ -116,7 +114,7 @@ getReifiedType(obj) { } /// Return the module name for a raw library object. -String getModuleName(Object module) => JS('', '#[#]', module, _moduleName); +String? getModuleName(Object module) => JS('', '#[#]', module, _moduleName); final _loadedModules = JS('', 'new Map()'); final _loadedPartMaps = JS('', 'new Map()'); @@ -126,7 +124,7 @@ List getModuleNames() { return JS>('', 'Array.from(#.keys())', _loadedModules); } -String getSourceMap(String moduleName) { +String? getSourceMap(String moduleName) { return JS('!', '#.get(#)', _loadedSourceMaps, moduleName); } @@ -143,7 +141,7 @@ getModulePartMap(String name) => JS('', '#.get(#)', _loadedPartMaps, name); /// Track all libraries void trackLibraries( - String moduleName, Object libraries, Object parts, String sourceMap) { + String moduleName, Object libraries, Object parts, String? sourceMap) { if (parts is String) { // Added for backwards compatibility. // package:build_web_compilers currently invokes this without [parts] @@ -159,9 +157,9 @@ void trackLibraries( _parts = null; } -List _libraries; -Map _libraryObjects; -Map> _parts; +List? _libraries; +Map? _libraryObjects; +Map?>? _parts; _computeLibraryMetadata() { _libraries = []; @@ -174,16 +172,16 @@ _computeLibraryMetadata() { // TODO(nshahan) Can we optimize this cast and the one below to use // JsArray.of() to be more efficient? var libraries = getOwnPropertyNames(module).cast(); - _libraries.addAll(libraries); + _libraries!.addAll(libraries); for (var library in libraries) { - _libraryObjects[library] = JS('', '#.#', module, library); + _libraryObjects![library] = JS('', '#.#', module, library); } // Add parts from each module. var partMap = getModulePartMap(name); libraries = getOwnPropertyNames(partMap).cast(); for (var library in libraries) { - _parts[library] = List.from(JS('List', '#.#', partMap, library)); + _parts![library] = List.from(JS('List', '#.#', partMap, library)); } } } @@ -191,11 +189,11 @@ _computeLibraryMetadata() { /// Returns the JS library object for a given library [uri] or /// undefined / null if it isn't loaded. Top-level types and /// methods are available on this object. -Object getLibrary(String uri) { +Object? getLibrary(String uri) { if (_libraryObjects == null) { _computeLibraryMetadata(); } - return _libraryObjects[uri]; + return _libraryObjects![uri]; } /// Returns a JSArray of library uris (e.g, @@ -205,7 +203,7 @@ List getLibraries() { if (_libraries == null) { _computeLibraryMetadata(); } - return _libraries; + return _libraries!; } /// Returns a JSArray of part uris for a given [libraryUri]. @@ -225,5 +223,5 @@ List getParts(String libraryUri) { if (_parts == null) { _computeLibraryMetadata(); } - return _parts[libraryUri] ?? []; + return _parts![libraryUri] ?? []; } diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart index 433393d451b..4867462ec9e 100644 --- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart +++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart @@ -2,8 +2,6 @@ // 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.6 - @ReifyFunctionTypes(false) library dart._runtime; diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart index 625e44f9cb3..f5f25a0cc46 100644 --- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart +++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart @@ -2,8 +2,6 @@ // 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.6 - /// This library defines the representation of runtime types. part of dart._runtime; @@ -118,7 +116,7 @@ class DynamicType extends DartType { bool is_T(object) => true; @JSExportName('as') - Object as_T(Object object) => object; + Object? as_T(Object? object) => object; } @notNull @@ -144,7 +142,7 @@ bool isDartFunction(obj) => Expando _assertInteropExpando = Expando(); @NoReifyGeneric() -F tearoffInterop(F f) { +F tearoffInterop(F f) { // Wrap a JS function with a closure that ensures all function arguments are // native JS functions. if (!_isJsObject(f) || f == null) return f; @@ -171,10 +169,10 @@ F tearoffInterop(F f) { /// we disable type checks for in these cases, and allow any JS object to work /// as if it were an instance of this JS type. class LazyJSType extends DartType { - Function() _getRawJSTypeFn; + Function()? _getRawJSTypeFn; @notNull final String _dartName; - Object _rawJSType; + Object? _rawJSType; LazyJSType(this._getRawJSTypeFn, this._dartName); @@ -183,7 +181,7 @@ class LazyJSType extends DartType { return raw != null ? typeName(raw) : "JSObject<$_dartName>"; } - Object _getRawJSType() { + Object? _getRawJSType() { var raw = _rawJSType; if (raw != null) return raw; @@ -193,7 +191,7 @@ class LazyJSType extends DartType { // overhead, especially if exceptions are being thrown. Also it means the // behavior of a given type check can change later on. try { - raw = _getRawJSTypeFn(); + raw = _getRawJSTypeFn!(); } catch (e) {} if (raw == null) { @@ -434,7 +432,7 @@ class VoidType extends DartType { bool is_T(object) => true; @JSExportName('as') - Object as_T(Object object) => object; + Object? as_T(Object? object) => object; } @JSExportName('void') @@ -685,7 +683,7 @@ class FunctionType extends AbstractFunctionType { // Named arguments native JS Object of the form { namedArgName: namedArgType } final named; final requiredNamed; - String _stringValue; + String? _stringValue; /// Construct a function type. /// @@ -743,7 +741,7 @@ class FunctionType extends AbstractFunctionType { } /// Maps argument names to their canonicalized type. - Map _createNameMap(List names) { + Map _createNameMap(List names) { var result = {}; // TODO: Remove this sort if ordering can be conserved. JS('', '#.sort()', names); @@ -763,7 +761,7 @@ class FunctionType extends AbstractFunctionType { _createNameMap(getOwnPropertyNames(requiredNamed).toList()); get name { - if (_stringValue != null) return _stringValue; + if (_stringValue != null) return _stringValue!; var buffer = '('; for (var i = 0; JS('!', '# < #.length', i, args); ++i) { if (i > 0) { @@ -858,7 +856,7 @@ class GenericFunctionTypeIdentifier extends AbstractFunctionType { final typeFormals; final typeBounds; final FunctionType function; - String _stringValue; + String? _stringValue; GenericFunctionTypeIdentifier( this.typeFormals, this.typeBounds, this.function); @@ -869,7 +867,7 @@ class GenericFunctionTypeIdentifier extends AbstractFunctionType { /// Type formal names may not correspond to those of the originating type. /// We should consider auto-generating these to avoid confusion. toString() { - if (_stringValue != null) return _stringValue; + if (_stringValue != null) return _stringValue!; String s = "<"; var typeFormals = this.typeFormals; var typeBounds = this.typeBounds; @@ -994,7 +992,7 @@ class GenericFunctionType extends AbstractFunctionType { // formal if known, or it will be the original TypeVariable if we are still // solving for it. This array is passed to `instantiateToBounds` as we are // progressively solving for type variables. - var defaults = List.filled(typeFormals.length, null); + var defaults = List.filled(typeFormals.length, null); // not ground var partials = Map.identity(); @@ -1037,9 +1035,9 @@ class GenericFunctionType extends AbstractFunctionType { while (hasProgress) { hasProgress = false; for (var typeFormal in partials.keys) { - var partialBound = partials[typeFormal]; + var partialBound = partials[typeFormal]!; if (!hasFreeFormal(partialBound)) { - int index = all[typeFormal]; + int index = all[typeFormal]!; defaults[index] = instantiateTypeBounds(defaults)[index]; partials.remove(typeFormal); hasProgress = true; @@ -1079,7 +1077,7 @@ class GenericFunctionType extends AbstractFunctionType { } } -List _typeFormalsFromFunction(Object typeConstructor) { +List _typeFormalsFromFunction(Object? typeConstructor) { // Extract parameter names from the function parameters. // // This is not robust in general for user-defined JS functions, but it @@ -1610,7 +1608,7 @@ bool _isInterfaceSubtype(t1, t2, @notNull bool strictMode) => JS('', '''(() => { return false; })()'''); -Object extractTypeArguments(T instance, Function f) { +Object? extractTypeArguments(T instance, Function f) { if (instance == null) { throw ArgumentError('Cannot extract type of null instance.'); } @@ -1622,7 +1620,7 @@ Object extractTypeArguments(T instance, Function f) { throw ArgumentError('Cannot extract from non-class type ($type).'); } var typeArguments = getGenericArgs(type); - if (typeArguments.isEmpty) { + if (typeArguments!.isEmpty) { throw ArgumentError('Cannot extract from non-generic type ($type).'); } var supertype = _getMatchingSupertype(getReifiedType(instance), type); @@ -1646,14 +1644,14 @@ class _TypeInferrer { typeVariables, typeVariables.map((_) => TypeConstraint())); /// Returns the inferred types based on the current constraints. - List getInferredTypes() { + List? getInferredTypes() { var result = []; for (var constraint in _typeVariables.values) { // Prefer the known bound, if any. if (constraint.lower != null) { - result.add(constraint.lower); + result.add(constraint.lower!); } else if (constraint.upper != null) { - result.add(constraint.upper); + result.add(constraint.upper!); } else { return null; } @@ -1670,11 +1668,11 @@ class _TypeInferrer { _isSubtypeMatch(subtype, supertype); void _constrainLower(TypeVariable parameter, Object lower) { - _typeVariables[parameter]._constrainLower(lower); + _typeVariables[parameter]!._constrainLower(lower); } void _constrainUpper(TypeVariable parameter, Object upper) { - _typeVariables[parameter]._constrainUpper(upper); + _typeVariables[parameter]!._constrainUpper(upper); } bool _isFunctionSubtypeMatch(FunctionType subtype, FunctionType supertype) { @@ -1740,13 +1738,13 @@ class _TypeInferrer { for (var name in supertypeNamed.keys) { var subtypeParamType = subtypeNamed[name]; if (subtypeParamType == null) return false; - if (!_isSubtypeMatch(supertypeNamed[name], subtypeParamType)) { + if (!_isSubtypeMatch(supertypeNamed[name]!, subtypeParamType)) { return false; } } for (var name in supertypeRequiredNamed.keys) { - var subtypeParamType = subtypeRequiredNamed[name] ?? subtypeNamed[name]; - if (!_isSubtypeMatch(supertypeRequiredNamed[name], subtypeParamType)) { + var subtypeParamType = subtypeRequiredNamed[name] ?? subtypeNamed[name]!; + if (!_isSubtypeMatch(supertypeRequiredNamed[name]!, subtypeParamType)) { return false; } } @@ -1777,8 +1775,8 @@ class _TypeInferrer { var matchingSupertype = _getMatchingSupertype(subtype, supertype); if (matchingSupertype == null) return false; - var matchingTypeArgs = getGenericArgs(matchingSupertype); - var supertypeTypeArgs = getGenericArgs(supertype); + var matchingTypeArgs = getGenericArgs(matchingSupertype)!; + var supertypeTypeArgs = getGenericArgs(supertype)!; for (int i = 0; i < supertypeTypeArgs.length; i++) { if (!_isSubtypeMatch(matchingTypeArgs[i], supertypeTypeArgs[i])) { return false; @@ -1824,13 +1822,13 @@ class _TypeInferrer { // Handle FutureOr union type. if (_isFutureOr(subtype)) { - var subtypeArg = getGenericArgs(subtype)[0]; + var subtypeArg = getGenericArgs(subtype)![0]; if (_isFutureOr(supertype)) { // `FutureOr

` is a subtype match for `FutureOr` with respect to `L` // under constraints `C`: // - If `P` is a subtype match for `Q` with respect to `L` under constraints // `C`. - var supertypeArg = getGenericArgs(supertype)[0]; + var supertypeArg = getGenericArgs(supertype)![0]; return _isSubtypeMatch(subtypeArg, supertypeArg); } @@ -1843,7 +1841,7 @@ class _TypeInferrer { var subtypeFuture = JS('!', '#(#)', getGenericClass(Future), subtypeArg); return _isSubtypeMatch(subtypeFuture, supertype) && - _isSubtypeMatch(subtypeArg, supertype); + _isSubtypeMatch(subtypeArg!, supertype); } if (_isFutureOr(supertype)) { @@ -1855,7 +1853,7 @@ class _TypeInferrer { // constraints `C` // - And `P` is a subtype match for `Q` with respect to `L` under // constraints `C` - var supertypeArg = getGenericArgs(supertype)[0]; + var supertypeArg = getGenericArgs(supertype)![0]; var supertypeFuture = JS('!', '#(#)', getGenericClass(Future), supertypeArg); return _isSubtypeMatch(subtype, supertypeFuture) || @@ -1950,11 +1948,11 @@ class _TypeInferrer { class TypeConstraint { /// The lower bound of the type being constrained. This bound must be a /// subtype of the type being constrained. - Object lower; + Object? lower; /// The upper bound of the type being constrained. The type being constrained /// must be a subtype of this bound. - Object upper; + Object? upper; void _constrainLower(Object type) { var _lower = lower; @@ -1991,7 +1989,7 @@ class TypeConstraint { /// Finds a supertype of [subtype] that matches the class [supertype], but may /// contain different generic type arguments. -Object _getMatchingSupertype(Object subtype, Object supertype) { +Object? _getMatchingSupertype(Object? subtype, Object supertype) { if (identical(subtype, supertype)) return supertype; if (subtype == null || _equalType(subtype, Object)) return null; @@ -2014,7 +2012,7 @@ Object _getMatchingSupertype(Object subtype, Object supertype) { // Check interfaces. var getInterfaces = getImplements(subtype); if (getInterfaces != null) { - for (var iface in getInterfaces()) { + for (var iface in getInterfaces()!) { result = _getMatchingSupertype(iface, supertype); if (result != null) return result; } diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/utils.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/utils.dart index d202ff05f7c..07a2faa1c22 100644 --- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/utils.dart +++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/utils.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart._runtime; /// This library defines a set of general javascript utilities for us @@ -19,11 +17,11 @@ defineValue(obj, name, value) { } final Function(Object, Object, - {Object get, - Object set, - Object value, - bool configurable, - bool writable}) defineAccessor = JS('', 'Object.defineProperty'); + {Object? get, + Object? set, + Object? value, + bool? configurable, + bool? writable}) defineAccessor = JS('', 'Object.defineProperty'); final dynamic Function(Object, Object) getOwnPropertyDescriptor = JS('', 'Object.getOwnPropertyDescriptor'); diff --git a/sdk/lib/_internal/js_dev_runtime/private/debugger.dart b/sdk/lib/_internal/js_dev_runtime/private/debugger.dart index db11479b08a..f77d5c329d9 100644 --- a/sdk/lib/_internal/js_dev_runtime/private/debugger.dart +++ b/sdk/lib/_internal/js_dev_runtime/private/debugger.dart @@ -2,8 +2,6 @@ // 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.6 - library dart._debugger; import 'dart:_foreign_helper' show JS; @@ -171,7 +169,7 @@ bool hasMethod(object, String name) { /// [JsonMLFormatter] consumes [NameValuePair] objects and class NameValuePair { NameValuePair( - {this.name, + {this.name = '', this.value, this.config = JsonMLConfig.none, this.hideName = false}); @@ -187,7 +185,7 @@ class NameValuePair { int get hashCode => name.hashCode; final String name; - final Object value; + final Object? value; final JsonMLConfig config; final bool hideName; @@ -197,8 +195,8 @@ class NameValuePair { class MapEntry { MapEntry({this.key, this.value}); - final Object key; - final Object value; + final Object? key; + final Object? value; } class IterableSpan { @@ -216,7 +214,7 @@ class IterableSpan { /// 10000-length subset and 1 1-length subset. int get maxPowerOfSubsetSize => (log(length - .5) / log(_maxSpanLength)).truncate(); - int get subsetSize => pow(_maxSpanLength, maxPowerOfSubsetSize); + int get subsetSize => pow(_maxSpanLength, maxPowerOfSubsetSize).toInt(); Map asMap() => iterable.skip(start).take(length).toList().asMap(); @@ -284,7 +282,7 @@ safeProperties(object) => Map.fromIterable( /// Devtools Formatter API. class JsonMLElement { dynamic _attributes; - List _jsonML; + late List _jsonML; JsonMLElement(tagName) { _attributes = JS('', '{}'); @@ -408,7 +406,7 @@ class JsonMLFormatter { // The value is indented when it is on a different line from the name // by setting right padding of the name to -13px and the padding of the // value to 13px. - JsonMLElement nameSpan; + JsonMLElement? nameSpan; var valueStyle = ''; if (!child.hideName) { nameSpan = JsonMLElement('span') @@ -444,38 +442,36 @@ class JsonMLFormatter { abstract class Formatter { bool accept(object, config); - String preview(object); + String? preview(object); bool hasChildren(object); - List children(object); + List? children(object); } class DartFormatter { - List _formatters; + final List _formatters; - DartFormatter() { - // The order of formatters matters as formatters earlier in the list take - // precedence. - _formatters = [ - ObjectInternalsFormatter(), - ClassFormatter(), - TypeFormatter(), - NamedConstructorFormatter(), - MapFormatter(), - MapOverviewFormatter(), - IterableFormatter(), - IterableSpanFormatter(), - MapEntryFormatter(), - StackTraceFormatter(), - ErrorAndExceptionFormatter(), - FunctionFormatter(), - HeritageClauseFormatter(), - LibraryModuleFormatter(), - LibraryFormatter(), - ObjectFormatter(), - ]; - } + DartFormatter() + : _formatters = [ + // Formatters earlier in the list take precedence. + ObjectInternalsFormatter(), + ClassFormatter(), + TypeFormatter(), + NamedConstructorFormatter(), + MapFormatter(), + MapOverviewFormatter(), + IterableFormatter(), + IterableSpanFormatter(), + MapEntryFormatter(), + StackTraceFormatter(), + ErrorAndExceptionFormatter(), + FunctionFormatter(), + HeritageClauseFormatter(), + LibraryModuleFormatter(), + LibraryFormatter(), + ObjectFormatter(), + ]; - String preview(object, config) { + String? preview(object, config) { try { if (object == null || object is num || @@ -509,7 +505,7 @@ class DartFormatter { return false; } - List children(object, config) { + List? children(object, config) { try { if (object != null) { for (var formatter in _formatters) { @@ -558,7 +554,7 @@ class ObjectFormatter extends Formatter { bool hasChildren(object) => true; - List children(object) { + children(object) { var type = dart.getType(object); var ret = LinkedHashSet(); // We use a Set rather than a List to avoid duplicates. @@ -591,12 +587,12 @@ class ObjectInternalsFormatter extends ObjectFormatter { /// Formatter for module Dart Library objects. class LibraryModuleFormatter implements Formatter { - accept(object, config) => dart.getModuleName(object) != null; + bool accept(object, config) => dart.getModuleName(object) != null; bool hasChildren(object) => true; String preview(object) { - var libraryNames = dart.getModuleName(object).split('/'); + var libraryNames = dart.getModuleName(object)!.split('/'); // Library names are received with a repeat directory name, so strip the // last directory entry here to make the path cleaner. For example, the // library "third_party/dart/utf/utf" shoud display as @@ -622,7 +618,7 @@ class LibraryModuleFormatter implements Formatter { class LibraryFormatter implements Formatter { var genericParameters = HashMap(); - accept(object, config) => object is Library; + bool accept(object, config) => object is Library; bool hasChildren(object) => true; @@ -657,7 +653,7 @@ class LibraryFormatter implements Formatter { /// we can distinguish them based on whether they have been tagged with /// runtime type information. class FunctionFormatter implements Formatter { - accept(object, config) { + bool accept(object, config) { if (_typeof(object) != 'function') return false; return dart.getReifiedType(object) != null; } @@ -690,7 +686,7 @@ class FunctionFormatter implements Formatter { class MapOverviewFormatter implements Formatter { // Because this comes after MapFormatter in the list, internal // maps will be picked up by that formatter. - accept(object, config) => object is Map; + bool accept(object, config) => object is Map; bool hasChildren(object) => true; @@ -718,7 +714,7 @@ class MapOverviewFormatter implements Formatter { /// This is only used for internal maps, or when shown as [[entries]] /// from MapOverViewFormatter. class MapFormatter implements Formatter { - accept(object, config) => + bool accept(object, config) => object is InternalMap || config == JsonMLConfig.asMap; bool hasChildren(object) => true; @@ -779,7 +775,7 @@ class IterableFormatter implements Formatter { } class NamedConstructorFormatter implements Formatter { - accept(object, config) => object is NamedConstructor; + bool accept(object, config) => object is NamedConstructor; // TODO(bmilligan): Display the signature of the named constructor as the // preview. @@ -798,7 +794,7 @@ class NamedConstructorFormatter implements Formatter { /// Formatter for synthetic MapEntry objects used to display contents of a Map /// cleanly. class MapEntryFormatter implements Formatter { - accept(object, config) => object is MapEntry; + bool accept(object, config) => object is MapEntry; String preview(object) { MapEntry entry = object; @@ -839,7 +835,7 @@ class HeritageClauseFormatter implements Formatter { /// Formatter for synthetic IterableSpan objects used to display contents of /// an Iterable cleanly. class IterableSpanFormatter implements Formatter { - accept(object, config) => object is IterableSpan; + bool accept(object, config) => object is IterableSpan; String preview(object) { return '[${object.start}...${object.end - 1}]'; @@ -854,7 +850,7 @@ class IterableSpanFormatter implements Formatter { class ErrorAndExceptionFormatter extends ObjectFormatter { static final RegExp _pattern = RegExp(r'\d+\:\d+'); - accept(object, config) => object is Error || object is Exception; + bool accept(object, config) => object is Error || object is Exception; bool hasChildren(object) => true; @@ -867,8 +863,8 @@ class ErrorAndExceptionFormatter extends ObjectFormatter { l.contains(_pattern) && !l.contains('dart:sdk') && !l.contains('dart_sdk'), - orElse: () => null); - return line != null ? '${object} at ${line}' : '${object}'; + orElse: () => ''); + return line != '' ? '${object} at ${line}' : '${object}'; } List children(object) { @@ -890,7 +886,7 @@ class ErrorAndExceptionFormatter extends ObjectFormatter { } class StackTraceFormatter implements Formatter { - accept(object, config) => object is StackTrace; + bool accept(object, config) => object is StackTrace; String preview(object) => 'StackTrace'; @@ -908,13 +904,13 @@ class StackTraceFormatter implements Formatter { } class ClassFormatter implements Formatter { - accept(object, config) => config == JsonMLConfig.asClass; + bool accept(object, config) => config == JsonMLConfig.asClass; String preview(type) { - var implements = dart.getImplements(type); + var implements = dart.getImplements(type)(); var typeName = getTypeName(type); if (implements != null) { - var typeNames = implements().map(getTypeName); + var typeNames = implements.map(getTypeName); return '${typeName} implements ${typeNames.join(", ")}'; } else { return typeName; @@ -979,7 +975,7 @@ class ClassFormatter implements Formatter { } class TypeFormatter implements Formatter { - accept(object, config) => object is Type; + bool accept(object, config) => object is Type; String preview(object) => object.toString(); @@ -995,7 +991,7 @@ typedef String StackTraceMapper(String stackTrace); /// /// Raw JS stack traces are used if $dartStackTraceUtility has not been /// specified. -StackTraceMapper get stackTraceMapper { +StackTraceMapper? get stackTraceMapper { var _util = JS('', r'#.$dartStackTraceUtility', dart.global_); return _util != null ? JS('!', '#.mapper', _util) : null; } diff --git a/sdk/lib/_internal/js_dev_runtime/private/foreign_helper.dart b/sdk/lib/_internal/js_dev_runtime/private/foreign_helper.dart index b46e8173c83..7f115054065 100644 --- a/sdk/lib/_internal/js_dev_runtime/private/foreign_helper.dart +++ b/sdk/lib/_internal/js_dev_runtime/private/foreign_helper.dart @@ -2,8 +2,6 @@ // 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.6 - library dart._foreign_helper; /** @@ -108,7 +106,7 @@ library dart._foreign_helper; */ // Add additional optional arguments if needed. The method is treated internally // as a variable argument method. -T JS(String typeDescription, String codeTemplate, +external T JS(String typeDescription, String codeTemplate, [arg0, arg1, arg2, @@ -128,7 +126,7 @@ T JS(String typeDescription, String codeTemplate, arg16, arg17, arg18, - arg19]) {} + arg19]); /// Annotates the compiled Js name for fields and methods. /// Similar behaviour to `JS` from `package:js/js.dart` (but usable from runtime @@ -161,73 +159,73 @@ JS_INTERCEPTOR_CONSTANT(Type type) {} /** * Returns the prefix used for generated is checks on classes. */ -String JS_OPERATOR_IS_PREFIX() {} +external String JS_OPERATOR_IS_PREFIX(); /** * Returns the prefix used for generated type argument substitutions on classes. */ -String JS_OPERATOR_AS_PREFIX() {} +external String JS_OPERATOR_AS_PREFIX(); /// Returns the name of the class `Object` in the generated code. -String JS_OBJECT_CLASS_NAME() {} +external String JS_OBJECT_CLASS_NAME(); /// Returns the name of the class `Null` in the generated code. -String JS_NULL_CLASS_NAME() {} +external String JS_NULL_CLASS_NAME(); /// Returns the name of the class `Function` in the generated code. -String JS_FUNCTION_CLASS_NAME() {} +external String JS_FUNCTION_CLASS_NAME(); /** * Returns the field name used for determining if an object or its * interceptor has JavaScript indexing behavior. */ -String JS_IS_INDEXABLE_FIELD_NAME() {} +external String JS_IS_INDEXABLE_FIELD_NAME(); /// Returns the name used for generated function types on classes and methods. -String JS_SIGNATURE_NAME() {} +external String JS_SIGNATURE_NAME(); /// Returns the name used to tag typedefs. -String JS_TYPEDEF_TAG() {} +external String JS_TYPEDEF_TAG(); /// Returns the name used to tag function type representations in JavaScript. -String JS_FUNCTION_TYPE_TAG() {} +external String JS_FUNCTION_TYPE_TAG(); /** * Returns the name used to tag void return in function type representations * in JavaScript. */ -String JS_FUNCTION_TYPE_VOID_RETURN_TAG() {} +external String JS_FUNCTION_TYPE_VOID_RETURN_TAG(); /** * Returns the name used to tag return types in function type representations * in JavaScript. */ -String JS_FUNCTION_TYPE_RETURN_TYPE_TAG() {} +external String JS_FUNCTION_TYPE_RETURN_TYPE_TAG(); /** * Returns the name used to tag required parameters in function type * representations in JavaScript. */ -String JS_FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG() {} +external String JS_FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG(); /** * Returns the name used to tag optional parameters in function type * representations in JavaScript. */ -String JS_FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG() {} +external String JS_FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG(); /** * Returns the name used to tag named parameters in function type * representations in JavaScript. */ -String JS_FUNCTION_TYPE_NAMED_PARAMETERS_TAG() {} +external String JS_FUNCTION_TYPE_NAMED_PARAMETERS_TAG(); /// Returns the JS name for [name] from the Namer. -String JS_GET_NAME(String name) {} +external String JS_GET_NAME(String name); /// Returns the state of a flag that is determined by the state of the compiler /// when the program has been analyzed. -bool JS_GET_FLAG(String name) {} +external bool JS_GET_FLAG(String name); /** * Pretend [code] is executed. Generates no executable code. This is used to diff --git a/sdk/lib/_internal/js_dev_runtime/private/identity_hash_map.dart b/sdk/lib/_internal/js_dev_runtime/private/identity_hash_map.dart index fa62a8fb799..eda6c44b4eb 100644 --- a/sdk/lib/_internal/js_dev_runtime/private/identity_hash_map.dart +++ b/sdk/lib/_internal/js_dev_runtime/private/identity_hash_map.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart._js_helper; class IdentityMap extends InternalMap { @@ -35,11 +33,11 @@ class IdentityMap extends InternalMap { Iterable get keys => _JSMapIterable(this, true); Iterable get values => _JSMapIterable(this, false); - bool containsKey(Object key) { + bool containsKey(Object? key) { return JS('!', '#.has(#)', _map, key); } - bool containsValue(Object value) { + bool containsValue(Object? value) { for (var v in JS('', '#.values()', _map)) { if (v == value) return true; } @@ -56,7 +54,7 @@ class IdentityMap extends InternalMap { } } - V operator [](Object key) { + V? operator [](Object? key) { V value = JS('', '#.get(#)', _map, key); return value == null ? null : value; // coerce undefined to null. } @@ -75,13 +73,13 @@ class IdentityMap extends InternalMap { return JS('', '#.get(#)', _map, key); } V value = ifAbsent(); - if (value == null) value = null; // coerce undefined to null. + if (value == null) JS('', '# = null', value); JS('', '#.set(#, #)', _map, key, value); _modifications = (_modifications + 1) & 0x3ffffff; return value; } - V remove(Object key) { + V? remove(Object? key) { V value = JS('', '#.get(#)', _map, key); if (JS('!', '#.delete(#)', _map, key)) { _modifications = (_modifications + 1) & 0x3ffffff; @@ -130,10 +128,10 @@ class _JSMapIterable extends EfficientLengthIterable { Iterator get iterator => DartIterator(_jsIterator()); - bool contains(Object element) => + bool contains(Object? element) => _isKeys ? _map.containsKey(element) : _map.containsValue(element); - void forEach(void f(E element)) { + void forEach(void Function(E) f) { for (var entry in this) f(entry); } } diff --git a/sdk/lib/_internal/js_dev_runtime/private/interceptors.dart b/sdk/lib/_internal/js_dev_runtime/private/interceptors.dart index db812301505..04d492fd7fd 100644 --- a/sdk/lib/_internal/js_dev_runtime/private/interceptors.dart +++ b/sdk/lib/_internal/js_dev_runtime/private/interceptors.dart @@ -2,8 +2,6 @@ // 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.6 - library dart._interceptors; import 'dart:collection'; @@ -122,15 +120,15 @@ class JSNoSuchMethodError extends NativeError implements NoSuchMethodError { static final _extensionName = RegExp(r"^Symbol\(dartx\.(.+)\)$"); static final _privateName = RegExp(r"^Symbol\((_.+)\)$"); - String _fieldName(String message) { - var match = _nullError.firstMatch(message); + String? _fieldName(String message) { + RegExpMatch? match = _nullError.firstMatch(message); if (match == null) return null; - var name = match[1]; + String name = match[1]!; match = _extensionName.firstMatch(name) ?? _privateName.firstMatch(name); return match != null ? match[1] : name; } - String _functionCallTarget(String message) { + String? _functionCallTarget(String message) { var match = _notAFunction.firstMatch(message); return match != null ? match[1] : null; } @@ -180,7 +178,7 @@ class JSFunction extends Interceptor { // TODO(jmesserly): remove these once we canonicalize tearoffs. operator ==(other) { if (other == null) return false; - var boundObj = JS('', '#._boundObject', this); + var boundObj = JS('', '#._boundObject', this); if (boundObj == null) return JS('!', '# === #', this, other); return JS( 'bool', @@ -192,7 +190,7 @@ class JSFunction extends Interceptor { } get hashCode { - var boundObj = JS('', '#._boundObject', this); + var boundObj = JS('', '#._boundObject', this); if (boundObj == null) return identityHashCode(this); var boundMethod = JS('!', '#._boundMethod', this); @@ -229,7 +227,7 @@ class JSRangeError extends Interceptor implements ArgumentError { // Warning: calls to these methods need to be removed before custom elements // and cross-frame dom objects behave correctly in ddc. // See https://github.com/dart-lang/sdk/issues/28326 -findInterceptorConstructorForType(Type type) {} -findConstructorForNativeSubclassType(Type type, String name) {} +findInterceptorConstructorForType(Type? type) {} +findConstructorForNativeSubclassType(Type? type, String name) {} getNativeInterceptor(object) {} setDispatchProperty(object, value) {} diff --git a/sdk/lib/_internal/js_dev_runtime/private/isolate_helper.dart b/sdk/lib/_internal/js_dev_runtime/private/isolate_helper.dart index 78e8e19da46..65766534c7b 100644 --- a/sdk/lib/_internal/js_dev_runtime/private/isolate_helper.dart +++ b/sdk/lib/_internal/js_dev_runtime/private/isolate_helper.dart @@ -2,8 +2,6 @@ // 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.6 - library dart._isolate_helper; import 'dart:_runtime' as dart; @@ -36,7 +34,7 @@ final global = dart.global_; class TimerImpl implements Timer { final bool _once; - int _handle; + int? _handle; int _tick = 0; TimerImpl(int milliseconds, void callback()) : _once = true { diff --git a/sdk/lib/_internal/js_dev_runtime/private/js_array.dart b/sdk/lib/_internal/js_dev_runtime/private/js_array.dart index 913053b446a..4538120ee4e 100644 --- a/sdk/lib/_internal/js_dev_runtime/private/js_array.dart +++ b/sdk/lib/_internal/js_dev_runtime/private/js_array.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart._interceptors; /** @@ -120,7 +118,7 @@ class JSArray implements List, JSIndexable { return JS('var', r'#.pop()', this); } - bool remove(Object element) { + bool remove(Object? element) { checkGrowable('remove'); var length = this.length; for (int i = 0; i < length; i++) { @@ -135,17 +133,17 @@ class JSArray implements List, JSIndexable { /** * Removes elements matching [test] from [this] List. */ - void removeWhere(bool test(E element)) { + void removeWhere(bool Function(E) test) { checkGrowable('removeWhere'); _removeWhere(test, true); } - void retainWhere(bool test(E element)) { + void retainWhere(bool Function(E) test) { checkGrowable('retainWhere'); _removeWhere(test, false); } - void _removeWhere(bool test(E element), bool removeMatching) { + void _removeWhere(bool Function(E) test, bool removeMatching) { // Performed in two steps, to avoid exposing an inconsistent state // to the [test] function. First the elements to retain are found, and then // the original list is updated to contain those elements. @@ -156,8 +154,6 @@ class JSArray implements List, JSIndexable { List retained = []; int end = this.length; for (int i = 0; i < end; i++) { - // TODO(22407): Improve bounds check elimination to allow this JS code to - // be replaced by indexing. var element = JS('', '#[#]', this, i); // !test() ensures bool conversion in checked mode. if (!test(element) == removeMatching) { @@ -174,11 +170,11 @@ class JSArray implements List, JSIndexable { } } - Iterable where(bool f(E element)) { + Iterable where(bool Function(E) f) { return WhereIterable(this, f); } - Iterable expand(Iterable f(E element)) { + Iterable expand(Iterable Function(E) f) { return ExpandIterable(this, f); } @@ -196,24 +192,22 @@ class JSArray implements List, JSIndexable { length = 0; } - void forEach(void f(E element)) { + void forEach(void Function(E) f) { int end = this.length; for (int i = 0; i < end; i++) { - // TODO(22407): Improve bounds check elimination to allow this JS code to - // be replaced by indexing. var element = JS('', '#[#]', this, i); f(element); if (this.length != end) throw ConcurrentModificationError(this); } } - Iterable map(T f(E element)) { + Iterable map(T Function(E) f) { return MappedListIterable(this, f); } String join([String separator = ""]) { var length = this.length; - var list = List(length); + var list = List.filled(length, ""); for (int i = 0; i < length; i++) { list[i] = "${this[i]}"; } @@ -232,7 +226,7 @@ class JSArray implements List, JSIndexable { return SubListIterable(this, n, null); } - Iterable skipWhile(bool test(E value)) { + Iterable skipWhile(bool Function(E) test) { return SkipWhileIterable(this, test); } @@ -241,8 +235,6 @@ class JSArray implements List, JSIndexable { if (length == 0) throw IterableElementError.noElement(); E value = this[0]; for (int i = 1; i < length; i++) { - // TODO(22407): Improve bounds check elimination to allow this JS code to - // be replaced by indexing. var element = JS('', '#[#]', this, i); value = combine(value, element); if (length != this.length) throw ConcurrentModificationError(this); @@ -250,12 +242,10 @@ class JSArray implements List, JSIndexable { return value; } - T fold(T initialValue, T combine(T previousValue, E element)) { + T fold(T initialValue, T Function(T previousValue, E element) combine) { var value = initialValue; int length = this.length; for (int i = 0; i < length; i++) { - // TODO(22407): Improve bounds check elimination to allow this JS code to - // be replaced by indexing. var element = JS('', '#[#]', this, i); value = combine(value, element); if (this.length != length) throw ConcurrentModificationError(this); @@ -263,11 +253,9 @@ class JSArray implements List, JSIndexable { return value; } - E firstWhere(bool test(E value), {E orElse()}) { + E firstWhere(bool Function(E) test, {E Function()? orElse}) { int end = this.length; for (int i = 0; i < end; ++i) { - // TODO(22407): Improve bounds check elimination to allow this JS code to - // be replaced by indexing. var element = JS('', '#[#]', this, i); if (test(element)) return element; if (this.length != end) throw ConcurrentModificationError(this); @@ -276,11 +264,9 @@ class JSArray implements List, JSIndexable { throw IterableElementError.noElement(); } - E lastWhere(bool test(E element), {E orElse()}) { + E lastWhere(bool Function(E) test, {E Function()? orElse}) { int length = this.length; for (int i = length - 1; i >= 0; i--) { - // TODO(22407): Improve bounds check elimination to allow this JS code to - // be replaced by indexing. var element = JS('', '#[#]', this, i); if (test(element)) return element; if (length != this.length) { @@ -291,13 +277,11 @@ class JSArray implements List, JSIndexable { throw IterableElementError.noElement(); } - E singleWhere(bool test(E element), {E orElse()}) { + E singleWhere(bool Function(E) test, {E Function()? orElse}) { int length = this.length; - E match = null; + E? match = null; bool matchFound = false; for (int i = 0; i < length; i++) { - // TODO(22407): Improve bounds check elimination to allow this JS code to - // be replaced by indexing. var element = JS('', '#[#]', this, i); if (test(element)) { if (matchFound) { @@ -310,7 +294,7 @@ class JSArray implements List, JSIndexable { throw ConcurrentModificationError(this); } } - if (matchFound) return match; + if (matchFound) return match as E; if (orElse != null) return orElse(); throw IterableElementError.noElement(); } @@ -319,7 +303,7 @@ class JSArray implements List, JSIndexable { return this[index]; } - List sublist(@nullCheck int start, [int end]) { + List sublist(@nullCheck int start, [int? end]) { if (start < 0 || start > length) { throw RangeError.range(start, 0, length, "start"); } @@ -373,7 +357,7 @@ class JSArray implements List, JSIndexable { if (length == 0) return; RangeError.checkNotNegative(skipCount, "skipCount"); - List otherList; + var otherList = []; int otherStart = 0; // TODO(floitsch): Make this accept more. if (iterable is List) { @@ -405,12 +389,12 @@ class JSArray implements List, JSIndexable { } } - void fillRange(@nullCheck int start, @nullCheck int end, [E fillValue]) { + void fillRange(@nullCheck int start, @nullCheck int end, [E? fillValue]) { checkMutable('fill range'); RangeError.checkValidRange(start, end, this.length); + E checkedFillValue = fillValue as E; for (int i = start; i < end; i++) { - // Store is safe since [fillValue] type has been checked as parameter. - JS('', '#[#] = #', this, i, fillValue); + JS('', '#[#] = #', this, i, checkedFillValue); } } @@ -443,11 +427,9 @@ class JSArray implements List, JSIndexable { } } - bool any(bool test(E element)) { + bool any(bool Function(E) test) { int end = this.length; for (int i = 0; i < end; i++) { - // TODO(22407): Improve bounds check elimination to allow this JS code to - // be replaced by indexing. var element = JS('', '#[#]', this, i); if (test(element)) return true; if (this.length != end) throw ConcurrentModificationError(this); @@ -455,11 +437,9 @@ class JSArray implements List, JSIndexable { return false; } - bool every(bool test(E element)) { + bool every(bool Function(E) test) { int end = this.length; for (int i = 0; i < end; i++) { - // TODO(22407): Improve bounds check elimination to allow this JS code to - // be replaced by indexing. var element = JS('', '#[#]', this, i); if (!test(element)) return false; if (this.length != end) throw ConcurrentModificationError(this); @@ -469,16 +449,17 @@ class JSArray implements List, JSIndexable { Iterable get reversed => ReversedListIterable(this); - void sort([int compare(E a, E b)]) { + void sort([int Function(E, E)? compare]) { checkMutable('sort'); if (compare == null) { - Sort.sort(this, (a, b) => Comparable.compare(a, b)); + Sort.sort( + this, (a, b) => Comparable.compare(a as Comparable, b as Comparable)); } else { Sort.sort(this, compare); } } - void shuffle([Random random]) { + void shuffle([Random? random]) { checkMutable('shuffle'); if (random == null) random = Random(); int length = this.length; @@ -491,7 +472,7 @@ class JSArray implements List, JSIndexable { } } - int indexOf(Object element, [@nullCheck int start = 0]) { + int indexOf(Object? element, [@nullCheck int start = 0]) { int length = this.length; if (start >= length) { return -1; @@ -507,15 +488,15 @@ class JSArray implements List, JSIndexable { return -1; } - int lastIndexOf(Object element, [int _startIndex]) { + int lastIndexOf(Object? element, [int? startIndex]) { @notNull - int startIndex = _startIndex ?? this.length - 1; - if (startIndex >= this.length) { - startIndex = this.length - 1; - } else if (startIndex < 0) { + int start = startIndex ?? this.length - 1; + if (start >= this.length) { + start = this.length - 1; + } else if (start < 0) { return -1; } - for (int i = startIndex; i >= 0; i--) { + for (int i = start; i >= 0; i--) { if (this[i] == element) { return i; } @@ -523,7 +504,7 @@ class JSArray implements List, JSIndexable { return -1; } - bool contains(Object other) { + bool contains(Object? other) { var length = this.length; for (int i = 0; i < length; i++) { var element = JS('', '#[#]', this, i); @@ -601,15 +582,9 @@ class JSArray implements List, JSIndexable { Iterable whereType() => new WhereTypeIterable(this); - List operator +(List other) { - int totalLength = this.length + other.length; - return [] - ..length = totalLength - ..setRange(0, this.length, this) - ..setRange(this.length, totalLength, other); - } + List operator +(List other) => [...this, ...other]; - int indexWhere(bool test(E element), [int start = 0]) { + int indexWhere(bool Function(E) test, [int start = 0]) { if (start >= this.length) return -1; if (start < 0) start = 0; for (int i = start; i < this.length; i++) { @@ -618,7 +593,7 @@ class JSArray implements List, JSIndexable { return -1; } - int lastIndexWhere(bool test(E element), [int start]) { + int lastIndexWhere(bool Function(E) test, [int? start]) { if (start == null) start = this.length - 1; if (start < 0) return -1; for (int i = start; i >= 0; i--) { @@ -665,14 +640,14 @@ class ArrayIterator implements Iterator { final int _length; @notNull int _index; - E _current; + E? _current; ArrayIterator(JSArray iterable) : _iterable = iterable, _length = iterable.length, _index = 0; - E get current => _current; + E get current => _current as E; bool moveNext() { @notNull diff --git a/sdk/lib/_internal/js_dev_runtime/private/js_helper.dart b/sdk/lib/_internal/js_dev_runtime/private/js_helper.dart index b7d17d0d332..11a3a8eee71 100644 --- a/sdk/lib/_internal/js_dev_runtime/private/js_helper.dart +++ b/sdk/lib/_internal/js_dev_runtime/private/js_helper.dart @@ -2,8 +2,6 @@ // 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.6 - library dart._js_helper; import 'dart:collection'; @@ -45,11 +43,11 @@ const _Patch patch = _Patch(); // https://github.com/dart-lang/sdk/issues/28320 class DartIterator implements Iterator { final _jsIterator; - E _current; + E? _current; DartIterator(this._jsIterator); - E get current => _current; + E get current => _current as E; bool moveNext() { final ret = JS('', '#.next()', _jsIterator); @@ -70,11 +68,11 @@ class SyncIterable extends IterableBase { } class Primitives { - static int parseInt(@nullCheck String source, int _radix) { + static int? parseInt(@nullCheck String source, int? _radix) { var re = JS('', r'/^\s*[+-]?((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$/i'); // TODO(jmesserly): this isn't reified List, but it's safe to use as // long as we use it locally and don't expose it to user code. - List match = JS('', '#.exec(#)', re, source); + List? match = JS('', '#.exec(#)', re, source); int digitsIndex = 1; int hexIndex = 2; int decimalIndex = 3; @@ -84,7 +82,7 @@ class Primitives { // again. return null; } - String decimalMatch = match[decimalIndex]; + String? decimalMatch = match[decimalIndex]; if (_radix == null) { if (decimalMatch != null) { // Cannot fail because we know that the digits are all decimal. @@ -140,7 +138,7 @@ class Primitives { return JS('!', r'parseInt(#, #)', source, radix); } - static double parseDouble(@nullCheck String source) { + static double? parseDouble(@nullCheck String source) { // Notice that JS parseFloat accepts garbage at the end of the string. // Accept only: // - [+/-]NaN @@ -171,10 +169,9 @@ class Primitives { static int dateNow() => JS('!', r'Date.now()'); static void initTicker() { - if (timerFrequency != null) return; + if (timerFrequency != 0) return; // Start with low-resolution. We overwrite the fields if we find better. timerFrequency = 1000; - timerTicks = dateNow; if (JS('!', 'typeof window == "undefined"')) return; var jsWindow = JS('var', 'window'); if (jsWindow == null) return; @@ -185,8 +182,9 @@ class Primitives { timerTicks = () => (1000 * JS('!', '#.now()', performance)).floor(); } - static int timerFrequency; - static num Function() timerTicks; + /// 0 frequency indicates the default uninitialized state. + static int timerFrequency = 0; + static int Function() timerTicks = dateNow; // Low-resolution version. static bool get isD8 { return JS( @@ -310,7 +308,7 @@ class Primitives { // Example: "Wed May 16 2012 21:13:00 GMT+0200 (CEST)". // We extract this name using a regexp. var d = lazyAsJsDate(receiver); - List match = JS('JSArray|Null', r'/\((.*)\)/.exec(#.toString())', d); + List? match = JS('JSArray|Null', r'/\((.*)\)/.exec(#.toString())', d); if (match != null) return match[1]; // Internet Explorer 10+ emits the zone name without parenthesis: @@ -345,7 +343,7 @@ class Primitives { return -JS('!', r'#.getTimezoneOffset()', lazyAsJsDate(receiver)); } - static num valueFromDecomposedDate( + static int? valueFromDecomposedDate( @nullCheck int years, @nullCheck int month, @nullCheck int day, @@ -356,12 +354,12 @@ class Primitives { @nullCheck bool isUtc) { final int MAX_MILLISECONDS_SINCE_EPOCH = 8640000000000000; var jsMonth = month - 1; - num value; + int value; if (isUtc) { - value = JS('!', r'Date.UTC(#, #, #, #, #, #, #)', years, jsMonth, day, - hours, minutes, seconds, milliseconds); + value = JS('!', r'Date.UTC(#, #, #, #, #, #, #)', years, jsMonth, + day, hours, minutes, seconds, milliseconds); } else { - value = JS('!', r'new Date(#, #, #, #, #, #, #).valueOf()', years, + value = JS('!', r'new Date(#, #, #, #, #, #, #).valueOf()', years, jsMonth, day, hours, minutes, seconds, milliseconds); } if (value.isNaN || @@ -373,14 +371,14 @@ class Primitives { return value; } - static num patchUpY2K(value, years, isUtc) { - var date = JS('', r'new Date(#)', value); + static int patchUpY2K(value, years, isUtc) { + var date = JS('!', r'new Date(#)', value); if (isUtc) { - JS('', r'#.setUTCFullYear(#)', date, years); + JS('!', r'#.setUTCFullYear(#)', date, years); } else { - JS('', r'#.setFullYear(#)', date, years); + JS('!', r'#.setFullYear(#)', date, years); } - return JS('!', r'#.valueOf()', date); + return JS('!', r'#.valueOf()', date); } // Lazily keep a JS Date stored in the JS object. @@ -453,7 +451,7 @@ class Primitives { return value; } - static getProperty(object, key) { + static Object? getProperty(Object? object, Object key) { if (object == null || object is bool || object is num || object is String) { throw argumentErrorValue(object); } @@ -489,7 +487,7 @@ Error diagnoseIndexError(indexable, int index) { * describes the problem. */ @NoInline() -Error diagnoseRangeError(int start, int end, int length) { +Error diagnoseRangeError(int? start, int? end, int length) { if (start == null) { return ArgumentError.value(start, 'start'); } @@ -538,9 +536,9 @@ throwConcurrentModificationError(collection) { } class JsNoSuchMethodError extends Error implements NoSuchMethodError { - final String _message; - final String _method; - final String _receiver; + final String? _message; + final String? _method; + final String? _receiver; JsNoSuchMethodError(this._message, match) : _method = match == null ? null : JS('String|Null', '#.method', match), @@ -582,11 +580,11 @@ fillLiteralMap(keyValuePairs, Map result) { return result; } -bool jsHasOwnProperty(var jsObject, String property) { +bool jsHasOwnProperty(jsObject, String property) { return JS('!', r'#.hasOwnProperty(#)', jsObject, property); } -jsPropertyAccess(var jsObject, String property) { +jsPropertyAccess(jsObject, String property) { return JS('var', r'#[#]', jsObject, property); } @@ -720,12 +718,12 @@ class RuntimeError extends Error { /// Error thrown by DDC when an `assert()` fails (with or without a message). class AssertionErrorImpl extends AssertionError { - final String _fileUri; - final int _line; - final int _column; - final String _conditionSource; + final String? _fileUri; + final int? _line; + final int? _column; + final String? _conditionSource; - AssertionErrorImpl(Object message, + AssertionErrorImpl(Object? message, [this._fileUri, this._line, this._column, this._conditionSource]) : super(message); @@ -791,7 +789,7 @@ class PrivateSymbol implements Symbol { static String getName(Symbol symbol) => (symbol as PrivateSymbol)._name; - static Object getNativeSymbol(Symbol symbol) { + static Object? getNativeSymbol(Symbol symbol) { if (symbol is PrivateSymbol) return symbol._nativeSymbol; return null; } diff --git a/sdk/lib/_internal/js_dev_runtime/private/js_number.dart b/sdk/lib/_internal/js_dev_runtime/private/js_number.dart index 3d974a79a16..d2b9661247a 100644 --- a/sdk/lib/_internal/js_dev_runtime/private/js_number.dart +++ b/sdk/lib/_internal/js_dev_runtime/private/js_number.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart._interceptors; /** @@ -55,14 +53,14 @@ class JSNumber extends Interceptor implements int, double { @notNull JSNumber remainder(@nullCheck num b) { - return JS('!', r'# % #', this, b); + return JS('!', r'# % #', this, b); } @notNull - JSNumber abs() => JS('!', r'Math.abs(#)', this); + JSNumber abs() => JS('!', r'Math.abs(#)', this); @notNull - JSNumber get sign => this > 0 ? 1 : this < 0 ? -1 : this; + JSNumber get sign => (this > 0 ? 1 : this < 0 ? -1 : this) as JSNumber; @notNull static const int _MIN_INT32 = -0x80000000; @@ -112,17 +110,17 @@ class JSNumber extends Interceptor implements int, double { } @notNull - double ceilToDouble() => JS('!', r'Math.ceil(#)', this); + double ceilToDouble() => JS('!', r'Math.ceil(#)', this); @notNull - double floorToDouble() => JS('!', r'Math.floor(#)', this); + double floorToDouble() => JS('!', r'Math.floor(#)', this); @notNull double roundToDouble() { if (this < 0) { - return JS('!', r'-Math.round(-#)', this); + return JS('!', r'-Math.round(-#)', this); } else { - return JS('!', r'Math.round(#)', this); + return JS('!', r'Math.round(#)', this); } } @@ -153,7 +151,7 @@ class JSNumber extends Interceptor implements int, double { } @notNull - String toStringAsExponential([int fractionDigits]) { + String toStringAsExponential([int? fractionDigits]) { String result; if (fractionDigits != null) { @notNull @@ -196,7 +194,7 @@ class JSNumber extends Interceptor implements int, double { static String _handleIEtoString(String result) { // Result is probably IE's untraditional format for large numbers, // e.g., "8.0000000000008(e+15)" for 0x8000000000000800.toString(16). - var match = JS( + var match = JS( '', r'/^([\da-z]+)(?:\.([\da-z]+))?\(e\+(\d+)\)$/.exec(#)', result); if (match == null) { // Then we don't know how to handle it at all. @@ -258,38 +256,38 @@ class JSNumber extends Interceptor implements int, double { } @notNull - JSNumber operator -() => JS('!', r'-#', this); + JSNumber operator -() => JS('!', r'-#', this); @notNull JSNumber operator +(@nullCheck num other) { - return JS('!', '# + #', this, other); + return JS('!', '# + #', this, other); } @notNull JSNumber operator -(@nullCheck num other) { - return JS('!', '# - #', this, other); + return JS('!', '# - #', this, other); } @notNull double operator /(@nullCheck num other) { - return JS('!', '# / #', this, other); + return JS('!', '# / #', this, other); } @notNull JSNumber operator *(@nullCheck num other) { - return JS('!', '# * #', this, other); + return JS('!', '# * #', this, other); } @notNull JSNumber operator %(@nullCheck num other) { // Euclidean Modulo. - num result = JS('!', r'# % #', this, other); + JSNumber result = JS('!', r'# % #', this, other); if (result == 0) return (0 as JSNumber); // Make sure we don't return -0.0. if (result > 0) return result; - if (JS('!', '#', other) < 0) { - return result - JS('!', '#', other); + if (JS('!', '#', other) < 0) { + return result - JS('!', '#', other); } else { - return result + JS('!', '#', other); + return result + JS('!', '#', other); } } @@ -308,7 +306,7 @@ class JSNumber extends Interceptor implements int, double { @notNull int _tdivSlow(num other) { - return (JS('!', r'# / #', this, other)).toInt(); + return JS('!', r'# / #', this, other).toInt(); } // TODO(ngeoffray): Move the bit operations below to [JSInt] and diff --git a/sdk/lib/_internal/js_dev_runtime/private/js_primitives.dart b/sdk/lib/_internal/js_dev_runtime/private/js_primitives.dart index f6c0c59cbfd..1347b621ffe 100644 --- a/sdk/lib/_internal/js_dev_runtime/private/js_primitives.dart +++ b/sdk/lib/_internal/js_dev_runtime/private/js_primitives.dart @@ -2,8 +2,6 @@ // 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.6 - /// dart2js "primitives", that is, features that cannot be implemented without /// access to JavaScript features. library dart2js._js_primitives; diff --git a/sdk/lib/_internal/js_dev_runtime/private/js_rti.dart b/sdk/lib/_internal/js_dev_runtime/private/js_rti.dart index e058820bad0..483e721d286 100644 --- a/sdk/lib/_internal/js_dev_runtime/private/js_rti.dart +++ b/sdk/lib/_internal/js_dev_runtime/private/js_rti.dart @@ -2,28 +2,26 @@ // 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.6 - part of dart._js_helper; // TODO(leafp): Maybe get rid of this? Currently used by the interceptors // library, but that should probably be culled as well. -Type getRuntimeType(var object) => +Type? getRuntimeType(object) => JS('Type|null', 'dart.getReifiedType(#)', object); /// Returns the property [index] of the JavaScript array [array]. -getIndex(var array, int index) { +getIndex(array, int index) { assert(isJsArray(array)); return JS('var', r'#[#]', array, index); } /// Returns the length of the JavaScript array [array]. -int getLength(var array) { +int getLength(array) { assert(isJsArray(array)); return JS('!', r'#.length', array); } /// Returns whether [value] is a JavaScript array. -bool isJsArray(var value) { +bool isJsArray(value) { return value is JSArray; } diff --git a/sdk/lib/_internal/js_dev_runtime/private/js_string.dart b/sdk/lib/_internal/js_dev_runtime/private/js_string.dart index de63d0a1161..2987812ee4e 100644 --- a/sdk/lib/_internal/js_dev_runtime/private/js_string.dart +++ b/sdk/lib/_internal/js_dev_runtime/private/js_string.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart._interceptors; /** @@ -37,7 +35,7 @@ class JSString extends Interceptor implements String, JSIndexable { return allMatchesInStringUnchecked(this, string, start); } - Match matchAsPrefix(@nullCheck String string, [@nullCheck int start = 0]) { + Match? matchAsPrefix(@nullCheck String string, [@nullCheck int start = 0]) { int stringLength = JS('!', '#.length', string); if (start < 0 || start > stringLength) { throw RangeError.range(start, 0, stringLength); @@ -71,13 +69,13 @@ class JSString extends Interceptor implements String, JSIndexable { } @notNull - String replaceAllMapped(Pattern from, String convert(Match match)) { + String replaceAllMapped(Pattern from, String Function(Match) convert) { return this.splitMapJoin(from, onMatch: convert); } @notNull String splitMapJoin(Pattern from, - {String onMatch(Match match), String onNonMatch(String nonMatch)}) { + {String Function(Match)? onMatch, String Function(String)? onNonMatch}) { return stringReplaceAllFuncUnchecked(this, from, onMatch, onNonMatch); } @@ -110,9 +108,9 @@ class JSString extends Interceptor implements String, JSIndexable { @notNull String replaceRange( - @nullCheck int start, int end, @nullCheck String replacement) { - end = RangeError.checkValidRange(start, end, this.length); - return stringReplaceRangeUnchecked(this, start, end, replacement); + @nullCheck int start, int? end, @nullCheck String replacement) { + var e = RangeError.checkValidRange(start, end, this.length); + return stringReplaceRangeUnchecked(this, start, e, replacement); } @notNull @@ -166,7 +164,7 @@ class JSString extends Interceptor implements String, JSIndexable { } @notNull - String substring(@nullCheck int startIndex, [int _endIndex]) { + String substring(@nullCheck int startIndex, [int? _endIndex]) { var length = this.length; final endIndex = _endIndex ?? length; if (startIndex < 0) throw RangeError.value(startIndex); @@ -418,7 +416,7 @@ class JSString extends Interceptor implements String, JSIndexable { } if (pattern is JSSyntaxRegExp) { JSSyntaxRegExp re = pattern; - Match match = firstMatchAfter(re, this, start); + Match? match = firstMatchAfter(re, this, start); return (match == null) ? -1 : match.start; } var length = this.length; @@ -429,7 +427,7 @@ class JSString extends Interceptor implements String, JSIndexable { } @notNull - int lastIndexOf(@nullCheck Pattern pattern, [int _start]) { + int lastIndexOf(@nullCheck Pattern pattern, [int? _start]) { var length = this.length; var start = _start ?? length; if (start < 0 || start > length) { @@ -497,7 +495,7 @@ class JSString extends Interceptor implements String, JSIndexable { Type get runtimeType => String; @notNull - final int length; + int get length native; @notNull String operator [](@nullCheck int index) { diff --git a/sdk/lib/_internal/js_dev_runtime/private/linked_hash_map.dart b/sdk/lib/_internal/js_dev_runtime/private/linked_hash_map.dart index d9051f4a956..f797ea49566 100644 --- a/sdk/lib/_internal/js_dev_runtime/private/linked_hash_map.dart +++ b/sdk/lib/_internal/js_dev_runtime/private/linked_hash_map.dart @@ -2,8 +2,6 @@ // 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.6 - // Efficient JavaScript based implementation of a linked hash map used as a // backing map for constant maps and the [LinkedHashMap] patch @@ -74,7 +72,7 @@ class LinkedMap extends InternalMap { K key = JS('', '#[#]', entries, i); V value = JS('', '#[#]', entries, i + 1); if (key == null) { - key = null; + key = JS('', 'null'); } else if (JS('!', '#[#] !== #', key, dart.extensionSymbol('_equals'), dart.identityEquals)) { key = putLinkedMapKey(key, keyMap); @@ -96,17 +94,15 @@ class LinkedMap extends InternalMap { Iterable get values => _JSMapIterable(this, false); @notNull - bool containsKey(Object key) { + bool containsKey(Object? key) { if (key == null) { - key = null; + key = JS('', 'null'); } else if (JS('!', '#[#] !== #', key, dart.extensionSymbol('_equals'), dart.identityEquals)) { - @notNull - var k = key; - var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, k.hashCode); + var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, key.hashCode); if (buckets != null) { for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) { - k = JS('', '#[#]', buckets, i); + K k = JS('', '#[#]', buckets, i); if (k == key) return true; } } @@ -115,7 +111,7 @@ class LinkedMap extends InternalMap { return JS('!', '#.has(#)', _map, key); } - bool containsValue(Object value) { + bool containsValue(Object? value) { for (var v in JS('', '#.values()', _map)) { if (v == value) return true; } @@ -127,7 +123,7 @@ class LinkedMap extends InternalMap { int length = JS('', '#.size', map); other.forEach((K key, V value) { if (key == null) { - key = null; + key = JS('', 'null'); } else if (JS('!', '#[#] !== #', key, dart.extensionSymbol('_equals'), dart.identityEquals)) { key = putLinkedMapKey(key, _keyMap); @@ -139,17 +135,15 @@ class LinkedMap extends InternalMap { } } - V operator [](Object key) { + V? operator [](Object? key) { if (key == null) { - key = null; + key = JS('', 'null'); } else if (JS('!', '#[#] !== #', key, dart.extensionSymbol('_equals'), dart.identityEquals)) { - @notNull - var k = key; - var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, k.hashCode); + var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, key.hashCode); if (buckets != null) { for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) { - k = JS('', '#[#]', buckets, i); + K k = JS('', '#[#]', buckets, i); if (k == key) return JS('', '#.get(#)', _map, k); } } @@ -161,7 +155,7 @@ class LinkedMap extends InternalMap { void operator []=(K key, V value) { if (key == null) { - key = null; + key = JS('', 'null'); } else if (JS('!', '#[#] !== #', key, dart.extensionSymbol('_equals'), dart.identityEquals)) { key = putLinkedMapKey(key, _keyMap); @@ -177,7 +171,7 @@ class LinkedMap extends InternalMap { V putIfAbsent(K key, V ifAbsent()) { var map = _map; if (key == null) { - key = null; + key = JS('', 'null'); if (JS('!', '#.has(null)', map)) return JS('', '#.get(null)', map); } else if (JS('!', '#[#] !== #', key, dart.extensionSymbol('_equals'), dart.identityEquals)) { @@ -198,24 +192,25 @@ class LinkedMap extends InternalMap { return JS('', '#.get(#)', map, key); } V value = ifAbsent(); - if (value == null) value = null; // coerce undefined to null. + if (value == null) { + value = JS('', 'null'); + } JS('', '#.set(#, #)', map, key, value); _modifications = (_modifications + 1) & 0x3ffffff; return value; } - V remove(Object key) { + V? remove(Object? key) { if (key == null) { - key = null; + key = JS('', 'null'); } else if (JS('!', '#[#] !== #', key, dart.extensionSymbol('_equals'), dart.identityEquals)) { @notNull - var k = key; - var hash = JS('!', '# & 0x3ffffff', k.hashCode); + var hash = JS('!', '# & 0x3ffffff', key.hashCode); var buckets = JS('', '#.get(#)', _keyMap, hash); if (buckets == null) return null; // not found for (int i = 0, n = JS('!', '#.length', buckets);;) { - k = JS('', '#[#]', buckets, i); + K k = JS('', '#[#]', buckets, i); if (k == key) { key = k; if (n == 1) { @@ -266,14 +261,14 @@ K putLinkedMapKey(@notNull K key, keyMap) { class ImmutableMap extends LinkedMap { ImmutableMap.from(JSArray entries) : super.from(entries); - void operator []=(Object key, Object value) { + void operator []=(K key, V value) { throw _unsupported(); } void addAll(Object other) => throw _unsupported(); void clear() => throw _unsupported(); - V remove(Object key) => throw _unsupported(); - V putIfAbsent(Object key, Object ifAbsent()) => throw _unsupported(); + V? remove(Object? key) => throw _unsupported(); + V putIfAbsent(K key, V ifAbsent()) => throw _unsupported(); static Error _unsupported() => UnsupportedError("Cannot modify unmodifiable map"); diff --git a/sdk/lib/_internal/js_dev_runtime/private/mirror_helper.dart b/sdk/lib/_internal/js_dev_runtime/private/mirror_helper.dart index dc635a973a9..1b78136eb25 100644 --- a/sdk/lib/_internal/js_dev_runtime/private/mirror_helper.dart +++ b/sdk/lib/_internal/js_dev_runtime/private/mirror_helper.dart @@ -1,7 +1,6 @@ // Copyright (c) 2013, 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.6 /** * Helps dealing with reflection in the case that the source code has been diff --git a/sdk/lib/_internal/js_dev_runtime/private/native_helper.dart b/sdk/lib/_internal/js_dev_runtime/private/native_helper.dart index d7a312c1280..cc214e81bc3 100644 --- a/sdk/lib/_internal/js_dev_runtime/private/native_helper.dart +++ b/sdk/lib/_internal/js_dev_runtime/private/native_helper.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart._js_helper; // Obsolete in dart dev compiler. Added only so that the same version of diff --git a/sdk/lib/_internal/js_dev_runtime/private/native_typed_data.dart b/sdk/lib/_internal/js_dev_runtime/private/native_typed_data.dart index 14f173d37bb..3a7f409444f 100644 --- a/sdk/lib/_internal/js_dev_runtime/private/native_typed_data.dart +++ b/sdk/lib/_internal/js_dev_runtime/private/native_typed_data.dart @@ -2,8 +2,6 @@ // 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.6 - /// Specialized integers and floating point numbers, /// with SIMD support and efficient lists. library dart.typed_data.implementation; @@ -32,69 +30,69 @@ class NativeByteBuffer implements ByteBuffer { Type get runtimeType => ByteBuffer; - Uint8List asUint8List([int offsetInBytes = 0, int length]) { + Uint8List asUint8List([int offsetInBytes = 0, int? length]) { return NativeUint8List.view(this, offsetInBytes, length); } - Int8List asInt8List([int offsetInBytes = 0, int length]) { + Int8List asInt8List([int offsetInBytes = 0, int? length]) { return NativeInt8List.view(this, offsetInBytes, length); } - Uint8ClampedList asUint8ClampedList([int offsetInBytes = 0, int length]) { + Uint8ClampedList asUint8ClampedList([int offsetInBytes = 0, int? length]) { return NativeUint8ClampedList.view(this, offsetInBytes, length); } - Uint16List asUint16List([int offsetInBytes = 0, int length]) { + Uint16List asUint16List([int offsetInBytes = 0, int? length]) { return NativeUint16List.view(this, offsetInBytes, length); } - Int16List asInt16List([int offsetInBytes = 0, int length]) { + Int16List asInt16List([int offsetInBytes = 0, int? length]) { return NativeInt16List.view(this, offsetInBytes, length); } - Uint32List asUint32List([int offsetInBytes = 0, int length]) { + Uint32List asUint32List([int offsetInBytes = 0, int? length]) { return NativeUint32List.view(this, offsetInBytes, length); } - Int32List asInt32List([int offsetInBytes = 0, int length]) { + Int32List asInt32List([int offsetInBytes = 0, int? length]) { return NativeInt32List.view(this, offsetInBytes, length); } - Uint64List asUint64List([int offsetInBytes = 0, int length]) { + Uint64List asUint64List([int offsetInBytes = 0, int? length]) { throw UnsupportedError("Uint64List not supported by dart2js."); } - Int64List asInt64List([int offsetInBytes = 0, int length]) { + Int64List asInt64List([int offsetInBytes = 0, int? length]) { throw UnsupportedError("Int64List not supported by dart2js."); } - Int32x4List asInt32x4List([int offsetInBytes = 0, int length]) { - NativeInt32List storage = + Int32x4List asInt32x4List([int offsetInBytes = 0, int? length]) { + var storage = this.asInt32List(offsetInBytes, length != null ? length * 4 : null); return NativeInt32x4List._externalStorage(storage); } - Float32List asFloat32List([int offsetInBytes = 0, int length]) { + Float32List asFloat32List([int offsetInBytes = 0, int? length]) { return NativeFloat32List.view(this, offsetInBytes, length); } - Float64List asFloat64List([int offsetInBytes = 0, int length]) { + Float64List asFloat64List([int offsetInBytes = 0, int? length]) { return NativeFloat64List.view(this, offsetInBytes, length); } - Float32x4List asFloat32x4List([int offsetInBytes = 0, int length]) { - NativeFloat32List storage = + Float32x4List asFloat32x4List([int offsetInBytes = 0, int? length]) { + var storage = this.asFloat32List(offsetInBytes, length != null ? length * 4 : null); return NativeFloat32x4List._externalStorage(storage); } - Float64x2List asFloat64x2List([int offsetInBytes = 0, int length]) { - NativeFloat64List storage = + Float64x2List asFloat64x2List([int offsetInBytes = 0, int? length]) { + var storage = this.asFloat64List(offsetInBytes, length != null ? length * 2 : null); return NativeFloat64x2List._externalStorage(storage); } - ByteData asByteData([int offsetInBytes = 0, int length]) { + ByteData asByteData([int offsetInBytes = 0, int? length]) { return NativeByteData.view(this, offsetInBytes, length); } } @@ -105,7 +103,7 @@ class NativeByteBuffer implements ByteBuffer { class NativeFloat32x4List extends Object with ListMixin, FixedLengthListMixin implements Float32x4List { - final NativeFloat32List _storage; + final Float32List _storage; /// Creates a [Float32x4List] of the specified length (in elements), /// all of whose elements are initially zero. @@ -164,10 +162,10 @@ class NativeFloat32x4List extends Object _storage[(index * 4) + 3] = value.w; } - Float32x4List sublist(int start, [int end]) { - end = _checkValidRange(start, end, this.length); + Float32x4List sublist(int start, [int? end]) { + var stop = _checkValidRange(start, end, this.length); return NativeFloat32x4List._externalStorage( - _storage.sublist(start * 4, end * 4)); + _storage.sublist(start * 4, stop * 4)); } } @@ -236,10 +234,10 @@ class NativeInt32x4List extends Object _storage[(index * 4) + 3] = value.w; } - Int32x4List sublist(int start, [int end]) { - end = _checkValidRange(start, end, this.length); + Int32x4List sublist(int start, [int? end]) { + var stop = _checkValidRange(start, end, this.length); return NativeInt32x4List._externalStorage( - _storage.sublist(start * 4, end * 4)); + _storage.sublist(start * 4, stop * 4)); } } @@ -249,7 +247,7 @@ class NativeInt32x4List extends Object class NativeFloat64x2List extends Object with ListMixin, FixedLengthListMixin implements Float64x2List { - final NativeFloat64List _storage; + final Float64List _storage; /// Creates a [Float64x2List] of the specified length (in elements), /// all of whose elements are initially zero. @@ -302,10 +300,10 @@ class NativeFloat64x2List extends Object _storage[(index * 2) + 1] = value.y; } - Float64x2List sublist(int start, [int end]) { - end = _checkValidRange(start, end, this.length); + Float64x2List sublist(int start, [int? end]) { + var stop = _checkValidRange(start, end, this.length); return NativeFloat64x2List._externalStorage( - _storage.sublist(start * 2, end * 2)); + _storage.sublist(start * 2, stop * 2)); } } @@ -313,8 +311,7 @@ class NativeFloat64x2List extends Object class NativeTypedData implements TypedData { /// Returns the byte buffer associated with this object. @Creates('NativeByteBuffer') - // May be Null for IE's CanvasPixelArray. - @Returns('NativeByteBuffer|Null') + @Returns('NativeByteBuffer') external ByteBuffer get buffer; /// Returns the length of this view, in bytes. @@ -366,7 +363,7 @@ void _checkViewArguments(buffer, offsetInBytes, length) { if (offsetInBytes is! int) { throw ArgumentError('Invalid view offsetInBytes $offsetInBytes'); } - if (length != null && length is! int) { + if (length is! int?) { throw ArgumentError('Invalid view length $length'); } } @@ -375,7 +372,7 @@ void _checkViewArguments(buffer, offsetInBytes, length) { // returns a copy of the list. List _ensureNativeList(List list) { if (list is JSIndexable) return list; - List result = List(list.length); + List result = List.filled(list.length, null); for (int i = 0; i < list.length; i++) { result[i] = list[i]; } @@ -399,7 +396,7 @@ class NativeByteData extends NativeTypedData implements ByteData { /// if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than /// the length of [buffer]. factory NativeByteData.view( - ByteBuffer buffer, int offsetInBytes, int length) { + ByteBuffer buffer, int offsetInBytes, int? length) { _checkViewArguments(buffer, offsetInBytes, length); return length == null ? _create2(buffer, offsetInBytes) @@ -421,7 +418,7 @@ class NativeByteData extends NativeTypedData implements ByteData { @JSName('getFloat32') @Returns('double') - double _getFloat32(int byteOffset, [bool littleEndian]) native; + double _getFloat32(int byteOffset, [bool? littleEndian]) native; /// Returns the floating point number represented by the eight bytes at /// the specified [byteOffset] in this object, in IEEE 754 @@ -434,7 +431,7 @@ class NativeByteData extends NativeTypedData implements ByteData { @JSName('getFloat64') @Returns('double') - double _getFloat64(int byteOffset, [bool littleEndian]) native; + double _getFloat64(int byteOffset, [bool? littleEndian]) native; /// Returns the (possibly negative) integer represented by the two bytes at /// the specified [byteOffset] in this object, in two's complement binary @@ -449,7 +446,7 @@ class NativeByteData extends NativeTypedData implements ByteData { @JSName('getInt16') @Returns('int') - int _getInt16(int byteOffset, [bool littleEndian]) native; + int _getInt16(int byteOffset, [bool? littleEndian]) native; /// Returns the (possibly negative) integer represented by the four bytes at /// the specified [byteOffset] in this object, in two's complement binary @@ -464,7 +461,7 @@ class NativeByteData extends NativeTypedData implements ByteData { @JSName('getInt32') @Returns('int') - int _getInt32(int byteOffset, [bool littleEndian]) native; + int _getInt32(int byteOffset, [bool? littleEndian]) native; /// Returns the (possibly negative) integer represented by the eight bytes at /// the specified [byteOffset] in this object, in two's complement binary @@ -498,7 +495,7 @@ class NativeByteData extends NativeTypedData implements ByteData { @JSName('getUint16') @Returns('int') - int _getUint16(int byteOffset, [bool littleEndian]) native; + int _getUint16(int byteOffset, [bool? littleEndian]) native; /// Returns the positive integer represented by the four bytes starting /// at the specified [byteOffset] in this object, in unsigned binary @@ -512,7 +509,7 @@ class NativeByteData extends NativeTypedData implements ByteData { @JSName('getUint32') @Returns('int') - int _getUint32(int byteOffset, [bool littleEndian]) native; + int _getUint32(int byteOffset, [bool? littleEndian]) native; /// Returns the positive integer represented by the eight bytes starting /// at the specified [byteOffset] in this object, in unsigned binary @@ -552,7 +549,7 @@ class NativeByteData extends NativeTypedData implements ByteData { _setFloat32(byteOffset, value, Endian.little == endian); @JSName('setFloat32') - void _setFloat32(int byteOffset, num value, [bool littleEndian]) native; + void _setFloat32(int byteOffset, num value, [bool? littleEndian]) native; /// Sets the eight bytes starting at the specified [byteOffset] in this /// object to the IEEE 754 double-precision binary floating-point @@ -564,7 +561,7 @@ class NativeByteData extends NativeTypedData implements ByteData { _setFloat64(byteOffset, value, Endian.little == endian); @JSName('setFloat64') - void _setFloat64(int byteOffset, num value, [bool littleEndian]) native; + void _setFloat64(int byteOffset, num value, [bool? littleEndian]) native; /// Sets the two bytes starting at the specified [byteOffset] in this /// object to the two's complement binary representation of the specified @@ -577,7 +574,7 @@ class NativeByteData extends NativeTypedData implements ByteData { _setInt16(byteOffset, value, Endian.little == endian); @JSName('setInt16') - void _setInt16(int byteOffset, int value, [bool littleEndian]) native; + void _setInt16(int byteOffset, int value, [bool? littleEndian]) native; /// Sets the four bytes starting at the specified [byteOffset] in this /// object to the two's complement binary representation of the specified @@ -590,7 +587,7 @@ class NativeByteData extends NativeTypedData implements ByteData { _setInt32(byteOffset, value, Endian.little == endian); @JSName('setInt32') - void _setInt32(int byteOffset, int value, [bool littleEndian]) native; + void _setInt32(int byteOffset, int value, [bool? littleEndian]) native; /// Sets the eight bytes starting at the specified [byteOffset] in this /// object to the two's complement binary representation of the specified @@ -623,7 +620,7 @@ class NativeByteData extends NativeTypedData implements ByteData { _setUint16(byteOffset, value, Endian.little == endian); @JSName('setUint16') - void _setUint16(int byteOffset, int value, [bool littleEndian]) native; + void _setUint16(int byteOffset, int value, [bool? littleEndian]) native; /// Sets the four bytes starting at the specified [byteOffset] in this object /// to the unsigned binary representation of the specified [value], @@ -636,7 +633,7 @@ class NativeByteData extends NativeTypedData implements ByteData { _setUint32(byteOffset, value, Endian.little == endian); @JSName('setUint32') - void _setUint32(int byteOffset, int value, [bool littleEndian]) native; + void _setUint32(int byteOffset, int value, [bool? littleEndian]) native; /// Sets the eight bytes starting at the specified [byteOffset] in this object /// to the unsigned binary representation of the specified [value], @@ -751,7 +748,7 @@ class NativeFloat32List extends NativeTypedArrayOfDouble _create1(_ensureNativeList(elements)); factory NativeFloat32List.view( - ByteBuffer buffer, int offsetInBytes, int length) { + ByteBuffer buffer, int offsetInBytes, int? length) { _checkViewArguments(buffer, offsetInBytes, length); return length == null ? _create2(buffer, offsetInBytes) @@ -760,10 +757,10 @@ class NativeFloat32List extends NativeTypedArrayOfDouble Type get runtimeType => Float32List; - Float32List sublist(int start, [int end]) { - end = _checkValidRange(start, end, this.length); + Float32List sublist(int start, [int? end]) { + var stop = _checkValidRange(start, end, this.length); var source = - JS('!', '#.subarray(#, #)', this, start, end); + JS('!', '#.subarray(#, #)', this, start, stop); return _create1(source); } @@ -786,7 +783,7 @@ class NativeFloat64List extends NativeTypedArrayOfDouble _create1(_ensureNativeList(elements)); factory NativeFloat64List.view( - ByteBuffer buffer, int offsetInBytes, int length) { + ByteBuffer buffer, int offsetInBytes, int? length) { _checkViewArguments(buffer, offsetInBytes, length); return length == null ? _create2(buffer, offsetInBytes) @@ -795,9 +792,9 @@ class NativeFloat64List extends NativeTypedArrayOfDouble Type get runtimeType => Float64List; - Float64List sublist(int start, [int end]) { - end = _checkValidRange(start, end, this.length); - var source = JS('NativeFloat64List', '#.subarray(#, #)', this, start, end); + Float64List sublist(int start, [int? end]) { + var stop = _checkValidRange(start, end, this.length); + var source = JS('NativeFloat64List', '#.subarray(#, #)', this, start, stop); return _create1(source); } @@ -819,7 +816,7 @@ class NativeInt16List extends NativeTypedArrayOfInt implements Int16List { _create1(_ensureNativeList(elements)); factory NativeInt16List.view( - NativeByteBuffer buffer, int offsetInBytes, int length) { + NativeByteBuffer buffer, int offsetInBytes, int? length) { _checkViewArguments(buffer, offsetInBytes, length); return length == null ? _create2(buffer, offsetInBytes) @@ -833,9 +830,9 @@ class NativeInt16List extends NativeTypedArrayOfInt implements Int16List { return JS('!', '#[#]', this, index); } - Int16List sublist(int start, [int end]) { - end = _checkValidRange(start, end, this.length); - var source = JS('NativeInt16List', '#.subarray(#, #)', this, start, end); + Int16List sublist(int start, [int? end]) { + var stop = _checkValidRange(start, end, this.length); + var source = JS('NativeInt16List', '#.subarray(#, #)', this, start, stop); return _create1(source); } @@ -857,7 +854,7 @@ class NativeInt32List extends NativeTypedArrayOfInt implements Int32List { _create1(_ensureNativeList(elements)); factory NativeInt32List.view( - ByteBuffer buffer, int offsetInBytes, int length) { + ByteBuffer buffer, int offsetInBytes, int? length) { _checkViewArguments(buffer, offsetInBytes, length); return length == null ? _create2(buffer, offsetInBytes) @@ -871,9 +868,10 @@ class NativeInt32List extends NativeTypedArrayOfInt implements Int32List { return JS('!', '#[#]', this, index); } - Int32List sublist(int start, [int end]) { - end = _checkValidRange(start, end, this.length); - var source = JS('!', '#.subarray(#, #)', this, start, end); + Int32List sublist(int start, [int? end]) { + var stop = _checkValidRange(start, end, this.length); + var source = + JS('!', '#.subarray(#, #)', this, start, stop); return _create1(source); } @@ -895,7 +893,7 @@ class NativeInt8List extends NativeTypedArrayOfInt implements Int8List { _create1(_ensureNativeList(elements)); factory NativeInt8List.view( - ByteBuffer buffer, int offsetInBytes, int length) { + ByteBuffer buffer, int offsetInBytes, int? length) { _checkViewArguments(buffer, offsetInBytes, length); return length == null ? _create2(buffer, offsetInBytes) @@ -909,9 +907,9 @@ class NativeInt8List extends NativeTypedArrayOfInt implements Int8List { return JS('!', '#[#]', this, index); } - Int8List sublist(int start, [int end]) { - end = _checkValidRange(start, end, this.length); - var source = JS('!', '#.subarray(#, #)', this, start, end); + Int8List sublist(int start, [int? end]) { + var stop = _checkValidRange(start, end, this.length); + var source = JS('!', '#.subarray(#, #)', this, start, stop); return _create1(source); } @@ -921,7 +919,7 @@ class NativeInt8List extends NativeTypedArrayOfInt implements Int8List { static NativeInt8List _create2(arg1, arg2) => JS('!', 'new Int8Array(#, #)', arg1, arg2); - static Int8List _create3(arg1, arg2, arg3) => + static NativeInt8List _create3(arg1, arg2, arg3) => JS('!', 'new Int8Array(#, #, #)', arg1, arg2, arg3); } @@ -933,7 +931,7 @@ class NativeUint16List extends NativeTypedArrayOfInt implements Uint16List { _create1(_ensureNativeList(list)); factory NativeUint16List.view( - ByteBuffer buffer, int offsetInBytes, int length) { + ByteBuffer buffer, int offsetInBytes, int? length) { _checkViewArguments(buffer, offsetInBytes, length); return length == null ? _create2(buffer, offsetInBytes) @@ -947,10 +945,10 @@ class NativeUint16List extends NativeTypedArrayOfInt implements Uint16List { return JS('!', '#[#]', this, index); } - Uint16List sublist(int start, [int end]) { - end = _checkValidRange(start, end, this.length); + Uint16List sublist(int start, [int? end]) { + var stop = _checkValidRange(start, end, this.length); var source = - JS('!', '#.subarray(#, #)', this, start, end); + JS('!', '#.subarray(#, #)', this, start, stop); return _create1(source); } @@ -972,7 +970,7 @@ class NativeUint32List extends NativeTypedArrayOfInt implements Uint32List { _create1(_ensureNativeList(elements)); factory NativeUint32List.view( - ByteBuffer buffer, int offsetInBytes, int length) { + ByteBuffer buffer, int offsetInBytes, int? length) { _checkViewArguments(buffer, offsetInBytes, length); return length == null ? _create2(buffer, offsetInBytes) @@ -986,10 +984,10 @@ class NativeUint32List extends NativeTypedArrayOfInt implements Uint32List { return JS('!', '#[#]', this, index); } - Uint32List sublist(int start, [int end]) { - end = _checkValidRange(start, end, this.length); + Uint32List sublist(int start, [int? end]) { + var stop = _checkValidRange(start, end, this.length); var source = - JS('!', '#.subarray(#, #)', this, start, end); + JS('!', '#.subarray(#, #)', this, start, stop); return _create1(source); } @@ -1012,7 +1010,7 @@ class NativeUint8ClampedList extends NativeTypedArrayOfInt _create1(_ensureNativeList(elements)); factory NativeUint8ClampedList.view( - ByteBuffer buffer, int offsetInBytes, int length) { + ByteBuffer buffer, int offsetInBytes, int? length) { _checkViewArguments(buffer, offsetInBytes, length); return length == null ? _create2(buffer, offsetInBytes) @@ -1028,10 +1026,10 @@ class NativeUint8ClampedList extends NativeTypedArrayOfInt return JS('!', '#[#]', this, index); } - Uint8ClampedList sublist(int start, [int end]) { - end = _checkValidRange(start, end, this.length); + Uint8ClampedList sublist(int start, [int? end]) { + var stop = _checkValidRange(start, end, this.length); var source = - JS('!', '#.subarray(#, #)', this, start, end); + JS('!', '#.subarray(#, #)', this, start, stop); return _create1(source); } @@ -1062,7 +1060,7 @@ class NativeUint8List extends NativeTypedArrayOfInt implements Uint8List { _create1(_ensureNativeList(elements)); factory NativeUint8List.view( - ByteBuffer buffer, int offsetInBytes, int length) { + ByteBuffer buffer, int offsetInBytes, int? length) { _checkViewArguments(buffer, offsetInBytes, length); return length == null ? _create2(buffer, offsetInBytes) @@ -1078,9 +1076,10 @@ class NativeUint8List extends NativeTypedArrayOfInt implements Uint8List { return JS('!', '#[#]', this, index); } - Uint8List sublist(int start, [int end]) { - end = _checkValidRange(start, end, this.length); - var source = JS('!', '#.subarray(#, #)', this, start, end); + Uint8List sublist(int start, [int? end]) { + var stop = _checkValidRange(start, end, this.length); + var source = + JS('!', '#.subarray(#, #)', this, start, stop); return _create1(source); } @@ -1466,7 +1465,7 @@ class NativeInt32x4 implements Int32x4 { floatList[1] = f.y; floatList[2] = f.z; floatList[3] = f.w; - NativeInt32List view = floatList.buffer.asInt32List(); + Int32List view = floatList.buffer.asInt32List(); return NativeInt32x4._truncated(view[0], view[1], view[2], view[3]); } @@ -1684,7 +1683,7 @@ class NativeFloat64x2 implements Float64x2 { final double y; static NativeFloat64List _list = NativeFloat64List(2); - static NativeUint32List _uint32View = _list.buffer.asUint32List(); + static Uint32List _uint32View = _list.buffer.asUint32List(); NativeFloat64x2(this.x, this.y) { if (x is! num) throw ArgumentError(x); @@ -1815,7 +1814,7 @@ void _checkValidIndex(int index, List list, int length) { /// /// Returns the actual value of `end`, which is `length` if `end` is `null`, and /// the original value of `end` otherwise. -int _checkValidRange(int start, int end, int length) { +int _checkValidRange(int start, int? end, int length) { if (_isInvalidArrayIndex(start) || // Ensures start is non-negative int. ((end == null) ? start > length diff --git a/sdk/lib/_internal/js_dev_runtime/private/profile.dart b/sdk/lib/_internal/js_dev_runtime/private/profile.dart index 0b3086214af..ede43638034 100644 --- a/sdk/lib/_internal/js_dev_runtime/private/profile.dart +++ b/sdk/lib/_internal/js_dev_runtime/private/profile.dart @@ -2,19 +2,15 @@ // 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.6 - /// This file supports profiling dynamic calls. part of dart._debugger; class _MethodStats { final String typeName; final String frame; - double count; + double count = 0.0; - _MethodStats(this.typeName, this.frame) { - count = 0.0; - } + _MethodStats(this.typeName, this.frame); } class _CallMethodRecord { @@ -29,7 +25,7 @@ int _callRecordSampleSize = 5000; /// If the number of dynamic calls exceeds [_callRecordSampleSize] this list /// will represent a random sample of the dynamic calls made. -List<_CallMethodRecord> _callMethodRecords = List(); +var _callMethodRecords = <_CallMethodRecord>[]; /// If the number of dynamic calls exceeds [_callRecordSampleSize] this value /// will be greater than [_callMethodRecords.length]. @@ -45,7 +41,7 @@ num _minCount = 2; /// speedup lookup of source map frames when running the profiler. /// The number of source map entries looked up makes caching more important /// in this case than for typical source map use cases. -Map _frameMappingCache = Map(); +var _frameMappingCache = {}; List> getDynamicStats() { // Process the accumulated method stats. This may be quite slow as processing @@ -56,7 +52,7 @@ List> getDynamicStats() { // raw number of dynamic calls so that the magnitude of the dynamic call // performance hit is clear to users. - Map callMethodStats = Map(); + var callMethodStats = {}; if (_callMethodRecords.length > 0) { // Ratio between total record count and sampled records count. var recordRatio = _totalCallRecords / _callMethodRecords.length; @@ -67,8 +63,8 @@ List> getDynamicStats() { // runtime. var src = frames .skip(2) - .map((f) => - _frameMappingCache.putIfAbsent(f, () => stackTraceMapper('\n$f'))) + .map((f) => _frameMappingCache.putIfAbsent( + f, () => stackTraceMapper!('\n$f'))) .firstWhere((f) => !f.startsWith('dart:'), orElse: () => ''); var actualTypeName = dart.typeName(record.type); @@ -83,7 +79,7 @@ List> getDynamicStats() { // complete profile. if (_totalCallRecords != _callMethodRecords.length) { for (var k in callMethodStats.keys.toList()) { - var stats = callMethodStats[k]; + var stats = callMethodStats[k]!; var threshold = _minCount * recordRatio; if (stats.count + 0.001 < threshold) { callMethodStats.remove(k); @@ -94,12 +90,11 @@ List> getDynamicStats() { _callMethodRecords.clear(); _totalCallRecords = 0; var keys = callMethodStats.keys.toList(); - keys.sort( - (a, b) => callMethodStats[b].count.compareTo(callMethodStats[a].count)); - List> ret = []; + (a, b) => callMethodStats[b]!.count.compareTo(callMethodStats[a]!.count)); + var ret = >[]; for (var key in keys) { - var stats = callMethodStats[key]; + var stats = callMethodStats[key]!; ret.add([stats.typeName, stats.frame, stats.count.round()]); } return ret; diff --git a/sdk/lib/_internal/js_dev_runtime/private/regexp_helper.dart b/sdk/lib/_internal/js_dev_runtime/private/regexp_helper.dart index 0a79d98f14c..6ce53ac45a6 100644 --- a/sdk/lib/_internal/js_dev_runtime/private/regexp_helper.dart +++ b/sdk/lib/_internal/js_dev_runtime/private/regexp_helper.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart._js_helper; // Helper method used by internal libraries. @@ -117,10 +115,11 @@ class JSSyntaxRegExp implements RegExp { throw FormatException("Illegal RegExp pattern: $source, $errorMessage"); } - RegExpMatch firstMatch(@nullCheck String string) { - List m = JS('JSExtendableArray|Null', r'#.exec(#)', _nativeRegExp, string); + RegExpMatch? firstMatch(@nullCheck String string) { + List? m = + JS('JSExtendableArray|Null', r'#.exec(#)', _nativeRegExp, string); if (m == null) return null; - return _MatchImplementation(this, JSArray.of(m)); + return _MatchImplementation(this, m); } @notNull @@ -128,7 +127,7 @@ class JSSyntaxRegExp implements RegExp { return JS('!', r'#.test(#)', _nativeRegExp, string); } - String stringMatch(String string) { + String? stringMatch(String string) { var match = firstMatch(string); if (match != null) return match.group(0); return null; @@ -142,27 +141,29 @@ class JSSyntaxRegExp implements RegExp { return _AllMatchesIterable(this, string, start); } - RegExpMatch _execGlobal(String string, int start) { + RegExpMatch? _execGlobal(String string, int start) { Object regexp = _nativeGlobalVersion; JS("void", "#.lastIndex = #", regexp, start); - List match = JS("JSExtendableArray|Null", "#.exec(#)", regexp, string); + List? match = + JS("JSExtendableArray|Null", "#.exec(#)", regexp, string); if (match == null) return null; - return _MatchImplementation(this, JSArray.of(match)); + return _MatchImplementation(this, match); } - RegExpMatch _execAnchored(String string, int start) { + RegExpMatch? _execAnchored(String string, int start) { Object regexp = _nativeAnchoredVersion; JS("void", "#.lastIndex = #", regexp, start); - List match = JS("JSExtendableArray|Null", "#.exec(#)", regexp, string); + List? match = + JS("JSExtendableArray|Null", "#.exec(#)", regexp, string); if (match == null) return null; // If the last capture group participated, the original regexp did not // match at the start position. if (match[match.length - 1] != null) return null; match.length -= 1; - return _MatchImplementation(this, JSArray.of(match)); + return _MatchImplementation(this, match); } - RegExpMatch matchAsPrefix(String string, [int start = 0]) { + Match? matchAsPrefix(String string, [int start = 0]) { if (start < 0 || start > string.length) { throw RangeError.range(start, 0, string.length); } @@ -190,22 +191,22 @@ class _MatchImplementation implements RegExpMatch { int get start => JS("int", "#.index", _match); int get end => start + _match[0].length; - String group(int index) => _match[index]; - String operator [](int index) => group(index); + String? group(int index) => _match[index]; + String? operator [](int index) => group(index); int get groupCount => _match.length - 1; - List groups(List groups) { - List out = []; + List groups(List groups) { + List out = []; for (int i in groups) { out.add(group(i)); } return out; } - String namedGroup(String name) { - var groups = JS('Object|Null', '#.groups', _match); + String? namedGroup(String name) { + var groups = JS('Object|Null', '#.groups', _match); if (groups != null) { - var result = JS('String|Null', '#[#]', groups, name); + var result = JS('', '#[#]', groups, name); if (result != null || JS('!', '# in #', name, groups)) { return result; } @@ -214,7 +215,7 @@ class _MatchImplementation implements RegExpMatch { } Iterable get groupNames { - var groups = JS('Object|Null', '#.groups', _match); + var groups = JS('Object|Null', '#.groups', _match); if (groups != null) { var keys = JSArray.of(JS('', 'Object.keys(#)', groups)); return SubListIterable(keys, 0, null); @@ -236,13 +237,13 @@ class _AllMatchesIterable extends IterableBase { class _AllMatchesIterator implements Iterator { final JSSyntaxRegExp _regExp; - String _string; + String? _string; int _nextIndex; - RegExpMatch _current; + RegExpMatch? _current; _AllMatchesIterator(this._regExp, this._string, this._nextIndex); - RegExpMatch get current => _current; + RegExpMatch get current => _current as RegExpMatch; static bool _isLeadSurrogate(int c) { return c >= 0xd800 && c <= 0xdbff; @@ -253,9 +254,10 @@ class _AllMatchesIterator implements Iterator { } bool moveNext() { - if (_string == null) return false; - if (_nextIndex <= _string.length) { - var match = _regExp._execGlobal(_string, _nextIndex); + var string = _string; + if (string == null) return false; + if (_nextIndex <= string.length) { + var match = _regExp._execGlobal(string, _nextIndex); if (match != null) { _current = match; int nextIndex = match.end; @@ -264,9 +266,9 @@ class _AllMatchesIterator implements Iterator { // is in unicode mode and it would put us within a surrogate // pair. In that case, advance past the code point as a whole. if (_regExp.isUnicode && - _nextIndex + 1 < _string.length && - _isLeadSurrogate(_string.codeUnitAt(_nextIndex)) && - _isTrailSurrogate(_string.codeUnitAt(_nextIndex + 1))) { + _nextIndex + 1 < string.length && + _isLeadSurrogate(string.codeUnitAt(_nextIndex)) && + _isTrailSurrogate(string.codeUnitAt(_nextIndex + 1))) { nextIndex++; } nextIndex++; @@ -282,6 +284,6 @@ class _AllMatchesIterator implements Iterator { } /** Find the first match of [regExp] in [string] at or after [start]. */ -RegExpMatch firstMatchAfter(JSSyntaxRegExp regExp, String string, int start) { +RegExpMatch? firstMatchAfter(JSSyntaxRegExp regExp, String string, int start) { return regExp._execGlobal(string, start); } diff --git a/sdk/lib/_internal/js_dev_runtime/private/string_helper.dart b/sdk/lib/_internal/js_dev_runtime/private/string_helper.dart index 326af1128fe..7a0de57baf9 100644 --- a/sdk/lib/_internal/js_dev_runtime/private/string_helper.dart +++ b/sdk/lib/_internal/js_dev_runtime/private/string_helper.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart._js_helper; @notNull @@ -41,7 +39,7 @@ class StringMatch implements Match { } List groups(List groups_) { - List result = List(); + List result = []; for (int g in groups_) { result.add(group(g)); } @@ -81,7 +79,7 @@ class _StringAllMatchesIterator implements Iterator { final String _input; final String _pattern; int _index; - Match _current; + Match? _current; _StringAllMatchesIterator(this._input, this._pattern, this._index); @@ -104,7 +102,7 @@ class _StringAllMatchesIterator implements Iterator { return true; } - Match get current => _current; + Match get current => _current!; } @notNull @@ -176,15 +174,15 @@ String stringReplaceAllUnchecked(@notNull String receiver, } } -String _matchString(Match match) => match[0]; +String _matchString(Match match) => match[0]!; String _stringIdentity(String string) => string; @notNull String stringReplaceAllFuncUnchecked( String receiver, @nullCheck Pattern pattern, - String onMatch(Match match), - String onNonMatch(String nonMatch)) { + String Function(Match)? onMatch, + String Function(String)? onNonMatch) { if (onMatch == null) onMatch = _matchString; if (onNonMatch == null) onNonMatch = _stringIdentity; if (pattern is String) { diff --git a/sdk/lib/_internal/js_runtime/lib/annotations.dart b/sdk/lib/_internal/js_runtime/lib/annotations.dart index 971d2bd756c..f53c5f3c238 100644 --- a/sdk/lib/_internal/js_runtime/lib/annotations.dart +++ b/sdk/lib/_internal/js_runtime/lib/annotations.dart @@ -2,8 +2,6 @@ // 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.6 - part of _js_helper; /// Marks a class as native and defines its JavaScript name(s). diff --git a/sdk/lib/_internal/js_runtime/lib/async_patch.dart b/sdk/lib/_internal/js_runtime/lib/async_patch.dart index 3da215e6ba3..45ed0c5c202 100644 --- a/sdk/lib/_internal/js_runtime/lib/async_patch.dart +++ b/sdk/lib/_internal/js_runtime/lib/async_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // Patch file for the dart:async library. import 'dart:_js_helper' @@ -122,7 +120,7 @@ class Timer { class _TimerImpl implements Timer { final bool _once; - int _handle; + int? _handle; int _tick = 0; _TimerImpl(int milliseconds, void callback()) : _once = true { @@ -197,15 +195,24 @@ class _AsyncAwaitCompleter implements Completer { _AsyncAwaitCompleter() : isSync = false; - void complete([FutureOr value]) { - if (!isSync || value is Future) { + void complete([FutureOr? value]) { + // All paths require that if value is null, null as T succeeds. + value = (value == null) ? value as T : value; + if (!isSync) { _future._asyncComplete(value); + } else if (value is Future) { + assert(!_future._isComplete); + _future._chainFuture(value); } else { - _future._completeWithValue(value); + // TODO(40014): Remove cast when type promotion works. + // This would normally be `as T` but we use `as dynamic` to make the + // unneeded check be implict to match dart2js unsound optimizations in the + // user code. + _future._completeWithValue(value as dynamic); } } - void completeError(Object e, [StackTrace st]) { + void completeError(Object e, [StackTrace? st]) { st ??= AsyncError.defaultStackTrace(e); if (isSync) { _future._completeError(e, st); @@ -280,7 +287,7 @@ dynamic _asyncRethrow(dynamic object, Completer completer) { /// The [bodyFunction] argument is the continuation that should be invoked /// when the future completes. void _awaitOnObject(object, _WrappedAsyncBody bodyFunction) { - Function thenCallback = + FutureOr Function(dynamic) thenCallback = (result) => bodyFunction(async_error_codes.SUCCESS, result); Function errorCallback = (dynamic error, StackTrace stackTrace) { @@ -377,7 +384,7 @@ void _asyncStarHelper( if (identical(bodyFunctionOrErrorCode, async_error_codes.SUCCESS)) { // This happens on return from the async* function. if (controller.isCanceled) { - controller.cancelationFuture._completeWithValue(null); + controller.cancelationFuture!._completeWithValue(null); } else { controller.close(); } @@ -385,7 +392,7 @@ void _asyncStarHelper( } else if (identical(bodyFunctionOrErrorCode, async_error_codes.ERROR)) { // The error is a js-error. if (controller.isCanceled) { - controller.cancelationFuture._completeError( + controller.cancelationFuture!._completeError( unwrapException(object), getTraceFromException(object)); } else { controller.addError( @@ -451,7 +458,7 @@ Stream _streamOfController(_AsyncStarStreamController controller) { /// If yielding while the subscription is paused it will become suspended. And /// only resume after the subscription is resumed or canceled. class _AsyncStarStreamController { - StreamController controller; + late StreamController controller; Stream get stream => controller.stream; /// True when the async* function has yielded while being paused. @@ -461,7 +468,7 @@ class _AsyncStarStreamController { bool get isPaused => controller.isPaused; - _Future cancelationFuture = null; + _Future? cancelationFuture = null; /// True after the StreamSubscription has been cancelled. /// When this is true, errors thrown from the async* body should go to the @@ -565,22 +572,21 @@ class _SyncStarIterator implements Iterator { dynamic _body; // The current value, unless iterating a non-sync* nested iterator. - T _current = null; + T? _current = null; // This is the nested iterator when iterating a yield* of a non-sync iterator. - // TODO(32956): In strong-mode, yield* takes an Iterable (possibly checked - // with an implicit downcast), so change type to Iterator. - Iterator _nestedIterator = null; + Iterator? _nestedIterator = null; // Stack of suspended state machines when iterating a yield* of a sync* // iterator. - List _suspendedBodies = null; + List? _suspendedBodies = null; _SyncStarIterator(this._body); T get current { - if (_nestedIterator == null) return _current; - return _nestedIterator.current; + var nested = _nestedIterator; + if (nested == null) return _current as dynamic; // implicit: as T; + return nested.current; } _runBody() { @@ -611,7 +617,7 @@ class _SyncStarIterator implements Iterator { bool moveNext() { while (true) { if (_nestedIterator != null) { - if (_nestedIterator.moveNext()) { + if (_nestedIterator!.moveNext()) { return true; } else { _nestedIterator = null; @@ -621,13 +627,14 @@ class _SyncStarIterator implements Iterator { if (value is _IterationMarker) { int state = value.state; if (state == _IterationMarker.ITERATION_ENDED) { - if (_suspendedBodies == null || _suspendedBodies.isEmpty) { + var suspendedBodies = _suspendedBodies; + if (suspendedBodies == null || suspendedBodies.isEmpty) { _current = null; // Rely on [_body] to repeatedly return `ITERATION_ENDED`. return false; } // Resume the innermost suspended iterator. - _body = _suspendedBodies.removeLast(); + _body = suspendedBodies.removeLast(); continue; } else if (state == _IterationMarker.UNCAUGHT_ERROR) { // Rely on [_body] to repeatedly return `UNCAUGHT_ERROR`. @@ -636,8 +643,12 @@ class _SyncStarIterator implements Iterator { JS('', 'throw #', value.value); } else { assert(state == _IterationMarker.YIELD_STAR); - Iterator inner = value.value.iterator; + Iterator inner = value.value.iterator; if (inner is _SyncStarIterator) { + // The test needs to be 'is _SyncStarIterator' for promotion to + // work. However, that test is much more expensive, so we use an + // unsafe cast. + _SyncStarIterator innerSyncStarIterator = JS('', '#', inner); // Suspend the current state machine and start acting on behalf of // the nested state machine. // @@ -645,7 +656,7 @@ class _SyncStarIterator implements Iterator { // suspending the current body when all it will do is step without // effect to ITERATION_ENDED. (_suspendedBodies ??= []).add(_body); - _body = inner._body; + _body = innerSyncStarIterator._body; continue; } else { _nestedIterator = inner; diff --git a/sdk/lib/_internal/js_runtime/lib/collection_patch.dart b/sdk/lib/_internal/js_runtime/lib/collection_patch.dart index b46544640c2..a1d76bfe4ff 100644 --- a/sdk/lib/_internal/js_runtime/lib/collection_patch.dart +++ b/sdk/lib/_internal/js_runtime/lib/collection_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // Patch file for dart:collection classes. import 'dart:_foreign_helper' show JS; import 'dart:_js_helper' @@ -30,9 +28,9 @@ const int _mask30 = 0x3fffffff; // Low 30 bits. class HashMap { @patch factory HashMap( - {bool equals(K key1, K key2), - int hashCode(K key), - bool isValidKey(potentialKey)}) { + {bool equals(K key1, K key2)?, + int hashCode(K key)?, + bool isValidKey(potentialKey)?}) { if (isValidKey == null) { if (hashCode == null) { if (equals == null) { @@ -82,7 +80,7 @@ class _HashMap extends MapBase implements HashMap { // list of all the keys. We cache that on the instance and clear the // the cache whenever the key set changes. This is also used to // guard against concurrent modifications. - List _keys; + List? _keys; _HashMap(); @@ -95,10 +93,10 @@ class _HashMap extends MapBase implements HashMap { } Iterable get values { - return new MappedIterable(keys, (each) => this[each]); + return new MappedIterable(keys, (each) => this[each] as V); } - bool containsKey(Object key) { + bool containsKey(Object? key) { if (_isStringKey(key)) { var strings = _strings; return (strings == null) ? false : _hasTableEntry(strings, key); @@ -110,14 +108,14 @@ class _HashMap extends MapBase implements HashMap { } } - bool _containsKey(Object key) { + bool _containsKey(Object? key) { var rest = _rest; if (rest == null) return false; var bucket = _getBucket(rest, key); return _findBucketIndex(bucket, key) >= 0; } - bool containsValue(Object value) { + bool containsValue(Object? value) { return _computeKeys().any((each) => this[each] == value); } @@ -127,7 +125,7 @@ class _HashMap extends MapBase implements HashMap { }); } - V operator [](Object key) { + V? operator [](Object? key) { if (_isStringKey(key)) { var strings = _strings; return JS('', '#', strings == null ? null : _getTableEntry(strings, key)); @@ -139,7 +137,7 @@ class _HashMap extends MapBase implements HashMap { } } - V _get(Object key) { + V? _get(Object? key) { var rest = _rest; if (rest == null) return null; var bucket = _getBucket(rest, key); @@ -183,13 +181,13 @@ class _HashMap extends MapBase implements HashMap { } V putIfAbsent(K key, V ifAbsent()) { - if (containsKey(key)) return this[key]; + if (containsKey(key)) return this[key] as V; V value = ifAbsent(); this[key] = value; return value; } - V remove(Object key) { + V? remove(Object? key) { if (_isStringKey(key)) { return _removeHashTableEntry(_strings, key); } else if (_isNumericKey(key)) { @@ -199,7 +197,7 @@ class _HashMap extends MapBase implements HashMap { } } - V _remove(Object key) { + V? _remove(Object? key) { var rest = _rest; if (rest == null) return null; var hash = _computeHashCode(key); @@ -228,7 +226,7 @@ class _HashMap extends MapBase implements HashMap { List keys = _computeKeys(); for (int i = 0, length = keys.length; i < length; i++) { var key = JS('var', '#[#]', keys, i); - action(key, this[key]); + action(key, this[key] as V); if (JS('bool', '# !== #', keys, _keys)) { throw new ConcurrentModificationError(this); } @@ -236,8 +234,9 @@ class _HashMap extends MapBase implements HashMap { } List _computeKeys() { - if (_keys != null) return _keys; - List result = new List(_length); + var result = _keys; + if (result != null) return result; + result = List.filled(_length, null); int index = 0; // Add all string keys to the list. @@ -283,7 +282,8 @@ class _HashMap extends MapBase implements HashMap { } } assert(index == _length); - return _keys = result; + _keys = result; + return result; } void _addHashTableEntry(var table, K key, V value) { @@ -294,7 +294,7 @@ class _HashMap extends MapBase implements HashMap { _setTableEntry(table, key, value); } - V _removeHashTableEntry(var table, Object key) { + V? _removeHashTableEntry(var table, Object? key) { if (table != null && _hasTableEntry(table, key)) { V value = _getTableEntry(table, key); _deleteTableEntry(table, key); @@ -408,10 +408,10 @@ class _CustomHashMap extends _HashMap { final _Hasher _hashCode; final _Predicate _validKey; - _CustomHashMap(this._equals, this._hashCode, bool validKey(potentialKey)) + _CustomHashMap(this._equals, this._hashCode, bool validKey(potentialKey)?) : _validKey = (validKey != null) ? validKey : ((v) => v is K); - V operator [](Object key) { + V? operator [](Object? key) { if (!_validKey(key)) return null; return super._get(key); } @@ -420,12 +420,12 @@ class _CustomHashMap extends _HashMap { super._set(key, value); } - bool containsKey(Object key) { + bool containsKey(Object? key) { if (!_validKey(key)) return false; return super._containsKey(key); } - V remove(Object key) { + V? remove(Object? key) { if (!_validKey(key)) return null; return super._remove(key); } @@ -458,7 +458,7 @@ class _HashMapKeyIterable extends EfficientLengthIterable { return new _HashMapKeyIterator(_map, _map._computeKeys()); } - bool contains(Object element) { + bool contains(Object? element) { return _map.containsKey(element); } @@ -477,11 +477,11 @@ class _HashMapKeyIterator implements Iterator { final _map; final List _keys; int _offset = 0; - E _current; + E? _current; _HashMapKeyIterator(this._map, this._keys); - E get current => _current; + E get current => _current as E; bool moveNext() { var keys = _keys; @@ -506,9 +506,9 @@ class _HashMapKeyIterator implements Iterator { class LinkedHashMap { @patch factory LinkedHashMap( - {bool equals(K key1, K key2), - int hashCode(K key), - bool isValidKey(potentialKey)}) { + {bool equals(K key1, K key2)?, + int hashCode(K key)?, + bool isValidKey(potentialKey)?}) { if (isValidKey == null) { if (hashCode == null) { if (equals == null) { @@ -613,11 +613,11 @@ class _Es6LinkedIdentityHashMap extends _LinkedIdentityHashMap Iterable get values => new _Es6MapIterable(this, false); - bool containsKey(Object key) { + bool containsKey(Object? key) { return JS('bool', '#.has(#)', _map, key); } - bool containsValue(Object value) { + bool containsValue(Object? value) { return values.any((each) => each == value); } @@ -627,7 +627,7 @@ class _Es6LinkedIdentityHashMap extends _LinkedIdentityHashMap }); } - V operator [](Object key) { + V? operator [](Object? key) { return JS('var', '#.get(#)', _map, key); } @@ -637,14 +637,14 @@ class _Es6LinkedIdentityHashMap extends _LinkedIdentityHashMap } V putIfAbsent(K key, V ifAbsent()) { - if (containsKey(key)) return this[key]; + if (containsKey(key)) return this[key] as V; V value = ifAbsent(); this[key] = value; return value; } - V remove(Object key) { - V value = this[key]; + V? remove(Object? key) { + V? value = this[key]; JS('bool', '#.delete(#)', _map, key); _modified(); return value; @@ -693,7 +693,7 @@ class _Es6MapIterable extends EfficientLengthIterable { Iterator get iterator => new _Es6MapIterator(_map, _map._modifications, _isKeys); - bool contains(Object element) => _map.containsKey(element); + bool contains(Object? element) => _map.containsKey(element); void forEach(void f(E element)) { var jsIterator; @@ -722,8 +722,8 @@ class _Es6MapIterator implements Iterator { final bool _isKeys; var _jsIterator; var _next; - E _current; - bool _done; + E? _current; + bool _done = false; _Es6MapIterator(this._map, this._modifications, this._isKeys) { if (_isKeys) { @@ -731,10 +731,9 @@ class _Es6MapIterator implements Iterator { } else { _jsIterator = JS('var', '#.values()', _map._map); } - _done = false; } - E get current => _current; + E get current => _current as E; bool moveNext() { if (_modifications != _map._modifications) { @@ -761,10 +760,10 @@ class _LinkedCustomHashMap extends JsLinkedHashMap { final _Predicate _validKey; _LinkedCustomHashMap( - this._equals, this._hashCode, bool validKey(potentialKey)) + this._equals, this._hashCode, bool validKey(potentialKey)?) : _validKey = (validKey != null) ? validKey : ((v) => v is K); - V operator [](Object key) { + V? operator [](Object? key) { if (!_validKey(key)) return null; return super.internalGet(key); } @@ -773,12 +772,12 @@ class _LinkedCustomHashMap extends JsLinkedHashMap { super.internalSet(key, value); } - bool containsKey(Object key) { + bool containsKey(Object? key) { if (!_validKey(key)) return false; return super.internalContainsKey(key); } - V remove(Object key) { + V? remove(Object? key) { if (!_validKey(key)) return null; return super.internalRemove(key); } @@ -805,9 +804,9 @@ class _LinkedCustomHashMap extends JsLinkedHashMap { class HashSet { @patch factory HashSet( - {bool equals(E e1, E e2), - int hashCode(E e), - bool isValidKey(potentialKey)}) { + {bool equals(E e1, E e2)?, + int hashCode(E e)?, + bool isValidKey(potentialKey)?}) { if (isValidKey == null) { if (hashCode == null) { if (equals == null) { @@ -858,7 +857,7 @@ class _HashSet extends _SetBase implements HashSet { // list of all the elements. We cache that on the instance and clear // the cache whenever the set changes. This is also used to // guard against concurrent modifications. - List _elements; + List? _elements; _HashSet(); @@ -874,7 +873,7 @@ class _HashSet extends _SetBase implements HashSet { bool get isEmpty => _length == 0; bool get isNotEmpty => !isEmpty; - bool contains(Object object) { + bool contains(Object? object) { if (_isStringElement(object)) { var strings = _strings; return (strings == null) ? false : _hasTableEntry(strings, object); @@ -886,21 +885,21 @@ class _HashSet extends _SetBase implements HashSet { } } - bool _contains(Object object) { + bool _contains(Object? object) { var rest = _rest; if (rest == null) return false; var bucket = _getBucket(rest, object); return _findBucketIndex(bucket, object) >= 0; } - E lookup(Object object) { + E? lookup(Object? object) { if (_isStringElement(object) || _isNumericElement(object)) { - return this.contains(object) ? object : null; + return this.contains(object) ? object as E : null; } return _lookup(object); } - E _lookup(Object object) { + E? _lookup(Object? object) { var rest = _rest; if (rest == null) return null; var bucket = _getBucket(rest, object); @@ -947,7 +946,7 @@ class _HashSet extends _SetBase implements HashSet { } } - bool remove(Object object) { + bool remove(Object? object) { if (_isStringElement(object)) { return _removeHashTableEntry(_strings, object); } else if (_isNumericElement(object)) { @@ -957,7 +956,7 @@ class _HashSet extends _SetBase implements HashSet { } } - bool _remove(Object object) { + bool _remove(Object? object) { var rest = _rest; if (rest == null) return false; var hash = _computeHashCode(object); @@ -985,8 +984,9 @@ class _HashSet extends _SetBase implements HashSet { } List _computeElements() { - if (_elements != null) return _elements; - List result = new List(_length); + var result = _elements; + if (result != null) return result; + result = List.filled(_length, null); int index = 0; // Add all string elements to the list. @@ -1031,7 +1031,8 @@ class _HashSet extends _SetBase implements HashSet { } } assert(index == _length); - return _elements = result; + _elements = result; + return result; } bool _addHashTableEntry(var table, E element) { @@ -1042,7 +1043,7 @@ class _HashSet extends _SetBase implements HashSet { return true; } - bool _removeHashTableEntry(var table, Object element) { + bool _removeHashTableEntry(var table, Object? element) { if (table != null && _hasTableEntry(table, element)) { _deleteTableEntry(table, element); _length--; @@ -1143,7 +1144,7 @@ class _CustomHashSet extends _HashSet { _Equality _equality; _Hasher _hasher; _Predicate _validKey; - _CustomHashSet(this._equality, this._hasher, bool validKey(potentialKey)) + _CustomHashSet(this._equality, this._hasher, bool validKey(potentialKey)?) : _validKey = (validKey != null) ? validKey : ((x) => x is E); Set _newSet() => new _CustomHashSet(_equality, _hasher, _validKey); @@ -1168,17 +1169,17 @@ class _CustomHashSet extends _HashSet { bool add(E object) => super._add(object); - bool contains(Object object) { + bool contains(Object? object) { if (!_validKey(object)) return false; return super._contains(object); } - E lookup(Object object) { + E? lookup(Object? object) { if (!_validKey(object)) return null; return super._lookup(object); } - bool remove(Object object) { + bool remove(Object? object) { if (!_validKey(object)) return false; return super._remove(object); } @@ -1189,11 +1190,11 @@ class _HashSetIterator implements Iterator { final _set; final List _elements; int _offset = 0; - E _current; + E? _current; _HashSetIterator(this._set, this._elements); - E get current => _current; + E get current => _current as E; bool moveNext() { var elements = _elements; @@ -1218,9 +1219,9 @@ class _HashSetIterator implements Iterator { class LinkedHashSet { @patch factory LinkedHashSet( - {bool equals(E e1, E e2), - int hashCode(E e), - bool isValidKey(potentialKey)}) { + {bool equals(E e1, E e2)?, + int hashCode(E e)?, + bool isValidKey(potentialKey)?}) { if (isValidKey == null) { if (hashCode == null) { if (equals == null) { @@ -1293,8 +1294,8 @@ class _LinkedHashSet extends _SetBase implements LinkedHashSet { // The elements are stored in cells that are linked together // to form a double linked list. - _LinkedHashSetCell _first; - _LinkedHashSetCell _last; + _LinkedHashSetCell? _first; + _LinkedHashSetCell? _last; // We track the number of modifications done to the element set to // be able to throw when the set is modified while being iterated @@ -1319,38 +1320,38 @@ class _LinkedHashSet extends _SetBase implements LinkedHashSet { bool get isEmpty => _length == 0; bool get isNotEmpty => !isEmpty; - bool contains(Object object) { + bool contains(Object? object) { if (_isStringElement(object)) { var strings = _strings; if (strings == null) return false; - _LinkedHashSetCell cell = _getTableEntry(strings, object); + _LinkedHashSetCell? cell = _getTableEntry(strings, object); return cell != null; } else if (_isNumericElement(object)) { var nums = _nums; if (nums == null) return false; - _LinkedHashSetCell cell = _getTableEntry(nums, object); + _LinkedHashSetCell? cell = _getTableEntry(nums, object); return cell != null; } else { return _contains(object); } } - bool _contains(Object object) { + bool _contains(Object? object) { var rest = _rest; if (rest == null) return false; var bucket = _getBucket(rest, object); return _findBucketIndex(bucket, object) >= 0; } - E lookup(Object object) { + E? lookup(Object? object) { if (_isStringElement(object) || _isNumericElement(object)) { - return this.contains(object) ? object : null; + return this.contains(object) ? object as E : null; } else { return _lookup(object); } } - E _lookup(Object object) { + E? _lookup(Object? object) { var rest = _rest; if (rest == null) return null; var bucket = _getBucket(rest, object); @@ -1360,7 +1361,7 @@ class _LinkedHashSet extends _SetBase implements LinkedHashSet { } void forEach(void action(E element)) { - _LinkedHashSetCell cell = _first; + _LinkedHashSetCell? cell = _first; int modifications = _modifications; while (cell != null) { action(cell._element); @@ -1372,13 +1373,15 @@ class _LinkedHashSet extends _SetBase implements LinkedHashSet { } E get first { - if (_first == null) throw new StateError("No elements"); - return _first._element; + var first = _first; + if (first == null) throw new StateError("No elements"); + return first._element; } E get last { - if (_last == null) throw new StateError("No elements"); - return _last._element; + var last = _last; + if (last == null) throw new StateError("No elements"); + return last._element; } // Collection. @@ -1413,7 +1416,7 @@ class _LinkedHashSet extends _SetBase implements LinkedHashSet { return true; } - bool remove(Object object) { + bool remove(Object? object) { if (_isStringElement(object)) { return _removeHashTableEntry(_strings, object); } else if (_isNumericElement(object)) { @@ -1423,7 +1426,7 @@ class _LinkedHashSet extends _SetBase implements LinkedHashSet { } } - bool _remove(Object object) { + bool _remove(Object? object) { var rest = _rest; if (rest == null) return false; var hash = _computeHashCode(object); @@ -1448,10 +1451,10 @@ class _LinkedHashSet extends _SetBase implements LinkedHashSet { } void _filterWhere(bool test(E element), bool removeMatching) { - _LinkedHashSetCell cell = _first; + _LinkedHashSetCell? cell = _first; while (cell != null) { E element = cell._element; - _LinkedHashSetCell next = cell._next; + _LinkedHashSetCell? next = cell._next; int modifications = _modifications; bool shouldRemove = (removeMatching == test(element)); if (modifications != _modifications) { @@ -1471,15 +1474,15 @@ class _LinkedHashSet extends _SetBase implements LinkedHashSet { } bool _addHashTableEntry(var table, E element) { - _LinkedHashSetCell cell = _getTableEntry(table, element); + _LinkedHashSetCell? cell = _getTableEntry(table, element); if (cell != null) return false; _setTableEntry(table, element, _newLinkedCell(element)); return true; } - bool _removeHashTableEntry(var table, Object element) { + bool _removeHashTableEntry(var table, Object? element) { if (table == null) return false; - _LinkedHashSetCell cell = _getTableEntry(table, element); + _LinkedHashSetCell? cell = _getTableEntry(table, element); if (cell == null) return false; _unlinkCell(cell); _deleteTableEntry(table, element); @@ -1499,7 +1502,7 @@ class _LinkedHashSet extends _SetBase implements LinkedHashSet { if (_first == null) { _first = _last = cell; } else { - _LinkedHashSetCell last = _last; + _LinkedHashSetCell last = _last!; cell._previous = last; _last = last._next = cell; } @@ -1510,8 +1513,8 @@ class _LinkedHashSet extends _SetBase implements LinkedHashSet { // Unlink the given cell from the linked list of cells. void _unlinkCell(_LinkedHashSetCell cell) { - _LinkedHashSetCell previous = cell._previous; - _LinkedHashSetCell next = cell._next; + _LinkedHashSetCell? previous = cell._previous; + _LinkedHashSetCell? next = cell._next; if (previous == null) { assert(cell == _first); _first = next; @@ -1617,7 +1620,7 @@ class _LinkedCustomHashSet extends _LinkedHashSet { _Hasher _hasher; _Predicate _validKey; _LinkedCustomHashSet( - this._equality, this._hasher, bool validKey(potentialKey)) + this._equality, this._hasher, bool validKey(potentialKey)?) : _validKey = (validKey != null) ? validKey : ((x) => x is E); Set _newSet() => @@ -1644,30 +1647,30 @@ class _LinkedCustomHashSet extends _LinkedHashSet { bool add(E element) => super._add(element); - bool contains(Object object) { + bool contains(Object? object) { if (!_validKey(object)) return false; return super._contains(object); } - E lookup(Object object) { + E? lookup(Object? object) { if (!_validKey(object)) return null; return super._lookup(object); } - bool remove(Object object) { + bool remove(Object? object) { if (!_validKey(object)) return false; return super._remove(object); } - bool containsAll(Iterable elements) { - for (Object element in elements) { + bool containsAll(Iterable elements) { + for (Object? element in elements) { if (!_validKey(element) || !this.contains(element)) return false; } return true; } - void removeAll(Iterable elements) { - for (Object element in elements) { + void removeAll(Iterable elements) { + for (Object? element in elements) { if (_validKey(element)) { super._remove(element); } @@ -1678,8 +1681,8 @@ class _LinkedCustomHashSet extends _LinkedHashSet { class _LinkedHashSetCell { final _element; - _LinkedHashSetCell _next; - _LinkedHashSetCell _previous; + _LinkedHashSetCell? _next; + _LinkedHashSetCell? _previous; _LinkedHashSetCell(this._element); } @@ -1688,52 +1691,26 @@ class _LinkedHashSetCell { class _LinkedHashSetIterator implements Iterator { final _set; final int _modifications; - _LinkedHashSetCell _cell; - E _current; + _LinkedHashSetCell? _cell; + E? _current; _LinkedHashSetIterator(this._set, this._modifications) { _cell = _set._first; } - E get current => _current; + E get current => _current as E; bool moveNext() { + var cell = _cell; if (_modifications != _set._modifications) { throw new ConcurrentModificationError(_set); - } else if (_cell == null) { + } else if (cell == null) { _current = null; return false; } else { - _current = _cell._element; - _cell = _cell._next; + _current = cell._element; + _cell = cell._next; return true; } } } - -@patch -abstract class _SplayTree> { - @patch - Node _splayMin(Node node) { - Node current = node; - while (current.left != null) { - Node left = current.left; - current.left = left.right; - left.right = current; - current = left; - } - return current; - } - - @patch - Node _splayMax(Node node) { - Node current = node; - while (current.right != null) { - Node right = current.right; - current.right = right.left; - right.left = current; - current = right; - } - return current; - } -} diff --git a/sdk/lib/_internal/js_runtime/lib/constant_map.dart b/sdk/lib/_internal/js_runtime/lib/constant_map.dart index fce892204a9..0f673d875ba 100644 --- a/sdk/lib/_internal/js_runtime/lib/constant_map.dart +++ b/sdk/lib/_internal/js_runtime/lib/constant_map.dart @@ -2,8 +2,6 @@ // 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.6 - part of _js_helper; class ConstantMapView extends UnmodifiableMapView @@ -14,7 +12,7 @@ class ConstantMapView extends UnmodifiableMapView abstract class ConstantMap implements Map { // Used to create unmodifiable maps from other maps. factory ConstantMap.from(Map other) { - List keys = new List.from(other.keys); + var keys = new List.from(other.keys); bool allStrings = true; for (var k in keys) { if (k is! String) { @@ -30,7 +28,7 @@ abstract class ConstantMap implements Map { for (var k in keys) { V v = other[k]; if (k != '__proto__') { - if (!jsHasOwnProperty(object, k)) length++; + if (!jsHasOwnProperty(object, k as String)) length++; JS('void', '#[#] = #', object, k, v); } else { containsProto = true; @@ -56,18 +54,27 @@ abstract class ConstantMap implements Map { String toString() => MapBase.mapToString(this); - static Null _throwUnmodifiable() { + static Never _throwUnmodifiable() { throw new UnsupportedError('Cannot modify unmodifiable Map'); } - void operator []=(K key, V val) => _throwUnmodifiable(); - V putIfAbsent(K key, V ifAbsent()) => _throwUnmodifiable(); - V remove(Object key) => _throwUnmodifiable(); + void operator []=(K key, V val) { + _throwUnmodifiable(); + } + + V putIfAbsent(K key, V ifAbsent()) { + _throwUnmodifiable(); + } + + V? remove(Object? key) { + _throwUnmodifiable(); + } + void clear() => _throwUnmodifiable(); void addAll(Map other) => _throwUnmodifiable(); Iterable> get entries sync* { - for (var key in keys) yield new MapEntry(key, this[key]); + for (var key in keys) yield new MapEntry(key, this[key]!); } void addEntries(Iterable> entries) { @@ -83,7 +90,7 @@ abstract class ConstantMap implements Map { return result; } - V update(K key, V update(V value), {V ifAbsent()}) { + V update(K key, V update(V value), {V ifAbsent()?}) { _throwUnmodifiable(); } @@ -111,17 +118,17 @@ class ConstantStringMap extends ConstantMap { int get length => JS('JSUInt31', '#', _length); List get _keysArray => JS('JSUnmodifiableArray', '#', _keys); - bool containsValue(Object needle) { + bool containsValue(Object? needle) { return values.any((V value) => value == needle); } - bool containsKey(Object key) { + bool containsKey(Object? key) { if (key is! String) return false; if ('__proto__' == key) return false; return jsHasOwnProperty(_jsObject, key); } - V operator [](Object key) { + V? operator [](Object? key) { if (!containsKey(key)) return null; return JS('', '#', _fetch(key)); } @@ -157,7 +164,7 @@ class ConstantProtoMap extends ConstantStringMap { final V _protoValue; - bool containsKey(Object key) { + bool containsKey(Object? key) { if (key is! String) return false; if ('__proto__' == key) return true; return jsHasOwnProperty(_jsObject, key); @@ -187,7 +194,7 @@ class GeneralConstantMap extends ConstantMap { // We cannot create the backing map on creation since hashCode interceptors // have not been defined when constants are created. Map _getMap() { - LinkedHashMap backingMap = JS('LinkedHashMap|Null', r'#.$map', this); + LinkedHashMap? backingMap = JS('LinkedHashMap|Null', r'#.$map', this); if (backingMap == null) { backingMap = new JsLinkedHashMap(); fillLiteralMap(_jsData, backingMap); @@ -196,15 +203,15 @@ class GeneralConstantMap extends ConstantMap { return backingMap; } - bool containsValue(Object needle) { + bool containsValue(Object? needle) { return _getMap().containsValue(needle); } - bool containsKey(Object key) { + bool containsKey(Object? key) { return _getMap().containsKey(key); } - V operator [](Object key) { + V? operator [](Object? key) { return _getMap()[key]; } diff --git a/sdk/lib/_internal/js_runtime/lib/convert_patch.dart b/sdk/lib/_internal/js_runtime/lib/convert_patch.dart index bcd9ef66a1e..d7dfb5f6102 100644 --- a/sdk/lib/_internal/js_runtime/lib/convert_patch.dart +++ b/sdk/lib/_internal/js_runtime/lib/convert_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // Patch file for dart:convert library. import 'dart:_js_helper' show argumentErrorValue, patch; @@ -28,7 +26,7 @@ import 'dart:_native_typed_data' show NativeUint8List; /// /// Throws [FormatException] if the input is not valid JSON text. @patch -_parseJson(String source, reviver(key, value)) { +_parseJson(String source, reviver(key, value)?) { if (source is! String) throw argumentErrorValue(source); var parsed; @@ -36,7 +34,7 @@ _parseJson(String source, reviver(key, value)) { parsed = JS('=Object|JSExtendableArray|Null|bool|num|String', 'JSON.parse(#)', source); } catch (e) { - throw new FormatException(JS('String', 'String(#)', e)); + throw FormatException(JS('String', 'String(#)', e)); } if (reviver == null) { @@ -49,20 +47,20 @@ _parseJson(String source, reviver(key, value)) { /// Walks the raw JavaScript value [json], replacing JavaScript Objects with /// Maps. [json] is expected to be freshly allocated so elements can be replaced /// in-place. -_convertJsonToDart(json, reviver(key, value)) { - assert(reviver != null); +_convertJsonToDart(json, reviver(Object? key, Object? value)) { walk(e) { // JavaScript null, string, number, bool are in the correct representation. - if (JS('bool', '# == null', e) || JS('bool', 'typeof # != "object"', e)) { + if (JS('bool', '# == null', e) || + JS('bool', 'typeof # != "object"', e)) { return e; } // This test is needed to avoid identifying '{"__proto__":[]}' as an Array. // TODO(sra): Replace this test with cheaper '#.constructor === Array' when // bug 621 below is fixed. - if (JS('bool', 'Object.getPrototypeOf(#) === Array.prototype', e)) { + if (JS('bool', 'Object.getPrototypeOf(#) === Array.prototype', e)) { // In-place update of the elements since JS Array is a Dart List. - for (int i = 0; i < JS('int', '#.length', e); i++) { + for (int i = 0; i < JS('int', '#.length', e); i++) { // Use JS indexing to avoid range checks. We know this is the only // reference to the list, but the compiler will likely never be able to // tell that this instance of the list cannot have its length changed by @@ -76,7 +74,7 @@ _convertJsonToDart(json, reviver(key, value)) { // Otherwise it is a plain object, so copy to a JSON map, so we process // and revive all entries recursively. - _JsonMap map = new _JsonMap(e); + _JsonMap map = _JsonMap(e); var processed = map._processed; List keys = map._computeKeys(); for (int i = 0; i < keys.length; i++) { @@ -98,19 +96,20 @@ _convertJsonToDartLazy(object) { if (object == null) return null; // JavaScript string, number, bool already has the correct representation. - if (JS('bool', 'typeof # != "object"', object)) { + if (JS('bool', 'typeof # != "object"', object)) { return object; } // This test is needed to avoid identifying '{"__proto__":[]}' as an array. // TODO(sra): Replace this test with cheaper '#.constructor === Array' when // bug https://code.google.com/p/v8/issues/detail?id=621 is fixed. - if (JS('bool', 'Object.getPrototypeOf(#) !== Array.prototype', object)) { - return new _JsonMap(object); + if (JS( + 'bool', 'Object.getPrototypeOf(#) !== Array.prototype', object)) { + return _JsonMap(object); } // Update the elements in place since JS arrays are Dart lists. - for (int i = 0; i < JS('int', '#.length', object); i++) { + for (int i = 0; i < JS('int', '#.length', object); i++) { // Use JS indexing to avoid range checks. We know this is the only // reference to the list, but the compiler will likely never be able to // tell that this instance of the list cannot have its length changed by @@ -157,12 +156,12 @@ class _JsonMap extends MapBase { Iterable get keys { if (_isUpgraded) return _upgradedMap.keys; - return new _JsonMapKeyIterable(this); + return _JsonMapKeyIterable(this); } Iterable get values { if (_isUpgraded) return _upgradedMap.values; - return new MappedIterable(_computeKeys(), (each) => this[each]); + return MappedIterable(_computeKeys(), (each) => this[each]); } operator []=(key, value) { @@ -209,7 +208,7 @@ class _JsonMap extends MapBase { return value; } - remove(Object key) { + remove(Object? key) { if (!_isUpgraded && !containsKey(key)) return null; return _upgrade().remove(key); } @@ -249,7 +248,7 @@ class _JsonMap extends MapBase { // Check if invoking the callback function changed // the key set. If so, throw an exception. if (!identical(keys, _data)) { - throw new ConcurrentModificationError(this); + throw ConcurrentModificationError(this); } } } @@ -270,7 +269,7 @@ class _JsonMap extends MapBase { List _computeKeys() { assert(!_isUpgraded); - List keys = _data; + List? keys = _data; if (keys == null) { keys = _data = new JSArray.typed(_getPropertyNames(_original)); } @@ -293,7 +292,7 @@ class _JsonMap extends MapBase { // safely force a concurrent modification error in case // someone is iterating over the map here. if (keys.isEmpty) { - keys.add(null); + keys.add(""); } else { keys.clear(); } @@ -316,15 +315,15 @@ class _JsonMap extends MapBase { // Private JavaScript helper methods. // ------------------------------------------ - static bool _hasProperty(object, String key) => - JS('bool', 'Object.prototype.hasOwnProperty.call(#,#)', object, key); + static bool _hasProperty(object, String key) => JS( + 'bool', 'Object.prototype.hasOwnProperty.call(#,#)', object, key); static _getProperty(object, String key) => JS('', '#[#]', object, key); static _setProperty(object, String key, value) => JS('', '#[#]=#', object, key, value); static List _getPropertyNames(object) => JS('JSExtendableArray', 'Object.keys(#)', object); static bool _isUnprocessed(object) => - JS('bool', 'typeof(#)=="undefined"', object); + JS('bool', 'typeof(#)=="undefined"', object); static _newJavaScriptObject() => JS('=Object', 'Object.create(null)'); } @@ -352,14 +351,14 @@ class _JsonMapKeyIterable extends ListIterable { /// Delegate to [parent.containsKey] to ensure the performance expected /// from [Map.keys.containsKey]. - bool contains(Object key) => _parent.containsKey(key); + bool contains(Object? key) => _parent.containsKey(key); } @patch class JsonDecoder { @patch - StringConversionSink startChunkedConversion(Sink sink) { - return new _JsonDecoderSink(_reviver, sink); + StringConversionSink startChunkedConversion(Sink sink) { + return _JsonDecoderSink(_reviver, sink); } } @@ -368,18 +367,17 @@ class JsonDecoder { /// /// The sink only creates one object, but its input can be chunked. // TODO(floitsch): don't accumulate everything before starting to decode. -class _JsonDecoderSink extends _StringSinkConversionSink { - final Function(Object key, Object value) _reviver; - final Sink _sink; +class _JsonDecoderSink extends _StringSinkConversionSink { + final Object? Function(Object? key, Object? value)? _reviver; + final Sink _sink; - _JsonDecoderSink(this._reviver, this._sink) : super(new StringBuffer('')); + _JsonDecoderSink(this._reviver, this._sink) : super(StringBuffer('')); void close() { super.close(); - StringBuffer buffer = _stringSink; - String accumulated = buffer.toString(); - buffer.clear(); - Object decoded = _parseJson(accumulated, _reviver); + String accumulated = _stringSink.toString(); + _stringSink.clear(); + Object? decoded = _parseJson(accumulated, _reviver); _sink.add(decoded); _sink.close(); } @@ -397,19 +395,20 @@ class Utf8Decoder { } @patch - static String _convertIntercepted( - bool allowMalformed, List codeUnits, int start, int end) { + static String? _convertIntercepted( + bool allowMalformed, List codeUnits, int start, int? end) { // Test `codeUnits is NativeUint8List`. Dart's NativeUint8List is // implemented by JavaScript's Uint8Array. - if (JS('bool', '# instanceof Uint8Array', codeUnits)) { + if (JS('bool', '# instanceof Uint8Array', codeUnits)) { // JS 'cast' to avoid a downcast equivalent to the is-check we hand-coded. - NativeUint8List casted = JS('NativeUint8List', '#', codeUnits); + NativeUint8List casted = + JS('NativeUint8List', '#', codeUnits); // Always use Dart implementation for short strings. end ??= casted.length; if (end - start < _shortInputThreshold) { return null; } - String result = + String? result = _convertInterceptedUint8List(allowMalformed, casted, start, end); if (result != null && allowMalformed) { // In principle, TextDecoder should have provided the correct result @@ -425,7 +424,7 @@ class Utf8Decoder { return null; // This call was not intercepted. } - static String _convertInterceptedUint8List( + static String? _convertInterceptedUint8List( bool allowMalformed, NativeUint8List codeUnits, int start, int end) { final decoder = allowMalformed ? _decoderNonfatal : _decoder; if (decoder == null) return null; @@ -436,16 +435,18 @@ class Utf8Decoder { int length = codeUnits.length; end = RangeError.checkValidRange(start, end, length); - return _useTextDecoder(decoder, - JS('NativeUint8List', '#.subarray(#, #)', codeUnits, start, end)); + return _useTextDecoder( + decoder, + JS( + 'NativeUint8List', '#.subarray(#, #)', codeUnits, start, end)); } - static String _useTextDecoder(decoder, NativeUint8List codeUnits) { + static String? _useTextDecoder(decoder, NativeUint8List codeUnits) { // If the input is malformed, catch the exception and return `null` to fall // back on unintercepted decoder. The fallback will either succeed in // decoding, or report the problem better than TextDecoder. try { - return JS('String', '#.decode(#)', decoder, codeUnits); + return JS('String', '#.decode(#)', decoder, codeUnits); } catch (e) {} return null; } @@ -472,12 +473,12 @@ class _Utf8Decoder { _Utf8Decoder(this.allowMalformed) : _state = beforeBom; @patch - String convertSingle(List codeUnits, int start, int maybeEnd) { + String convertSingle(List codeUnits, int start, int? maybeEnd) { return convertGeneral(codeUnits, start, maybeEnd, true); } @patch - String convertChunked(List codeUnits, int start, int maybeEnd) { + String convertChunked(List codeUnits, int start, int? maybeEnd) { return convertGeneral(codeUnits, start, maybeEnd, false); } } diff --git a/sdk/lib/_internal/js_runtime/lib/core_patch.dart b/sdk/lib/_internal/js_runtime/lib/core_patch.dart index 4a557d4d61f..6ffa92ea5fa 100644 --- a/sdk/lib/_internal/js_runtime/lib/core_patch.dart +++ b/sdk/lib/_internal/js_runtime/lib/core_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // Patch file for dart:core classes. import "dart:_internal" hide Symbol, LinkedList, LinkedListEntry; import "dart:_internal" as _symbol_dev; @@ -34,9 +32,10 @@ import "dart:convert" show Encoding, utf8; import 'dart:typed_data' show Endian, Uint8List, Uint16List; -String _symbolToString(Symbol symbol) => _symbol_dev.Symbol.getName(symbol); +String _symbolToString(Symbol symbol) => + _symbol_dev.Symbol.getName(symbol as _symbol_dev.Symbol); -Map _symbolMapToStringMap(Map map) { +Map? _symbolMapToStringMap(Map? map) { if (map == null) return null; var result = new Map(); map.forEach((Symbol key, value) { @@ -46,13 +45,13 @@ Map _symbolMapToStringMap(Map map) { } @patch -int identityHashCode(Object object) => objectHashCode(object); +int identityHashCode(Object? object) => objectHashCode(object); // Patch for Object implementation. @patch class Object { @patch - bool operator ==(other) => identical(this, other); + bool operator ==(Object other) => identical(this, other); @patch int get hashCode => Primitives.objectHashCode(this); @@ -80,8 +79,8 @@ class Null { @patch class Function { @patch - static apply(Function function, List positionalArguments, - [Map namedArguments]) { + static apply(Function function, List? positionalArguments, + [Map? namedArguments]) { return Primitives.applyFunction( function, positionalArguments, @@ -103,27 +102,27 @@ class Expando { final Object _jsWeakMapOrKey; @patch - Expando([String name]) + Expando([String? name]) : this.name = name, _jsWeakMapOrKey = JS('bool', 'typeof WeakMap == "function"') ? JS('=Object', 'new WeakMap()') : _createKey(); @patch - T operator [](Object object) { + T? operator [](Object object) { if (_jsWeakMapOrKey is! String) { _checkType(object); // WeakMap doesn't check on reading, only writing. return JS('', '#.get(#)', _jsWeakMapOrKey, object); } - return _getFromObject(_jsWeakMapOrKey, object); + return _getFromObject(_jsWeakMapOrKey as String, object) as T?; } @patch - void operator []=(Object object, T value) { + void operator []=(Object object, T? value) { if (_jsWeakMapOrKey is! String) { JS('void', '#.set(#, #)', _jsWeakMapOrKey, object, value); } else { - _setOnObject(_jsWeakMapOrKey, object, value); + _setOnObject(_jsWeakMapOrKey as String, object, value); } } @@ -132,7 +131,7 @@ class Expando { return (values == null) ? null : Primitives.getProperty(values, key); } - static void _setOnObject(String key, Object object, Object value) { + static void _setOnObject(String key, Object object, Object? value) { var values = Primitives.getProperty(object, _EXPANDO_PROPERTY_NAME); if (values == null) { values = new Object(); @@ -155,15 +154,15 @@ class Expando { class int { @patch static int parse(String source, - {int radix, @deprecated int onError(String source)}) { - int value = tryParse(source, radix: radix); + {int? radix, @deprecated int onError(String source)?}) { + int? value = tryParse(source, radix: radix); if (value != null) return value; if (onError != null) return onError(source); throw new FormatException(source); } @patch - static int tryParse(String source, {int radix}) { + static int? tryParse(String source, {int? radix}) { return Primitives.parseInt(source, radix); } } @@ -172,15 +171,15 @@ class int { class double { @patch static double parse(String source, - [@deprecated double onError(String source)]) { - double value = tryParse(source); + [@deprecated double onError(String source)?]) { + double? value = tryParse(source); if (value != null) return value; if (onError != null) return onError(source); throw new FormatException('Invalid double', source); } @patch - static double tryParse(String source) { + static double? tryParse(String source) { return Primitives.parseDouble(source); } } @@ -195,11 +194,11 @@ class BigInt implements Comparable { static BigInt get two => _BigIntImpl.two; @patch - static BigInt parse(String source, {int radix}) => + static BigInt parse(String source, {int? radix}) => _BigIntImpl.parse(source, radix: radix); @patch - static BigInt tryParse(String source, {int radix}) => + static BigInt? tryParse(String source, {int? radix}) => _BigIntImpl._tryParse(source, radix: radix); @patch @@ -221,7 +220,7 @@ class Error { } @patch - StackTrace get stackTrace => Primitives.extractStackTrace(this); + StackTrace? get stackTrace => Primitives.extractStackTrace(this); } @patch @@ -286,7 +285,7 @@ class DateTime { } @patch - static int _brokenDownDateToValue(int year, int month, int day, int hour, + static int? _brokenDownDateToValue(int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond, bool isUtc) { return Primitives.valueFromDecomposedDate( year, @@ -362,7 +361,7 @@ class DateTime { int get weekday => Primitives.getWeekday(this); @patch - bool operator ==(dynamic other) => + bool operator ==(Object other) => other is DateTime && _value == other.millisecondsSinceEpoch && isUtc == other.isUtc; @@ -386,9 +385,9 @@ class DateTime { @patch class Stopwatch { @patch - static void _initTicker() { + static int _initTicker() { Primitives.initTicker(); - _frequency = Primitives.timerFrequency; + return Primitives.timerFrequency; } @patch @@ -415,11 +414,11 @@ class Stopwatch { @patch class List { @patch - factory List([int length]) = JSArray.list; + factory List([int? length]) = JSArray.list; @patch factory List.filled(int length, E fill, {bool growable: false}) { - List result = growable + var result = growable ? new JSArray.growable(length) : new JSArray.fixed(length); if (length != 0 && fill != null) { @@ -433,6 +432,11 @@ class List { return result; } + @patch + factory List.empty({bool growable: false}) { + return growable ? new JSArray.growable(0) : new JSArray.fixed(0); + } + @patch factory List.from(Iterable elements, {bool growable: true}) { List list = []; @@ -449,9 +453,21 @@ class List { return List.from(elements, growable: growable); } + @patch + factory List.generate(int length, E generator(int index), + {bool growable = true}) { + final result = growable + ? new JSArray.growable(length) + : new JSArray.fixed(length); + for (int i = 0; i < length; i++) { + result[i] = generator(i); + } + return result; + } + @patch factory List.unmodifiable(Iterable elements) { - List result = new List.from(elements, growable: false); + var result = List.from(elements, growable: false); return makeFixedListUnmodifiable(result); } } @@ -469,9 +485,12 @@ class Map { class String { @patch factory String.fromCharCodes(Iterable charCodes, - [int start = 0, int end]) { + [int start = 0, int? end]) { if (charCodes is JSArray) { - JSArray array = charCodes; + // Type promotion doesn't work unless the check is `is JSArray`, + // which is more expensive. + // TODO(41383): Optimize `is JSArray` rather than do weird 'casts'. + JSArray array = JS('JSArray', '#', charCodes); return _stringFromJSArray(array, start, end); } if (charCodes is NativeUint8List) { @@ -485,24 +504,24 @@ class String { return Primitives.stringFromCharCode(charCode); } - static String _stringFromJSArray(List list, int start, int endOrNull) { + static String _stringFromJSArray(JSArray list, int start, int? endOrNull) { int len = list.length; int end = RangeError.checkValidRange(start, endOrNull, len); if (start > 0 || end < len) { - list = list.sublist(start, end); + list = JS('JSArray', '#.slice(#, #)', list, start, end); } return Primitives.stringFromCharCodes(list); } static String _stringFromUint8List( - NativeUint8List charCodes, int start, int endOrNull) { + NativeUint8List charCodes, int start, int? endOrNull) { int len = charCodes.length; int end = RangeError.checkValidRange(start, endOrNull, len); return Primitives.stringFromNativeUint8List(charCodes, start, end); } static String _stringFromIterable( - Iterable charCodes, int start, int end) { + Iterable charCodes, int start, int? end) { if (start < 0) throw new RangeError.range(start, 0, charCodes.length); if (end != null && end < start) { throw new RangeError.range(end, start, charCodes.length); @@ -557,7 +576,7 @@ class RegExp { @pragma( 'dart2js:noInline') // No inlining since we recognize the call in optimizer. @patch -bool identical(Object a, Object b) { +bool identical(Object? a, Object? b) { return JS('bool', '(# == null ? # == null : # === #)', a, b, a, b); } @@ -572,7 +591,7 @@ class StringBuffer { int get length => _contents.length; @patch - void write(Object obj) { + void write(Object? obj) { _writeString('$obj'); } @@ -582,12 +601,12 @@ class StringBuffer { } @patch - void writeAll(Iterable objects, [String separator = ""]) { + void writeAll(Iterable objects, [String separator = ""]) { _contents = _writeAll(_contents, objects, separator); } @patch - void writeln([Object obj = ""]) { + void writeln([Object? obj = ""]) { _writeString('$obj\n'); } @@ -599,7 +618,7 @@ class StringBuffer { @patch String toString() => Primitives.flattenString(_contents); - void _writeString(str) { + void _writeString(String str) { _contents = Primitives.stringConcatUnchecked(_contents, str); } @@ -620,28 +639,28 @@ class StringBuffer { return string; } - static String _writeOne(String string, Object obj) { + static String _writeOne(String string, Object? obj) { return Primitives.stringConcatUnchecked(string, '$obj'); } } @patch class NoSuchMethodError { - final Object _receiver; + final Object? _receiver; final Symbol _memberName; - final List _arguments; - final Map _namedArguments; - final List _existingArgumentNames; + final List? _arguments; + final Map? _namedArguments; + final List? _existingArgumentNames; @patch - NoSuchMethodError.withInvocation(Object receiver, Invocation invocation) + NoSuchMethodError.withInvocation(Object? receiver, Invocation invocation) : this(receiver, invocation.memberName, invocation.positionalArguments, invocation.namedArguments); @patch - NoSuchMethodError(Object receiver, Symbol memberName, - List positionalArguments, Map namedArguments, - [List existingArgumentNames = null]) + NoSuchMethodError(Object? receiver, Symbol memberName, + List? positionalArguments, Map? namedArguments, + [List? existingArgumentNames = null]) : _receiver = receiver, _memberName = memberName, _arguments = positionalArguments, @@ -650,17 +669,19 @@ class NoSuchMethodError { @patch String toString() { - StringBuffer sb = new StringBuffer(''); + StringBuffer sb = StringBuffer(''); String comma = ''; - if (_arguments != null) { - for (var argument in _arguments) { + var arguments = _arguments; + if (arguments != null) { + for (var argument in arguments) { sb.write(comma); sb.write(Error.safeToString(argument)); comma = ', '; } } - if (_namedArguments != null) { - _namedArguments.forEach((Symbol key, var value) { + var namedArguments = _namedArguments; + if (namedArguments != null) { + namedArguments.forEach((Symbol key, var value) { sb.write(comma); sb.write(_symbolToString(key)); sb.write(": "); @@ -671,12 +692,13 @@ class NoSuchMethodError { String memberName = _symbolToString(_memberName); String receiverText = Error.safeToString(_receiver); String actualParameters = '$sb'; - if (_existingArgumentNames == null) { + var existingArgumentNames = _existingArgumentNames; + if (existingArgumentNames == null) { return "NoSuchMethodError: method not found: '$memberName'\n" "Receiver: ${receiverText}\n" "Arguments: [$actualParameters]"; } else { - String formalParameters = _existingArgumentNames.join(', '); + String formalParameters = existingArgumentNames.join(', '); return "NoSuchMethodError: incorrect number of arguments passed to " "method named '$memberName'\n" "Receiver: ${receiverText}\n" @@ -697,7 +719,7 @@ class _CompileTimeError extends Error { class Uri { @patch static Uri get base { - String uri = Primitives.currentUri(); + String? uri = Primitives.currentUri(); if (uri != null) return Uri.parse(uri); throw new UnsupportedError("'Uri.base' is not supported"); } @@ -924,14 +946,14 @@ class _BigIntImpl implements BigInt { // Result cache for last _divRem call. // Result cache for last _divRem call. - static Uint16List _lastDividendDigits; - static int _lastDividendUsed; - static Uint16List _lastDivisorDigits; - static int _lastDivisorUsed; - static Uint16List _lastQuoRemDigits; - static int _lastQuoRemUsed; - static int _lastRemUsed; - static int _lastRem_nsh; + static Uint16List? _lastDividendDigits; + static int? _lastDividendUsed; + static Uint16List? _lastDivisorDigits; + static int? _lastDivisorUsed; + static late Uint16List _lastQuoRemDigits; + static late int _lastQuoRemUsed; + static late int _lastRemUsed; + static late int _lastRem_nsh; /// Whether this bigint is negative. final bool _isNegative; @@ -970,7 +992,7 @@ class _BigIntImpl implements BigInt { /// /// Throws a [FormatException] if the [source] is not a valid integer literal, /// optionally prefixed by a sign. - static _BigIntImpl parse(String source, {int radix}) { + static _BigIntImpl parse(String source, {int? radix}) { var result = _tryParse(source, radix: radix); if (result == null) { throw new FormatException("Could not parse BigInt", source); @@ -989,7 +1011,7 @@ class _BigIntImpl implements BigInt { // Read in the source 4 digits at a time. // The first part may have a few leading virtual '0's to make the remaining // parts all have exactly 4 digits. - int digitInPartCount = 4 - source.length.remainder(4); + var digitInPartCount = 4 - source.length.remainder(4); if (digitInPartCount == 4) digitInPartCount = 0; for (int i = 0; i < source.length; i++) { part = part * 10 + source.codeUnitAt(i) - _0; @@ -1031,7 +1053,7 @@ class _BigIntImpl implements BigInt { /// If [isNegative] is true, negates the result before returning it. /// /// The [source] (substring) must be a valid hex literal. - static _BigIntImpl _parseHex(String source, int startPos, bool isNegative) { + static _BigIntImpl? _parseHex(String source, int startPos, bool isNegative) { int hexDigitsPerChunk = _digitBits ~/ 4; int sourceLength = source.length - startPos; int chunkCount = (sourceLength / hexDigitsPerChunk).ceil(); @@ -1065,7 +1087,7 @@ class _BigIntImpl implements BigInt { /// /// The [source] will be checked for invalid characters. If it is invalid, /// this function returns `null`. - static _BigIntImpl _parseRadix(String source, int radix, bool isNegative) { + static _BigIntImpl? _parseRadix(String source, int radix, bool isNegative) { var result = zero; var base = new _BigIntImpl._fromInt(radix); for (int i = 0; i < source.length; i++) { @@ -1082,7 +1104,7 @@ class _BigIntImpl implements BigInt { /// Returns the parsed big integer, or `null` if it failed. /// /// If the [radix] is `null` accepts decimal literals or `0x` hex literals. - static _BigIntImpl _tryParse(String source, {int radix}) { + static _BigIntImpl? _tryParse(String source, {int? radix}) { if (source == "") return null; var match = _parseRE.firstMatch(source); @@ -1094,9 +1116,9 @@ class _BigIntImpl implements BigInt { bool isNegative = match[signIndex] == "-"; - String decimalMatch = match[decimalIndex]; - String hexMatch = match[hexIndex]; - String nonDecimalMatch = match[nonDecimalHexIndex]; + String? decimalMatch = match[decimalIndex]; + String? hexMatch = match[hexIndex]; + String? nonDecimalMatch = match[nonDecimalHexIndex]; if (radix == null) { if (decimalMatch != null) { @@ -1120,11 +1142,11 @@ class _BigIntImpl implements BigInt { return _parseDecimal(decimalMatch, isNegative); } if (radix == 16 && (decimalMatch != null || nonDecimalMatch != null)) { - return _parseHex(decimalMatch ?? nonDecimalMatch, 0, isNegative); + return _parseHex(decimalMatch ?? nonDecimalMatch!, 0, isNegative); } return _parseRadix( - decimalMatch ?? nonDecimalMatch ?? hexMatch, radix, isNegative); + decimalMatch ?? nonDecimalMatch ?? hexMatch!, radix, isNegative); } static RegExp _parseRE = RegExp( @@ -1173,7 +1195,7 @@ class _BigIntImpl implements BigInt { if (value.abs() < 0x100000000) return new _BigIntImpl._fromInt(value.toInt()); if (value is double) return new _BigIntImpl._fromDouble(value); - return new _BigIntImpl._fromInt(value); + return new _BigIntImpl._fromInt(value as int); } factory _BigIntImpl._fromInt(int value) { diff --git a/sdk/lib/_internal/js_runtime/lib/developer_patch.dart b/sdk/lib/_internal/js_runtime/lib/developer_patch.dart index 77b5c1a76fa..aff3f5572bb 100644 --- a/sdk/lib/_internal/js_runtime/lib/developer_patch.dart +++ b/sdk/lib/_internal/js_runtime/lib/developer_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // Patch file for dart:developer library. import 'dart:_js_helper' show patch, ForceInline; @@ -13,7 +11,7 @@ import 'dart:isolate'; @patch @pragma('dart2js:tryInline') -bool debugger({bool when: true, String message}) { +bool debugger({bool when = true, String? message}) { if (when) { JS('', 'debugger'); } @@ -21,26 +19,26 @@ bool debugger({bool when: true, String message}) { } @patch -Object inspect(Object object) { +Object? inspect(Object? object) { return object; } @patch void log(String message, - {DateTime time, - int sequenceNumber, - int level: 0, - String name: '', - Zone zone, - Object error, - StackTrace stackTrace}) { + {DateTime? time, + int? sequenceNumber, + int level = 0, + String name = '', + Zone? zone, + Object? error, + StackTrace? stackTrace}) { // TODO. } -final _extensions = new Map(); +final _extensions = {}; @patch -ServiceExtensionHandler _lookupExtension(String method) { +ServiceExtensionHandler? _lookupExtension(String method) { return _extensions[method]; } @@ -110,7 +108,7 @@ void _webServerControl(SendPort sendPort, bool enable) { } @patch -String _getIsolateIDFromSendPort(SendPort sendPort) { +String? _getIsolateIDFromSendPort(SendPort sendPort) { return null; } @@ -124,7 +122,7 @@ class UserTag { } class _FakeUserTag implements UserTag { - static Map _instances = {}; + static final _instances = {}; _FakeUserTag.real(this.label); @@ -136,13 +134,10 @@ class _FakeUserTag implements UserTag { } // Throw an exception if we've reached the maximum number of user tags. if (_instances.length == UserTag.MAX_USER_TAGS) { - throw new UnsupportedError( + throw UnsupportedError( 'UserTag instance limit (${UserTag.MAX_USER_TAGS}) reached.'); } - // Create a new instance and add it to the instance map. - var instance = new _FakeUserTag.real(label); - _instances[label] = instance; - return instance; + return _instances[label] = _FakeUserTag.real(label); } final String label; diff --git a/sdk/lib/_internal/js_runtime/lib/foreign_helper.dart b/sdk/lib/_internal/js_runtime/lib/foreign_helper.dart index 26bcf37cae3..88ca3d2a9e0 100644 --- a/sdk/lib/_internal/js_runtime/lib/foreign_helper.dart +++ b/sdk/lib/_internal/js_runtime/lib/foreign_helper.dart @@ -2,8 +2,6 @@ // 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.6 - library _foreign_helper; import 'dart:_js_embedded_names' show JsGetName, JsBuiltin; diff --git a/sdk/lib/_internal/js_runtime/lib/instantiation.dart b/sdk/lib/_internal/js_runtime/lib/instantiation.dart index cb8a9b185fa..da3fcbdef60 100644 --- a/sdk/lib/_internal/js_runtime/lib/instantiation.dart +++ b/sdk/lib/_internal/js_runtime/lib/instantiation.dart @@ -2,8 +2,6 @@ // 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.6 - part of _js_helper; /// Support class for generic function type instantiation (binding of types). diff --git a/sdk/lib/_internal/js_runtime/lib/interceptors.dart b/sdk/lib/_internal/js_runtime/lib/interceptors.dart index e0aa3973bf9..fc97282b896 100644 --- a/sdk/lib/_internal/js_runtime/lib/interceptors.dart +++ b/sdk/lib/_internal/js_runtime/lib/interceptors.dart @@ -2,8 +2,6 @@ // 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.6 - library _interceptors; import 'dart:_js_embedded_names' @@ -63,17 +61,6 @@ part 'js_string.dart'; final String DART_CLOSURE_PROPERTY_NAME = getIsolateAffinityTag(r'_$dart_dartClosure'); -String _symbolToString(Symbol symbol) => _symbol_dev.Symbol.getName(symbol); - -_symbolMapToStringMap(Map map) { - if (map == null) return null; - var result = new Map(); - map.forEach((Symbol key, value) { - result[_symbolToString(key)] = value; - }); - return result; -} - getDispatchProperty(object) { return JS( '', '#[#]', object, JS_EMBEDDED_GLOBAL('String', DISPATCH_PROPERTY_NAME)); @@ -123,7 +110,7 @@ makeDispatchRecord(interceptor, proto, extension, indexability) { dispatchRecordInterceptor(record) => JS('', '#.i', record); dispatchRecordProto(record) => JS('', '#.p', record); dispatchRecordExtension(record) => JS('', '#.e', record); -dispatchRecordIndexability(record) => JS('bool|Null', '#.x', record); +bool? dispatchRecordIndexability(record) => JS('bool|Null', '#.x', record); /// Returns the interceptor for a native class instance. Used by /// [getInterceptor]. @@ -197,7 +184,10 @@ getNativeInterceptor(object) { } // A JS String or Symbol. -final JS_INTEROP_INTERCEPTOR_TAG = getIsolateAffinityTag(r'_$dart_js'); +dynamic _JS_INTEROP_INTERCEPTOR_TAG = null; +get JS_INTEROP_INTERCEPTOR_TAG { + return _JS_INTEROP_INTERCEPTOR_TAG ??= getIsolateAffinityTag(r'_$dart_js'); +} lookupInterceptorByConstructor(constructor) { return constructor == null @@ -236,7 +226,7 @@ get typeToInterceptorMap { return JS_EMBEDDED_GLOBAL('', TYPE_TO_INTERCEPTOR_MAP); } -int findIndexForNativeSubclassType(Type type) { +int? findIndexForNativeSubclassType(Type? type) { if (JS('bool', '# == null', typeToInterceptorMap)) return null; List map = JS('JSFixedArray', '#', typeToInterceptorMap); for (int i = 0; i + 1 < map.length; i += 3) { @@ -247,7 +237,7 @@ int findIndexForNativeSubclassType(Type type) { return null; } -findInterceptorConstructorForType(Type type) { +findInterceptorConstructorForType(Type? type) { var index = findIndexForNativeSubclassType(type); if (index == null) return null; List map = JS('JSFixedArray', '#', typeToInterceptorMap); @@ -258,7 +248,7 @@ findInterceptorConstructorForType(Type type) { /// `null` if there is no such constructor. /// /// The returned function takes one argument, the web component object. -findConstructorForNativeSubclassType(Type type, String name) { +findConstructorForNativeSubclassType(Type? type, String name) { var index = findIndexForNativeSubclassType(type); if (index == null) return null; List map = JS('JSFixedArray', '#', typeToInterceptorMap); @@ -267,7 +257,7 @@ findConstructorForNativeSubclassType(Type type, String name) { return constructorFn; } -findInterceptorForType(Type type) { +findInterceptorForType(Type? type) { var constructor = findInterceptorConstructorForType(type); if (constructor == null) return null; return JS('', '#.prototype', constructor); diff --git a/sdk/lib/_internal/js_runtime/lib/internal_patch.dart b/sdk/lib/_internal/js_runtime/lib/internal_patch.dart index 7e3b4564029..e2922cade2e 100644 --- a/sdk/lib/_internal/js_runtime/lib/internal_patch.dart +++ b/sdk/lib/_internal/js_runtime/lib/internal_patch.dart @@ -2,15 +2,20 @@ // 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.6 - import 'dart:core' hide Symbol; -import 'dart:core' as core; +import 'dart:core' as core show Symbol; import 'dart:_js_primitives' show printString; -import 'dart:_js_helper' show patch, NoInline; +import 'dart:_js_helper' show patch; import 'dart:_interceptors' show JSArray; import 'dart:_foreign_helper' show JS, JS_GET_FLAG; +@patch +@pragma('dart2js:tryInline') +bool typeAcceptsNull() { + bool isLegacySubtyping = JS_GET_FLAG('LEGACY'); + return isLegacySubtyping || null is T; +} + @patch class Symbol implements core.Symbol { @patch @@ -18,7 +23,7 @@ class Symbol implements core.Symbol { @patch int get hashCode { - int hash = JS('int|Null', '#._hashCode', this); + int? hash = JS('int|Null', '#._hashCode', this); if (hash != null) return hash; const arbitraryPrime = 664597; hash = 0x1fffffff & (arbitraryPrime * _name.hashCode); diff --git a/sdk/lib/_internal/js_runtime/lib/io_patch.dart b/sdk/lib/_internal/js_runtime/lib/io_patch.dart index 13333189150..77a253027ff 100644 --- a/sdk/lib/_internal/js_runtime/lib/io_patch.dart +++ b/sdk/lib/_internal/js_runtime/lib/io_patch.dart @@ -2,8 +2,6 @@ // 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.6 - import 'dart:_js_helper' show patch; import 'dart:_internal' hide Symbol; import 'dart:async'; @@ -75,7 +73,7 @@ class _AsyncDirectoryListerOps { @patch class _EventHandler { @patch - static void _sendData(Object sender, SendPort sendPort, int data) { + static void _sendData(Object? sender, SendPort sendPort, int data) { throw new UnsupportedError("EventHandler._sendData"); } } @@ -305,7 +303,7 @@ class _Platform { @patch class _ProcessUtils { @patch - static void _exit(int status) { + static Never _exit(int status) { throw new UnsupportedError("ProcessUtils._exit"); } @@ -325,7 +323,7 @@ class _ProcessUtils { } @patch - static int _pid(Process process) { + static int _pid(Process? process) { throw new UnsupportedError("ProcessUtils._pid"); } @@ -352,8 +350,8 @@ class ProcessInfo { class Process { @patch static Future start(String executable, List arguments, - {String workingDirectory, - Map environment, + {String? workingDirectory, + Map? environment, bool includeParentEnvironment: true, bool runInShell: false, ProcessStartMode mode: ProcessStartMode.normal}) { @@ -362,8 +360,8 @@ class Process { @patch static Future run(String executable, List arguments, - {String workingDirectory, - Map environment, + {String? workingDirectory, + Map? environment, bool includeParentEnvironment: true, bool runInShell: false, Encoding stdoutEncoding: systemEncoding, @@ -373,8 +371,8 @@ class Process { @patch static ProcessResult runSync(String executable, List arguments, - {String workingDirectory, - Map environment, + {String? workingDirectory, + Map? environment, bool includeParentEnvironment: true, bool runInShell: false, Encoding stdoutEncoding: systemEncoding, @@ -411,13 +409,13 @@ class InternetAddress { } @patch - factory InternetAddress(String address, {InternetAddressType type}) { + factory InternetAddress(String address, {InternetAddressType? type}) { throw new UnsupportedError("InternetAddress"); } @patch factory InternetAddress.fromRawAddress(Uint8List rawAddress, - {InternetAddressType type}) { + {InternetAddressType? type}) { throw new UnsupportedError("InternetAddress.fromRawAddress"); } @@ -434,8 +432,8 @@ class InternetAddress { } @patch - static InternetAddress tryParse(String address) { - throw new UnsupportedError("InternetAddress.tryParse"); + static InternetAddress? tryParse(String address) { + throw UnsupportedError("InternetAddress.tryParse"); } } @@ -476,14 +474,14 @@ class ServerSocket { @patch class RawSocket { @patch - static Future connect(host, int port, - {sourceAddress, Duration timeout}) { + static Future connect(dynamic host, int port, + {dynamic sourceAddress, Duration? timeout}) { throw new UnsupportedError("RawSocket constructor"); } @patch - static Future> startConnect(host, int port, - {sourceAddress}) { + static Future> startConnect(dynamic host, int port, + {dynamic sourceAddress}) { throw new UnsupportedError("RawSocket constructor"); } } @@ -491,14 +489,14 @@ class RawSocket { @patch class Socket { @patch - static Future _connect(host, int port, - {sourceAddress, Duration timeout}) { + static Future _connect(dynamic host, int port, + {dynamic sourceAddress, Duration? timeout}) { throw new UnsupportedError("Socket constructor"); } @patch - static Future> _startConnect(host, int port, - {sourceAddress}) { + static Future> _startConnect(dynamic host, int port, + {dynamic sourceAddress}) { throw new UnsupportedError("Socket constructor"); } } @@ -514,7 +512,7 @@ class SecureSocket { @patch class RawSynchronousSocket { @patch - static RawSynchronousSocket connectSync(host, int port) { + static RawSynchronousSocket connectSync(dynamic host, int port) { throw new UnsupportedError("RawSynchronousSocket.connectSync"); } } @@ -556,7 +554,7 @@ class X509Certificate { @patch class RawDatagramSocket { @patch - static Future bind(host, int port, + static Future bind(dynamic host, int port, {bool reuseAddress: true, bool reusePort: false, int ttl: 1}) { throw new UnsupportedError("RawDatagramSocket.bind"); } @@ -618,14 +616,14 @@ class RawZLibFilter { int windowBits, int memLevel, int strategy, - List dictionary, + List? dictionary, bool raw) { throw new UnsupportedError("_newZLibDeflateFilter"); } @patch static RawZLibFilter _makeZLibInflateFilter( - int windowBits, List dictionary, bool raw) { + int windowBits, List? dictionary, bool raw) { throw new UnsupportedError("_newZLibInflateFilter"); } } diff --git a/sdk/lib/_internal/js_runtime/lib/isolate_patch.dart b/sdk/lib/_internal/js_runtime/lib/isolate_patch.dart index bb6363f4727..4c7f5c5f395 100644 --- a/sdk/lib/_internal/js_runtime/lib/isolate_patch.dart +++ b/sdk/lib/_internal/js_runtime/lib/isolate_patch.dart @@ -2,14 +2,12 @@ // 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.6 - // Patch file for the dart:isolate library. import "dart:async"; import 'dart:_foreign_helper' show JS; import 'dart:_js_helper' show patch; -import "dart:typed_data" show ByteData, TypedData, Uint8List; +import "dart:typed_data" show TypedData; @patch class Isolate { @@ -19,45 +17,46 @@ class Isolate { } @patch - String get debugName { + String? get debugName { throw new UnsupportedError("Isolate.debugName"); } @patch - static Future get packageRoot { + static Future get packageRoot { throw new UnsupportedError("Isolate.packageRoot"); } @patch - static Future get packageConfig { + static Future get packageConfig { throw new UnsupportedError("Isolate.packageConfig"); } @patch - static Future resolvePackageUri(Uri packageUri) { + static Future resolvePackageUri(Uri packageUri) { throw new UnsupportedError("Isolate.resolvePackageUri"); } @patch static Future spawn(void entryPoint(T message), T message, - {bool paused: false, - bool errorsAreFatal, - SendPort onExit, - SendPort onError}) { + {bool paused = false, + bool errorsAreFatal = true, + SendPort? onExit, + SendPort? onError}) { throw new UnsupportedError("Isolate.spawn"); } @patch static Future spawnUri(Uri uri, List args, var message, - {bool paused: false, - SendPort onExit, - SendPort onError, - bool errorsAreFatal, - bool checked, - Map environment, - Uri packageRoot, - Uri packageConfig, - bool automaticPackageResolution: false}) { + {bool paused = false, + SendPort? onExit, + SendPort? onError, + bool errorsAreFatal = true, + bool? checked, + Map? environment, + Uri? packageRoot, + Uri? packageConfig, + bool automaticPackageResolution = false, + String? debugName}) { throw new UnsupportedError("Isolate.spawnUri"); } @@ -72,7 +71,7 @@ class Isolate { } @patch - void addOnExitListener(SendPort responsePort, {Object response}) { + void addOnExitListener(SendPort responsePort, {Object? response}) { throw new UnsupportedError("Isolate.addOnExitListener"); } @@ -87,12 +86,13 @@ class Isolate { } @patch - void kill({int priority: beforeNextEvent}) { + void kill({int priority = beforeNextEvent}) { throw new UnsupportedError("Isolate.kill"); } @patch - void ping(SendPort responsePort, {Object response, int priority: immediate}) { + void ping(SendPort responsePort, + {Object? response, int priority = immediate}) { throw new UnsupportedError("Isolate.ping"); } @@ -119,8 +119,10 @@ class ReceivePort { } class _ReceivePortImpl extends Stream implements ReceivePort { - StreamSubscription listen(void onData(var event), - {Function onError, void onDone(), bool cancelOnError}) { + StreamSubscription listen(void Function(dynamic)? onData, + {Function? onError, + void Function()? onDone, + bool? cancelOnError = true}) { throw new UnsupportedError("ReceivePort.listen"); } @@ -132,7 +134,7 @@ class _ReceivePortImpl extends Stream implements ReceivePort { @patch class RawReceivePort { @patch - factory RawReceivePort([Function handler]) { + factory RawReceivePort([Function? handler]) { throw new UnsupportedError('new RawReceivePort'); } } diff --git a/sdk/lib/_internal/js_runtime/lib/js_array.dart b/sdk/lib/_internal/js_runtime/lib/js_array.dart index 7b92c3d062c..d13165860bb 100644 --- a/sdk/lib/_internal/js_runtime/lib/js_array.dart +++ b/sdk/lib/_internal/js_runtime/lib/js_array.dart @@ -2,8 +2,6 @@ // 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.6 - part of _interceptors; class _Growable { @@ -16,7 +14,7 @@ const _ListConstructorSentinel = const _Growable(); /// class as an interceptor, and changes references to [:this:] to /// actually use the receiver of the method, which is generated as an extra /// argument added to each member. -class JSArray extends Interceptor implements List, JSIndexable { +class JSArray extends Interceptor implements List, JSIndexable { const JSArray(); // This factory constructor is the redirection target of the List() factory @@ -82,7 +80,7 @@ class JSArray extends Interceptor implements List, JSIndexable { factory JSArray.markGrowable(allocation) => JS('JSExtendableArray', '#', new JSArray.typed(allocation)); - static List markFixedList(List list) { + static List markFixedList(List list) { // Functions are stored in the hidden class and not as properties in // the object. We never actually look at the value, but only want // to know if the property exists. @@ -90,7 +88,7 @@ class JSArray extends Interceptor implements List, JSIndexable { return JS('JSFixedArray', '#', list); } - static List markUnmodifiableList(List list) { + static List markUnmodifiableList(List list) { // Functions are stored in the hidden class and not as properties in // the object. We never actually look at the value, but only want // to know if the property exists. @@ -178,7 +176,7 @@ class JSArray extends Interceptor implements List, JSIndexable { return JS('', r'#.pop()', this); } - bool remove(Object element) { + bool remove(Object? element) { checkGrowable('remove'); for (int i = 0; i < this.length; i++) { if (this[i] == element) { @@ -266,7 +264,7 @@ class JSArray extends Interceptor implements List, JSIndexable { } String join([String separator = '']) { - var list = new List(this.length); + var list = List.filled(this.length, ""); for (int i = 0; i < this.length; i++) { list[i] = '${this[i]}'; } @@ -316,7 +314,7 @@ class JSArray extends Interceptor implements List, JSIndexable { return value; } - E firstWhere(bool test(E value), {E orElse()}) { + E firstWhere(bool Function(E) test, {E Function()? orElse}) { var end = this.length; for (int i = 0; i < end; ++i) { // TODO(22407): Improve bounds check elimination to allow this JS code to @@ -329,7 +327,7 @@ class JSArray extends Interceptor implements List, JSIndexable { throw IterableElementError.noElement(); } - E lastWhere(bool test(E element), {E orElse()}) { + E lastWhere(bool Function(E) test, {E Function()? orElse}) { int length = this.length; for (int i = length - 1; i >= 0; i--) { // TODO(22407): Improve bounds check elimination to allow this JS code to @@ -344,9 +342,9 @@ class JSArray extends Interceptor implements List, JSIndexable { throw IterableElementError.noElement(); } - E singleWhere(bool test(E element), {E orElse()}) { + E singleWhere(bool Function(E) test, {E Function()? orElse}) { int length = this.length; - E match = null; + E? match = null; bool matchFound = false; for (int i = 0; i < length; i++) { // TODO(22407): Improve bounds check elimination to allow this JS code to @@ -363,7 +361,7 @@ class JSArray extends Interceptor implements List, JSIndexable { throw new ConcurrentModificationError(this); } } - if (matchFound) return match; + if (matchFound) return match as E; if (orElse != null) return orElse(); throw IterableElementError.noElement(); } @@ -372,7 +370,7 @@ class JSArray extends Interceptor implements List, JSIndexable { return this[index]; } - List sublist(int start, [int end]) { + List sublist(int start, [int? end]) { checkNull(start); // TODO(ahe): This is not specified but co19 tests it. if (start is! int) throw argumentErrorValue(start); if (start < 0 || start > length) { @@ -431,7 +429,7 @@ class JSArray extends Interceptor implements List, JSIndexable { int otherStart; // TODO(floitsch): Make this accept more. if (iterable is List) { - otherList = iterable; + otherList = JS>('', '#', iterable); otherStart = skipCount; } else { otherList = iterable.skip(skipCount).toList(growable: false); @@ -459,12 +457,14 @@ class JSArray extends Interceptor implements List, JSIndexable { } } - void fillRange(int start, int end, [E fillValue]) { + void fillRange(int start, int end, [E? fillValue]) { checkMutable('fill range'); RangeError.checkValidRange(start, end, this.length); + E checkedFillValue = fillValue as E; for (int i = start; i < end; i++) { - // Store is safe since [fillValue] type has been checked as parameter. - JS('', '#[#] = #', this, i, fillValue); + // Store is safe since [checkedFillValue] type has been checked as + // parameter and for null. + JS('', '#[#] = #', this, i, checkedFillValue); } } @@ -521,18 +521,16 @@ class JSArray extends Interceptor implements List, JSIndexable { Iterable get reversed => new ReversedListIterable(this); - void sort([int compare(E a, E b)]) { + void sort([int Function(E, E)? compare]) { checkMutable('sort'); Sort.sort(this, compare ?? _compareAny); } static int _compareAny(a, b) { - // In strong mode Comparable.compare requires an implicit cast to ensure - // `a` and `b` are Comparable. return Comparable.compare(a, b); } - void shuffle([Random random]) { + void shuffle([Random? random]) { checkMutable('shuffle'); if (random == null) random = new Random(); int length = this.length; @@ -545,14 +543,15 @@ class JSArray extends Interceptor implements List, JSIndexable { } } - int indexOf(Object element, [int start = 0]) { - if (start >= this.length) { + int indexOf(Object? element, [int start = 0]) { + int length = this.length; + if (start >= length) { return -1; } if (start < 0) { start = 0; } - for (int i = start; i < this.length; i++) { + for (int i = start; i < length; i++) { if (this[i] == element) { return i; } @@ -560,18 +559,15 @@ class JSArray extends Interceptor implements List, JSIndexable { return -1; } - int lastIndexOf(Object element, [int startIndex]) { - if (startIndex == null) { - startIndex = this.length - 1; - } else { - if (startIndex < 0) { - return -1; - } - if (startIndex >= this.length) { - startIndex = this.length - 1; - } + int lastIndexOf(Object? element, [int? startIndex]) { + int start = startIndex ?? this.length - 1; + if (start < 0) { + return -1; } - for (int i = startIndex; i >= 0; i--) { + if (start >= this.length) { + start = this.length - 1; + } + for (int i = start; i >= 0; i--) { if (this[i] == element) { return i; } @@ -579,9 +575,10 @@ class JSArray extends Interceptor implements List, JSIndexable { return -1; } - bool contains(Object other) { + bool contains(Object? other) { for (int i = 0; i < length; i++) { - if (this[i] == other) return true; + E element = JS('', '#[#]', this, i); + if (element == other) return true; } return false; } @@ -646,13 +643,7 @@ class JSArray extends Interceptor implements List, JSIndexable { Iterable whereType() => new WhereTypeIterable(this); - List operator +(List other) { - int totalLength = this.length + other.length; - return [] - ..length = totalLength - ..setRange(0, this.length, this) - ..setRange(this.length, totalLength, other); - } + List operator +(List other) => [...this, ...other]; int indexWhere(bool test(E element), [int start = 0]) { if (start >= this.length) return -1; @@ -663,7 +654,7 @@ class JSArray extends Interceptor implements List, JSIndexable { return -1; } - int lastIndexWhere(bool test(E element), [int start]) { + int lastIndexWhere(bool test(E element), [int? start]) { if (start == null) start = this.length - 1; if (start < 0) return -1; for (int i = start; i >= 0; i--) { @@ -692,7 +683,7 @@ class JSArray extends Interceptor implements List, JSIndexable { /// 'isGrowable' and 'isMutable' checks into the getInterceptor implementation /// so these classes can have specialized implementations. Doing so will /// challenge many assumptions in the JS backend. -class JSMutableArray extends JSArray implements JSMutableIndexable {} +class JSMutableArray extends JSArray implements JSMutableIndexable {} class JSFixedArray extends JSMutableArray {} @@ -706,14 +697,14 @@ class ArrayIterator implements Iterator { final JSArray _iterable; final int _length; int _index; - E _current; + E? _current; ArrayIterator(JSArray iterable) : _iterable = iterable, _length = iterable.length, _index = 0; - E get current => _current; + E get current => _current as E; bool moveNext() { int length = _iterable.length; diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart index e2116a6f03e..db4ef1bed05 100644 --- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart +++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart @@ -2,8 +2,6 @@ // 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.6 - library _js_helper; import 'dart:_js_embedded_names' @@ -132,8 +130,8 @@ String rawRtiToJsConstructorName(Object rti) { /// Given a raw constructor name, return the unminified name, if available, /// otherwise tag the name with `minified:`. String unminifyOrTag(String rawClassName) { - String preserved = unmangleGlobalNameIfPreservedAnyways(rawClassName); - if (preserved is String) return preserved; + String? preserved = unmangleGlobalNameIfPreservedAnyways(rawClassName); + if (preserved != null) return preserved; if (JS_GET_FLAG('MINIFIED')) return 'minified:${rawClassName}'; return rawClassName; } @@ -396,7 +394,7 @@ class JSInvocationMirror implements Invocation { class Primitives { static int objectHashCode(object) { - int hash = JS('int|Null', r'#.$identityHash', object); + int? hash = JS('int|Null', r'#.$identityHash', object); if (hash == null) { hash = JS('int', '(Math.random() * 0x3fffffff) | 0'); JS('void', r'#.$identityHash = #', object, hash); @@ -404,7 +402,7 @@ class Primitives { return JS('int', '#', hash); } - static int parseInt(String source, int radix) { + static int? parseInt(String source, int? radix) { checkString(source); var re = JS('', r'/^\s*[+-]?((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$/i'); var match = JS('JSExtendableArray|Null', '#.exec(#)', re, source); @@ -417,7 +415,7 @@ class Primitives { // again. return null; } - String decimalMatch = match[decimalIndex]; + Object? decimalMatch = match[decimalIndex]; if (radix == null) { if (decimalMatch != null) { // Cannot fail because we know that the digits are all decimal. @@ -475,7 +473,7 @@ class Primitives { return JS('int', r'parseInt(#, #)', source, radix); } - static double parseDouble(String source) { + static double? parseDouble(String source) { checkString(source); // Notice that JS parseFloat accepts garbage at the end of the string. // Accept only: @@ -522,7 +520,7 @@ class Primitives { // instance (`const JSString()`, should use `JSString.prototype`). // // These all should have a `constructor` property with a `name` property. - String name; + String? name; var interceptorConstructor = JS('', '#.constructor', interceptor); if (JS('bool', 'typeof # == "function"', interceptorConstructor)) { var interceptorConstructorName = JS('', '#.name', interceptorConstructor); @@ -570,7 +568,7 @@ class Primitives { // Type inference does not understand that [name] is now always a non-null // String. (There is some imprecision in the negation of the disjunction.) - name = JS('String', '#', name); + name = JS('String', '#', name); // TODO(kasperl): If the namer gave us a fresh global name, we may // want to remove the numeric suffix that makes it unique too. @@ -637,10 +635,9 @@ class Primitives { static int dateNow() => JS('int', r'Date.now()'); static void initTicker() { - if (timerFrequency != null) return; + if (timerFrequency != 0) return; // Start with low-resolution. We overwrite the fields if we find better. timerFrequency = 1000; - timerTicks = dateNow; if (JS('bool', 'typeof window == "undefined"')) return; var window = JS('var', 'window'); if (window == null) return; @@ -651,10 +648,10 @@ class Primitives { timerTicks = () => (1000 * JS('num', '#.now()', performance)).floor(); } - static int timerFrequency; - static Function timerTicks; + static int timerFrequency = 0; + static int Function() timerTicks = dateNow; // Low-resolution version. - static String currentUri() { + static String? currentUri() { requiresPreamble(); // In a browser return self.location.href. if (JS('bool', '!!self.location')) { @@ -766,7 +763,7 @@ class Primitives { // Example: "Wed May 16 2012 21:13:00 GMT+0200 (CEST)". // We extract this name using a regexp. var d = lazyAsJsDate(receiver); - List match = JS('JSArray|Null', r'/\((.*)\)/.exec(#.toString())', d); + List? match = JS('JSArray|Null', r'/\((.*)\)/.exec(#.toString())', d); if (match != null) return match[1]; // Internet Explorer 10+ emits the zone name without parenthesis: @@ -799,10 +796,11 @@ class Primitives { static int getTimeZoneOffsetInMinutes(DateTime receiver) { // Note that JS and Dart disagree on the sign of the offset. // Subtract to avoid -0.0 - return 0 - JS('int', r'#.getTimezoneOffset()', lazyAsJsDate(receiver)); + return 0 - JS('int', r'#.getTimezoneOffset()', lazyAsJsDate(receiver)) + as int; } - static int valueFromDecomposedDate( + static int? valueFromDecomposedDate( years, month, day, hours, minutes, seconds, milliseconds, isUtc) { final int MAX_MILLISECONDS_SINCE_EPOCH = 8640000000000000; checkInt(years); @@ -957,8 +955,8 @@ class Primitives { JS('void', '#[#] = #', object, key, value); } - static functionNoSuchMethod( - function, List positionalArguments, Map namedArguments) { + static functionNoSuchMethod(function, List? positionalArguments, + Map? namedArguments) { int argumentCount = 0; List arguments = []; List namedArgumentList = []; @@ -1021,8 +1019,8 @@ class Primitives { /// instead. For example, if the catch-all property contains the string /// "call$4", then the object's "call$4" property should be used as if it was /// the value of the catch-all property. - static applyFunction(Function function, List positionalArguments, - Map namedArguments) { + static applyFunction(Function function, List? positionalArguments, + Map? namedArguments) { // Fast shortcut for the common case. if (JS('bool', '# instanceof Array', positionalArguments) && (namedArguments == null || namedArguments.isEmpty)) { @@ -1084,8 +1082,8 @@ class Primitives { function, positionalArguments, namedArguments); } - static _genericApplyFunction2(Function function, List positionalArguments, - Map namedArguments) { + static _genericApplyFunction2(Function function, List? positionalArguments, + Map? namedArguments) { List arguments; if (positionalArguments != null) { if (JS('bool', '# instanceof Array', positionalArguments)) { @@ -1169,7 +1167,11 @@ class Primitives { List keys = JS('JSArray', r'Object.keys(#)', defaultValues); if (namedArguments == null) { for (String key in keys) { - arguments.add(JS('var', '#[#]', defaultValues, key)); + var defaultValue = JS('var', '#[#]', defaultValues, key); + if (isRequired(defaultValue)) { + return functionNoSuchMethod(function, arguments, namedArguments); + } + arguments.add(defaultValue); } } else { int used = 0; @@ -1178,7 +1180,11 @@ class Primitives { used++; arguments.add(namedArguments[key]); } else { - arguments.add(JS('var', r'#[#]', defaultValues, key)); + var defaultValue = JS('var', '#[#]', defaultValues, key); + if (isRequired(defaultValue)) { + return functionNoSuchMethod(function, arguments, namedArguments); + } + arguments.add(defaultValue); } } if (used != namedArguments.length) { @@ -1554,7 +1560,7 @@ class TypeErrorDecoder { // Look for the special pattern \$camelCase\$ (all the $ symbols // have been escaped already), as we will soon be inserting // regular expression syntax that we want interpreted by RegExp. - List match = + List? match = JS('JSExtendableArray|Null', r'#.match(/\\\$[a-zA-Z]+\\\$/g)', message); if (match == null) match = []; @@ -1719,7 +1725,7 @@ class TypeErrorDecoder { class NullError extends Error implements NoSuchMethodError { final String _message; - final String _method; + final String? _method; NullError(this._message, match) : _method = match == null ? null : JS('', '#.method', match); @@ -1732,8 +1738,8 @@ class NullError extends Error implements NoSuchMethodError { class JsNoSuchMethodError extends Error implements NoSuchMethodError { final String _message; - final String _method; - final String _receiver; + final String? _method; + final String? _receiver; JsNoSuchMethodError(this._message, match) : _method = match == null ? null : JS('String|Null', '#.method', match), @@ -1758,6 +1764,18 @@ class UnknownJsTypeError extends Error { String toString() => _message.isEmpty ? 'Error' : 'Error: $_message'; } +class NullThrownFromJavaScriptException implements Exception { + final dynamic _irritant; + NullThrownFromJavaScriptException(this._irritant); + + @override + String toString() { + String description = + JS('bool', '# === null', _irritant) ? 'null' : 'undefined'; + return "Throw of null ('$description' from JavaScript)"; + } +} + /// A wrapper around an exception, much like the one created by [wrapException] /// but with a pre-given stack-trace. class ExceptionAndStackTrace { @@ -1767,40 +1785,49 @@ class ExceptionAndStackTrace { ExceptionAndStackTrace(this.dartException, this.stackTrace); } -/// Called from catch blocks in generated code to extract the Dart -/// exception from the thrown value. The thrown value may have been -/// created by [wrapException] or it may be a 'native' JS exception. +/// Called from catch blocks in generated code to extract the Dart exception +/// from the thrown value. The thrown value may have been created by +/// [wrapException] or it may be a 'native' JavaScript exception. /// /// Some native exceptions are mapped to new Dart instances, others are /// returned unmodified. -unwrapException(ex) { - /// If error implements Error, save [ex] in [error.$thrownJsError]. - /// Otherwise, do nothing. Later, the stack trace can then be extracted from - /// [ex]. - saveStackTrace(error) { - if (error is Error) { - var thrownStackTrace = JS('', r'#.$thrownJsError', error); - if (thrownStackTrace == null) { - JS('void', r'#.$thrownJsError = #', error, ex); - } - } - return error; +Object unwrapException(Object? ex) { + // Dart converts `null` to `NullThrownError()`. JavaScript can still throw a + // nullish value. + if (ex == null) { + return NullThrownFromJavaScriptException(ex); } - // Note that we are checking if the object has the property. If it - // has, it could be set to null if the thrown value is null. - if (ex == null) return null; if (ex is ExceptionAndStackTrace) { - return saveStackTrace(ex.dartException); + return saveStackTrace(ex, ex.dartException); } + + // e.g. a primitive value thrown by JavaScript. if (JS('bool', 'typeof # !== "object"', ex)) return ex; if (JS('bool', r'"dartException" in #', ex)) { - return saveStackTrace(JS('', r'#.dartException', ex)); - } else if (!JS('bool', r'"message" in #', ex)) { + return saveStackTrace(ex, JS('', r'#.dartException', ex)); + } + return _unwrapNonDartException(ex); +} + +/// If error implements Dart [Error], save [ex] in [error.$thrownJsError]. +/// Otherwise, do nothing. Later, the stack trace can then be extracted from +/// [ex]. +Object saveStackTrace(Object ex, Object error) { + if (error is Error) { + var thrownStackTrace = JS('', r'#.$thrownJsError', error); + if (thrownStackTrace == null) { + JS('void', r'#.$thrownJsError = #', error, ex); + } + } + return error; +} + +Object _unwrapNonDartException(Object ex) { + if (!JS('bool', r'"message" in #', ex)) { return ex; } - // Grab hold of the exception message. This field is available on // all supported browsers. var message = JS('var', r'#.message', ex); @@ -1823,19 +1850,17 @@ unwrapException(ex) { switch (ieErrorCode) { case 438: return saveStackTrace( - new JsNoSuchMethodError('$message (Error $ieErrorCode)', null)); + ex, JsNoSuchMethodError('$message (Error $ieErrorCode)', null)); case 445: case 5007: return saveStackTrace( - new NullError('$message (Error $ieErrorCode)', null)); + ex, NullError('$message (Error $ieErrorCode)', null)); } } } if (JS('bool', r'# instanceof TypeError', ex)) { var match; - // Using JS to give type hints to the compiler to help tree-shaking. - // TODO(ahe): That should be unnecessary due to type inference. var nsme = TypeErrorDecoder.noSuchMethodPattern; var notClosure = TypeErrorDecoder.notClosurePattern; var nullCall = TypeErrorDecoder.nullCallPattern; @@ -1847,14 +1872,14 @@ unwrapException(ex) { var undefProperty = TypeErrorDecoder.undefinedPropertyPattern; var undefLiteralProperty = TypeErrorDecoder.undefinedLiteralPropertyPattern; if ((match = nsme.matchTypeError(message)) != null) { - return saveStackTrace(new JsNoSuchMethodError(message, match)); + return saveStackTrace(ex, JsNoSuchMethodError(message, match)); } else if ((match = notClosure.matchTypeError(message)) != null) { // notClosure may match "({c:null}).c()" or "({c:1}).c()", so we // cannot tell if this an attempt to invoke call on null or a // non-function object. // But we do know the method name is "call". JS('', '#.method = "call"', match); - return saveStackTrace(new JsNoSuchMethodError(message, match)); + return saveStackTrace(ex, JsNoSuchMethodError(message, match)); } else if ((match = nullCall.matchTypeError(message)) != null || (match = nullLiteralCall.matchTypeError(message)) != null || (match = undefCall.matchTypeError(message)) != null || @@ -1863,19 +1888,19 @@ unwrapException(ex) { (match = nullLiteralCall.matchTypeError(message)) != null || (match = undefProperty.matchTypeError(message)) != null || (match = undefLiteralProperty.matchTypeError(message)) != null) { - return saveStackTrace(new NullError(message, match)); + return saveStackTrace(ex, NullError(message, match)); } // If we cannot determine what kind of error this is, we fall back // to reporting this as a generic error. It's probably better than // nothing. return saveStackTrace( - new UnknownJsTypeError(message is String ? message : '')); + ex, UnknownJsTypeError(message is String ? message : '')); } if (JS('bool', r'# instanceof RangeError', ex)) { if (message is String && contains(message, 'call stack')) { - return new StackOverflowError(); + return StackOverflowError(); } // In general, a RangeError is thrown when trying to pass a number as an @@ -1886,7 +1911,7 @@ unwrapException(ex) { if (message is String) { message = JS('String', r'#.replace(/^RangeError:\s*/, "")', message); } - return saveStackTrace(new ArgumentError(message)); + return saveStackTrace(ex, ArgumentError(message)); } // Check for the Firefox specific stack overflow signal. @@ -1895,17 +1920,17 @@ unwrapException(ex) { r'typeof InternalError == "function" && # instanceof InternalError', ex)) { if (message is String && message == 'too much recursion') { - return new StackOverflowError(); + return StackOverflowError(); } } - // Just return the exception. We should not wrap it because in case - // the exception comes from the DOM, it is a JavaScript - // object backed by a native Dart class. + // Just return the exception. We should not wrap it because in case the + // exception comes from the DOM, it is a JavaScript object that has a Dart + // interceptor. return ex; } -String tryStringifyException(ex) { +String? tryStringifyException(ex) { // Since this function is called from [unwrapException] which is called from // code injected into a catch-clause, use JavaScript try-catch to avoid a // potential loop if stringifying crashes. @@ -1929,7 +1954,7 @@ StackTrace getTraceFromException(exception) { return exception.stackTrace; } if (exception == null) return new _StackTrace(exception); - _StackTrace trace = JS('_StackTrace|Null', r'#.$cachedTrace', exception); + _StackTrace? trace = JS('_StackTrace|Null', r'#.$cachedTrace', exception); if (trace != null) return trace; trace = new _StackTrace(exception); return JS('_StackTrace', r'#.$cachedTrace = #', exception, trace); @@ -1937,13 +1962,13 @@ StackTrace getTraceFromException(exception) { class _StackTrace implements StackTrace { var _exception; - String _trace; + String? _trace; _StackTrace(this._exception); String toString() { if (_trace != null) return JS('String', '#', _trace); - String trace; + String? trace; if (JS('bool', '# !== null', _exception) && JS('bool', 'typeof # === "object"', _exception)) { trace = JS('String|Null', r'#.stack', _exception); @@ -2074,7 +2099,7 @@ abstract class Closure implements Function { static fromTearOff( receiver, List functions, - int applyTrampolineIndex, + int? applyTrampolineIndex, var reflectionInfo, bool isStatic, bool isIntercepted, @@ -2095,8 +2120,8 @@ abstract class Closure implements Function { // TODO(ahe): All the place below using \$ should be rewritten to go // through the namer. var function = JS('', '#[#]', functions, 0); - String name = JS('String|Null', '#.\$stubName', function); - String callName = JS('String|Null', '#[#]', function, + String? name = JS('String|Null', '#.\$stubName', function); + String? callName = JS('String|Null', '#[#]', function, JS_GET_NAME(JsGetName.CALL_NAME_PROPERTY)); // This variable holds either an index into the types-table, or a function @@ -2134,7 +2159,7 @@ abstract class Closure implements Function { ? JS('StaticClosure', 'Object.create(#.constructor.prototype)', new StaticClosure()) : JS('BoundClosure', 'Object.create(#.constructor.prototype)', - new BoundClosure(null, null, null, null)); + new BoundClosure(null, null, null, '')); JS('', '#.\$initialize = #', prototype, JS('', '#.constructor', prototype)); @@ -2278,7 +2303,7 @@ abstract class Closure implements Function { } static cspForwardCall( - int arity, bool isSuperCall, String stubName, function) { + int arity, bool isSuperCall, String? stubName, function) { var getSelf = RAW_DART_FUNCTION_REF(BoundClosure.selfOf); // Handle intercepted stub-names with the default slow case. if (isSuperCall) arity = -1; @@ -2360,7 +2385,7 @@ abstract class Closure implements Function { static forwardCallTo(receiver, function, bool isIntercepted) { if (isIntercepted) return forwardInterceptedCallTo(receiver, function); - String stubName = JS('String|Null', '#.\$stubName', function); + String? stubName = JS('String|Null', '#.\$stubName', function); int arity = JS('int', '#.length', function); var lookedUpFunction = JS('', '#[#]', receiver, stubName); // The receiver[stubName] may not be equal to the function if we try to @@ -2397,7 +2422,7 @@ abstract class Closure implements Function { } static cspForwardInterceptedCall( - int arity, bool isSuperCall, String name, function) { + int arity, bool isSuperCall, String? name, function) { var getSelf = RAW_DART_FUNCTION_REF(BoundClosure.selfOf); var getReceiver = RAW_DART_FUNCTION_REF(BoundClosure.receiverOf); // Handle intercepted stub-names with the default slow case. @@ -2492,7 +2517,7 @@ abstract class Closure implements Function { static forwardInterceptedCallTo(receiver, function) { String selfField = BoundClosure.selfFieldName(); String receiverField = BoundClosure.receiverFieldName(); - String stubName = JS('String|Null', '#.\$stubName', function); + String? stubName = JS('String|Null', '#.\$stubName', function); int arity = JS('int', '#.length', function); bool isCsp = JS_GET_FLAG('USE_CONTENT_SECURITY_POLICY'); var lookedUpFunction = JS('', '#[#]', receiver, stubName); @@ -2537,7 +2562,7 @@ abstract class Closure implements Function { // to be visible to resolution and the generation of extra stubs. String toString() { - String name; + String? name; var constructor = JS('', '#.constructor', this); name = constructor == null ? null : JS('String|Null', '#.name', constructor); @@ -2564,7 +2589,7 @@ abstract class TearOffClosure extends Closure {} class StaticClosure extends TearOffClosure { String toString() { - String name = + String? name = JS('String|Null', '#[#]', this, STATIC_FUNCTION_NAME_PROPERTY_NAME); if (name == null) return 'Closure of unknown static method'; return "Closure '${unminifyOrTag(name)}'"; @@ -2642,22 +2667,22 @@ class BoundClosure extends TearOffClosure { static nameOf(BoundClosure closure) => closure._name; - static String selfFieldNameCache; + static String? selfFieldNameCache; static String selfFieldName() { if (selfFieldNameCache == null) { selfFieldNameCache = computeFieldNamed('self'); } - return selfFieldNameCache; + return selfFieldNameCache!; } - static String receiverFieldNameCache; + static String? receiverFieldNameCache; static String receiverFieldName() { if (receiverFieldNameCache == null) { receiverFieldNameCache = computeFieldNamed('receiver'); } - return receiverFieldNameCache; + return receiverFieldNameCache!; } @pragma('dart2js:noInline') @@ -2672,6 +2697,7 @@ class BoundClosure extends TearOffClosure { return JS('String', '#', name); } } + throw new ArgumentError("Field name $fieldName not found."); } } @@ -2768,7 +2794,7 @@ class JSName { /// The following methods are called by the runtime to implement checked mode /// and casts. We specialize each primitive type (eg int, bool), and use the /// compiler's convention to do is-checks on regular objects. -boolConversionCheck(value) { +bool boolConversionCheck(value) { // The value from kernel should always be true, false, or null. if (value == null) assertThrow('boolean expression must not be null'); return JS('bool', '#', value); @@ -2797,7 +2823,6 @@ class FallThroughErrorImplementation extends FallThroughError { /// Returns the negation of the condition. That is: `true` if the assert should /// fail. bool assertTest(condition) { - // Do bool success check first as it is common. if (true == condition) return false; if (false == condition) return true; bool checked = condition as bool; @@ -2824,8 +2849,8 @@ void assertHelper(condition) { /// resolved cannot be found. void throwNoSuchMethod(obj, name, arguments, expectedArgumentNames) { Symbol memberName = new _symbol_dev.Symbol.unvalidated(name); - throw new NoSuchMethodError(obj, memberName, arguments, - new Map(), expectedArgumentNames); + throw new NoSuchMethodError( + obj, memberName, arguments, new Map()); } /// Called by generated code when a static field's initializer references the @@ -2892,7 +2917,7 @@ LoadLibraryFunctionType _loadLibraryWrapper(String loadId) { return () => loadDeferredLibrary(loadId); } -final Map> _loadingLibraries = >{}; +final Map?> _loadingLibraries = ?>{}; final Set _loadedLibraries = new Set(); /// Events used to diagnose failures from deferred loading requests. @@ -2901,14 +2926,14 @@ final List _eventLog = []; typedef void DeferredLoadCallback(); // Function that will be called every time a new deferred import is loaded. -DeferredLoadCallback deferredLoadHook; +DeferredLoadCallback? deferredLoadHook; Future loadDeferredLibrary(String loadId) { // For each loadId there is a list of parts to load. The parts are represented // by an index. There are two arrays, one that maps the index into a Uri and // another that maps the index to a hash. var partsMap = JS_EMBEDDED_GLOBAL('', DEFERRED_LIBRARY_PARTS); - List indexes = JS('JSExtendableArray|Null', '#[#]', partsMap, loadId); + List? indexes = JS('JSExtendableArray|Null', '#[#]', partsMap, loadId); if (indexes == null) return new Future.value(null); List uris = []; List hashes = []; @@ -2966,7 +2991,7 @@ Future loadDeferredLibrary(String loadId) { waitingForLoad[i] = false; return new Future.value(); } - return _loadHunk(uris[i]).then((_) { + return _loadHunk(uris[i]).then((Null _) { waitingForLoad[i] = false; initializeSomeLoadedHunks(); }); @@ -2979,27 +3004,27 @@ Future loadDeferredLibrary(String loadId) { assert(nextHunkToInitialize == total); bool updated = _loadedLibraries.add(loadId); if (updated && deferredLoadHook != null) { - deferredLoadHook(); + deferredLoadHook!(); } }); } /// The `nonce` value on the current script used for strict-CSP, if any. -String _cspNonce = _computeCspNonce(); +String? _cspNonce = _computeCspNonce(); -String _computeCspNonce() { +String? _computeCspNonce() { var currentScript = JS_EMBEDDED_GLOBAL('', CURRENT_SCRIPT); if (currentScript == null) return null; - String nonce = JS('String|Null', '#.nonce', currentScript); + String? nonce = JS('String|Null', '#.nonce', currentScript); return (nonce != null && nonce != '') ? nonce : JS('String|Null', '#.getAttribute("nonce")', currentScript); } /// The 'crossOrigin' value on the current script used for CORS, if any. -String _crossOrigin = _computeCrossOrigin(); +String? _crossOrigin = _computeCrossOrigin(); -String _computeCrossOrigin() { +String? _computeCrossOrigin() { var currentScript = JS_EMBEDDED_GLOBAL('', CURRENT_SCRIPT); if (currentScript == null) return null; return JS('String|Null', '#.crossOrigin', currentScript); @@ -3012,12 +3037,12 @@ bool _isWorker() { } /// The src url for the script tag that loaded this code. -String thisScript = _computeThisScript(); +String? thisScript = _computeThisScript(); /// The src url for the script tag that loaded this function. /// /// Used to create JavaScript workers and load deferred libraries. -String _computeThisScript() { +String? _computeThisScript() { var currentScript = JS_EMBEDDED_GLOBAL('', CURRENT_SCRIPT); if (currentScript != null) { return JS('String', 'String(#.src)', currentScript); @@ -3064,14 +3089,14 @@ String _computeThisScriptFromTrace() { } Future _loadHunk(String hunkName) { - Future future = _loadingLibraries[hunkName]; + var future = _loadingLibraries[hunkName]; _eventLog.add(' - _loadHunk: $hunkName'); if (future != null) { _eventLog.add('reuse: $hunkName'); - return future.then((_) => null); + return future.then((Null _) => null); } - String uri = thisScript; + String uri = thisScript!; int index = uri.lastIndexOf('/'); uri = '${uri.substring(0, index + 1)}$hunkName'; @@ -3085,7 +3110,7 @@ Future _loadHunk(String hunkName) { completer.complete(null); } - void failure(error, String context, StackTrace stackTrace) { + void failure(error, String context, StackTrace? stackTrace) { _eventLog.add(' - download failed: $hunkName (context: $context)'); _loadingLibraries[hunkName] = null; stackTrace ??= StackTrace.current; @@ -3223,3 +3248,6 @@ String testingGetPlatformEnvironmentVariable() { class _Required { const _Required(); } + +const kRequiredSentinel = const _Required(); +bool isRequired(Object? value) => identical(kRequiredSentinel, value); diff --git a/sdk/lib/_internal/js_runtime/lib/js_names.dart b/sdk/lib/_internal/js_runtime/lib/js_names.dart index 767eced6e36..10efacf5aeb 100644 --- a/sdk/lib/_internal/js_runtime/lib/js_names.dart +++ b/sdk/lib/_internal/js_runtime/lib/js_names.dart @@ -2,8 +2,6 @@ // 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.6 - library dart._js_names; import 'dart:_js_embedded_names' @@ -50,7 +48,7 @@ class _LazyMangledNamesMap { _LazyMangledNamesMap(this._jsMangledNames); - String operator [](String key) { + String? operator [](String key) { var result = JS('var', '#[#]', _jsMangledNames, key); // Filter out all non-string values to protect against polution from // ancillary fields in [_jsMangledNames]. @@ -67,8 +65,8 @@ class _LazyMangledNamesMap { class _LazyMangledInstanceNamesMap extends _LazyMangledNamesMap { _LazyMangledInstanceNamesMap(_jsMangledNames) : super(_jsMangledNames); - String operator [](String key) { - String result = super[key]; + String? operator [](String key) { + String? result = super[key]; String setterPrefix = JS_GET_NAME(JsGetName.SETTER_PREFIX); if (result == null && key.startsWith(setterPrefix)) { String getterPrefix = JS_GET_NAME(JsGetName.GETTER_PREFIX); @@ -96,7 +94,7 @@ class _LazyReflectiveNamesMap { final _jsMangledNames; final bool _isInstance; int _cacheLength = 0; - Map _cache; + Map? _cache; _LazyReflectiveNamesMap(this._jsMangledNames, this._isInstance); @@ -126,12 +124,12 @@ class _LazyReflectiveNamesMap { int get _jsMangledNamesLength => JS('int', 'Object.keys(#).length', _jsMangledNames); - String operator [](String key) { + String? operator [](String key) { if (_cache == null || _jsMangledNamesLength != _cacheLength) { _cache = _updateReflectiveNames(); _cacheLength = _jsMangledNamesLength; } - return _cache[key]; + return _cache![key]; } } @@ -150,7 +148,7 @@ List extractKeys(victim) { /// This is used, for example, to return unmangled names from TypeImpl.toString /// *if* names are being preserved for other reasons (use of dart:mirrors, for /// example). -String unmangleGlobalNameIfPreservedAnyways(String name) { +String? unmangleGlobalNameIfPreservedAnyways(String name) { var names = JS_EMBEDDED_GLOBAL('', MANGLED_GLOBAL_NAMES); return JS('String|Null', '#', JsCache.fetch(names, name)); } diff --git a/sdk/lib/_internal/js_runtime/lib/js_number.dart b/sdk/lib/_internal/js_runtime/lib/js_number.dart index 610312b6348..489da646dea 100644 --- a/sdk/lib/_internal/js_runtime/lib/js_number.dart +++ b/sdk/lib/_internal/js_runtime/lib/js_number.dart @@ -2,8 +2,6 @@ // 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.6 - part of _interceptors; /// The super interceptor class for [JSInt] and [JSDouble]. The compiler @@ -68,7 +66,7 @@ class JSNumber extends Interceptor implements double { r'Math.abs(#)', this); - JSNumber get sign => this > 0 ? 1 : this < 0 ? -1 : this; + JSNumber get sign => (this > 0 ? 1 : this < 0 ? -1 : this) as JSNumber; static const int _MIN_INT32 = -0x80000000; static const int _MAX_INT32 = 0x7FFFFFFF; @@ -183,7 +181,7 @@ class JSNumber extends Interceptor implements double { return result; } - String toStringAsExponential([int fractionDigits]) { + String toStringAsExponential([int? fractionDigits]) { String result; if (fractionDigits != null) { checkInt(fractionDigits); @@ -234,7 +232,7 @@ class JSNumber extends Interceptor implements double { int exponent = JS('int', '+#', match[3]); if (match[2] != null) { result = JS('String', '# + #', result, match[2]); - exponent -= JS('int', '#.length', match[2]); + exponent -= JS('int', '#.length', match[2]); } return result + '0' * exponent; } @@ -308,13 +306,13 @@ class JSNumber extends Interceptor implements double { JSNumber operator %(num other) { if (other is! num) throw argumentErrorValue(other); // Euclidean Modulo. - num result = JS('num', r'# % #', this, other); + JSNumber result = JS('JSNumber', r'# % #', this, other); if (result == 0) return JS('num', '0'); // Make sure we don't return -0.0. if (result > 0) return result; if (JS('num', '#', other) < 0) { - return result - JS('num', '#', other); + return result - JS('JSNumber', '#', other); } else { - return result + JS('num', '#', other); + return result + JS('JSNumber', '#', other); } } @@ -469,7 +467,7 @@ class JSInt extends JSNumber implements int { this); @override - JSInt get sign => this > 0 ? 1 : this < 0 ? -1 : this; + JSInt get sign => (this > 0 ? 1 : this < 0 ? -1 : this) as JSInt; @override JSInt operator -() => JS('int', r'-#', this); @@ -488,7 +486,7 @@ class JSInt extends JSNumber implements int { } int get bitLength { - JSInt nonneg = this < 0 ? -this - 1 : this; + int nonneg = (this < 0 ? -this - 1 : this) as int; int wordBits = 32; while (nonneg >= 0x100000000) { nonneg = nonneg ~/ 0x100000000; diff --git a/sdk/lib/_internal/js_runtime/lib/js_patch.dart b/sdk/lib/_internal/js_runtime/lib/js_patch.dart index ab4a3328f6a..1ff2e550b21 100644 --- a/sdk/lib/_internal/js_runtime/lib/js_patch.dart +++ b/sdk/lib/_internal/js_runtime/lib/js_patch.dart @@ -2,21 +2,19 @@ // 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.6 - // Patch file for dart:js library. import 'dart:collection' show HashMap, ListMixin; import 'dart:typed_data' show TypedData; import 'dart:_foreign_helper' show JS, DART_CLOSURE_TO_JS; -import 'dart:_interceptors' show JavaScriptFunction, DART_CLOSURE_PROPERTY_NAME; +import 'dart:_interceptors' show DART_CLOSURE_PROPERTY_NAME; import 'dart:_js_helper' show patch, Primitives, getIsolateAffinityTag; import 'dart:_js' show isBrowserObject, convertFromBrowserObject; @patch JsObject get context => _context; -final JsObject _context = _wrapToDart(JS('', 'self')); +final JsObject _context = _castToJsObject(_wrapToDart(JS('', 'self'))); _convertDartFunction(Function f, {bool captureThis: false}) { return JS( @@ -45,7 +43,7 @@ _callDartFunction(callback, bool captureThis, self, List arguments) { @patch class JsObject { // The wrapped JS object. - final dynamic _jsObject; + final Object _jsObject; // This should only be called from _wrapToDart JsObject._fromJs(this._jsObject) { @@ -53,40 +51,42 @@ class JsObject { } @patch - factory JsObject(JsFunction constructor, [List arguments]) { + factory JsObject(JsFunction constructor, [List? arguments]) { var ctor = _convertToJS(constructor); if (arguments == null) { - return _wrapToDart(JS('', 'new #()', ctor)); + return _castToJsObject(_wrapToDart(JS('', 'new #()', ctor))); } if (JS('bool', '# instanceof Array', arguments)) { int argumentCount = JS('int', '#.length', arguments); switch (argumentCount) { case 0: - return _wrapToDart(JS('', 'new #()', ctor)); + return _castToJsObject(_wrapToDart(JS('', 'new #()', ctor))); case 1: var arg0 = _convertToJS(JS('', '#[0]', arguments)); - return _wrapToDart(JS('', 'new #(#)', ctor, arg0)); + return _castToJsObject(_wrapToDart(JS('', 'new #(#)', ctor, arg0))); case 2: var arg0 = _convertToJS(JS('', '#[0]', arguments)); var arg1 = _convertToJS(JS('', '#[1]', arguments)); - return _wrapToDart(JS('', 'new #(#, #)', ctor, arg0, arg1)); + return _castToJsObject( + _wrapToDart(JS('', 'new #(#, #)', ctor, arg0, arg1))); case 3: var arg0 = _convertToJS(JS('', '#[0]', arguments)); var arg1 = _convertToJS(JS('', '#[1]', arguments)); var arg2 = _convertToJS(JS('', '#[2]', arguments)); - return _wrapToDart(JS('', 'new #(#, #, #)', ctor, arg0, arg1, arg2)); + return _castToJsObject( + _wrapToDart(JS('', 'new #(#, #, #)', ctor, arg0, arg1, arg2))); case 4: var arg0 = _convertToJS(JS('', '#[0]', arguments)); var arg1 = _convertToJS(JS('', '#[1]', arguments)); var arg2 = _convertToJS(JS('', '#[2]', arguments)); var arg3 = _convertToJS(JS('', '#[3]', arguments)); - return _wrapToDart( - JS('', 'new #(#, #, #, #)', ctor, arg0, arg1, arg2, arg3)); + return _castToJsObject(_wrapToDart( + JS('', 'new #(#, #, #, #)', ctor, arg0, arg1, arg2, arg3))); } } @@ -97,7 +97,7 @@ class JsObject { // the arguments list passed to apply(). // After that, use the JavaScript 'new' operator which overrides any binding // of 'this' with the new instance. - var args = [null]..addAll(arguments.map(_convertToJS)); + var args = [null]..addAll(arguments.map(_convertToJS)); var factoryFunction = JS('', '#.bind.apply(#, #)', ctor, ctor, args); // Without this line, calling factoryFunction as a constructor throws JS('String', 'String(#)', factoryFunction); @@ -105,7 +105,7 @@ class JsObject { // object for which there is an interceptor var jsObj = JS('', 'new #()', factoryFunction); - return _wrapToDart(jsObj); + return _castToJsObject(_wrapToDart(jsObj)); // TODO(sra): Investigate: // @@ -116,25 +116,25 @@ class JsObject { } @patch - factory JsObject.fromBrowserObject(object) { + factory JsObject.fromBrowserObject(Object object) { if (object is num || object is String || object is bool || object == null) { throw ArgumentError("object cannot be a num, string, bool, or null"); } - return _wrapToDart(_convertToJS(object)); + return _castToJsObject(_wrapToDart(_convertToJS(object))); } @patch - factory JsObject.jsify(object) { + factory JsObject.jsify(Object object) { if ((object is! Map) && (object is! Iterable)) { throw ArgumentError("object must be a Map or Iterable"); } - return _wrapToDart(_convertDataTree(object)); + return _castToJsObject(_wrapToDart(_convertDataTree(object))); } - static _convertDataTree(data) { + static _convertDataTree(Object data) { var _convertedObjects = HashMap.identity(); - _convert(o) { + _convert(Object? o) { if (_convertedObjects.containsKey(o)) { return _convertedObjects[o]; } @@ -159,7 +159,7 @@ class JsObject { } @patch - dynamic operator [](property) { + dynamic operator [](Object property) { if (property is! String && property is! num) { throw ArgumentError("property is not a String or num"); } @@ -167,7 +167,7 @@ class JsObject { } @patch - void operator []=(property, value) { + void operator []=(Object property, Object? value) { if (property is! String && property is! num) { throw ArgumentError("property is not a String or num"); } @@ -175,11 +175,11 @@ class JsObject { } @patch - bool operator ==(other) => + bool operator ==(Object other) => other is JsObject && JS('bool', '# === #', _jsObject, other._jsObject); @patch - bool hasProperty(property) { + bool hasProperty(Object property) { if (property is! String && property is! num) { throw ArgumentError("property is not a String or num"); } @@ -187,7 +187,7 @@ class JsObject { } @patch - void deleteProperty(property) { + void deleteProperty(Object property) { if (property is! String && property is! num) { throw ArgumentError("property is not a String or num"); } @@ -209,7 +209,7 @@ class JsObject { } @patch - dynamic callMethod(method, [List args]) { + dynamic callMethod(Object method, [List? args]) { if (method is! String && method is! num) { throw ArgumentError("method is not a String or num"); } @@ -226,7 +226,7 @@ class JsFunction extends JsObject { return JsFunction._fromJs(jsFunc); } - JsFunction._fromJs(jsObject) : super._fromJs(jsObject); + JsFunction._fromJs(Object jsObject) : super._fromJs(jsObject); @patch dynamic apply(List args, {thisArg}) => _convertToDart(JS( @@ -246,7 +246,7 @@ class JsArray extends JsObject with ListMixin { factory JsArray.from(Iterable other) => JsArray._fromJs([]..addAll(other.map(_convertToJS))); - JsArray._fromJs(jsObject) : super._fromJs(jsObject); + JsArray._fromJs(Object jsObject) : super._fromJs(jsObject); _checkIndex(int index) { if (index is int && (index < 0 || index >= length)) { @@ -272,20 +272,16 @@ class JsArray extends JsObject with ListMixin { // Methods required by ListMixin @patch - E operator [](dynamic index) { - // TODO(justinfagnani): fix the semantics for non-ints - // dartbug.com/14605 - if (index is num && index == index.toInt()) { + E operator [](Object index) { + if (index is int) { _checkIndex(index); } return super[index]; } @patch - void operator []=(dynamic index, E value) { - // TODO(justinfagnani): fix the semantics for non-ints - // dartbug.com/14605 - if (index is num && index == index.toInt()) { + void operator []=(Object index, Object? value) { + if (index is int) { _checkIndex(index); } super[index] = value; @@ -317,7 +313,7 @@ class JsArray extends JsObject with ListMixin { @patch void addAll(Iterable iterable) { var list = (JS('bool', '# instanceof Array', iterable)) - ? iterable + ? JS('JSArray', '#', iterable) : List.from(iterable); callMethod('push', list); } @@ -352,13 +348,13 @@ class JsArray extends JsObject with ListMixin { int length = end - start; if (length == 0) return; if (skipCount < 0) throw ArgumentError(skipCount); - var args = [start, length] + var args = [start, length] ..addAll(iterable.skip(skipCount).take(length)); callMethod('splice', args); } @patch - void sort([int compare(E a, E b)]) { + void sort([int compare(E a, E b)?]) { // Note: arr.sort(null) is a type error in FF callMethod('sort', compare == null ? [] : [compare]); } @@ -373,6 +369,9 @@ const _JS_OBJECT_PROPERTY_NAME = r'_$dart_jsObject'; const _JS_FUNCTION_PROPERTY_NAME = r'$dart_jsFunction'; const _JS_FUNCTION_PROPERTY_NAME_CAPTURE_THIS = r'_$dart_jsFunctionCaptureThis'; +@pragma('dart2js:tryInline') +JsObject _castToJsObject(o) => JS('', '#', o); + bool _defineProperty(o, String name, value) { try { if (_isExtensible(o) && @@ -396,7 +395,7 @@ bool _hasOwnProperty(o, String name) { bool _isExtensible(o) => JS('bool', 'Object.isExtensible(#)', o); -Object _getOwnProperty(o, String name) { +Object? _getOwnProperty(o, String name) { if (_hasOwnProperty(o, name)) { return JS('', '#[#]', o, name); } @@ -408,7 +407,7 @@ bool _isLocalObject(o) => JS('bool', '# instanceof Object', o); // The shared constructor function for proxies to Dart objects in JavaScript. final _dartProxyCtor = JS('', 'function DartObject(o) { this.o = o; }'); -dynamic _convertToJS(dynamic o) { +Object? _convertToJS(Object? o) { // Note: we don't write `if (o == null) return null;` to make sure dart2js // doesn't convert `return null;` into `return;` (which would make `null` be // `undefined` in Javascprit). See dartbug.com/20305 for details. @@ -440,7 +439,7 @@ dynamic _convertToJS(dynamic o) { o, _JS_OBJECT_PROPERTY_NAME, (o) => JS('', 'new #(#)', ctor, o)); } -Object _getJsProxy(o, String propertyName, createProxy(o)) { +Object? _getJsProxy(o, String propertyName, createProxy(o)) { var jsProxy = _getOwnProperty(o, propertyName); if (jsProxy == null) { jsProxy = createProxy(o); @@ -451,7 +450,7 @@ Object _getJsProxy(o, String propertyName, createProxy(o)) { // converts a Dart object to a reference to a native JS object // which might be a DartObject JS->Dart proxy -Object _convertToDart(o) { +Object? _convertToDart(o) { if (JS('bool', '# == null', o) || JS('bool', 'typeof # == "string"', o) || JS('bool', 'typeof # == "number"', o) || @@ -484,7 +483,7 @@ Object _wrapToDart(o) { o, _DART_OBJECT_PROPERTY_NAME, (o) => JsObject._fromJs(o)); } -Object _getDartProxy(o, String propertyName, createProxy(o)) { +Object _getDartProxy(o, String propertyName, JsObject createProxy(o)) { var dartProxy = _getOwnProperty(o, propertyName); // Temporary fix for dartbug.com/15193 // In some cases it's possible to see a JavaScript object that diff --git a/sdk/lib/_internal/js_runtime/lib/js_primitives.dart b/sdk/lib/_internal/js_runtime/lib/js_primitives.dart index 542233357b5..97577a0ca05 100644 --- a/sdk/lib/_internal/js_runtime/lib/js_primitives.dart +++ b/sdk/lib/_internal/js_runtime/lib/js_primitives.dart @@ -2,8 +2,6 @@ // 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.6 - /// dart2js "primitives", that is, features that cannot be implemented without /// access to JavaScript features. library dart2js._js_primitives; diff --git a/sdk/lib/_internal/js_runtime/lib/js_rti.dart b/sdk/lib/_internal/js_runtime/lib/js_rti.dart index 3717b6e2f61..9b850c94a03 100644 --- a/sdk/lib/_internal/js_runtime/lib/js_rti.dart +++ b/sdk/lib/_internal/js_runtime/lib/js_rti.dart @@ -2,8 +2,6 @@ // 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.6 - /// This part contains helpers for supporting runtime type information. /// /// The helper use a mixture of Dart and JavaScript objects. To indicate which diff --git a/sdk/lib/_internal/js_runtime/lib/js_string.dart b/sdk/lib/_internal/js_runtime/lib/js_string.dart index d6af957d32a..8ba4c371a17 100644 --- a/sdk/lib/_internal/js_runtime/lib/js_string.dart +++ b/sdk/lib/_internal/js_runtime/lib/js_string.dart @@ -2,8 +2,6 @@ // 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.6 - part of _interceptors; /// The interceptor class for [String]. The compiler recognizes this @@ -34,7 +32,7 @@ class JSString extends Interceptor implements String, JSIndexable { return allMatchesInStringUnchecked(this, string, start); } - Match matchAsPrefix(String string, [int start = 0]) { + Match? matchAsPrefix(String string, [int start = 0]) { if (start < 0 || start > string.length) { throw new RangeError.range(start, 0, string.length); } @@ -64,12 +62,12 @@ class JSString extends Interceptor implements String, JSIndexable { return stringReplaceAllUnchecked(this, from, checkString(to)); } - String replaceAllMapped(Pattern from, String convert(Match match)) { + String replaceAllMapped(Pattern from, String Function(Match) convert) { return this.splitMapJoin(from, onMatch: convert); } String splitMapJoin(Pattern from, - {String onMatch(Match match), String onNonMatch(String nonMatch)}) { + {String Function(Match)? onMatch, String Function(String)? onNonMatch}) { return stringReplaceAllFuncUnchecked(this, from, onMatch, onNonMatch); } @@ -100,12 +98,12 @@ class JSString extends Interceptor implements String, JSIndexable { } } - String replaceRange(int start, int end, String replacement) { + String replaceRange(int start, int? end, String replacement) { checkString(replacement); checkInt(start); - end = RangeError.checkValidRange(start, end, this.length); - checkInt(end); - return stringReplaceRangeUnchecked(this, start, end, replacement); + var e = RangeError.checkValidRange(start, end, this.length); + checkInt(e); + return stringReplaceRangeUnchecked(this, start, e, replacement); } List _defaultSplit(Pattern pattern) { @@ -151,7 +149,7 @@ class JSString extends Interceptor implements String, JSIndexable { return pattern.matchAsPrefix(this, index) != null; } - String substring(int startIndex, [int endIndex]) { + String substring(int startIndex, [int? endIndex]) { checkInt(startIndex); if (endIndex == null) endIndex = length; checkInt(endIndex); @@ -354,7 +352,7 @@ class JSString extends Interceptor implements String, JSIndexable { throw const OutOfMemoryError(); } var result = ''; - var s = this; + String s = this; while (true) { if (times & 1 == 1) result = s + result; times = JS('JSUInt31', '# >>> 1', times); @@ -391,7 +389,7 @@ class JSString extends Interceptor implements String, JSIndexable { } if (pattern is JSSyntaxRegExp) { JSSyntaxRegExp re = pattern; - Match match = firstMatchAfter(re, this, start); + Match? match = firstMatchAfter(re, this, start); return (match == null) ? -1 : match.start; } for (int i = start; i <= this.length; i++) { @@ -400,7 +398,7 @@ class JSString extends Interceptor implements String, JSIndexable { return -1; } - int lastIndexOf(Pattern pattern, [int start]) { + int lastIndexOf(Pattern pattern, [int? start]) { checkNull(pattern); if (start == null) { start = length; @@ -451,12 +449,12 @@ class JSString extends Interceptor implements String, JSIndexable { // optimizations are smarter. int hash = 0; for (int i = 0; i < length; i++) { - hash = 0x1fffffff & (hash + JS('int', r'#.charCodeAt(#)', this, i)); + hash = 0x1fffffff & (hash + JS('int', r'#.charCodeAt(#)', this, i)); hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10)); hash = JS('int', '# ^ (# >> 6)', hash, hash); } hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3)); - hash = JS('int', '# ^ (# >> 11)', hash, hash); + hash = JS('int', '# ^ (# >> 11)', hash, hash); return 0x1fffffff & (hash + ((0x00003fff & hash) << 15)); } diff --git a/sdk/lib/_internal/js_runtime/lib/linked_hash_map.dart b/sdk/lib/_internal/js_runtime/lib/linked_hash_map.dart index dab8542f96f..70882d8a17d 100644 --- a/sdk/lib/_internal/js_runtime/lib/linked_hash_map.dart +++ b/sdk/lib/_internal/js_runtime/lib/linked_hash_map.dart @@ -2,8 +2,6 @@ // 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.6 - // Efficient JavaScript based implementation of a linked hash map used as a // backing map for constant maps and the [LinkedHashMap] patch @@ -29,8 +27,8 @@ class JsLinkedHashMap extends MapBase // The keys and values are stored in cells that are linked together // to form a double linked list. - LinkedHashMapCell _first; - LinkedHashMapCell _last; + LinkedHashMapCell? _first; + LinkedHashMapCell? _last; // We track the number of modifications done to the key set of the // hash map to be able to throw when the map is modified while being @@ -61,10 +59,10 @@ class JsLinkedHashMap extends MapBase } Iterable get values { - return new MappedIterable(keys, (each) => this[each]); + return new MappedIterable(keys, (each) => this[each] as V); } - bool containsKey(Object key) { + bool containsKey(Object? key) { if (_isStringKey(key)) { var strings = _strings; if (strings == null) return false; @@ -78,14 +76,14 @@ class JsLinkedHashMap extends MapBase } } - bool internalContainsKey(Object key) { + bool internalContainsKey(Object? key) { var rest = _rest; if (rest == null) return false; var bucket = _getBucket(rest, key); return internalFindBucketIndex(bucket, key) >= 0; } - bool containsValue(Object value) { + bool containsValue(Object? value) { return keys.any((each) => this[each] == value); } @@ -95,23 +93,23 @@ class JsLinkedHashMap extends MapBase }); } - V operator [](Object key) { + V? operator [](Object? key) { if (_isStringKey(key)) { var strings = _strings; if (strings == null) return null; - LinkedHashMapCell cell = _getTableCell(strings, key); + LinkedHashMapCell? cell = _getTableCell(strings, key); return JS('', '#', cell == null ? null : cell.hashMapCellValue); } else if (_isNumericKey(key)) { var nums = _nums; if (nums == null) return null; - LinkedHashMapCell cell = _getTableCell(nums, key); + LinkedHashMapCell? cell = _getTableCell(nums, key); return JS('', '#', cell == null ? null : cell.hashMapCellValue); } else { return internalGet(key); } } - V internalGet(Object key) { + V? internalGet(Object? key) { var rest = _rest; if (rest == null) return null; var bucket = _getBucket(rest, key); @@ -156,13 +154,13 @@ class JsLinkedHashMap extends MapBase } V putIfAbsent(K key, V ifAbsent()) { - if (containsKey(key)) return this[key]; + if (containsKey(key)) return this[key] as V; V value = ifAbsent(); this[key] = value; return value; } - V remove(Object key) { + V? remove(Object? key) { if (_isStringKey(key)) { return _removeHashTableEntry(_strings, key); } else if (_isNumericKey(key)) { @@ -172,7 +170,7 @@ class JsLinkedHashMap extends MapBase } } - V internalRemove(Object key) { + V? internalRemove(Object? key) { var rest = _rest; if (rest == null) return null; var hash = internalComputeHashCode(key); @@ -199,7 +197,7 @@ class JsLinkedHashMap extends MapBase } void forEach(void action(K key, V value)) { - LinkedHashMapCell cell = _first; + LinkedHashMapCell? cell = _first; int modifications = _modifications; while (cell != null) { K key = JS('', '#', cell.hashMapCellKey); @@ -213,7 +211,7 @@ class JsLinkedHashMap extends MapBase } void _addHashTableEntry(var table, K key, V value) { - LinkedHashMapCell cell = _getTableCell(table, key); + LinkedHashMapCell? cell = _getTableCell(table, key); if (cell == null) { _setTableEntry(table, key, _newLinkedCell(key, value)); } else { @@ -221,9 +219,9 @@ class JsLinkedHashMap extends MapBase } } - V _removeHashTableEntry(var table, Object key) { + V? _removeHashTableEntry(var table, Object? key) { if (table == null) return null; - LinkedHashMapCell cell = _getTableCell(table, key); + LinkedHashMapCell? cell = _getTableCell(table, key); if (cell == null) return null; _unlinkCell(cell); _deleteTableEntry(table, key); @@ -244,7 +242,7 @@ class JsLinkedHashMap extends MapBase if (_first == null) { _first = _last = cell; } else { - LinkedHashMapCell last = _last; + LinkedHashMapCell last = _last!; cell._previous = last; _last = last._next = cell; } @@ -255,8 +253,8 @@ class JsLinkedHashMap extends MapBase // Unlink the given cell from the linked list of cells. void _unlinkCell(LinkedHashMapCell cell) { - LinkedHashMapCell previous = cell._previous; - LinkedHashMapCell next = cell._next; + LinkedHashMapCell? previous = cell._previous; + LinkedHashMapCell? next = cell._next; if (previous == null) { assert(cell == _first); _first = next; @@ -291,7 +289,7 @@ class JsLinkedHashMap extends MapBase return JS('int', '# & 0x3ffffff', key.hashCode); } - List _getBucket(var table, var key) { + List? _getBucket(var table, var key) { var hash = internalComputeHashCode(key); return _getTableBucket(table, hash); } @@ -308,11 +306,11 @@ class JsLinkedHashMap extends MapBase String toString() => MapBase.mapToString(this); - LinkedHashMapCell _getTableCell(var table, var key) { + LinkedHashMapCell? _getTableCell(var table, var key) { return JS('var', '#[#]', table, key); } - List _getTableBucket(var table, var key) { + List? _getTableBucket(var table, var key) { return JS('var', '#[#]', table, key); } @@ -326,7 +324,7 @@ class JsLinkedHashMap extends MapBase } bool _containsTableEntry(var table, var key) { - LinkedHashMapCell cell = _getTableCell(table, key); + LinkedHashMapCell? cell = _getTableCell(table, key); return cell != null; } @@ -346,12 +344,12 @@ class JsLinkedHashMap extends MapBase class Es6LinkedHashMap extends JsLinkedHashMap { @override - LinkedHashMapCell _getTableCell(var table, var key) { + LinkedHashMapCell? _getTableCell(var table, var key) { return JS('var', '#.get(#)', table, key); } @override - List _getTableBucket(var table, var key) { + List? _getTableBucket(var table, var key) { return JS('var', '#.get(#)', table, key); } @@ -380,8 +378,8 @@ class LinkedHashMapCell { final dynamic hashMapCellKey; dynamic hashMapCellValue; - LinkedHashMapCell _next; - LinkedHashMapCell _previous; + LinkedHashMapCell? _next; + LinkedHashMapCell? _previous; LinkedHashMapCell(this.hashMapCellKey, this.hashMapCellValue); } @@ -397,12 +395,12 @@ class LinkedHashMapKeyIterable extends EfficientLengthIterable { return new LinkedHashMapKeyIterator(_map, _map._modifications); } - bool contains(Object element) { + bool contains(Object? element) { return _map.containsKey(element); } void forEach(void f(E element)) { - LinkedHashMapCell cell = _map._first; + LinkedHashMapCell? cell = _map._first; int modifications = _map._modifications; while (cell != null) { f(JS('', '#', cell.hashMapCellKey)); @@ -417,24 +415,26 @@ class LinkedHashMapKeyIterable extends EfficientLengthIterable { class LinkedHashMapKeyIterator implements Iterator { final dynamic _map; final int _modifications; - LinkedHashMapCell _cell; - E _current; + LinkedHashMapCell? _cell; + E? _current; LinkedHashMapKeyIterator(this._map, this._modifications) { _cell = _map._first; } - E get current => _current; + E get current => _current as E; bool moveNext() { if (_modifications != _map._modifications) { throw new ConcurrentModificationError(_map); - } else if (_cell == null) { + } + var cell = _cell; + if (cell == null) { _current = null; return false; } else { - _current = JS('', '#', _cell.hashMapCellKey); - _cell = _cell._next; + _current = JS('', '#', cell.hashMapCellKey); + _cell = cell._next; return true; } } diff --git a/sdk/lib/_internal/js_runtime/lib/math_patch.dart b/sdk/lib/_internal/js_runtime/lib/math_patch.dart index fc33945c891..585f4c5aec4 100644 --- a/sdk/lib/_internal/js_runtime/lib/math_patch.dart +++ b/sdk/lib/_internal/js_runtime/lib/math_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // Patch file for dart:math library. import 'dart:_foreign_helper' show JS; import 'dart:_js_helper' show patch, checkNum; @@ -65,10 +63,10 @@ const int _POW2_32 = 0x100000000; @patch class Random { - static Random _secureRandom; + static Random? _secureRandom; @patch - factory Random([int seed]) => + factory Random([int? seed]) => (seed == null) ? const _JSRandom() : new _Random(seed); @patch @@ -226,7 +224,7 @@ class _Random implements Random { do { _nextState(); rnd32 = _lo; - result = rnd32.remainder(max); // % max; + result = rnd32.remainder(max) as int; // % max; } while ((rnd32 - result + max) >= _POW2_32); return result; } @@ -308,7 +306,7 @@ class _JSSecureRandom implements Random { } _buffer.setUint32(0, 0); int start = 4 - byteCount; - int randomLimit = pow(256, byteCount); + int randomLimit = pow(256, byteCount) as int; while (true) { _getRandomBytes(start, byteCount); // The getUint32 method is big-endian as default. @@ -317,7 +315,7 @@ class _JSSecureRandom implements Random { // Max is power of 2. return random & (max - 1); } - int result = random.remainder(max); + int result = random.remainder(max) as int; // Ensure results have equal probability by rejecting values in the // last range of k*max .. 256**byteCount. // TODO: Consider picking a higher byte count if the last range is a diff --git a/sdk/lib/_internal/js_runtime/lib/mirrors_patch_cfe.dart b/sdk/lib/_internal/js_runtime/lib/mirrors_patch_cfe.dart index 4265799540c..cd961a023a9 100644 --- a/sdk/lib/_internal/js_runtime/lib/mirrors_patch_cfe.dart +++ b/sdk/lib/_internal/js_runtime/lib/mirrors_patch_cfe.dart @@ -2,8 +2,6 @@ // 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.6 - // Patch library for dart:mirrors. import 'dart:_js_helper' show patch; diff --git a/sdk/lib/_internal/js_runtime/lib/native_helper.dart b/sdk/lib/_internal/js_runtime/lib/native_helper.dart index d8d4e1d4bd7..f5f40b7c2ae 100644 --- a/sdk/lib/_internal/js_runtime/lib/native_helper.dart +++ b/sdk/lib/_internal/js_runtime/lib/native_helper.dart @@ -2,8 +2,6 @@ // 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.6 - part of _js_helper; // TODO(ngeoffray): stop using this method once our optimizers can @@ -43,19 +41,19 @@ getPropertyFromPrototype(var object, String name) { /// Returns a String tag identifying the type of the native object, or `null`. /// The tag is not the name of the type, but usually the name of the JavaScript /// constructor function. Initialized by [initHooks]. -Function getTagFunction; +Function? getTagFunction; /// If a lookup via [getTagFunction] on an object [object] that has [tag] fails, /// this function is called to provide an alternate tag. This allows us to fail /// gracefully if we can make a good guess, for example, when browsers add novel /// kinds of HTMLElement that we have never heard of. Initialized by /// [initHooks]. -Function alternateTagFunction; +Function? alternateTagFunction; /// Returns the prototype for the JavaScript constructor named by an input tag. /// Returns `null` if there is no such constructor, or if pre-patching of the /// constructor is to be avoided. Initialized by [initHooks]. -Function prototypeForTagFunction; +Function? prototypeForTagFunction; String toStringForNativeObject(var obj) { // TODO(sra): Is this code dead? @@ -63,7 +61,7 @@ String toStringForNativeObject(var obj) { // been called via an interceptor and initialized it. String name = getTagFunction == null ? '' - : JS('String', '#', getTagFunction(obj)); + : JS('String', '#', getTagFunction!(obj)); return 'Instance of $name'; } @@ -148,7 +146,7 @@ const DISCRIMINATED_MARK = '*'; @pragma('dart2js:noInline') lookupAndCacheInterceptor(obj) { assert(!isDartObject(obj)); - String tag = getTagFunction(obj); + String tag = getTagFunction!(obj); // Fast path for instance (and uncached) tags because the lookup is repeated // for each instance (or getInterceptor call). @@ -161,8 +159,9 @@ lookupAndCacheInterceptor(obj) { // [initNativeDispatch]. var interceptorClass = lookupInterceptor(tag); if (interceptorClass == null) { - tag = alternateTagFunction(obj, tag); - if (tag != null) { + String? altTag = alternateTagFunction!(obj, tag); + if (altTag != null) { + tag = altTag; // Fast path for instance and uncached tags again. record = propertyGet(dispatchRecordsForInstanceTags, tag); if (record != null) return patchInstance(obj, record); @@ -291,7 +290,7 @@ void initNativeDispatchContinue() { var fun = JS('=Object', 'function () {}'); for (int i = 0; i < tags.length; i++) { var tag = tags[i]; - var proto = prototypeForTagFunction(tag); + var proto = prototypeForTagFunction!(tag); if (proto != null) { var interceptorClass = JS('', '#[#]', map, tag); var record = makeDefaultDispatchRecord(tag, interceptorClass, proto); diff --git a/sdk/lib/_internal/js_runtime/lib/native_typed_data.dart b/sdk/lib/_internal/js_runtime/lib/native_typed_data.dart index c9a52eaa9a1..39d527b1483 100644 --- a/sdk/lib/_internal/js_runtime/lib/native_typed_data.dart +++ b/sdk/lib/_internal/js_runtime/lib/native_typed_data.dart @@ -2,8 +2,6 @@ // 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.6 - /// Specialized integers and floating point numbers, /// with SIMD support and efficient lists. library dart.typed_data.implementation; @@ -28,73 +26,73 @@ import 'dart:typed_data'; @Native('ArrayBuffer') class NativeByteBuffer implements ByteBuffer { @JSName('byteLength') - final int lengthInBytes; + int get lengthInBytes native; Type get runtimeType => ByteBuffer; - Uint8List asUint8List([int offsetInBytes = 0, int length]) { + Uint8List asUint8List([int offsetInBytes = 0, int? length]) { return NativeUint8List.view(this, offsetInBytes, length); } - Int8List asInt8List([int offsetInBytes = 0, int length]) { + Int8List asInt8List([int offsetInBytes = 0, int? length]) { return NativeInt8List.view(this, offsetInBytes, length); } - Uint8ClampedList asUint8ClampedList([int offsetInBytes = 0, int length]) { + Uint8ClampedList asUint8ClampedList([int offsetInBytes = 0, int? length]) { return NativeUint8ClampedList.view(this, offsetInBytes, length); } - Uint16List asUint16List([int offsetInBytes = 0, int length]) { + Uint16List asUint16List([int offsetInBytes = 0, int? length]) { return NativeUint16List.view(this, offsetInBytes, length); } - Int16List asInt16List([int offsetInBytes = 0, int length]) { + Int16List asInt16List([int offsetInBytes = 0, int? length]) { return NativeInt16List.view(this, offsetInBytes, length); } - Uint32List asUint32List([int offsetInBytes = 0, int length]) { + Uint32List asUint32List([int offsetInBytes = 0, int? length]) { return NativeUint32List.view(this, offsetInBytes, length); } - Int32List asInt32List([int offsetInBytes = 0, int length]) { + Int32List asInt32List([int offsetInBytes = 0, int? length]) { return NativeInt32List.view(this, offsetInBytes, length); } - Uint64List asUint64List([int offsetInBytes = 0, int length]) { + Uint64List asUint64List([int offsetInBytes = 0, int? length]) { throw UnsupportedError('Uint64List not supported by dart2js.'); } - Int64List asInt64List([int offsetInBytes = 0, int length]) { + Int64List asInt64List([int offsetInBytes = 0, int? length]) { throw UnsupportedError('Int64List not supported by dart2js.'); } - Int32x4List asInt32x4List([int offsetInBytes = 0, int length]) { - NativeInt32List storage = + Int32x4List asInt32x4List([int offsetInBytes = 0, int? length]) { + var storage = this.asInt32List(offsetInBytes, length != null ? length * 4 : null); return NativeInt32x4List._externalStorage(storage); } - Float32List asFloat32List([int offsetInBytes = 0, int length]) { + Float32List asFloat32List([int offsetInBytes = 0, int? length]) { return NativeFloat32List.view(this, offsetInBytes, length); } - Float64List asFloat64List([int offsetInBytes = 0, int length]) { + Float64List asFloat64List([int offsetInBytes = 0, int? length]) { return NativeFloat64List.view(this, offsetInBytes, length); } - Float32x4List asFloat32x4List([int offsetInBytes = 0, int length]) { - NativeFloat32List storage = + Float32x4List asFloat32x4List([int offsetInBytes = 0, int? length]) { + var storage = this.asFloat32List(offsetInBytes, length != null ? length * 4 : null); return NativeFloat32x4List._externalStorage(storage); } - Float64x2List asFloat64x2List([int offsetInBytes = 0, int length]) { - NativeFloat64List storage = + Float64x2List asFloat64x2List([int offsetInBytes = 0, int? length]) { + var storage = this.asFloat64List(offsetInBytes, length != null ? length * 2 : null); return NativeFloat64x2List._externalStorage(storage); } - ByteData asByteData([int offsetInBytes = 0, int length]) { + ByteData asByteData([int offsetInBytes = 0, int? length]) { return NativeByteData.view(this, offsetInBytes, length); } } @@ -105,7 +103,7 @@ class NativeByteBuffer implements ByteBuffer { class NativeFloat32x4List extends Object with ListMixin, FixedLengthListMixin implements Float32x4List { - final NativeFloat32List _storage; + final Float32List _storage; /// Creates a [Float32x4List] of the specified length (in elements), /// all of whose elements are initially zero. @@ -164,10 +162,10 @@ class NativeFloat32x4List extends Object _storage[(index * 4) + 3] = value.w; } - Float32x4List sublist(int start, [int end]) { - end = _checkValidRange(start, end, this.length); + Float32x4List sublist(int start, [int? end]) { + var stop = _checkValidRange(start, end, this.length); return NativeFloat32x4List._externalStorage( - _storage.sublist(start * 4, end * 4)); + _storage.sublist(start * 4, stop * 4)); } } @@ -236,10 +234,10 @@ class NativeInt32x4List extends Object _storage[(index * 4) + 3] = value.w; } - Int32x4List sublist(int start, [int end]) { - end = _checkValidRange(start, end, this.length); + Int32x4List sublist(int start, [int? end]) { + var stop = _checkValidRange(start, end, this.length); return NativeInt32x4List._externalStorage( - _storage.sublist(start * 4, end * 4)); + _storage.sublist(start * 4, stop * 4)); } } @@ -249,7 +247,7 @@ class NativeInt32x4List extends Object class NativeFloat64x2List extends Object with ListMixin, FixedLengthListMixin implements Float64x2List { - final NativeFloat64List _storage; + final Float64List _storage; /// Creates a [Float64x2List] of the specified length (in elements), /// all of whose elements are initially zero. @@ -302,10 +300,10 @@ class NativeFloat64x2List extends Object _storage[(index * 2) + 1] = value.y; } - Float64x2List sublist(int start, [int end]) { - end = _checkValidRange(start, end, this.length); + Float64x2List sublist(int start, [int? end]) { + var stop = _checkValidRange(start, end, this.length); return NativeFloat64x2List._externalStorage( - _storage.sublist(start * 2, end * 2)); + _storage.sublist(start * 2, stop * 2)); } } @@ -314,20 +312,20 @@ class NativeTypedData implements TypedData { /// Returns the byte buffer associated with this object. @Creates('NativeByteBuffer') @Returns('NativeByteBuffer') - final ByteBuffer buffer; + ByteBuffer get buffer native; /// Returns the length of this view, in bytes. @JSName('byteLength') - final int lengthInBytes; + int get lengthInBytes native; /// Returns the offset in bytes into the underlying byte buffer of this view. @JSName('byteOffset') - final int offsetInBytes; + int get offsetInBytes native; /// Returns the number of bytes in the representation of each element in this /// list. @JSName('BYTES_PER_ELEMENT') - final int elementSizeInBytes; + int get elementSizeInBytes native; void _invalidPosition(int position, int length, String name) { if (position is! int) { @@ -350,7 +348,8 @@ class NativeTypedData implements TypedData { // because passing unvalidated values to the native constructors can cause // conversions or create views. int _checkLength(length) { - return length is int ? length : throw ArgumentError('Invalid length $length'); + if (length is! int) throw ArgumentError('Invalid length $length'); + return length; } // Validates `.view` constructor arguments. Checking is necessary because @@ -364,7 +363,7 @@ void _checkViewArguments(buffer, offsetInBytes, length) { if (offsetInBytes is! int) { throw ArgumentError('Invalid view offsetInBytes $offsetInBytes'); } - if (length != null && length is! int) { + if (length is! int?) { throw ArgumentError('Invalid view length $length'); } } @@ -373,7 +372,7 @@ void _checkViewArguments(buffer, offsetInBytes, length) { // returns a copy of the list. List _ensureNativeList(List list) { if (list is JSIndexable) return list; - List result = List(list.length); + List result = List.filled(list.length, null); for (int i = 0; i < list.length; i++) { result[i] = list[i]; } @@ -397,7 +396,7 @@ class NativeByteData extends NativeTypedData implements ByteData { /// if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than /// the length of [buffer]. factory NativeByteData.view( - ByteBuffer buffer, int offsetInBytes, int length) { + ByteBuffer buffer, int offsetInBytes, int? length) { _checkViewArguments(buffer, offsetInBytes, length); return length == null ? _create2(buffer, offsetInBytes) @@ -418,8 +417,8 @@ class NativeByteData extends NativeTypedData implements ByteData { _getFloat32(byteOffset, Endian.little == endian); @JSName('getFloat32') - @Returns('num') - num _getFloat32(int byteOffset, [bool littleEndian]) native; + @Returns('double') + double _getFloat32(int byteOffset, [bool? littleEndian]) native; /// Returns the floating point number represented by the eight bytes at /// the specified [byteOffset] in this object, in IEEE 754 @@ -431,8 +430,8 @@ class NativeByteData extends NativeTypedData implements ByteData { _getFloat64(byteOffset, Endian.little == endian); @JSName('getFloat64') - @Returns('num') - num _getFloat64(int byteOffset, [bool littleEndian]) native; + @Returns('double') + double _getFloat64(int byteOffset, [bool? littleEndian]) native; /// Returns the (possibly negative) integer represented by the two bytes at /// the specified [byteOffset] in this object, in two's complement binary @@ -447,7 +446,7 @@ class NativeByteData extends NativeTypedData implements ByteData { @JSName('getInt16') @Returns('int') - int _getInt16(int byteOffset, [bool littleEndian]) native; + int _getInt16(int byteOffset, [bool? littleEndian]) native; /// Returns the (possibly negative) integer represented by the four bytes at /// the specified [byteOffset] in this object, in two's complement binary @@ -462,7 +461,7 @@ class NativeByteData extends NativeTypedData implements ByteData { @JSName('getInt32') @Returns('int') - int _getInt32(int byteOffset, [bool littleEndian]) native; + int _getInt32(int byteOffset, [bool? littleEndian]) native; /// Returns the (possibly negative) integer represented by the eight bytes at /// the specified [byteOffset] in this object, in two's complement binary @@ -496,7 +495,7 @@ class NativeByteData extends NativeTypedData implements ByteData { @JSName('getUint16') @Returns('JSUInt31') - int _getUint16(int byteOffset, [bool littleEndian]) native; + int _getUint16(int byteOffset, [bool? littleEndian]) native; /// Returns the positive integer represented by the four bytes starting /// at the specified [byteOffset] in this object, in unsigned binary @@ -510,7 +509,7 @@ class NativeByteData extends NativeTypedData implements ByteData { @JSName('getUint32') @Returns('JSUInt32') - int _getUint32(int byteOffset, [bool littleEndian]) native; + int _getUint32(int byteOffset, [bool? littleEndian]) native; /// Returns the positive integer represented by the eight bytes starting /// at the specified [byteOffset] in this object, in unsigned binary @@ -550,7 +549,7 @@ class NativeByteData extends NativeTypedData implements ByteData { _setFloat32(byteOffset, value, Endian.little == endian); @JSName('setFloat32') - void _setFloat32(int byteOffset, num value, [bool littleEndian]) native; + void _setFloat32(int byteOffset, num value, [bool? littleEndian]) native; /// Sets the eight bytes starting at the specified [byteOffset] in this /// object to the IEEE 754 double-precision binary floating-point @@ -562,7 +561,7 @@ class NativeByteData extends NativeTypedData implements ByteData { _setFloat64(byteOffset, value, Endian.little == endian); @JSName('setFloat64') - void _setFloat64(int byteOffset, num value, [bool littleEndian]) native; + void _setFloat64(int byteOffset, num value, [bool? littleEndian]) native; /// Sets the two bytes starting at the specified [byteOffset] in this /// object to the two's complement binary representation of the specified @@ -575,7 +574,7 @@ class NativeByteData extends NativeTypedData implements ByteData { _setInt16(byteOffset, value, Endian.little == endian); @JSName('setInt16') - void _setInt16(int byteOffset, int value, [bool littleEndian]) native; + void _setInt16(int byteOffset, int value, [bool? littleEndian]) native; /// Sets the four bytes starting at the specified [byteOffset] in this /// object to the two's complement binary representation of the specified @@ -588,7 +587,7 @@ class NativeByteData extends NativeTypedData implements ByteData { _setInt32(byteOffset, value, Endian.little == endian); @JSName('setInt32') - void _setInt32(int byteOffset, int value, [bool littleEndian]) native; + void _setInt32(int byteOffset, int value, [bool? littleEndian]) native; /// Sets the eight bytes starting at the specified [byteOffset] in this /// object to the two's complement binary representation of the specified @@ -621,7 +620,7 @@ class NativeByteData extends NativeTypedData implements ByteData { _setUint16(byteOffset, value, Endian.little == endian); @JSName('setUint16') - void _setUint16(int byteOffset, int value, [bool littleEndian]) native; + void _setUint16(int byteOffset, int value, [bool? littleEndian]) native; /// Sets the four bytes starting at the specified [byteOffset] in this object /// to the unsigned binary representation of the specified [value], @@ -634,7 +633,7 @@ class NativeByteData extends NativeTypedData implements ByteData { _setUint32(byteOffset, value, Endian.little == endian); @JSName('setUint32') - void _setUint32(int byteOffset, int value, [bool littleEndian]) native; + void _setUint32(int byteOffset, int value, [bool? littleEndian]) native; /// Sets the eight bytes starting at the specified [byteOffset] in this object /// to the unsigned binary representation of the specified [value], @@ -666,8 +665,8 @@ class NativeByteData extends NativeTypedData implements ByteData { JS('NativeByteData', 'new DataView(#, #, #)', arg1, arg2, arg3); } -abstract class NativeTypedArray extends NativeTypedData - implements JavaScriptIndexingBehavior { +abstract class NativeTypedArray extends NativeTypedData + implements JavaScriptIndexingBehavior { int get length => JS('JSUInt32', '#.length', this); void _setRangeFast( @@ -693,7 +692,7 @@ abstract class NativeTypedArray extends NativeTypedData } } -abstract class NativeTypedArrayOfDouble extends NativeTypedArray +abstract class NativeTypedArrayOfDouble extends NativeTypedArray with ListMixin, FixedLengthListMixin { double operator [](int index) { _checkValidIndex(index, this, this.length); @@ -715,7 +714,7 @@ abstract class NativeTypedArrayOfDouble extends NativeTypedArray } } -abstract class NativeTypedArrayOfInt extends NativeTypedArray +abstract class NativeTypedArrayOfInt extends NativeTypedArray with ListMixin, FixedLengthListMixin implements List { // operator[]() is not here since different versions have different return @@ -745,7 +744,7 @@ class NativeFloat32List extends NativeTypedArrayOfDouble _create1(_ensureNativeList(elements)); factory NativeFloat32List.view( - ByteBuffer buffer, int offsetInBytes, int length) { + ByteBuffer buffer, int offsetInBytes, int? length) { _checkViewArguments(buffer, offsetInBytes, length); return length == null ? _create2(buffer, offsetInBytes) @@ -754,9 +753,9 @@ class NativeFloat32List extends NativeTypedArrayOfDouble Type get runtimeType => Float32List; - Float32List sublist(int start, [int end]) { - end = _checkValidRange(start, end, this.length); - var source = JS('NativeFloat32List', '#.subarray(#, #)', this, start, end); + Float32List sublist(int start, [int? end]) { + var stop = _checkValidRange(start, end, this.length); + var source = JS('NativeFloat32List', '#.subarray(#, #)', this, start, stop); return _create1(source); } @@ -779,7 +778,7 @@ class NativeFloat64List extends NativeTypedArrayOfDouble _create1(_ensureNativeList(elements)); factory NativeFloat64List.view( - ByteBuffer buffer, int offsetInBytes, int length) { + ByteBuffer buffer, int offsetInBytes, int? length) { _checkViewArguments(buffer, offsetInBytes, length); return length == null ? _create2(buffer, offsetInBytes) @@ -788,9 +787,9 @@ class NativeFloat64List extends NativeTypedArrayOfDouble Type get runtimeType => Float64List; - Float64List sublist(int start, [int end]) { - end = _checkValidRange(start, end, this.length); - var source = JS('NativeFloat64List', '#.subarray(#, #)', this, start, end); + Float64List sublist(int start, [int? end]) { + var stop = _checkValidRange(start, end, this.length); + var source = JS('NativeFloat64List', '#.subarray(#, #)', this, start, stop); return _create1(source); } @@ -812,7 +811,7 @@ class NativeInt16List extends NativeTypedArrayOfInt implements Int16List { _create1(_ensureNativeList(elements)); factory NativeInt16List.view( - NativeByteBuffer buffer, int offsetInBytes, int length) { + NativeByteBuffer buffer, int offsetInBytes, int? length) { _checkViewArguments(buffer, offsetInBytes, length); return length == null ? _create2(buffer, offsetInBytes) @@ -826,9 +825,9 @@ class NativeInt16List extends NativeTypedArrayOfInt implements Int16List { return JS('int', '#[#]', this, index); } - Int16List sublist(int start, [int end]) { - end = _checkValidRange(start, end, this.length); - var source = JS('NativeInt16List', '#.subarray(#, #)', this, start, end); + Int16List sublist(int start, [int? end]) { + var stop = _checkValidRange(start, end, this.length); + var source = JS('NativeInt16List', '#.subarray(#, #)', this, start, stop); return _create1(source); } @@ -850,7 +849,7 @@ class NativeInt32List extends NativeTypedArrayOfInt implements Int32List { _create1(_ensureNativeList(elements)); factory NativeInt32List.view( - ByteBuffer buffer, int offsetInBytes, int length) { + ByteBuffer buffer, int offsetInBytes, int? length) { _checkViewArguments(buffer, offsetInBytes, length); return length == null ? _create2(buffer, offsetInBytes) @@ -864,9 +863,9 @@ class NativeInt32List extends NativeTypedArrayOfInt implements Int32List { return JS('int', '#[#]', this, index); } - Int32List sublist(int start, [int end]) { - end = _checkValidRange(start, end, this.length); - var source = JS('NativeInt32List', '#.subarray(#, #)', this, start, end); + Int32List sublist(int start, [int? end]) { + var stop = _checkValidRange(start, end, this.length); + var source = JS('NativeInt32List', '#.subarray(#, #)', this, start, stop); return _create1(source); } @@ -888,7 +887,7 @@ class NativeInt8List extends NativeTypedArrayOfInt implements Int8List { _create1(_ensureNativeList(elements)); factory NativeInt8List.view( - ByteBuffer buffer, int offsetInBytes, int length) { + ByteBuffer buffer, int offsetInBytes, int? length) { _checkViewArguments(buffer, offsetInBytes, length); return length == null ? _create2(buffer, offsetInBytes) @@ -902,9 +901,9 @@ class NativeInt8List extends NativeTypedArrayOfInt implements Int8List { return JS('int', '#[#]', this, index); } - Int8List sublist(int start, [int end]) { - end = _checkValidRange(start, end, this.length); - var source = JS('NativeInt8List', '#.subarray(#, #)', this, start, end); + Int8List sublist(int start, [int? end]) { + var stop = _checkValidRange(start, end, this.length); + var source = JS('NativeInt8List', '#.subarray(#, #)', this, start, stop); return _create1(source); } @@ -914,7 +913,7 @@ class NativeInt8List extends NativeTypedArrayOfInt implements Int8List { static NativeInt8List _create2(arg1, arg2) => JS('NativeInt8List', 'new Int8Array(#, #)', arg1, arg2); - static Int8List _create3(arg1, arg2, arg3) => + static NativeInt8List _create3(arg1, arg2, arg3) => JS('NativeInt8List', 'new Int8Array(#, #, #)', arg1, arg2, arg3); } @@ -926,7 +925,7 @@ class NativeUint16List extends NativeTypedArrayOfInt implements Uint16List { _create1(_ensureNativeList(list)); factory NativeUint16List.view( - ByteBuffer buffer, int offsetInBytes, int length) { + ByteBuffer buffer, int offsetInBytes, int? length) { _checkViewArguments(buffer, offsetInBytes, length); return length == null ? _create2(buffer, offsetInBytes) @@ -940,9 +939,9 @@ class NativeUint16List extends NativeTypedArrayOfInt implements Uint16List { return JS('JSUInt31', '#[#]', this, index); } - Uint16List sublist(int start, [int end]) { - end = _checkValidRange(start, end, this.length); - var source = JS('NativeUint16List', '#.subarray(#, #)', this, start, end); + Uint16List sublist(int start, [int? end]) { + var stop = _checkValidRange(start, end, this.length); + var source = JS('NativeUint16List', '#.subarray(#, #)', this, start, stop); return _create1(source); } @@ -964,7 +963,7 @@ class NativeUint32List extends NativeTypedArrayOfInt implements Uint32List { _create1(_ensureNativeList(elements)); factory NativeUint32List.view( - ByteBuffer buffer, int offsetInBytes, int length) { + ByteBuffer buffer, int offsetInBytes, int? length) { _checkViewArguments(buffer, offsetInBytes, length); return length == null ? _create2(buffer, offsetInBytes) @@ -978,9 +977,9 @@ class NativeUint32List extends NativeTypedArrayOfInt implements Uint32List { return JS('JSUInt32', '#[#]', this, index); } - Uint32List sublist(int start, [int end]) { - end = _checkValidRange(start, end, this.length); - var source = JS('NativeUint32List', '#.subarray(#, #)', this, start, end); + Uint32List sublist(int start, [int? end]) { + var stop = _checkValidRange(start, end, this.length); + var source = JS('NativeUint32List', '#.subarray(#, #)', this, start, stop); return _create1(source); } @@ -1003,7 +1002,7 @@ class NativeUint8ClampedList extends NativeTypedArrayOfInt _create1(_ensureNativeList(elements)); factory NativeUint8ClampedList.view( - ByteBuffer buffer, int offsetInBytes, int length) { + ByteBuffer buffer, int offsetInBytes, int? length) { _checkViewArguments(buffer, offsetInBytes, length); return length == null ? _create2(buffer, offsetInBytes) @@ -1019,10 +1018,10 @@ class NativeUint8ClampedList extends NativeTypedArrayOfInt return JS('JSUInt31', '#[#]', this, index); } - Uint8ClampedList sublist(int start, [int end]) { - end = _checkValidRange(start, end, this.length); + Uint8ClampedList sublist(int start, [int? end]) { + var stop = _checkValidRange(start, end, this.length); var source = - JS('NativeUint8ClampedList', '#.subarray(#, #)', this, start, end); + JS('NativeUint8ClampedList', '#.subarray(#, #)', this, start, stop); return _create1(source); } @@ -1052,7 +1051,7 @@ class NativeUint8List extends NativeTypedArrayOfInt implements Uint8List { _create1(_ensureNativeList(elements)); factory NativeUint8List.view( - ByteBuffer buffer, int offsetInBytes, int length) { + ByteBuffer buffer, int offsetInBytes, int? length) { _checkViewArguments(buffer, offsetInBytes, length); return length == null ? _create2(buffer, offsetInBytes) @@ -1068,9 +1067,9 @@ class NativeUint8List extends NativeTypedArrayOfInt implements Uint8List { return JS('JSUInt31', '#[#]', this, index); } - Uint8List sublist(int start, [int end]) { - end = _checkValidRange(start, end, this.length); - var source = JS('NativeUint8List', '#.subarray(#, #)', this, start, end); + Uint8List sublist(int start, [int? end]) { + var stop = _checkValidRange(start, end, this.length); + var source = JS('NativeUint8List', '#.subarray(#, #)', this, start, stop); return _create1(source); } @@ -1456,7 +1455,7 @@ class NativeInt32x4 implements Int32x4 { floatList[1] = f.y; floatList[2] = f.z; floatList[3] = f.w; - NativeInt32List view = floatList.buffer.asInt32List(); + var view = floatList.buffer.asInt32List(); return NativeInt32x4._truncated(view[0], view[1], view[2], view[3]); } @@ -1674,7 +1673,7 @@ class NativeFloat64x2 implements Float64x2 { final double y; static NativeFloat64List _list = NativeFloat64List(2); - static NativeUint32List _uint32View = _list.buffer.asUint32List(); + static Uint32List _uint32View = _list.buffer.asUint32List(); NativeFloat64x2(this.x, this.y) { if (x is! num) throw ArgumentError(x); @@ -1805,7 +1804,7 @@ void _checkValidIndex(int index, List list, int length) { /// /// Returns the actual value of `end`, which is `length` if `end` is `null`, and /// the original value of `end` otherwise. -int _checkValidRange(int start, int end, int length) { +int _checkValidRange(int start, int? end, int length) { if (_isInvalidArrayIndex(start) || // Ensures start is non-negative int. ((end == null) ? start > length diff --git a/sdk/lib/_internal/js_runtime/lib/regexp_helper.dart b/sdk/lib/_internal/js_runtime/lib/regexp_helper.dart index dc59c106807..8eaad602f0c 100644 --- a/sdk/lib/_internal/js_runtime/lib/regexp_helper.dart +++ b/sdk/lib/_internal/js_runtime/lib/regexp_helper.dart @@ -2,8 +2,6 @@ // 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.6 - part of _js_helper; // Helper method used by internal libraries. @@ -111,8 +109,8 @@ class JSSyntaxRegExp implements RegExp { throw new FormatException('Illegal RegExp pattern ($errorMessage)', source); } - RegExpMatch firstMatch(String string) { - List m = JS('JSExtendableArray|Null', r'#.exec(#)', _nativeRegExp, + RegExpMatch? firstMatch(String string) { + JSArray? m = JS('JSExtendableArray|Null', r'#.exec(#)', _nativeRegExp, checkString(string)); if (m == null) return null; return new _MatchImplementation(this, m); @@ -122,7 +120,7 @@ class JSSyntaxRegExp implements RegExp { return JS('bool', r'#.test(#)', _nativeRegExp, checkString(string)); } - String stringMatch(String string) { + String? stringMatch(String string) { var match = firstMatch(string); if (match != null) return match.group(0); return null; @@ -137,18 +135,18 @@ class JSSyntaxRegExp implements RegExp { return new _AllMatchesIterable(this, string, start); } - RegExpMatch _execGlobal(String string, int start) { + RegExpMatch? _execGlobal(String string, int start) { Object regexp = _nativeGlobalVersion; JS('void', '#.lastIndex = #', regexp, start); - List match = JS('JSExtendableArray|Null', '#.exec(#)', regexp, string); + JSArray? match = JS('JSExtendableArray|Null', '#.exec(#)', regexp, string); if (match == null) return null; return new _MatchImplementation(this, match); } - RegExpMatch _execAnchored(String string, int start) { + RegExpMatch? _execAnchored(String string, int start) { Object regexp = _nativeAnchoredVersion; JS('void', '#.lastIndex = #', regexp, start); - List match = JS('JSExtendableArray|Null', '#.exec(#)', regexp, string); + JSArray? match = JS('JSExtendableArray|Null', '#.exec(#)', regexp, string); if (match == null) return null; // If the last capture group participated, the original regexp did not // match at the start position. @@ -156,7 +154,7 @@ class JSSyntaxRegExp implements RegExp { return new _MatchImplementation(this, match); } - RegExpMatch matchAsPrefix(String string, [int start = 0]) { + RegExpMatch? matchAsPrefix(String string, [int start = 0]) { if (start < 0 || start > string.length) { throw new RangeError.range(start, 0, string.length); } @@ -190,21 +188,20 @@ class _MatchImplementation implements RegExpMatch { int get start => JS('returns:int;depends:none;effects:none;gvn:true', '#.index', _match); - int get end => - start + + int get end => (start + JS('returns:int;depends:none;effects:none;gvn:true', '#[0].length', - _match); + _match)) as int; // The JS below changes the static type to avoid an implicit cast. // TODO(sra): Find a nicer way to do this, e.g. unsafeCast. - String group(int index) => JS('String|Null', '#', _match[index]); + String? group(int index) => JS('String|Null', '#', _match[index]); - String operator [](int index) => group(index); + String? operator [](int index) => group(index); int get groupCount => _match.length - 1; - List groups(List groups) { - List out = []; + List groups(List groups) { + List out = []; for (int i in groups) { out.add(group(i)); } @@ -246,13 +243,13 @@ class _AllMatchesIterable extends IterableBase { class _AllMatchesIterator implements Iterator { final JSSyntaxRegExp _regExp; - String _string; + String? _string; int _nextIndex; - RegExpMatch _current; + RegExpMatch? _current; _AllMatchesIterator(this._regExp, this._string, this._nextIndex); - RegExpMatch get current => _current; + RegExpMatch get current => _current!; static bool _isLeadSurrogate(int c) { return c >= 0xd800 && c <= 0xdbff; @@ -263,9 +260,10 @@ class _AllMatchesIterator implements Iterator { } bool moveNext() { - if (_string == null) return false; - if (_nextIndex <= _string.length) { - var match = _regExp._execGlobal(_string, _nextIndex); + var string = _string; + if (string == null) return false; + if (_nextIndex <= string.length) { + RegExpMatch? match = _regExp._execGlobal(string, _nextIndex); if (match != null) { _current = match; int nextIndex = match.end; @@ -274,9 +272,9 @@ class _AllMatchesIterator implements Iterator { // is in unicode mode and it would put us within a surrogate // pair. In that case, advance past the code point as a whole. if (_regExp.isUnicode && - _nextIndex + 1 < _string.length && - _isLeadSurrogate(_string.codeUnitAt(_nextIndex)) && - _isTrailSurrogate(_string.codeUnitAt(_nextIndex + 1))) { + _nextIndex + 1 < string.length && + _isLeadSurrogate(string.codeUnitAt(_nextIndex)) && + _isTrailSurrogate(string.codeUnitAt(_nextIndex + 1))) { nextIndex++; } nextIndex++; @@ -292,6 +290,6 @@ class _AllMatchesIterator implements Iterator { } /// Find the first match of [regExp] in [string] at or after [start]. -RegExpMatch firstMatchAfter(JSSyntaxRegExp regExp, String string, int start) { +RegExpMatch? firstMatchAfter(JSSyntaxRegExp regExp, String string, int start) { return regExp._execGlobal(string, start); } diff --git a/sdk/lib/_internal/js_runtime/lib/rti.dart b/sdk/lib/_internal/js_runtime/lib/rti.dart index d23d8e24cb3..39ec922797a 100644 --- a/sdk/lib/_internal/js_runtime/lib/rti.dart +++ b/sdk/lib/_internal/js_runtime/lib/rti.dart @@ -2,8 +2,6 @@ // 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.6 - /// This library contains support for runtime type information. library rti; @@ -16,6 +14,7 @@ import 'dart:_foreign_helper' JS_EMBEDDED_GLOBAL, JS_GET_FLAG, JS_GET_NAME, + JS_STRING_CONCAT, RAW_DART_FUNCTION_REF, TYPE_REF, LEGACY_TYPE_REF; @@ -37,6 +36,13 @@ import 'dart:_js_embedded_names' import 'dart:_recipe_syntax'; +// The top type `Object?` is used throughout this library even when values are +// not nullable or have narrower types in order to avoid incurring type checks +// before the type checking infrastructure has been set up. +// We could use `dynamic`, but this would allow inadvertent implicit downcasts. +// TODO(fishythefish, dart-lang/language#115): Replace `Object?` with a typedef +// when possible. + /// An Rti object represents both a type (e.g `Map`) and a type /// environment (`Map` binds `Map.K=int` and `Map.V=String`). /// @@ -53,30 +59,36 @@ class Rti { /// JavaScript method for 'as' check. The method is called from generated code, /// e.g. `o as T` generates something like `rtiForT._as(o)`. @pragma('dart2js:noElision') - dynamic _as; + Object? _as; /// JavaScript method for 'is' test. The method is called from generated /// code, e.g. `o is T` generates something like `rtiForT._is(o)`. @pragma('dart2js:noElision') - dynamic _is; + Object? _is; - static void _setAsCheckFunction(Rti rti, fn) { + static void _setAsCheckFunction(Rti rti, Object? fn) { rti._as = fn; } - static void _setIsTestFunction(Rti rti, fn) { + static void _setIsTestFunction(Rti rti, Object? fn) { rti._is = fn; } @pragma('dart2js:tryInline') - static bool _isCheck(Rti rti, object) { + static bool _asCheck(Rti rti, Object? object) { + return JS( + 'bool', '#.#(#)', rti, JS_GET_NAME(JsGetName.RTI_FIELD_AS), object); + } + + @pragma('dart2js:tryInline') + static bool _isCheck(Rti rti, Object? object) { return JS( 'bool', '#.#(#)', rti, JS_GET_NAME(JsGetName.RTI_FIELD_IS), object); } /// Method called from generated code to evaluate a type environment recipe in /// `this` type environment. - Rti _eval(recipe) { + Rti _eval(Object? recipe) { // TODO(sra): Clone the fast-path of _Universe.evalInEnvironment to here. return _rtiEval(this, _Utils.asString(recipe)); } @@ -84,12 +96,12 @@ class Rti { /// Method called from generated code to extend `this` type environment (an /// interface or binding Rti) with function type arguments (a singleton /// argument or tuple of arguments). - Rti _bind(typeOrTuple) => _rtiBind(this, _castToRti(typeOrTuple)); + Rti _bind(Object? typeOrTuple) => _rtiBind(this, _Utils.asRti(typeOrTuple)); /// Method called from generated code to extend `this` type (as a singleton /// type environment) with function type arguments (a singleton argument or /// tuple of arguments). - Rti _bind1(Rti typeOrTuple) => _rtiBind1(this, typeOrTuple); + Rti _bind1(Object? typeOrTuple) => _rtiBind1(this, _Utils.asRti(typeOrTuple)); // Precomputed derived types. These fields are used to hold derived types that // are computed eagerly. @@ -101,17 +113,17 @@ class Rti { /// If kind == kindStar, holds T? where T is the base type. /// - This case is lazily initialized during subtype checks. @pragma('dart2js:noElision') - dynamic _precomputed1; + Object? _precomputed1; - static Object _getPrecomputed1(Rti rti) => rti._precomputed1; + static Object? _getPrecomputed1(Rti rti) => rti._precomputed1; - static void _setPrecomputed1(Rti rti, precomputed) { + static void _setPrecomputed1(Rti rti, Object? precomputed) { rti._precomputed1 = precomputed; } - static Rti _getQuestionFromStar(universe, Rti rti) { + static Rti _getQuestionFromStar(Object? universe, Rti rti) { assert(_getKind(rti) == kindStar); - Rti question = _castToRtiOrNull(_getPrecomputed1(rti)); + Rti? question = _Utils.asRtiOrNull(_getPrecomputed1(rti)); if (question == null) { question = _Universe._lookupQuestionRti(universe, _getStarArgument(rti), true); @@ -120,9 +132,9 @@ class Rti { return question; } - static Rti _getFutureFromFutureOr(universe, Rti rti) { + static Rti _getFutureFromFutureOr(Object? universe, Rti rti) { assert(_getKind(rti) == kindFutureOr); - Rti future = _castToRtiOrNull(_getPrecomputed1(rti)); + Rti? future = _Utils.asRtiOrNull(_getPrecomputed1(rti)); if (future == null) { future = _Universe._lookupFutureRti(universe, _getFutureOrArgument(rti)); Rti._setPrecomputed1(rti, future); @@ -130,25 +142,25 @@ class Rti { return future; } - dynamic _precomputed2; - dynamic _precomputed3; - dynamic _precomputed4; + Object? _precomputed2; + Object? _precomputed3; + Object? _precomputed4; // Data value used by some tests. @pragma('dart2js:noElision') - Object _specializedTestResource; + Object? _specializedTestResource; - static Object _getSpecializedTestResource(Rti rti) { + static Object? _getSpecializedTestResource(Rti rti) { return rti._specializedTestResource; } - static void _setSpecializedTestResource(Rti rti, Object value) { + static void _setSpecializedTestResource(Rti rti, Object? value) { rti._specializedTestResource = value; } // The Type object corresponding to this Rti. - Object _cachedRuntimeType; - static _Type _getCachedRuntimeType(Rti rti) => + Object? _cachedRuntimeType; + static _Type? _getCachedRuntimeType(Rti rti) => JS('_Type|Null', '#', rti._cachedRuntimeType); static void _setCachedRuntimeType(Rti rti, _Type type) { rti._cachedRuntimeType = type; @@ -160,7 +172,7 @@ class Rti { /// /// The zero initializer ensures dart2js type analysis considers [_kind] is /// non-nullable. - Object /*int*/ _kind = 0; + Object? /*int*/ _kind = 0; static int _getKind(Rti rti) => _Utils.asInt(rti._kind); static void _setKind(Rti rti, int kind) { @@ -168,27 +180,27 @@ class Rti { } // Terminal terms. - static const kindNever = 1; - static const kindDynamic = 2; - static const kindVoid = 3; // TODO(sra): Use `dynamic` instead? - static const kindAny = 4; // Dart1-style 'dynamic' for JS-interop. - static const kindErased = 5; + static const int kindNever = 1; + static const int kindDynamic = 2; + static const int kindVoid = 3; // TODO(sra): Use `dynamic` instead? + static const int kindAny = 4; // Dart1-style 'dynamic' for JS-interop. + static const int kindErased = 5; // Unary terms. - static const kindStar = 6; - static const kindQuestion = 7; - static const kindFutureOr = 8; + static const int kindStar = 6; + static const int kindQuestion = 7; + static const int kindFutureOr = 8; // More complex terms. - static const kindInterface = 9; + static const int kindInterface = 9; // A vector of type parameters from enclosing functions and closures. - static const kindBinding = 10; - static const kindFunction = 11; - static const kindGenericFunction = 12; - static const kindGenericFunctionParameter = 13; + static const int kindBinding = 10; + static const int kindFunction = 11; + static const int kindGenericFunction = 12; + static const int kindGenericFunctionParameter = 13; static bool _isUnionOfFunctionType(Rti rti) { int kind = Rti._getKind(rti); if (kind == kindStar || kind == kindQuestion || kind == kindFutureOr) { - return _isUnionOfFunctionType(_castToRti(_getPrimary(rti))); + return _isUnionOfFunctionType(_Utils.asRti(_getPrimary(rti))); } return kind == kindFunction || kind == kindGenericFunction; } @@ -202,10 +214,10 @@ class Rti { /// - Return type of a function type. /// - Underlying function type for a generic function. /// - de Bruijn index for a generic function parameter. - dynamic _primary; + Object? _primary; - static Object _getPrimary(Rti rti) => rti._primary; - static void _setPrimary(Rti rti, value) { + static Object? _getPrimary(Rti rti) => rti._primary; + static void _setPrimary(Rti rti, Object? value) { rti._primary = value; } @@ -216,10 +228,10 @@ class Rti { /// kindBinding. /// - The [_FunctionParameters] of a function type. /// - The type parameter bounds of a generic function. - dynamic _rest; + Object? _rest; - static Object _getRest(Rti rti) => rti._rest; - static void _setRest(Rti rti, value) { + static Object? _getRest(Rti rti) => rti._rest; + static void _setRest(Rti rti, Object? value) { rti._rest = value; } @@ -237,7 +249,7 @@ class Rti { static Rti _getBindingBase(Rti rti) { assert(_getKind(rti) == kindBinding); - return _castToRti(_getPrimary(rti)); + return _Utils.asRti(_getPrimary(rti)); } static JSArray _getBindingArguments(Rti rti) { @@ -247,22 +259,22 @@ class Rti { static Rti _getStarArgument(Rti rti) { assert(_getKind(rti) == kindStar); - return _castToRti(_getPrimary(rti)); + return _Utils.asRti(_getPrimary(rti)); } static Rti _getQuestionArgument(Rti rti) { assert(_getKind(rti) == kindQuestion); - return _castToRti(_getPrimary(rti)); + return _Utils.asRti(_getPrimary(rti)); } static Rti _getFutureOrArgument(Rti rti) { assert(_getKind(rti) == kindFutureOr); - return _castToRti(_getPrimary(rti)); + return _Utils.asRti(_getPrimary(rti)); } static Rti _getReturnType(Rti rti) { assert(_getKind(rti) == kindFunction); - return _castToRti(_getPrimary(rti)); + return _Utils.asRti(_getPrimary(rti)); } static _FunctionParameters _getFunctionParameters(Rti rti) { @@ -272,7 +284,7 @@ class Rti { static Rti _getGenericFunctionBase(Rti rti) { assert(_getKind(rti) == kindGenericFunction); - return _castToRti(_getPrimary(rti)); + return _Utils.asRti(_getPrimary(rti)); } static JSArray _getGenericFunctionBounds(Rti rti) { @@ -294,10 +306,10 @@ class Rti { /// type environment. The ambiguity between 'generic class is the environment' /// and 'generic class is a singleton type argument' is resolved by using /// different indexing in the recipe. - Object _evalCache; + Object? _evalCache; - static Object _getEvalCache(Rti rti) => rti._evalCache; - static void _setEvalCache(Rti rti, value) { + static Object? _getEvalCache(Rti rti) => rti._evalCache; + static void _setEvalCache(Rti rti, Object? value) { rti._evalCache = value; } @@ -314,10 +326,10 @@ class Rti { /// On [Rti]s that are generic function types, results of instantiation are /// cached on the generic function type to ensure fast repeated /// instantiations. - Object _bindCache; + Object? _bindCache; - static Object _getBindCache(Rti rti) => rti._bindCache; - static void _setBindCache(Rti rti, value) { + static Object? _getBindCache(Rti rti) => rti._bindCache; + static void _setBindCache(Rti rti, Object? value) { rti._bindCache = value; } @@ -325,10 +337,10 @@ class Rti { return new Rti(); } - Object _canonicalRecipe; + Object? _canonicalRecipe; static String _getCanonicalRecipe(Rti rti) { - Object s = rti._canonicalRecipe; + var s = rti._canonicalRecipe; assert(_Utils.isString(s), 'Missing canonical recipe'); return _Utils.asString(s); } @@ -339,45 +351,43 @@ class Rti { } class _FunctionParameters { - // TODO(fishythefish): Support required named parameters. - static _FunctionParameters allocate() => _FunctionParameters(); - Object _requiredPositional; + Object? _requiredPositional; static JSArray _getRequiredPositional(_FunctionParameters parameters) => JS('JSUnmodifiableArray', '#', parameters._requiredPositional); static void _setRequiredPositional( - _FunctionParameters parameters, Object requiredPositional) { + _FunctionParameters parameters, Object? requiredPositional) { parameters._requiredPositional = requiredPositional; } - Object _optionalPositional; + Object? _optionalPositional; static JSArray _getOptionalPositional(_FunctionParameters parameters) => JS('JSUnmodifiableArray', '#', parameters._optionalPositional); static void _setOptionalPositional( - _FunctionParameters parameters, Object optionalPositional) { + _FunctionParameters parameters, Object? optionalPositional) { parameters._optionalPositional = optionalPositional; } - /// These are alternating name/type pairs; that is, the optional named - /// parameters of the function + /// These are a sequence of name/bool/type triplets that correspond to named + /// parameters. /// - /// void foo({int bar, double baz}) + /// void foo({int bar, required double baz}) /// - /// would be encoded as ["bar", int, "baz", double], where the even indices are - /// the name [String]s and the odd indices are the type [Rti]s. + /// would be encoded as ["bar", false, int, "baz", true, double], where each + /// triplet consists of the name [String], a bool indicating whether or not + /// the parameter is required, and the [Rti]. /// - /// Invariant: These pairs are sorted by name in lexicographically ascending order. - Object _optionalNamed; - static JSArray _getOptionalNamed(_FunctionParameters parameters) => - JS('JSUnmodifiableArray', '#', parameters._optionalNamed); - static void _setOptionalNamed( - _FunctionParameters parameters, Object optionalNamed) { - parameters._optionalNamed = optionalNamed; + /// Invariant: These groups are sorted by name in lexicographically ascending order. + Object? _named; + static JSArray _getNamed(_FunctionParameters parameters) => + JS('JSUnmodifiableArray', '#', parameters._named); + static void _setNamed(_FunctionParameters parameters, Object? named) { + parameters._named = named; } } -Object _theUniverse() => JS_EMBEDDED_GLOBAL('', RTI_UNIVERSE); +Object? _theUniverse() => JS_EMBEDDED_GLOBAL('', RTI_UNIVERSE); Rti _rtiEval(Rti environment, String recipe) { return _Universe.evalInEnvironment(_theUniverse(), environment, recipe); @@ -406,7 +416,7 @@ Rti findType(String recipe) { } /// Evaluate a type recipe in the environment of an instance. -Rti evalInInstance(instance, String recipe) { +Rti evalInInstance(Object? instance, String recipe) { return _rtiEval(instanceType(instance), recipe); } @@ -418,8 +428,8 @@ Rti evalInInstance(instance, String recipe) { /// /// Called from generated code. @pragma('dart2js:noInline') -Rti instantiatedGenericFunctionType( - Rti genericFunctionRti, Rti instantiationRti) { +Rti? instantiatedGenericFunctionType( + Rti? genericFunctionRti, Rti instantiationRti) { // If --lax-runtime-type-to-string is enabled and we never check the function // type, then the function won't have a signature, so its RTI will be null. In // this case, there is nothing to instantiate, so we return `null` and the @@ -436,7 +446,7 @@ Rti instantiatedGenericFunctionType( } String key = Rti._getCanonicalRecipe(instantiationRti); var probe = _Utils.mapGet(cache, key); - if (probe != null) return _castToRti(probe); + if (probe != null) return _Utils.asRti(probe); Rti rti = _substitute(_theUniverse(), Rti._getGenericFunctionBase(genericFunctionRti), typeArguments, 0); _Utils.mapSet(cache, key, rti); @@ -455,7 +465,7 @@ Rti instantiatedGenericFunctionType( /// In order to do a partial substitution - that is, substituting only some /// type parameters rather than all of them - we encode the unsubstituted /// positions of the argument list as `undefined` or `null`. -Rti _substitute(universe, Rti rti, Object typeArguments, int depth) { +Rti _substitute(Object? universe, Rti rti, Object? typeArguments, int depth) { int kind = Rti._getKind(rti); switch (kind) { case Rti.kindErased: @@ -465,26 +475,26 @@ Rti _substitute(universe, Rti rti, Object typeArguments, int depth) { case Rti.kindAny: return rti; case Rti.kindStar: - Rti baseType = _castToRti(Rti._getPrimary(rti)); + Rti baseType = _Utils.asRti(Rti._getPrimary(rti)); Rti substitutedBaseType = _substitute(universe, baseType, typeArguments, depth); if (_Utils.isIdentical(substitutedBaseType, baseType)) return rti; return _Universe._lookupStarRti(universe, substitutedBaseType, true); case Rti.kindQuestion: - Rti baseType = _castToRti(Rti._getPrimary(rti)); + Rti baseType = _Utils.asRti(Rti._getPrimary(rti)); Rti substitutedBaseType = _substitute(universe, baseType, typeArguments, depth); if (_Utils.isIdentical(substitutedBaseType, baseType)) return rti; return _Universe._lookupQuestionRti(universe, substitutedBaseType, true); case Rti.kindFutureOr: - Rti baseType = _castToRti(Rti._getPrimary(rti)); + Rti baseType = _Utils.asRti(Rti._getPrimary(rti)); Rti substitutedBaseType = _substitute(universe, baseType, typeArguments, depth); if (_Utils.isIdentical(substitutedBaseType, baseType)) return rti; return _Universe._lookupFutureOrRti(universe, substitutedBaseType, true); case Rti.kindInterface: - Object interfaceTypeArguments = Rti._getInterfaceTypeArguments(rti); - Object substitutedInterfaceTypeArguments = _substituteArray( + var interfaceTypeArguments = Rti._getInterfaceTypeArguments(rti); + var substitutedInterfaceTypeArguments = _substituteArray( universe, interfaceTypeArguments, typeArguments, depth); if (_Utils.isIdentical( substitutedInterfaceTypeArguments, interfaceTypeArguments)) @@ -494,8 +504,8 @@ Rti _substitute(universe, Rti rti, Object typeArguments, int depth) { case Rti.kindBinding: Rti base = Rti._getBindingBase(rti); Rti substitutedBase = _substitute(universe, base, typeArguments, depth); - Object arguments = Rti._getBindingArguments(rti); - Object substitutedArguments = + var arguments = Rti._getBindingArguments(rti); + var substitutedArguments = _substituteArray(universe, arguments, typeArguments, depth); if (_Utils.isIdentical(substitutedBase, base) && _Utils.isIdentical(substitutedArguments, arguments)) return rti; @@ -515,9 +525,9 @@ Rti _substitute(universe, Rti rti, Object typeArguments, int depth) { return _Universe._lookupFunctionRti( universe, substitutedReturnType, substitutedFunctionParameters); case Rti.kindGenericFunction: - Object bounds = Rti._getGenericFunctionBounds(rti); + var bounds = Rti._getGenericFunctionBounds(rti); depth += _Utils.arrayLength(bounds); - Object substitutedBounds = + var substitutedBounds = _substituteArray(universe, bounds, typeArguments, depth); Rti base = Rti._getGenericFunctionBase(rti); Rti substitutedBase = _substitute(universe, base, typeArguments, depth); @@ -536,19 +546,19 @@ Rti _substitute(universe, Rti rti, Object typeArguments, int depth) { // positions of the argument list as `undefined` (which will compare equal // to `null`). if (argument == null) return rti; - return _castToRti(argument); + return _Utils.asRti(argument); default: throw AssertionError('Attempted to substitute unexpected RTI kind $kind'); } } -Object _substituteArray( - universe, Object rtiArray, Object typeArguments, int depth) { +Object? _substituteArray( + Object? universe, Object? rtiArray, Object? typeArguments, int depth) { bool changed = false; int length = _Utils.arrayLength(rtiArray); - Object result = JS('', '[]'); + Object? result = JS('', '[]'); for (int i = 0; i < length; i++) { - Rti rti = _castToRti(_Utils.arrayAt(rtiArray, i)); + Rti rti = _Utils.asRti(_Utils.arrayAt(rtiArray, i)); Rti substitutedRti = _substitute(universe, rti, typeArguments, depth); if (_Utils.isNotIdentical(substitutedRti, rti)) { changed = true; @@ -558,70 +568,69 @@ Object _substituteArray( return changed ? result : rtiArray; } -Object _substituteNamed( - universe, Object namedArray, Object typeArguments, int depth) { +Object? _substituteNamed( + Object? universe, Object? namedArray, Object? typeArguments, int depth) { bool changed = false; int length = _Utils.arrayLength(namedArray); - assert(length.isEven); - Object result = JS('', '[]'); - for (int i = 0; i < length; i += 2) { + assert(_Utils.isMultipleOf(length, 3)); + Object? result = JS('', '[]'); + for (int i = 0; i < length; i += 3) { String name = _Utils.asString(_Utils.arrayAt(namedArray, i)); - Rti rti = _castToRti(_Utils.arrayAt(namedArray, i + 1)); + bool isRequired = _Utils.asBool(_Utils.arrayAt(namedArray, i + 1)); + Rti rti = _Utils.asRti(_Utils.arrayAt(namedArray, i + 2)); Rti substitutedRti = _substitute(universe, rti, typeArguments, depth); if (_Utils.isNotIdentical(substitutedRti, rti)) { changed = true; } _Utils.arrayPush(result, name); + _Utils.arrayPush(result, isRequired); _Utils.arrayPush(result, substitutedRti); } return changed ? result : namedArray; } -// TODO(fishythefish): Support required named parameters. -_FunctionParameters _substituteFunctionParameters(universe, - _FunctionParameters functionParameters, Object typeArguments, int depth) { - Object requiredPositional = +_FunctionParameters _substituteFunctionParameters(Object? universe, + _FunctionParameters functionParameters, Object? typeArguments, int depth) { + var requiredPositional = _FunctionParameters._getRequiredPositional(functionParameters); - Object substitutedRequiredPositional = + var substitutedRequiredPositional = _substituteArray(universe, requiredPositional, typeArguments, depth); - Object optionalPositional = + var optionalPositional = _FunctionParameters._getOptionalPositional(functionParameters); - Object substitutedOptionalPositional = + var substitutedOptionalPositional = _substituteArray(universe, optionalPositional, typeArguments, depth); - Object optionalNamed = - _FunctionParameters._getOptionalNamed(functionParameters); - Object substitutedOptionalNamed = - _substituteNamed(universe, optionalNamed, typeArguments, depth); + var named = _FunctionParameters._getNamed(functionParameters); + var substitutedNamed = + _substituteNamed(universe, named, typeArguments, depth); if (_Utils.isIdentical(substitutedRequiredPositional, requiredPositional) && _Utils.isIdentical(substitutedOptionalPositional, optionalPositional) && - _Utils.isIdentical(substitutedOptionalNamed, optionalNamed)) - return functionParameters; + _Utils.isIdentical(substitutedNamed, named)) return functionParameters; _FunctionParameters result = _FunctionParameters.allocate(); _FunctionParameters._setRequiredPositional( result, substitutedRequiredPositional); _FunctionParameters._setOptionalPositional( result, substitutedOptionalPositional); - _FunctionParameters._setOptionalNamed(result, substitutedOptionalNamed); + _FunctionParameters._setNamed(result, substitutedNamed); return result; } -bool _isDartObject(object) => _Utils.instanceOf(object, +bool _isDartObject(Object? object) => _Utils.instanceOf(object, JS_BUILTIN('depends:none;effects:none;', JsBuiltin.dartObjectConstructor)); -bool _isClosure(object) => _Utils.instanceOf(object, +bool _isClosure(Object? object) => _Utils.instanceOf(object, JS_BUILTIN('depends:none;effects:none;', JsBuiltin.dartClosureConstructor)); /// Returns the structural function [Rti] of [closure], or `null`. /// [closure] must be a subclass of [Closure]. /// Called from generated code. -Rti closureFunctionType(closure) { +Rti? closureFunctionType(Object? closure) { var signatureName = JS_GET_NAME(JsGetName.SIGNATURE_NAME); var signature = JS('', '#[#]', closure, signatureName); if (signature != null) { if (JS('bool', 'typeof # == "number"', signature)) { return getTypeFromTypesTable(_Utils.asInt(signature)); } - return _castToRti(JS('', '#[#]()', closure, signatureName)); + return _Utils.asRti(JS('', '#[#]()', closure, signatureName)); } return null; } @@ -631,13 +640,13 @@ Rti closureFunctionType(closure) { /// [testRti] to choose the appropriate type. /// /// Called from generated code. -Rti instanceOrFunctionType(object, Rti testRti) { +Rti instanceOrFunctionType(Object? object, Rti testRti) { if (Rti._isUnionOfFunctionType(testRti)) { if (_isClosure(object)) { // If [testRti] is e.g. `FutureOr` (where `Action` is some // function type), we don't need to worry about the `Future` // branch because closures can't be `Future`s. - Rti rti = closureFunctionType(object); + Rti? rti = closureFunctionType(object); if (rti != null) return rti; } } @@ -647,7 +656,7 @@ Rti instanceOrFunctionType(object, Rti testRti) { /// Returns the Rti type of [object]. /// This is the general entry for obtaining the interface type of any value. /// Called from generated code. -Rti instanceType(object) { +Rti instanceType(Object? object) { // TODO(sra): Add interceptor-based specializations of this method. Inject a // _getRti method into (Dart)Object, JSArray, and Interceptor. Then calls to // this method can be generated as `getInterceptor(o)._getRti(o)`, allowing @@ -670,7 +679,7 @@ Rti instanceType(object) { /// Returns the Rti type of JavaScript Array [object]. /// Called from generated code. -Rti _arrayInstanceType(object) { +Rti _arrayInstanceType(Object? object) { // A JavaScript Array can come from three places: // 1. This Dart program. // 2. Another Dart program loaded in the JavaScript environment. @@ -691,40 +700,40 @@ Rti _arrayInstanceType(object) { var defaultRti = getJSArrayInteropRti(); // Case 3. - if (rti == null) return _castToRti(defaultRti); + if (rti == null) return _Utils.asRti(defaultRti); // Case 2 and perhaps case 3. Check constructor of extracted type against a // known instance of Rti - this is an easy way to get the constructor. if (JS('bool', '#.constructor !== #.constructor', rti, defaultRti)) { - return _castToRti(defaultRti); + return _Utils.asRti(defaultRti); } // Case 1. - return _castToRti(rti); + return _Utils.asRti(rti); } /// Returns the Rti type of user-defined class [object]. /// [object] must not be an intercepted class or a closure. /// Called from generated code. -Rti _instanceType(object) { +Rti _instanceType(Object? object) { var rti = JS('', r'#[#]', object, JS_GET_NAME(JsGetName.RTI_NAME)); - return rti != null ? _castToRti(rti) : _instanceTypeFromConstructor(object); + return rti != null ? _Utils.asRti(rti) : _instanceTypeFromConstructor(object); } -String instanceTypeName(object) { +String instanceTypeName(Object? object) { Rti rti = instanceType(object); return _rtiToString(rti, null); } -Rti _instanceTypeFromConstructor(instance) { +Rti _instanceTypeFromConstructor(Object? instance) { var constructor = JS('', '#.constructor', instance); var probe = JS('', r'#[#]', constructor, CONSTRUCTOR_RTI_CACHE_PROPERTY_NAME); - if (probe != null) return _castToRti(probe); + if (probe != null) return _Utils.asRti(probe); return _instanceTypeFromConstructorMiss(instance, constructor); } @pragma('dart2js:noInline') -Rti _instanceTypeFromConstructorMiss(instance, constructor) { +Rti _instanceTypeFromConstructorMiss(Object? instance, Object? constructor) { // Subclasses of Closure are synthetic classes. The synthetic classes all // extend a 'normal' class (Closure, BoundClosure, StaticClosure), so make // them appear to be the superclass. Instantiations have a `$ti` field so @@ -746,13 +755,12 @@ Rti _instanceTypeFromConstructorMiss(instance, constructor) { /// Returns the structural function type of [object], or `null` if the object is /// not a closure. -Rti _instanceFunctionType(object) => +Rti? _instanceFunctionType(Object? object) => _isClosure(object) ? closureFunctionType(object) : null; /// Returns Rti from types table. The types table is initialized with recipe /// strings. -Rti getTypeFromTypesTable(/*int*/ _index) { - int index = _Utils.asInt(_index); +Rti getTypeFromTypesTable(int index) { var table = JS_EMBEDDED_GLOBAL('', TYPES); var type = _Utils.arrayAt(table, index); if (_Utils.isString(type)) { @@ -760,17 +768,17 @@ Rti getTypeFromTypesTable(/*int*/ _index) { _Utils.arraySetAt(table, index, rti); return rti; } - return _castToRti(type); + return _Utils.asRti(type); } -Type getRuntimeType(object) { +Type getRuntimeType(Object? object) { Rti rti = _instanceFunctionType(object) ?? instanceType(object); return createRuntimeType(rti); } /// Called from generated code. Type createRuntimeType(Rti rti) { - _Type type = Rti._getCachedRuntimeType(rti); + _Type? type = Rti._getCachedRuntimeType(rti); if (type != null) return type; if (JS_GET_FLAG('PRINT_LEGACY_STARS')) { return _Type(rti); @@ -817,69 +825,139 @@ class _Type implements Type { // (e.g. we lower a check to a direct helper), and (2) `bool` does not flow to a // tested type parameter. The trick will be to ensure that `H._isBool` is // generated. -bool _installSpecializedIsTest(object) { +bool _installSpecializedIsTest(Object? object) { // This static method is installed on an Rti object as a JavaScript instance // method. The Rti object is 'this'. - Rti testRti = _castToRti(JS('', 'this')); - - var isFn = RAW_DART_FUNCTION_REF(_generalIsTestImplementation); + Rti testRti = _Utils.asRti(JS('', 'this')); if (isObjectType(testRti)) { - isFn = RAW_DART_FUNCTION_REF(_isObject); - Rti._setAsCheckFunction(testRti, RAW_DART_FUNCTION_REF(_asObject)); - } else if (isTopType(testRti)) { - isFn = RAW_DART_FUNCTION_REF(_isTop); - var asFn = RAW_DART_FUNCTION_REF(_asTop); - Rti._setAsCheckFunction(testRti, asFn); - } else if (_Utils.isIdentical(testRti, TYPE_REF())) { + return _finishIsFn(testRti, object, RAW_DART_FUNCTION_REF(_isObject)); + } + if (isTopType(testRti)) { + return _finishIsFn(testRti, object, RAW_DART_FUNCTION_REF(_isTop)); + } + + // `o is T*` generally behaves like `o is T`. + // The exeptions are `Object*` (handled above) and `Never*` + // + // `null is Never` --> `false` + // `null is Never*` --> `true` + Rti unstarred = Rti._getKind(testRti) == Rti.kindStar + ? Rti._getStarArgument(testRti) + : testRti; + + var isFn = _simpleSpecializedIsTest(unstarred); + if (isFn != null) { + return _finishIsFn(testRti, object, isFn); + } + + if (Rti._getKind(unstarred) == Rti.kindInterface) { + String name = Rti._getInterfaceName(unstarred); + var arguments = Rti._getInterfaceTypeArguments(unstarred); + // This recognizes interface types instantiated with Top, which includes the + // common case of interfaces that have no type parameters. + // TODO(sra): Can we easily recognize other interface types instantiated to + // bounds? + if (JS('bool', '#.every(#)', arguments, RAW_DART_FUNCTION_REF(isTopType))) { + String propertyName = + '${JS_GET_NAME(JsGetName.OPERATOR_IS_PREFIX)}${name}'; + Rti._setSpecializedTestResource(testRti, propertyName); + return _finishIsFn( + testRti, object, RAW_DART_FUNCTION_REF(_isTestViaProperty)); + } + // fall through to general implementation. + } else if (Rti._getKind(testRti) == Rti.kindQuestion) { + return _finishIsFn(testRti, object, + RAW_DART_FUNCTION_REF(_generalNullableIsTestImplementation)); + } + return _finishIsFn( + testRti, object, RAW_DART_FUNCTION_REF(_generalIsTestImplementation)); +} + +@pragma('dart2js:noInline') // Slightly smaller code. +bool _finishIsFn(Rti testRti, Object? object, Object? isFn) { + Rti._setIsTestFunction(testRti, isFn); + return Rti._isCheck(testRti, object); +} + +Object? _simpleSpecializedIsTest(Rti testRti) { + // Note: We must not match `Never` below. + var isFn = null; + if (_Utils.isIdentical(testRti, TYPE_REF())) { isFn = RAW_DART_FUNCTION_REF(_isInt); - } else if (_Utils.isIdentical(testRti, TYPE_REF())) { - isFn = RAW_DART_FUNCTION_REF(_isNum); - } else if (_Utils.isIdentical(testRti, TYPE_REF())) { + } else if (_Utils.isIdentical(testRti, TYPE_REF()) || + _Utils.isIdentical(testRti, TYPE_REF())) { isFn = RAW_DART_FUNCTION_REF(_isNum); } else if (_Utils.isIdentical(testRti, TYPE_REF())) { isFn = RAW_DART_FUNCTION_REF(_isString); } else if (_Utils.isIdentical(testRti, TYPE_REF())) { isFn = RAW_DART_FUNCTION_REF(_isBool); - } else if (Rti._getKind(testRti) == Rti.kindInterface) { - String name = Rti._getInterfaceName(testRti); - var arguments = Rti._getInterfaceTypeArguments(testRti); - if (JS('bool', '#.every(#)', arguments, RAW_DART_FUNCTION_REF(isTopType))) { - String propertyName = - '${JS_GET_NAME(JsGetName.OPERATOR_IS_PREFIX)}${name}'; - Rti._setSpecializedTestResource(testRti, propertyName); - isFn = RAW_DART_FUNCTION_REF(_isTestViaProperty); + } + return isFn; +} + +/// Called from generated code. +/// +/// The first time this default `_as` method is called, it replaces itself with +/// a specialized version. +bool _installSpecializedAsCheck(Object? object) { + // This static method is installed on an Rti object as a JavaScript instance + // method. The Rti object is 'this'. + Rti testRti = _Utils.asRti(JS('', 'this')); + + var asFn = RAW_DART_FUNCTION_REF(_generalAsCheckImplementation); + if (isTopType(testRti)) { + asFn = RAW_DART_FUNCTION_REF(_asTop); + } else if (isObjectType(testRti)) { + asFn = RAW_DART_FUNCTION_REF(_asObject); + } else { + if (JS_GET_FLAG('LEGACY') || isNullable(testRti)) { + asFn = RAW_DART_FUNCTION_REF(_generalNullableAsCheckImplementation); } } - Rti._setIsTestFunction(testRti, isFn); - return Rti._isCheck(testRti, object); + Rti._setAsCheckFunction(testRti, asFn); + return Rti._asCheck(testRti, object); } bool _nullIs(Rti testRti) { int kind = Rti._getKind(testRti); return isTopType(testRti) || - kind == Rti.kindStar && - Rti._getKind(Rti._getStarArgument(testRti)) == Rti.kindNever || + _Utils.isIdentical(testRti, LEGACY_TYPE_REF()) || kind == Rti.kindQuestion || isNullType(testRti); } /// Called from generated code. -bool _generalIsTestImplementation(object) { +bool _generalIsTestImplementation(Object? object) { // This static method is installed on an Rti object as a JavaScript instance // method. The Rti object is 'this'. - Rti testRti = _castToRti(JS('', 'this')); + Rti testRti = _Utils.asRti(JS('', 'this')); if (object == null) return _nullIs(testRti); Rti objectRti = instanceOrFunctionType(object, testRti); return isSubtype(_theUniverse(), objectRti, testRti); } +/// Specialized test for `x is T1` where `T1` has the form `T2?`. Test is +/// compositional, calling `T2._is(object)`, so if `T2` has a specialized +/// version, the composed test will be fast (but not quite as fast as a +/// single-step specialization). +/// /// Called from generated code. -bool _isTestViaProperty(object) { +bool _generalNullableIsTestImplementation(Object? object) { + if (object == null) return true; // This static method is installed on an Rti object as a JavaScript instance // method. The Rti object is 'this'. - Rti testRti = _castToRti(JS('', 'this')); + Rti testRti = _Utils.asRti(JS('', 'this')); + Rti baseRti = Rti._getQuestionArgument(testRti); + return Rti._isCheck(baseRti, object); +} + +/// Called from generated code. +bool _isTestViaProperty(Object? object) { + // This static method is installed on an Rti object as a JavaScript instance + // method. The Rti object is 'this'. + Rti testRti = _Utils.asRti(JS('', 'this')); if (object == null) return _nullIs(testRti); var tag = Rti._getSpecializedTestResource(testRti); @@ -894,15 +972,31 @@ bool _isTestViaProperty(object) { return JS('bool', '!!#[#]', interceptor, tag); } +/// General unspecialized 'as' check that works for any type. /// Called from generated code. -_generalAsCheckImplementation(object) { +Object? _generalAsCheckImplementation(Object? object) { // This static method is installed on an Rti object as a JavaScript instance // method. The Rti object is 'this'. - Rti testRti = _castToRti(JS('', 'this')); + Rti testRti = _Utils.asRti(JS('', 'this')); if (object == null) { if (JS_GET_FLAG('LEGACY') || isNullable(testRti)) return object; } else if (Rti._isCheck(testRti, object)) return object; + _failedAsCheck(object, testRti); +} +/// General 'as' check for types that accept `null`. +/// Called from generated code. +Object? _generalNullableAsCheckImplementation(Object? object) { + // This static method is installed on an Rti object as a JavaScript instance + // method. The Rti object is 'this'. + Rti testRti = _Utils.asRti(JS('', 'this')); + if (object == null) { + return object; + } else if (Rti._isCheck(testRti, object)) return object; + _failedAsCheck(object, testRti); +} + +void _failedAsCheck(Object? object, Rti testRti) { Rti objectRti = instanceOrFunctionType(object, testRti); String message = _Error.compose(object, objectRti, _rtiToString(testRti, null)); @@ -910,11 +1004,11 @@ _generalAsCheckImplementation(object) { } /// Called from generated code. -checkTypeBound(Rti type, Rti bound, variable, methodName) { +Rti checkTypeBound(Rti type, Rti bound, String variable, String methodName) { if (isSubtype(_theUniverse(), type, bound)) return type; String message = "The type argument '${_rtiToString(type, null)}' is not" " a subtype of the type variable bound '${_rtiToString(bound, null)}'" - " of type variable '${_Utils.asString(variable)}' in '$methodName'."; + " of type variable '$variable' in '$methodName'."; throw _TypeError.fromMessage(message); } @@ -928,7 +1022,8 @@ class _Error extends Error { final String _message; _Error(this._message); - static String compose(object, objectRti, checkedTypeDescription) { + static String compose( + Object? object, Rti? objectRti, String checkedTypeDescription) { String objectDescription = Error.safeToString(object); objectRti ??= instanceType(object); String objectTypeDescription = _rtiToString(objectRti, null); @@ -959,38 +1054,40 @@ class _TypeError extends _Error implements TypeError, CastError { /// Specialization for 'is Object'. /// Called from generated code via Rti `_is` method. -bool _isObject(object) { +bool _isObject(Object? object) { return !JS_GET_FLAG('NNBD') || object != null; } /// Specialization for 'as Object'. /// Called from generated code via Rti `_as` method. -dynamic _asObject(object) { +Object? _asObject(Object? object) { if (JS_GET_FLAG('LEGACY') || object != null) return object; throw _TypeError.forType(object, 'Object'); } /// Specialization for 'is dynamic' and other top types. /// Called from generated code via Rti `_is` method. -bool _isTop(object) { +bool _isTop(Object? object) { return true; } /// Specialization for 'as dynamic' and other top types. /// Called from generated code via Rti `_as` methods. -dynamic _asTop(object) { +Object? _asTop(Object? object) { return object; } /// Specialization for 'is bool'. /// Called from generated code. -bool _isBool(object) { +bool _isBool(Object? object) { return true == object || false == object; } -/// Specialization for 'as bool?'. +// TODO(fishythefish): Change `dynamic` to `Object?` below once promotion works. + +/// Specialization for 'as bool'. /// Called from generated code. -bool _asBool(object) { +bool _asBool(Object? object) { if (true == object) return true; if (false == object) return false; throw _TypeError.forType(object, 'bool'); @@ -998,7 +1095,7 @@ bool _asBool(object) { /// Specialization for 'as bool*'. /// Called from generated code. -bool /*?*/ _asBoolS(object) { +bool? _asBoolS(dynamic object) { if (true == object) return true; if (false == object) return false; if (object == null) return object; @@ -1007,7 +1104,7 @@ bool /*?*/ _asBoolS(object) { /// Specialization for 'as bool?'. /// Called from generated code. -bool /*?*/ _asBoolQ(object) { +bool? _asBoolQ(dynamic object) { if (true == object) return true; if (false == object) return false; if (object == null) return object; @@ -1016,14 +1113,14 @@ bool /*?*/ _asBoolQ(object) { /// Specialization for 'as double'. /// Called from generated code. -double /*?*/ _asDouble(object) { +double _asDouble(Object? object) { if (_isNum(object)) return _Utils.asDouble(object); throw _TypeError.forType(object, 'double'); } /// Specialization for 'as double*'. /// Called from generated code. -double /*?*/ _asDoubleS(object) { +double? _asDoubleS(dynamic object) { if (_isNum(object)) return _Utils.asDouble(object); if (object == null) return object; throw _TypeError.forType(object, 'double'); @@ -1031,7 +1128,7 @@ double /*?*/ _asDoubleS(object) { /// Specialization for 'as double?'. /// Called from generated code. -double /*?*/ _asDoubleQ(object) { +double? _asDoubleQ(dynamic object) { if (_isNum(object)) return _Utils.asDouble(object); if (object == null) return object; throw _TypeError.forType(object, 'double?'); @@ -1039,21 +1136,21 @@ double /*?*/ _asDoubleQ(object) { /// Specialization for 'is int'. /// Called from generated code. -bool _isInt(object) { +bool _isInt(Object? object) { return JS('bool', 'typeof # == "number"', object) && JS('bool', 'Math.floor(#) === #', object, object); } /// Specialization for 'as int'. /// Called from generated code. -int _asInt(object) { +int _asInt(Object? object) { if (_isInt(object)) return _Utils.asInt(object); throw _TypeError.forType(object, 'int'); } /// Specialization for 'as int*'. /// Called from generated code. -int /*?*/ _asIntS(object) { +int? _asIntS(dynamic object) { if (_isInt(object)) return _Utils.asInt(object); if (object == null) return object; throw _TypeError.forType(object, 'int'); @@ -1061,7 +1158,7 @@ int /*?*/ _asIntS(object) { /// Specialization for 'as int?'. /// Called from generated code. -int /*?*/ _asIntQ(object) { +int? _asIntQ(dynamic object) { if (_isInt(object)) return _Utils.asInt(object); if (object == null) return object; throw _TypeError.forType(object, 'int?'); @@ -1069,20 +1166,20 @@ int /*?*/ _asIntQ(object) { /// Specialization for 'is num' and 'is double'. /// Called from generated code. -bool _isNum(object) { +bool _isNum(Object? object) { return JS('bool', 'typeof # == "number"', object); } -/// Specialization for 'as num?'. +/// Specialization for 'as num'. /// Called from generated code. -num _asNum(object) { +num _asNum(Object? object) { if (_isNum(object)) return _Utils.asNum(object); throw _TypeError.forType(object, 'num'); } /// Specialization for 'as num*'. /// Called from generated code. -num /*?*/ _asNumS(object) { +num? _asNumS(dynamic object) { if (_isNum(object)) return _Utils.asNum(object); if (object == null) return object; throw _TypeError.forType(object, 'num'); @@ -1090,7 +1187,7 @@ num /*?*/ _asNumS(object) { /// Specialization for 'as num?'. /// Called from generated code. -num /*?*/ _asNumQ(object) { +num? _asNumQ(dynamic object) { if (_isNum(object)) return _Utils.asNum(object); if (object == null) return object; throw _TypeError.forType(object, 'num?'); @@ -1098,20 +1195,20 @@ num /*?*/ _asNumQ(object) { /// Specialization for 'is String'. /// Called from generated code. -bool _isString(object) { +bool _isString(Object? object) { return JS('bool', 'typeof # == "string"', object); } /// Specialization for 'as String'. /// Called from generated code. -String _asString(object) { +String _asString(Object? object) { if (_isString(object)) return _Utils.asString(object); throw _TypeError.forType(object, 'String'); } /// Specialization for 'as String*'. /// Called from generated code. -String /*?*/ _asStringS(object) { +String? _asStringS(dynamic object) { if (_isString(object)) return _Utils.asString(object); if (object == null) return object; throw _TypeError.forType(object, 'String'); @@ -1119,26 +1216,26 @@ String /*?*/ _asStringS(object) { /// Specialization for 'as String?'. /// Called from generated code. -String /*?*/ _asStringQ(object) { +String? _asStringQ(dynamic object) { if (_isString(object)) return _Utils.asString(object); if (object == null) return object; throw _TypeError.forType(object, 'String?'); } -String _rtiArrayToString(Object array, List genericContext) { +String _rtiArrayToString(Object? array, List? genericContext) { String s = '', sep = ''; for (int i = 0; i < _Utils.arrayLength(array); i++) { s += sep + - _rtiToString(_castToRti(_Utils.arrayAt(array, i)), genericContext); + _rtiToString(_Utils.asRti(_Utils.arrayAt(array, i)), genericContext); sep = ', '; } return s; } -String _functionRtiToString(Rti functionType, List genericContext, - {Object bounds = null}) { +String _functionRtiToString(Rti functionType, List? genericContext, + {Object? bounds = null}) { String typeParametersText = ''; - int outerContextLength; + int? outerContextLength; if (bounds != null) { int boundsLength = _Utils.arrayLength(bounds); @@ -1157,7 +1254,7 @@ String _functionRtiToString(Rti functionType, List genericContext, for (int i = 0; i < boundsLength; i++) { typeParametersText += typeSep; typeParametersText += genericContext[genericContext.length - 1 - i]; - Rti boundRti = _castToRti(_Utils.arrayAt(bounds, i)); + Rti boundRti = _Utils.asRti(_Utils.arrayAt(bounds, i)); if (!isTopType(boundRti)) { typeParametersText += ' extends ' + _rtiToString(boundRti, genericContext); @@ -1167,7 +1264,6 @@ String _functionRtiToString(Rti functionType, List genericContext, typeParametersText += '>'; } - // TODO(fishythefish): Support required named parameters. Rti returnType = Rti._getReturnType(functionType); _FunctionParameters parameters = Rti._getFunctionParameters(functionType); var requiredPositional = @@ -1176,9 +1272,9 @@ String _functionRtiToString(Rti functionType, List genericContext, var optionalPositional = _FunctionParameters._getOptionalPositional(parameters); int optionalPositionalLength = _Utils.arrayLength(optionalPositional); - var optionalNamed = _FunctionParameters._getOptionalNamed(parameters); - int optionalNamedLength = _Utils.arrayLength(optionalNamed); - assert(optionalPositionalLength == 0 || optionalNamedLength == 0); + var named = _FunctionParameters._getNamed(parameters); + int namedLength = _Utils.arrayLength(named); + assert(optionalPositionalLength == 0 || namedLength == 0); String returnTypeText = _rtiToString(returnType, genericContext); @@ -1186,8 +1282,8 @@ String _functionRtiToString(Rti functionType, List genericContext, String sep = ''; for (int i = 0; i < requiredPositionalLength; i++) { argumentsText += sep + - _rtiToString( - _castToRti(_Utils.arrayAt(requiredPositional, i)), genericContext); + _rtiToString(_Utils.asRti(_Utils.arrayAt(requiredPositional, i)), + genericContext); sep = ', '; } @@ -1196,22 +1292,25 @@ String _functionRtiToString(Rti functionType, List genericContext, sep = ''; for (int i = 0; i < optionalPositionalLength; i++) { argumentsText += sep + - _rtiToString(_castToRti(_Utils.arrayAt(optionalPositional, i)), + _rtiToString(_Utils.asRti(_Utils.arrayAt(optionalPositional, i)), genericContext); sep = ', '; } argumentsText += ']'; } - if (optionalNamedLength > 0) { + if (namedLength > 0) { argumentsText += sep + '{'; sep = ''; - for (int i = 0; i < optionalNamedLength; i += 2) { - argumentsText += sep + - _rtiToString(_castToRti(_Utils.arrayAt(optionalNamed, i + 1)), - genericContext) + + for (int i = 0; i < namedLength; i += 3) { + argumentsText += sep; + if (_Utils.asBool(_Utils.arrayAt(named, i + 1))) { + argumentsText += 'required '; + } + argumentsText += _rtiToString( + _Utils.asRti(_Utils.arrayAt(named, i + 2)), genericContext) + ' ' + - _Utils.asString(_Utils.arrayAt(optionalNamed, i)); + _Utils.asString(_Utils.arrayAt(named, i)); sep = ', '; } argumentsText += '}'; @@ -1219,7 +1318,7 @@ String _functionRtiToString(Rti functionType, List genericContext, if (outerContextLength != null) { // Pop all of the generic type parameters. - JS('', '#.length = #', genericContext, outerContextLength); + JS('', '#.length = #', genericContext!, outerContextLength); } // TODO(fishythefish): Below is the same format as the VM. Change to: @@ -1229,7 +1328,7 @@ String _functionRtiToString(Rti functionType, List genericContext, return '${typeParametersText}(${argumentsText}) => ${returnTypeText}'; } -String _rtiToString(Rti rti, List genericContext) { +String _rtiToString(Rti rti, List? genericContext) { int kind = Rti._getKind(rti); if (kind == Rti.kindErased) return 'erased'; @@ -1285,36 +1384,36 @@ String _rtiToString(Rti rti, List genericContext) { if (kind == Rti.kindGenericFunction) { Rti baseFunctionType = Rti._getGenericFunctionBase(rti); - Object bounds = Rti._getGenericFunctionBounds(rti); + var bounds = Rti._getGenericFunctionBounds(rti); return _functionRtiToString(baseFunctionType, genericContext, bounds: bounds); } if (kind == Rti.kindGenericFunctionParameter) { + var context = genericContext!; int index = Rti._getGenericFunctionParameterIndex(rti); - return genericContext[genericContext.length - 1 - index]; + return context[context.length - 1 - index]; } return '?'; } String _unminifyOrTag(String rawClassName) { - String preserved = unmangleGlobalNameIfPreservedAnyways(rawClassName); + String? preserved = unmangleGlobalNameIfPreservedAnyways(rawClassName); if (preserved != null) return preserved; return JS_GET_FLAG('MINIFIED') ? 'minified:$rawClassName' : rawClassName; } -String _rtiArrayToDebugString(Object array) { +String _rtiArrayToDebugString(Object? array) { String s = '[', sep = ''; for (int i = 0; i < _Utils.arrayLength(array); i++) { - s += sep + _rtiToDebugString(_castToRti(_Utils.arrayAt(array, i))); + s += sep + _rtiToDebugString(_Utils.asRti(_Utils.arrayAt(array, i))); sep = ', '; } return s + ']'; } String functionParametersToString(_FunctionParameters parameters) { - // TODO(fishythefish): Support required named parameters. String s = '(', sep = ''; var requiredPositional = _FunctionParameters._getRequiredPositional(parameters); @@ -1322,13 +1421,13 @@ String functionParametersToString(_FunctionParameters parameters) { var optionalPositional = _FunctionParameters._getOptionalPositional(parameters); int optionalPositionalLength = _Utils.arrayLength(optionalPositional); - var optionalNamed = _FunctionParameters._getOptionalNamed(parameters); - int optionalNamedLength = _Utils.arrayLength(optionalNamed); - assert(optionalPositionalLength == 0 || optionalNamedLength == 0); + var named = _FunctionParameters._getNamed(parameters); + int namedLength = _Utils.arrayLength(named); + assert(optionalPositionalLength == 0 || namedLength == 0); for (int i = 0; i < requiredPositionalLength; i++) { s += sep + - _rtiToDebugString(_castToRti(_Utils.arrayAt(requiredPositional, i))); + _rtiToDebugString(_Utils.asRti(_Utils.arrayAt(requiredPositional, i))); sep = ', '; } @@ -1337,20 +1436,24 @@ String functionParametersToString(_FunctionParameters parameters) { sep = ''; for (int i = 0; i < optionalPositionalLength; i++) { s += sep + - _rtiToDebugString(_castToRti(_Utils.arrayAt(optionalPositional, i))); + _rtiToDebugString( + _Utils.asRti(_Utils.arrayAt(optionalPositional, i))); sep = ', '; } s += ']'; } - if (optionalNamedLength > 0) { + if (namedLength > 0) { s += sep + '{'; sep = ''; - for (int i = 0; i < optionalNamedLength; i += 2) { - s += sep + - _rtiToDebugString(_castToRti(_Utils.arrayAt(optionalNamed, i + 1))) + + for (int i = 0; i < namedLength; i += 3) { + s += sep; + if (_Utils.asBool(_Utils.arrayAt(named, i + 1))) { + s += 'required '; + } + s += _rtiToDebugString(_Utils.asRti(_Utils.arrayAt(named, i + 2))) + ' ' + - _Utils.asString(_Utils.arrayAt(optionalNamed, i)); + _Utils.asString(_Utils.arrayAt(named, i)); sep = ', '; } s += '}'; @@ -1407,7 +1510,7 @@ String _rtiToDebugString(Rti rti) { if (kind == Rti.kindGenericFunction) { Rti baseFunctionType = Rti._getGenericFunctionBase(rti); - Object bounds = Rti._getGenericFunctionBounds(rti); + var bounds = Rti._getGenericFunctionBounds(rti); return 'genericFunction(${_rtiToDebugString(baseFunctionType)}, ${_rtiArrayToDebugString(bounds)})'; } @@ -1452,38 +1555,38 @@ class _Universe { // Field accessors. - static evalCache(universe) => + static Object evalCache(Object? universe) => JS('', '#.#', universe, RtiUniverseFieldNames.evalCache); - static Object typeRules(universe) => + static Object typeRules(Object? universe) => JS('', '#.#', universe, RtiUniverseFieldNames.typeRules); - static Object erasedTypes(universe) => + static Object erasedTypes(Object? universe) => JS('', '#.#', universe, RtiUniverseFieldNames.erasedTypes); - static Object typeParameterVariances(universe) => + static Object typeParameterVariances(Object? universe) => JS('', '#.#', universe, RtiUniverseFieldNames.typeParameterVariances); - static Object _findRule(universe, String targetType) => + static Object? _findRule(Object? universe, String targetType) => JS('', '#.#', typeRules(universe), targetType); - static Object findRule(universe, String targetType) { - Object rule = _findRule(universe, targetType); + static Object? findRule(Object? universe, String targetType) { + var rule = _findRule(universe, targetType); while (_Utils.isString(rule)) { rule = _findRule(universe, _Utils.asString(rule)); } return rule; } - static Rti findErasedType(universe, String cls) { - Object metadata = erasedTypes(universe); + static Rti findErasedType(Object? universe, String cls) { + var metadata = erasedTypes(universe); var probe = JS('', '#.#', metadata, cls); if (probe == null) { return eval(universe, cls, false); } else if (_Utils.isNum(probe)) { int length = _Utils.asInt(probe); Rti erased = _lookupErasedRti(universe); - Object arguments = JS('', '[]'); + Object? arguments = JS('', '[]'); for (int i = 0; i < length; i++) { _Utils.arrayPush(arguments, erased); } @@ -1491,58 +1594,58 @@ class _Universe { JS('', '#.# = #', metadata, cls, interface); return interface; } else { - return _castToRti(probe); + return _Utils.asRti(probe); } } - static Object findTypeParameterVariances(universe, String cls) => + static Object? findTypeParameterVariances(Object? universe, String cls) => JS('', '#.#', typeParameterVariances(universe), cls); - static void addRules(universe, rules) => + static void addRules(Object? universe, Object? rules) => _Utils.objectAssign(typeRules(universe), rules); - static void addErasedTypes(universe, types) => + static void addErasedTypes(Object? universe, Object? types) => _Utils.objectAssign(erasedTypes(universe), types); - static void addTypeParameterVariances(universe, variances) => + static void addTypeParameterVariances(Object? universe, Object? variances) => _Utils.objectAssign(typeParameterVariances(universe), variances); - static Object sharedEmptyArray(universe) => + static JSArray sharedEmptyArray(Object? universe) => JS('JSArray', '#.#', universe, RtiUniverseFieldNames.sharedEmptyArray); /// Evaluates [recipe] in the global environment. - static Rti eval(Object universe, String recipe, bool normalize) { + static Rti eval(Object? universe, String recipe, bool normalize) { var cache = evalCache(universe); - var probe = _cacheGet(cache, recipe); - if (probe != null) return _castToRti(probe); + var probe = _Utils.mapGet(cache, recipe); + if (probe != null) return _Utils.asRti(probe); Rti rti = _parseRecipe(universe, null, recipe, normalize); - _cacheSet(cache, recipe, rti); + _Utils.mapSet(cache, recipe, rti); return rti; } static Rti evalInEnvironment( - Object universe, Rti environment, String recipe) { + Object? universe, Rti environment, String recipe) { var cache = Rti._getEvalCache(environment); if (cache == null) { cache = JS('', 'new Map()'); Rti._setEvalCache(environment, cache); } - var probe = _cacheGet(cache, recipe); - if (probe != null) return _castToRti(probe); + var probe = _Utils.mapGet(cache, recipe); + if (probe != null) return _Utils.asRti(probe); Rti rti = _parseRecipe(universe, environment, recipe, true); - _cacheSet(cache, recipe, rti); + _Utils.mapSet(cache, recipe, rti); return rti; } - static Rti bind(Object universe, Rti environment, Rti argumentsRti) { + static Rti bind(Object? universe, Rti environment, Rti argumentsRti) { var cache = Rti._getBindCache(environment); if (cache == null) { cache = JS('', 'new Map()'); Rti._setBindCache(environment, cache); } String argumentsRecipe = Rti._getCanonicalRecipe(argumentsRti); - var probe = _cacheGet(cache, argumentsRecipe); - if (probe != null) return _castToRti(probe); + var probe = _Utils.mapGet(cache, argumentsRecipe); + if (probe != null) return _Utils.asRti(probe); var argumentsArray; if (Rti._getKind(argumentsRti) == Rti.kindBinding) { argumentsArray = Rti._getBindingArguments(argumentsRti); @@ -1550,59 +1653,74 @@ class _Universe { argumentsArray = JS('', '[#]', argumentsRti); } Rti rti = _lookupBindingRti(universe, environment, argumentsArray); - _cacheSet(cache, argumentsRecipe, rti); + _Utils.mapSet(cache, argumentsRecipe, rti); return rti; } - static Rti bind1(Object universe, Rti environment, Rti argumentsRti) { + static Rti bind1(Object? universe, Rti environment, Rti argumentsRti) { throw UnimplementedError('_Universe.bind1'); } - static Rti evalTypeVariable(Object universe, Rti environment, String name) { + static Rti evalTypeVariable(Object? universe, Rti environment, String name) { int kind = Rti._getKind(environment); if (kind == Rti.kindBinding) { environment = Rti._getBindingBase(environment); } String interfaceName = Rti._getInterfaceName(environment); - Object rule = _Universe.findRule(universe, interfaceName); + var rule = _Universe.findRule(universe, interfaceName); assert(rule != null); - String recipe = TypeRule.lookupTypeVariable(rule, name); + String? recipe = TypeRule.lookupTypeVariable(rule, name); if (recipe == null) { throw 'No "$name" in "${Rti._getCanonicalRecipe(environment)}"'; } return _Universe.evalInEnvironment(universe, environment, recipe); } - static _cacheGet(cache, key) => JS('', '#.get(#)', cache, key); - static void _cacheSet(cache, key, value) { - JS('', '#.set(#, #)', cache, key, value); - } - static Rti _parseRecipe( - Object universe, Object environment, String recipe, bool normalize) { - Object parser = _Parser.create(universe, environment, recipe, normalize); + Object? universe, Object? environment, String recipe, bool normalize) { + var parser = _Parser.create(universe, environment, recipe, normalize); Rti rti = _Parser.parse(parser); - if (rti != null) return rti; - throw UnimplementedError('_Universe._parseRecipe("$recipe")'); + return rti; } - static Rti _installTypeTests(Object universe, Rti rti) { + static Rti _installTypeTests(Object? universe, Rti rti) { // Set up methods to perform type tests. The general as-check methods use // the is-test method. The is-test method on first use overwrites itself, - // and possibly the as-check method, with a specialized version. - var asFn = RAW_DART_FUNCTION_REF(_generalAsCheckImplementation); + // and possibly the as-check methods, with a specialized version. + var asFn = RAW_DART_FUNCTION_REF(_installSpecializedAsCheck); var isFn = RAW_DART_FUNCTION_REF(_installSpecializedIsTest); Rti._setAsCheckFunction(rti, asFn); Rti._setIsTestFunction(rti, isFn); return rti; } - static Rti _installRti(Object universe, String key, Rti rti) { - _cacheSet(evalCache(universe), key, rti); + static Rti _installRti(Object? universe, String key, Rti rti) { + _Utils.mapSet(evalCache(universe), key, rti); return rti; } + // These helpers are used for creating canonical recipes. The key feature of + // the generated code is that it makes no reference to the constant pool, + // which does not exist when the type$ pool is created. + // + // The strange association is so that usage like + // + // s = _recipeJoin3(s, a, b); + // + // associates as `s+=(a+b)` rather than `s=s+a+b`. As recipe fragments are + // small, this tends to create smaller cons-string trees. + + static String _recipeJoin(String s1, String s2) => JS_STRING_CONCAT(s1, s2); + static String _recipeJoin3(String s1, String s2, String s3) => + JS_STRING_CONCAT(s1, JS_STRING_CONCAT(s2, s3)); + static String _recipeJoin4(String s1, String s2, String s3, String s4) => + JS_STRING_CONCAT(s1, JS_STRING_CONCAT(JS_STRING_CONCAT(s2, s3), s4)); + static String _recipeJoin5( + String s1, String s2, String s3, String s4, String s5) => + JS_STRING_CONCAT(s1, + JS_STRING_CONCAT(JS_STRING_CONCAT(JS_STRING_CONCAT(s2, s3), s4), s5)); + // For each kind of Rti there are three methods: // // * `lookupXXX` which takes the component parts and returns an existing Rti @@ -1621,68 +1739,68 @@ class _Universe { static String _canonicalRecipeOfDynamic() => Recipe.pushDynamicString; static String _canonicalRecipeOfVoid() => Recipe.pushVoidString; static String _canonicalRecipeOfNever() => - Recipe.pushNeverExtensionString + Recipe.extensionOpString; + _recipeJoin(Recipe.pushNeverExtensionString, Recipe.extensionOpString); static String _canonicalRecipeOfAny() => - Recipe.pushAnyExtensionString + Recipe.extensionOpString; + _recipeJoin(Recipe.pushAnyExtensionString, Recipe.extensionOpString); static String _canonicalRecipeOfStar(Rti baseType) => - Rti._getCanonicalRecipe(baseType) + Recipe.wrapStarString; + _recipeJoin(Rti._getCanonicalRecipe(baseType), Recipe.wrapStarString); static String _canonicalRecipeOfQuestion(Rti baseType) => - Rti._getCanonicalRecipe(baseType) + Recipe.wrapQuestionString; + _recipeJoin(Rti._getCanonicalRecipe(baseType), Recipe.wrapQuestionString); static String _canonicalRecipeOfFutureOr(Rti baseType) => - Rti._getCanonicalRecipe(baseType) + Recipe.wrapFutureOrString; + _recipeJoin(Rti._getCanonicalRecipe(baseType), Recipe.wrapFutureOrString); static String _canonicalRecipeOfGenericFunctionParameter(int index) => - '$index' + Recipe.genericFunctionTypeParameterIndexString; + _recipeJoin('$index', Recipe.genericFunctionTypeParameterIndexString); - static Rti _lookupErasedRti(universe) { + static Rti _lookupErasedRti(Object? universe) { return _lookupTerminalRti( universe, Rti.kindErased, _canonicalRecipeOfErased()); } - static Rti _lookupDynamicRti(universe) { + static Rti _lookupDynamicRti(Object? universe) { return _lookupTerminalRti( universe, Rti.kindDynamic, _canonicalRecipeOfDynamic()); } - static Rti _lookupVoidRti(universe) { + static Rti _lookupVoidRti(Object? universe) { return _lookupTerminalRti(universe, Rti.kindVoid, _canonicalRecipeOfVoid()); } - static Rti _lookupNeverRti(universe) { + static Rti _lookupNeverRti(Object? universe) { return _lookupTerminalRti( universe, Rti.kindNever, _canonicalRecipeOfNever()); } - static Rti _lookupAnyRti(universe) { + static Rti _lookupAnyRti(Object? universe) { return _lookupTerminalRti(universe, Rti.kindAny, _canonicalRecipeOfAny()); } - static Rti _lookupTerminalRti(universe, int kind, String key) { + static Rti _lookupTerminalRti(Object? universe, int kind, String key) { var cache = evalCache(universe); - var probe = _cacheGet(cache, key); - if (probe != null) return _castToRti(probe); + var probe = _Utils.mapGet(cache, key); + if (probe != null) return _Utils.asRti(probe); return _installRti(universe, key, _createTerminalRti(universe, kind, key)); } - static Rti _createTerminalRti(universe, int kind, String key) { + static Rti _createTerminalRti(Object? universe, int kind, String key) { Rti rti = Rti.allocate(); Rti._setKind(rti, kind); Rti._setCanonicalRecipe(rti, key); return _installTypeTests(universe, rti); } - static Rti _lookupStarRti(universe, Rti baseType, bool normalize) { + static Rti _lookupStarRti(Object? universe, Rti baseType, bool normalize) { String key = _canonicalRecipeOfStar(baseType); var cache = evalCache(universe); - var probe = _cacheGet(cache, key); - if (probe != null) return _castToRti(probe); + var probe = _Utils.mapGet(cache, key); + if (probe != null) return _Utils.asRti(probe); return _installRti( universe, key, _createStarRti(universe, baseType, key, normalize)); } static Rti _createStarRti( - universe, Rti baseType, String key, bool normalize) { + Object? universe, Rti baseType, String key, bool normalize) { if (normalize) { int baseKind = Rti._getKind(baseType); if (isStrongTopType(baseType) || @@ -1699,17 +1817,18 @@ class _Universe { return _installTypeTests(universe, rti); } - static Rti _lookupQuestionRti(universe, Rti baseType, bool normalize) { + static Rti _lookupQuestionRti( + Object? universe, Rti baseType, bool normalize) { String key = _canonicalRecipeOfQuestion(baseType); var cache = evalCache(universe); - var probe = _cacheGet(cache, key); - if (probe != null) return _castToRti(probe); + var probe = _Utils.mapGet(cache, key); + if (probe != null) return _Utils.asRti(probe); return _installRti( universe, key, _createQuestionRti(universe, baseType, key, normalize)); } static Rti _createQuestionRti( - universe, Rti baseType, String key, bool normalize) { + Object? universe, Rti baseType, String key, bool normalize) { if (normalize) { int baseKind = Rti._getKind(baseType); if (isStrongTopType(baseType) || @@ -1718,14 +1837,13 @@ class _Universe { baseKind == Rti.kindFutureOr && isNullable(Rti._getFutureOrArgument(baseType))) { return baseType; - } else if (baseKind == Rti.kindNever) { + } else if (baseKind == Rti.kindNever || + _Utils.isIdentical(baseType, LEGACY_TYPE_REF())) { return TYPE_REF(); } else if (baseKind == Rti.kindStar) { Rti starArgument = Rti._getStarArgument(baseType); int starArgumentKind = Rti._getKind(starArgument); - if (starArgumentKind == Rti.kindNever) { - return TYPE_REF(); - } else if (starArgumentKind == Rti.kindFutureOr && + if (starArgumentKind == Rti.kindFutureOr && isNullable(Rti._getFutureOrArgument(starArgument))) { return starArgument; } else { @@ -1740,17 +1858,18 @@ class _Universe { return _installTypeTests(universe, rti); } - static Rti _lookupFutureOrRti(universe, Rti baseType, bool normalize) { + static Rti _lookupFutureOrRti( + Object? universe, Rti baseType, bool normalize) { String key = _canonicalRecipeOfFutureOr(baseType); var cache = evalCache(universe); - var probe = _cacheGet(cache, key); - if (probe != null) return _castToRti(probe); + var probe = _Utils.mapGet(cache, key); + if (probe != null) return _Utils.asRti(probe); return _installRti( universe, key, _createFutureOrRti(universe, baseType, key, normalize)); } static Rti _createFutureOrRti( - universe, Rti baseType, String key, bool normalize) { + Object? universe, Rti baseType, String key, bool normalize) { if (normalize) { int baseKind = Rti._getKind(baseType); if (isTopType(baseType) || isObjectType(baseType)) { @@ -1759,7 +1878,7 @@ class _Universe { return _lookupFutureRti(universe, baseType); } else if (isNullType(baseType)) { return JS_GET_FLAG('NNBD') - ? _lookupQuestionRti(universe, TYPE_REF>(), false) + ? TYPE_REF?>() : TYPE_REF>(); } } @@ -1770,17 +1889,17 @@ class _Universe { return _installTypeTests(universe, rti); } - static Rti _lookupGenericFunctionParameterRti(universe, int index) { + static Rti _lookupGenericFunctionParameterRti(Object? universe, int index) { String key = _canonicalRecipeOfGenericFunctionParameter(index); var cache = evalCache(universe); - var probe = _cacheGet(cache, key); - if (probe != null) return _castToRti(probe); + var probe = _Utils.mapGet(cache, key); + if (probe != null) return _Utils.asRti(probe); return _installRti(universe, key, _createGenericFunctionParameterRti(universe, index, key)); } static Rti _createGenericFunctionParameterRti( - universe, int index, String key) { + Object? universe, int index, String key) { Rti rti = Rti.allocate(); Rti._setKind(rti, Rti.kindGenericFunctionParameter); Rti._setPrimary(rti, index); @@ -1788,56 +1907,59 @@ class _Universe { return _installTypeTests(universe, rti); } - static String _canonicalRecipeJoin(Object arguments) { + static String _canonicalRecipeJoin(Object? arguments) { String s = '', sep = ''; int length = _Utils.arrayLength(arguments); for (int i = 0; i < length; i++) { - Rti argument = _castToRti(_Utils.arrayAt(arguments, i)); + Rti argument = _Utils.asRti(_Utils.arrayAt(arguments, i)); String subrecipe = Rti._getCanonicalRecipe(argument); - s += sep + subrecipe; + s = _recipeJoin3(s, sep, subrecipe); sep = Recipe.separatorString; } return s; } - static String _canonicalRecipeJoinNamed(Object arguments) { + static String _canonicalRecipeJoinNamed(Object? arguments) { String s = '', sep = ''; int length = _Utils.arrayLength(arguments); - assert(length.isEven); - for (int i = 0; i < length; i += 2) { + assert(_Utils.isMultipleOf(length, 3)); + for (int i = 0; i < length; i += 3) { String name = _Utils.asString(_Utils.arrayAt(arguments, i)); - Rti type = _castToRti(_Utils.arrayAt(arguments, i + 1)); + bool isRequired = _Utils.asBool(_Utils.arrayAt(arguments, i + 1)); + String nameSep = isRequired + ? Recipe.requiredNameSeparatorString + : Recipe.nameSeparatorString; + Rti type = _Utils.asRti(_Utils.arrayAt(arguments, i + 2)); String subrecipe = Rti._getCanonicalRecipe(type); - s += sep + name + Recipe.nameSeparatorString + subrecipe; + s = _recipeJoin5(s, sep, name, nameSep, subrecipe); sep = Recipe.separatorString; } return s; } - static String _canonicalRecipeOfInterface(String name, Object arguments) { + static String _canonicalRecipeOfInterface(String name, Object? arguments) { assert(_Utils.isString(name)); String s = _Utils.asString(name); int length = _Utils.arrayLength(arguments); if (length != 0) { - s += Recipe.startTypeArgumentsString + - _canonicalRecipeJoin(arguments) + - Recipe.endTypeArgumentsString; + s = _recipeJoin4(s, Recipe.startTypeArgumentsString, + _canonicalRecipeJoin(arguments), Recipe.endTypeArgumentsString); } return s; } static Rti _lookupInterfaceRti( - Object universe, String name, Object arguments) { + Object? universe, String name, Object? arguments) { String key = _canonicalRecipeOfInterface(name, arguments); var cache = evalCache(universe); - var probe = _cacheGet(cache, key); - if (probe != null) return _castToRti(probe); + var probe = _Utils.mapGet(cache, key); + if (probe != null) return _Utils.asRti(probe); return _installRti( universe, key, _createInterfaceRti(universe, name, arguments, key)); } static Rti _createInterfaceRti( - Object universe, String name, Object typeArguments, String key) { + Object? universe, String name, Object? typeArguments, String key) { Rti rti = Rti.allocate(); Rti._setKind(rti, Rti.kindInterface); Rti._setPrimary(rti, name); @@ -1850,25 +1972,24 @@ class _Universe { return _installTypeTests(universe, rti); } - static Rti _lookupFutureRti(Object universe, Rti base) => _lookupInterfaceRti( - universe, - JS_GET_NAME(JsGetName.FUTURE_CLASS_TYPE_NAME), - JS('', '[#]', base)); + static Rti _lookupFutureRti(Object? universe, Rti base) => + _lookupInterfaceRti(universe, + JS_GET_NAME(JsGetName.FUTURE_CLASS_TYPE_NAME), JS('', '[#]', base)); - static String _canonicalRecipeOfBinding(Rti base, Object arguments) { - String s = Rti._getCanonicalRecipe(base); - s += Recipe - .toTypeString; // TODO(sra): Omit when base encoding is Rti without ToType. - s += Recipe.startTypeArgumentsString + - _canonicalRecipeJoin(arguments) + - Recipe.endTypeArgumentsString; - return s; + static String _canonicalRecipeOfBinding(Rti base, Object? arguments) { + return _recipeJoin5( + Rti._getCanonicalRecipe(base), + // TODO(sra): Omit when base encoding is Rti without ToType: + Recipe.toTypeString, + Recipe.startTypeArgumentsString, + _canonicalRecipeJoin(arguments), + Recipe.endTypeArgumentsString); } /// [arguments] becomes owned by the created Rti. - static Rti _lookupBindingRti(Object universe, Rti base, Object arguments) { + static Rti _lookupBindingRti(Object? universe, Rti base, Object? arguments) { Rti newBase = base; - Object newArguments = arguments; + var newArguments = arguments; if (Rti._getKind(base) == Rti.kindBinding) { newBase = Rti._getBindingBase(base); newArguments = @@ -1876,14 +1997,14 @@ class _Universe { } String key = _canonicalRecipeOfBinding(newBase, newArguments); var cache = evalCache(universe); - var probe = _cacheGet(cache, key); - if (probe != null) return _castToRti(probe); + var probe = _Utils.mapGet(cache, key); + if (probe != null) return _Utils.asRti(probe); return _installRti( universe, key, _createBindingRti(universe, newBase, newArguments, key)); } static Rti _createBindingRti( - Object universe, Rti base, Object arguments, String key) { + Object? universe, Rti base, Object? arguments, String key) { Rti rti = Rti.allocate(); Rti._setKind(rti, Rti.kindBinding); Rti._setPrimary(rti, base); @@ -1894,10 +2015,9 @@ class _Universe { static String _canonicalRecipeOfFunction( Rti returnType, _FunctionParameters parameters) => - Rti._getCanonicalRecipe(returnType) + - _canonicalRecipeOfFunctionParameters(parameters); + _recipeJoin(Rti._getCanonicalRecipe(returnType), + _canonicalRecipeOfFunctionParameters(parameters)); - // TODO(fishythefish): Support required named parameters. static String _canonicalRecipeOfFunctionParameters( _FunctionParameters parameters) { var requiredPositional = @@ -1906,43 +2026,43 @@ class _Universe { var optionalPositional = _FunctionParameters._getOptionalPositional(parameters); int optionalPositionalLength = _Utils.arrayLength(optionalPositional); - var optionalNamed = _FunctionParameters._getOptionalNamed(parameters); - int optionalNamedLength = _Utils.arrayLength(optionalNamed); - assert(optionalPositionalLength == 0 || optionalNamedLength == 0); + var named = _FunctionParameters._getNamed(parameters); + int namedLength = _Utils.arrayLength(named); + assert(optionalPositionalLength == 0 || namedLength == 0); - String recipe = Recipe.startFunctionArgumentsString + - _canonicalRecipeJoin(requiredPositional); + String recipe = _recipeJoin(Recipe.startFunctionArgumentsString, + _canonicalRecipeJoin(requiredPositional)); if (optionalPositionalLength > 0) { String sep = requiredPositionalLength > 0 ? Recipe.separatorString : ''; - recipe += sep + - Recipe.startOptionalGroupString + - _canonicalRecipeJoin(optionalPositional) + - Recipe.endOptionalGroupString; + recipe = _recipeJoin5( + recipe, + sep, + Recipe.startOptionalGroupString, + _canonicalRecipeJoin(optionalPositional), + Recipe.endOptionalGroupString); } - if (optionalNamedLength > 0) { + if (namedLength > 0) { String sep = requiredPositionalLength > 0 ? Recipe.separatorString : ''; - recipe += sep + - Recipe.startNamedGroupString + - _canonicalRecipeJoinNamed(optionalNamed) + - Recipe.endNamedGroupString; + recipe = _recipeJoin5(recipe, sep, Recipe.startNamedGroupString, + _canonicalRecipeJoinNamed(named), Recipe.endNamedGroupString); } - return recipe + Recipe.endFunctionArgumentsString; + return _recipeJoin(recipe, Recipe.endFunctionArgumentsString); } static Rti _lookupFunctionRti( - Object universe, Rti returnType, _FunctionParameters parameters) { + Object? universe, Rti returnType, _FunctionParameters parameters) { String key = _canonicalRecipeOfFunction(returnType, parameters); var cache = evalCache(universe); - var probe = _cacheGet(cache, key); - if (probe != null) return _castToRti(probe); + var probe = _Utils.mapGet(cache, key); + if (probe != null) return _Utils.asRti(probe); return _installRti(universe, key, _createFunctionRti(universe, returnType, parameters, key)); } - static Rti _createFunctionRti(Object universe, Rti returnType, + static Rti _createFunctionRti(Object? universe, Rti returnType, _FunctionParameters parameters, String key) { Rti rti = Rti.allocate(); Rti._setKind(rti, Rti.kindFunction); @@ -1953,18 +2073,19 @@ class _Universe { } static String _canonicalRecipeOfGenericFunction( - Rti baseFunctionType, Object bounds) => - Rti._getCanonicalRecipe(baseFunctionType) + - Recipe.startTypeArgumentsString + - _canonicalRecipeJoin(bounds) + - Recipe.endTypeArgumentsString; + Rti baseFunctionType, Object? bounds) => + _recipeJoin4( + Rti._getCanonicalRecipe(baseFunctionType), + Recipe.startTypeArgumentsString, + _canonicalRecipeJoin(bounds), + Recipe.endTypeArgumentsString); static Rti _lookupGenericFunctionRti( - Object universe, Rti baseFunctionType, Object bounds, bool normalize) { + Object? universe, Rti baseFunctionType, Object? bounds, bool normalize) { String key = _canonicalRecipeOfGenericFunction(baseFunctionType, bounds); var cache = evalCache(universe); - var probe = _cacheGet(cache, key); - if (probe != null) return _castToRti(probe); + var probe = _Utils.mapGet(cache, key); + if (probe != null) return _Utils.asRti(probe); return _installRti( universe, key, @@ -1972,14 +2093,14 @@ class _Universe { universe, baseFunctionType, bounds, key, normalize)); } - static Rti _createGenericFunctionRti(Object universe, Rti baseFunctionType, - Object bounds, String key, bool normalize) { + static Rti _createGenericFunctionRti(Object? universe, Rti baseFunctionType, + Object? bounds, String key, bool normalize) { if (normalize) { int length = _Utils.arrayLength(bounds); int count = 0; - Object typeArguments = JS('', 'new Array(#)', length); + Object? typeArguments = JS('', 'new Array(#)', length); for (int i = 0; i < length; i++) { - Rti bound = _castToRti(_Utils.arrayAt(bounds, i)); + Rti bound = _Utils.asRti(_Utils.arrayAt(bounds, i)); if (Rti._getKind(bound) == Rti.kindNever) { _Utils.arraySetAt(typeArguments, i, bound); count++; @@ -2129,7 +2250,7 @@ class _Parser { /// Marked as no-inline so the object literal is not cloned by inlining. @pragma('dart2js:noInline') static Object create( - Object universe, Object environment, String recipe, bool normalize) { + Object? universe, Object? environment, String recipe, bool normalize) { return JS( '', '{' @@ -2147,27 +2268,27 @@ class _Parser { } // Field accessors for the parser. - static Object universe(Object parser) => JS('', '#.u', parser); - static Rti environment(Object parser) => JS('Rti', '#.e', parser); - static String recipe(Object parser) => JS('String', '#.r', parser); - static Object stack(Object parser) => JS('', '#.s', parser); - static int position(Object parser) => JS('int', '#.p', parser); - static void setPosition(Object parser, int p) { + static Object universe(Object? parser) => JS('', '#.u', parser); + static Rti environment(Object? parser) => JS('Rti', '#.e', parser); + static String recipe(Object? parser) => JS('String', '#.r', parser); + static Object stack(Object? parser) => JS('', '#.s', parser); + static int position(Object? parser) => JS('int', '#.p', parser); + static void setPosition(Object? parser, int p) { JS('', '#.p = #', parser, p); } - static bool normalize(Object parser) => JS('bool', '#.n', parser); + static bool normalize(Object? parser) => JS('bool', '#.n', parser); static int charCodeAt(String s, int i) => JS('int', '#.charCodeAt(#)', s, i); - static void push(Object stack, Object value) { + static void push(Object? stack, Object? value) { JS('', '#.push(#)', stack, value); } - static Object pop(Object stack) => JS('', '#.pop()', stack); + static Object? pop(Object? stack) => JS('', '#.pop()', stack); - static Rti parse(Object parser) { + static Rti parse(Object? parser) { String source = _Parser.recipe(parser); - Object stack = _Parser.stack(parser); + var stack = _Parser.stack(parser); int i = 0; while (i < source.length) { int ch = charCodeAt(source, i); @@ -2184,6 +2305,11 @@ class _Parser { break; case Recipe.nameSeparator: + push(stack, false); + break; + + case Recipe.requiredNameSeparator: + push(stack, true); break; case Recipe.toType: @@ -2221,7 +2347,7 @@ class _Parser { break; case Recipe.wrapStar: - Object u = universe(parser); + var u = universe(parser); push( stack, _Universe._lookupStarRti( @@ -2231,7 +2357,7 @@ class _Parser { break; case Recipe.wrapQuestion: - Object u = universe(parser); + var u = universe(parser); push( stack, _Universe._lookupQuestionRti( @@ -2241,7 +2367,7 @@ class _Parser { break; case Recipe.wrapFutureOr: - Object u = universe(parser); + var u = universe(parser); push( stack, _Universe._lookupFutureOrRti( @@ -2279,16 +2405,16 @@ class _Parser { } } } - Object item = pop(stack); + var item = pop(stack); return toType(universe(parser), environment(parser), item); } - static void pushStackFrame(Object parser, Object stack) { + static void pushStackFrame(Object? parser, Object? stack) { push(stack, position(parser)); setPosition(parser, _Utils.arrayLength(stack)); } - static int handleDigit(int i, int digit, String source, Object stack) { + static int handleDigit(int i, int digit, String source, Object? stack) { int value = Recipe.digitValue(digit); for (; i < source.length; i++) { int ch = charCodeAt(source, i); @@ -2300,7 +2426,7 @@ class _Parser { } static int handleIdentifier( - Object parser, int start, String source, Object stack, bool hasPeriod) { + Object? parser, int start, String source, Object? stack, bool hasPeriod) { int i = start + 1; for (; i < source.length; i++) { int ch = charCodeAt(source, i); @@ -2325,10 +2451,10 @@ class _Parser { return i; } - static void handleTypeArguments(Object parser, Object stack) { - Object universe = _Parser.universe(parser); - Object arguments = collectArray(parser, stack); - Object head = pop(stack); + static void handleTypeArguments(Object? parser, Object? stack) { + var universe = _Parser.universe(parser); + var arguments = collectArray(parser, stack); + var head = pop(stack); if (_Utils.isString(head)) { String name = _Utils.asString(head); push(stack, _Universe._lookupInterfaceRti(universe, name, arguments)); @@ -2350,15 +2476,15 @@ class _Parser { } static const int optionalPositionalSentinel = -1; - static const int optionalNamedSentinel = -2; + static const int namedSentinel = -2; - static void handleFunctionArguments(Object parser, Object stack) { - Object universe = _Parser.universe(parser); + static void handleFunctionArguments(Object? parser, Object? stack) { + var universe = _Parser.universe(parser); _FunctionParameters parameters = _FunctionParameters.allocate(); - var optionalPositional = _Universe.sharedEmptyArray(universe); - var optionalNamed = _Universe.sharedEmptyArray(universe); + Object? optionalPositional = _Universe.sharedEmptyArray(universe); + Object? named = _Universe.sharedEmptyArray(universe); - Object head = pop(stack); + var head = pop(stack); if (_Utils.isNum(head)) { int sentinel = _Utils.asInt(head); switch (sentinel) { @@ -2366,8 +2492,8 @@ class _Parser { optionalPositional = pop(stack); break; - case optionalNamedSentinel: - optionalNamed = pop(stack); + case namedSentinel: + named = pop(stack); break; default: @@ -2381,25 +2507,25 @@ class _Parser { _FunctionParameters._setRequiredPositional( parameters, collectArray(parser, stack)); _FunctionParameters._setOptionalPositional(parameters, optionalPositional); - _FunctionParameters._setOptionalNamed(parameters, optionalNamed); + _FunctionParameters._setNamed(parameters, named); Rti returnType = toType(universe, environment(parser), pop(stack)); push(stack, _Universe._lookupFunctionRti(universe, returnType, parameters)); } - static void handleOptionalGroup(Object parser, Object stack) { - Object parameters = collectArray(parser, stack); + static void handleOptionalGroup(Object? parser, Object? stack) { + var parameters = collectArray(parser, stack); push(stack, parameters); push(stack, optionalPositionalSentinel); } - static void handleNamedGroup(Object parser, Object stack) { - Object parameters = collectNamed(parser, stack); + static void handleNamedGroup(Object? parser, Object? stack) { + var parameters = collectNamed(parser, stack); push(stack, parameters); - push(stack, optionalNamedSentinel); + push(stack, namedSentinel); } - static void handleExtendedOperations(Object parser, Object stack) { - Object top = pop(stack); + static void handleExtendedOperations(Object? parser, Object? stack) { + var top = pop(stack); if (0 == top) { push(stack, _Universe._lookupNeverRti(universe(parser))); return; @@ -2411,14 +2537,14 @@ class _Parser { throw AssertionError('Unexpected extended operation $top'); } - static Object collectArray(Object parser, Object stack) { + static JSArray collectArray(Object? parser, Object? stack) { var array = _Utils.arraySplice(stack, position(parser)); toTypes(_Parser.universe(parser), environment(parser), array); setPosition(parser, _Utils.asInt(pop(stack))); return array; } - static Object collectNamed(Object parser, Object stack) { + static JSArray collectNamed(Object? parser, Object? stack) { var array = _Utils.arraySplice(stack, position(parser)); toTypesNamed(_Parser.universe(parser), environment(parser), array); setPosition(parser, _Utils.asInt(pop(stack))); @@ -2427,7 +2553,7 @@ class _Parser { /// Coerce a stack item into an Rti object. Strings are converted to interface /// types, integers are looked up in the type environment. - static Rti toType(Object universe, Rti environment, Object item) { + static Rti toType(Object? universe, Rti environment, Object? item) { if (_Utils.isString(item)) { String name = _Utils.asString(item); return _Universe._lookupInterfaceRti( @@ -2435,11 +2561,11 @@ class _Parser { } else if (_Utils.isNum(item)) { return _Parser.indexToType(universe, environment, _Utils.asInt(item)); } else { - return _castToRti(item); + return _Utils.asRti(item); } } - static void toTypes(Object universe, Rti environment, Object items) { + static void toTypes(Object? universe, Rti environment, Object? items) { int length = _Utils.arrayLength(items); for (int i = 0; i < length; i++) { var item = _Utils.arrayAt(items, i); @@ -2448,24 +2574,24 @@ class _Parser { } } - static void toTypesNamed(Object universe, Rti environment, Object items) { + static void toTypesNamed(Object? universe, Rti environment, Object? items) { int length = _Utils.arrayLength(items); - assert(length.isEven); - for (int i = 1; i < length; i += 2) { + assert(_Utils.isMultipleOf(length, 3)); + for (int i = 2; i < length; i += 3) { var item = _Utils.arrayAt(items, i); Rti type = toType(universe, environment, item); _Utils.arraySetAt(items, i, type); } } - static Rti indexToType(Object universe, Rti environment, int index) { + static Rti indexToType(Object? universe, Rti environment, int index) { int kind = Rti._getKind(environment); if (kind == Rti.kindBinding) { if (index == 0) return Rti._getBindingBase(environment); var typeArguments = Rti._getBindingArguments(environment); int len = _Utils.arrayLength(typeArguments); if (index <= len) { - return _castToRti(_Utils.arrayAt(typeArguments, index - 1)); + return _Utils.asRti(_Utils.arrayAt(typeArguments, index - 1)); } // Is index into interface Rti in base. index -= len; @@ -2480,12 +2606,12 @@ class _Parser { var typeArguments = Rti._getInterfaceTypeArguments(environment); int len = _Utils.arrayLength(typeArguments); if (index <= len) { - return _castToRti(_Utils.arrayAt(typeArguments, index - 1)); + return _Utils.asRti(_Utils.arrayAt(typeArguments, index - 1)); } throw AssertionError('Bad index $index for $environment'); } - static Rti toGenericFunctionParameter(Object universe, Object item) { + static Rti toGenericFunctionParameter(Object? universe, Object? item) { assert(_Utils.isNum(item)); return _Universe._lookupGenericFunctionParameterRti( universe, _Utils.asInt(item)); @@ -2499,26 +2625,26 @@ class TypeRule { throw UnimplementedError("TypeRule is static methods only."); } - static String lookupTypeVariable(rule, String typeVariable) => + static String? lookupTypeVariable(Object? rule, String typeVariable) => JS('', '#.#', rule, typeVariable); - static JSArray lookupSupertype(rule, String supertype) => + static JSArray? lookupSupertype(Object? rule, String supertype) => JS('', '#.#', rule, supertype); } // This needs to be kept in sync with `Variance` in `entities.dart`. class Variance { // TODO(fishythefish): Try bitmask representation. - static const legacyCovariant = 0; - static const covariant = 1; - static const contravariant = 2; - static const invariant = 3; + static const int legacyCovariant = 0; + static const int covariant = 1; + static const int contravariant = 2; + static const int invariant = 3; } // -------- Subtype tests ------------------------------------------------------ // Future entry point from compiled code. -bool isSubtype(universe, Rti s, Rti t) { +bool isSubtype(Object? universe, Rti s, Rti t) { return _isSubtype(universe, s, null, t, null); } @@ -2545,7 +2671,7 @@ bool isSubtype(universe, Rti s, Rti t) { /// the bottom of the type hierarchy, `Object` is treated as nullable, and /// `required` is ignored on named parameters. This should provide the same /// subtyping results as pre-NNBD Dart. -bool _isSubtype(universe, Rti s, sEnv, Rti t, tEnv) { +bool _isSubtype(Object? universe, Rti s, Object? sEnv, Rti t, Object? tEnv) { bool isLegacy = JS_GET_FLAG('LEGACY'); // Reflexivity: @@ -2567,7 +2693,7 @@ bool _isSubtype(universe, Rti s, sEnv, Rti t, tEnv) { bool leftTypeVariable = sKind == Rti.kindGenericFunctionParameter; if (leftTypeVariable) { int index = Rti._getGenericFunctionParameterIndex(s); - Rti bound = _castToRti(_Utils.arrayAt(sEnv, index)); + Rti bound = _Utils.asRti(_Utils.arrayAt(sEnv, index)); if (_isSubtype(universe, bound, sEnv, t, tEnv)) return true; } @@ -2676,8 +2802,8 @@ bool _isSubtype(universe, Rti s, sEnv, Rti t, tEnv) { tEnv = tEnv == null ? tBounds : _Utils.arrayConcat(tBounds, tEnv); for (int i = 0; i < sLength; i++) { - var sBound = _Utils.arrayAt(sBounds, i); - var tBound = _Utils.arrayAt(tBounds, i); + var sBound = _Utils.asRti(_Utils.arrayAt(sBounds, i)); + var tBound = _Utils.asRti(_Utils.arrayAt(tBounds, i)); if (!_isSubtype(universe, sBound, sEnv, tBound, tEnv) || !_isSubtype(universe, tBound, tEnv, sBound, sEnv)) { return false; @@ -2702,8 +2828,8 @@ bool _isSubtype(universe, Rti s, sEnv, Rti t, tEnv) { return false; } -// TODO(fishythefish): Support required named parameters. -bool _isFunctionSubtype(universe, Rti s, sEnv, Rti t, tEnv) { +bool _isFunctionSubtype( + Object? universe, Rti s, Object? sEnv, Rti t, Object? tEnv) { assert(Rti._getKind(s) == Rti.kindFunction); assert(Rti._getKind(t) == Rti.kindFunction); @@ -2736,16 +2862,16 @@ bool _isFunctionSubtype(universe, Rti s, sEnv, Rti t, tEnv) { tRequiredPositionalLength + tOptionalPositionalLength) return false; for (int i = 0; i < sRequiredPositionalLength; i++) { - Rti sParameter = _castToRti(_Utils.arrayAt(sRequiredPositional, i)); - Rti tParameter = _castToRti(_Utils.arrayAt(tRequiredPositional, i)); + Rti sParameter = _Utils.asRti(_Utils.arrayAt(sRequiredPositional, i)); + Rti tParameter = _Utils.asRti(_Utils.arrayAt(tRequiredPositional, i)); if (!_isSubtype(universe, tParameter, tEnv, sParameter, sEnv)) { return false; } } for (int i = 0; i < requiredPositionalDelta; i++) { - Rti sParameter = _castToRti(_Utils.arrayAt(sOptionalPositional, i)); - Rti tParameter = _castToRti( + Rti sParameter = _Utils.asRti(_Utils.arrayAt(sOptionalPositional, i)); + Rti tParameter = _Utils.asRti( _Utils.arrayAt(tRequiredPositional, sRequiredPositionalLength + i)); if (!_isSubtype(universe, tParameter, tEnv, sParameter, sEnv)) { return false; @@ -2753,37 +2879,49 @@ bool _isFunctionSubtype(universe, Rti s, sEnv, Rti t, tEnv) { } for (int i = 0; i < tOptionalPositionalLength; i++) { - Rti sParameter = _castToRti( + Rti sParameter = _Utils.asRti( _Utils.arrayAt(sOptionalPositional, requiredPositionalDelta + i)); - Rti tParameter = _castToRti(_Utils.arrayAt(tOptionalPositional, i)); + Rti tParameter = _Utils.asRti(_Utils.arrayAt(tOptionalPositional, i)); if (!_isSubtype(universe, tParameter, tEnv, sParameter, sEnv)) { return false; } } - var sOptionalNamed = _FunctionParameters._getOptionalNamed(sParameters); - var tOptionalNamed = _FunctionParameters._getOptionalNamed(tParameters); - int sOptionalNamedLength = _Utils.arrayLength(sOptionalNamed); - int tOptionalNamedLength = _Utils.arrayLength(tOptionalNamed); + var sNamed = _FunctionParameters._getNamed(sParameters); + var tNamed = _FunctionParameters._getNamed(tParameters); + int sNamedLength = _Utils.arrayLength(sNamed); + int tNamedLength = _Utils.arrayLength(tNamed); - for (int i = 0, j = 0; j < tOptionalNamedLength; j += 2) { - String sName; - String tName = _Utils.asString(_Utils.arrayAt(tOptionalNamed, j)); - do { - if (i >= sOptionalNamedLength) return false; - sName = _Utils.asString(_Utils.arrayAt(sOptionalNamed, i)); - i += 2; - } while (_Utils.stringLessThan(sName, tName)); - if (_Utils.stringLessThan(tName, sName)) return false; - Rti sType = _castToRti(_Utils.arrayAt(sOptionalNamed, i - 1)); - Rti tType = _castToRti(_Utils.arrayAt(tOptionalNamed, j + 1)); - if (!_isSubtype(universe, tType, tEnv, sType, sEnv)) return false; + int sIndex = 0; + for (int tIndex = 0; tIndex < tNamedLength; tIndex += 3) { + String tName = _Utils.asString(_Utils.arrayAt(tNamed, tIndex)); + while (true) { + if (sIndex >= sNamedLength) return false; + String sName = _Utils.asString(_Utils.arrayAt(sNamed, sIndex)); + sIndex += 3; + if (_Utils.stringLessThan(tName, sName)) return false; + bool sIsRequired = _Utils.asBool(_Utils.arrayAt(sNamed, sIndex - 2)); + if (_Utils.stringLessThan(sName, tName)) { + if (sIsRequired) return false; + continue; + } + bool tIsRequired = _Utils.asBool(_Utils.arrayAt(tNamed, tIndex + 1)); + if (sIsRequired && !tIsRequired) return false; + Rti sType = _Utils.asRti(_Utils.arrayAt(sNamed, sIndex - 1)); + Rti tType = _Utils.asRti(_Utils.arrayAt(tNamed, tIndex + 2)); + if (!_isSubtype(universe, tType, tEnv, sType, sEnv)) return false; + break; + } + } + while (sIndex < sNamedLength) { + if (_Utils.asBool(_Utils.arrayAt(sNamed, sIndex + 1))) return false; + sIndex += 3; } - return true; } -bool _isInterfaceSubtype(universe, Rti s, sEnv, Rti t, tEnv) { +bool _isInterfaceSubtype( + Object? universe, Rti s, Object? sEnv, Rti t, Object? tEnv) { String sName = Rti._getInterfaceName(s); String tName = Rti._getInterfaceName(t); @@ -2795,7 +2933,7 @@ bool _isInterfaceSubtype(universe, Rti s, sEnv, Rti t, tEnv) { assert(length == _Utils.arrayLength(tArgs)); var sVariances; - bool hasVariances; + bool? hasVariances; if (JS_GET_FLAG("VARIANCE")) { sVariances = _Universe.findTypeParameterVariances(universe, sName); hasVariances = sVariances != null; @@ -2803,10 +2941,10 @@ bool _isInterfaceSubtype(universe, Rti s, sEnv, Rti t, tEnv) { } for (int i = 0; i < length; i++) { - Rti sArg = _castToRti(_Utils.arrayAt(sArgs, i)); - Rti tArg = _castToRti(_Utils.arrayAt(tArgs, i)); + Rti sArg = _Utils.asRti(_Utils.arrayAt(sArgs, i)); + Rti tArg = _Utils.asRti(_Utils.arrayAt(tArgs, i)); if (JS_GET_FLAG("VARIANCE")) { - int sVariance = hasVariances + int sVariance = hasVariances != null ? _Utils.asInt(_Utils.arrayAt(sVariances, i)) : Variance.legacyCovariant; switch (sVariance) { @@ -2854,7 +2992,7 @@ bool _isInterfaceSubtype(universe, Rti s, sEnv, Rti t, tEnv) { // We don't list Object explicitly as a supertype of each interface, so check // this trivial case first. if (isObjectType(t)) return true; - Object rule = _Universe.findRule(universe, sName); + var rule = _Universe.findRule(universe, sName); if (rule == null) return false; var supertypeArgs = TypeRule.lookupSupertype(rule, tName); if (supertypeArgs == null) return false; @@ -2864,7 +3002,7 @@ bool _isInterfaceSubtype(universe, Rti s, sEnv, Rti t, tEnv) { for (int i = 0; i < length; i++) { String recipe = _Utils.asString(_Utils.arrayAt(supertypeArgs, i)); Rti supertypeArg = _Universe.evalInEnvironment(universe, s, recipe); - Rti tArg = _castToRti(_Utils.arrayAt(tArgs, i)); + Rti tArg = _Utils.asRti(_Utils.arrayAt(tArgs, i)); if (!_isSubtype(universe, supertypeArg, sEnv, tArg, tEnv)) { return false; } @@ -2881,6 +3019,7 @@ bool isNullable(Rti t) { kind == Rti.kindFutureOr && isNullable(Rti._getFutureOrArgument(t)); } +@pragma('dart2js:parameter:trust') bool isTopType(Rti t) => isStrongTopType(t) || isLegacyObjectType(t) || @@ -2901,9 +3040,7 @@ bool isBottomType(Rti t) => bool isObjectType(Rti t) => _Utils.isIdentical(t, TYPE_REF()); bool isLegacyObjectType(Rti t) => _Utils.isIdentical(t, LEGACY_TYPE_REF()); -bool isNullableObjectType(Rti t) => - Rti._getKind(t) == Rti.kindQuestion && - isObjectType(Rti._getQuestionArgument(t)); +bool isNullableObjectType(Rti t) => _Utils.isIdentical(t, TYPE_REF()); bool isNullType(Rti t) => _Utils.isIdentical(t, TYPE_REF()) || _Utils.isIdentical(t, TYPE_REF()); @@ -2911,30 +3048,31 @@ bool isFunctionType(Rti t) => _Utils.isIdentical(t, TYPE_REF()); bool isJsFunctionType(Rti t) => _Utils.isIdentical(t, TYPE_REF()); -/// Unchecked cast to Rti. -Rti _castToRti(s) => JS('Rti', '#', s); -Rti /*?*/ _castToRtiOrNull(s) => JS('Rti|Null', '#', s); - class _Utils { - static bool asBool(Object o) => JS('bool', '#', o); - static double asDouble(Object o) => JS('double', '#', o); - static int asInt(Object o) => JS('int', '#', o); - static num asNum(Object o) => JS('num', '#', o); - static String asString(Object o) => JS('String', '#', o); + static bool asBool(Object? o) => JS('bool', '#', o); + static double asDouble(Object? o) => JS('double', '#', o); + static int asInt(Object? o) => JS('int', '#', o); + static num asNum(Object? o) => JS('num', '#', o); + static String asString(Object? o) => JS('String', '#', o); + static Rti asRti(Object? s) => JS('Rti', '#', s); + static Rti? asRtiOrNull(Object? s) => JS('Rti|Null', '#', s); - static bool isString(Object o) => JS('bool', 'typeof # == "string"', o); - static bool isNum(Object o) => JS('bool', 'typeof # == "number"', o); + static bool isString(Object? o) => JS('bool', 'typeof # == "string"', o); + static bool isNum(Object? o) => JS('bool', 'typeof # == "number"', o); - static bool instanceOf(Object o, Object constructor) => + static bool instanceOf(Object? o, Object? constructor) => JS('bool', '# instanceof #', o, constructor); - static bool isIdentical(s, t) => JS('bool', '# === #', s, t); - static bool isNotIdentical(s, t) => JS('bool', '# !== #', s, t); + static bool isIdentical(Object? s, Object? t) => JS('bool', '# === #', s, t); + static bool isNotIdentical(Object? s, Object? t) => + JS('bool', '# !== #', s, t); - static JSArray objectKeys(Object o) => + static bool isMultipleOf(int n, int d) => JS('bool', '# % # === 0', n, d); + + static JSArray objectKeys(Object? o) => JS('returns:JSArray;new:true;', 'Object.keys(#)', o); - static void objectAssign(Object o, Object other) { + static void objectAssign(Object? o, Object? other) { // TODO(fishythefish): Use `Object.assign()` when IE11 is deprecated. var keys = objectKeys(other); int length = arrayLength(keys); @@ -2944,26 +3082,26 @@ class _Utils { } } - static bool isArray(Object o) => JS('bool', 'Array.isArray(#)', o); + static bool isArray(Object? o) => JS('bool', 'Array.isArray(#)', o); - static int arrayLength(Object array) => JS('int', '#.length', array); + static int arrayLength(Object? array) => JS('int', '#.length', array); - static Object arrayAt(Object array, int i) => JS('', '#[#]', array, i); + static Object? arrayAt(Object? array, int i) => JS('', '#[#]', array, i); - static void arraySetAt(Object array, int i, Object value) { + static void arraySetAt(Object? array, int i, Object? value) { JS('', '#[#] = #', array, i, value); } - static JSArray arrayShallowCopy(Object array) => + static JSArray arrayShallowCopy(Object? array) => JS('JSArray', '#.slice()', array); - static JSArray arraySplice(Object array, int position) => + static JSArray arraySplice(Object? array, int position) => JS('JSArray', '#.splice(#)', array, position); - static JSArray arrayConcat(Object a1, Object a2) => + static JSArray arrayConcat(Object? a1, Object? a2) => JS('JSArray', '#.concat(#)', a1, a2); - static void arrayPush(Object array, Object value) { + static void arrayPush(Object? array, Object? value) { JS('', '#.push(#)', array, value); } @@ -2973,56 +3111,57 @@ class _Utils { static bool stringLessThan(String s1, String s2) => JS('bool', '# < #', s1, s2); - static mapGet(cache, key) => JS('', '#.get(#)', cache, key); + static Object? mapGet(Object? cache, Object? key) => + JS('', '#.get(#)', cache, key); - static void mapSet(cache, key, value) { + static void mapSet(Object? cache, Object? key, Object? value) { JS('', '#.set(#, #)', cache, key, value); } } + // -------- Entry points for testing ------------------------------------------- -String testingCanonicalRecipe(rti) { +String testingCanonicalRecipe(Rti rti) { return Rti._getCanonicalRecipe(rti); } -String testingRtiToString(rti) { - return _rtiToString(_castToRti(rti), null); +String testingRtiToString(Rti rti) { + return _rtiToString(rti, null); } -String testingRtiToDebugString(rti) { - return _rtiToDebugString(_castToRti(rti)); +String testingRtiToDebugString(Rti rti) { + return _rtiToDebugString(rti); } Object testingCreateUniverse() { return _Universe.create(); } -void testingAddRules(universe, rules) { +void testingAddRules(Object? universe, Object? rules) { _Universe.addRules(universe, rules); } -void testingAddTypeParameterVariances(universe, variances) { +void testingAddTypeParameterVariances(Object? universe, Object? variances) { _Universe.addTypeParameterVariances(universe, variances); } -bool testingIsSubtype(universe, rti1, rti2) { - return isSubtype(universe, _castToRti(rti1), _castToRti(rti2)); +bool testingIsSubtype(Object? universe, Rti rti1, Rti rti2) { + return isSubtype(universe, rti1, rti2); } -Object testingUniverseEval(universe, String recipe) { +Rti testingUniverseEval(Object? universe, String recipe) { return _Universe.eval(universe, recipe, true); } -void testingUniverseEvalOverride(universe, String recipe, Rti rti) { +void testingUniverseEvalOverride(Object? universe, String recipe, Rti rti) { var cache = _Universe.evalCache(universe); - _Universe._cacheSet(cache, recipe, rti); + _Utils.mapSet(cache, recipe, rti); } -Object testingEnvironmentEval(universe, environment, String recipe) { - return _Universe.evalInEnvironment(universe, _castToRti(environment), recipe); +Rti testingEnvironmentEval(Object? universe, Rti environment, String recipe) { + return _Universe.evalInEnvironment(universe, environment, recipe); } -Object testingEnvironmentBind(universe, environment, arguments) { - return _Universe.bind( - universe, _castToRti(environment), _castToRti(arguments)); +Rti testingEnvironmentBind(Object? universe, Rti environment, Rti arguments) { + return _Universe.bind(universe, environment, arguments); } diff --git a/sdk/lib/_internal/js_runtime/lib/shared/async_await_error_codes.dart b/sdk/lib/_internal/js_runtime/lib/shared/async_await_error_codes.dart index 5bcc5127922..f87406b31b0 100644 --- a/sdk/lib/_internal/js_runtime/lib/shared/async_await_error_codes.dart +++ b/sdk/lib/_internal/js_runtime/lib/shared/async_await_error_codes.dart @@ -2,8 +2,6 @@ // 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.6 - /// Contains error codes that transformed async/async* functions use to /// communicate with js_helper functions. diff --git a/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart b/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart index c927beadbb3..31b46c5f8c2 100644 --- a/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart +++ b/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart @@ -2,8 +2,6 @@ // 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.6 - /// Contains the names of globals that are embedded into the output by the /// compiler. /// diff --git a/sdk/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart b/sdk/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart index 62372e7958b..c1838614fa6 100644 --- a/sdk/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart +++ b/sdk/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart @@ -2,8 +2,6 @@ // 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.6 - /// Constants and predicates used for encoding and decoding type recipes. /// /// This library is shared between the compiler and the runtime system. diff --git a/sdk/lib/_internal/js_runtime/lib/string_helper.dart b/sdk/lib/_internal/js_runtime/lib/string_helper.dart index eff87831a43..3e07cdd0d3a 100644 --- a/sdk/lib/_internal/js_runtime/lib/string_helper.dart +++ b/sdk/lib/_internal/js_runtime/lib/string_helper.dart @@ -2,8 +2,6 @@ // 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.6 - part of _js_helper; stringIndexOfStringUnchecked(receiver, other, startIndex) { @@ -42,7 +40,7 @@ class StringMatch implements Match { } List groups(List groups_) { - List result = new List(); + List result = []; for (int g in groups_) { result.add(group(g)); } @@ -82,7 +80,7 @@ class _StringAllMatchesIterator implements Iterator { final String _input; final String _pattern; int _index; - Match _current; + Match? _current; _StringAllMatchesIterator(this._input, this._pattern, this._index); @@ -105,7 +103,7 @@ class _StringAllMatchesIterator implements Iterator { return true; } - Match get current => _current; + Match get current => _current!; } stringContainsUnchecked(receiver, other, startIndex) { @@ -218,7 +216,7 @@ String stringReplaceAllUsingSplitJoin(receiver, pattern, replacement) { return JS('String', '#.split(#).join(#)', receiver, pattern, replacement); } -String _matchString(Match match) => match[0]; +String? _matchString(Match match) => match[0]; String _stringIdentity(String string) => string; stringReplaceAllFuncUnchecked(receiver, pattern, onMatch, onNonMatch) { diff --git a/sdk/lib/_internal/js_runtime/lib/typed_data_patch.dart b/sdk/lib/_internal/js_runtime/lib/typed_data_patch.dart index 9cf539b7944..d1c6a1a19f3 100644 --- a/sdk/lib/_internal/js_runtime/lib/typed_data_patch.dart +++ b/sdk/lib/_internal/js_runtime/lib/typed_data_patch.dart @@ -2,8 +2,6 @@ // 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.6 - import 'dart:_js_helper' show patch; import 'dart:_native_typed_data'; diff --git a/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart b/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart index eacc877636d..ab7da7eba9d 100644 --- a/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart +++ b/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart @@ -2,7 +2,7 @@ // 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.6 +// @dart = 2.5 library libraries; diff --git a/sdk/lib/_internal/vm/bin/builtin.dart b/sdk/lib/_internal/vm/bin/builtin.dart index a86de3859b3..8dcbadf4e7f 100644 --- a/sdk/lib/_internal/vm/bin/builtin.dart +++ b/sdk/lib/_internal/vm/bin/builtin.dart @@ -2,8 +2,6 @@ // 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.6 - library builtin; // NOTE: Do not import 'dart:io' in builtin. @@ -32,15 +30,15 @@ void _print(arg) { _getPrintClosure() => _print; // The current working directory when the embedder was launched. -Uri _workingDirectory; +late Uri _workingDirectory; // The URI that the root script was loaded from. Remembered so that // package imports can be resolved relative to it. The root script is the basis // for the root library in the VM. -Uri _rootScript; +Uri? _rootScript; // packagesConfig specified for the isolate. -Uri _packagesConfigUri; +Uri? _packagesConfigUri; // Packages are either resolved looking up in a map or resolved from within a // package root. @@ -49,11 +47,11 @@ bool get _packagesReady => (_packageMap != null) || (_packageError != null); // Error string set if there was an error resolving package configuration. // For example not finding a .packages file or packages/ directory, malformed // .packages file or any other related error. -String _packageError = null; +String? _packageError = null; // The map describing how certain package names are mapped to Uris. -Uri _packageConfig = null; -Map _packageMap = null; +Uri? _packageConfig = null; +Map? _packageMap = null; // Special handling for Windows paths so that they are compatible with URI // handling. @@ -130,7 +128,7 @@ Uri _resolvePackageUri(Uri uri) { "'package:${uri.path}/', not 'package:${uri.path}'"; } var packageName = uri.path.substring(0, packageNameEnd); - final mapping = _packageMap[packageName]; + final mapping = _packageMap![packageName]; if (_traceLoading) { _log("Mapped '$packageName' package to '$mapping'"); } @@ -151,14 +149,14 @@ Uri _resolvePackageUri(Uri uri) { return resolvedUri; } -void _requestPackagesMap(Uri packageConfig) { +void _requestPackagesMap(Uri? packageConfig) { dynamic msg = null; if (packageConfig != null) { // Explicitly specified .packages path. msg = _handlePackagesRequest(_traceLoading, -2, packageConfig); } else { // Search for .packages starting at the root script. - msg = _handlePackagesRequest(_traceLoading, -1, _rootScript); + msg = _handlePackagesRequest(_traceLoading, -1, _rootScript!); } if (_traceLoading) { _log("Requested packages map for '$_rootScript'."); @@ -175,10 +173,11 @@ void _requestPackagesMap(Uri packageConfig) { assert(msg.length >= 2); assert(msg[1] == null); _packageConfig = Uri.parse(msg[0]); - _packageMap = new Map(); + final pmap = new Map(); + _packageMap = pmap; for (var i = 2; i < msg.length; i += 2) { // TODO(iposva): Complain about duplicate entries. - _packageMap[msg[i]] = Uri.parse(msg[i + 1]); + pmap[msg[i]] = Uri.parse(msg[i + 1]); } if (_traceLoading) { _log("Setup package map: $_packageMap"); @@ -291,7 +290,7 @@ List _parsePackageConfig(bool traceLoading, Uri packageConfig, String data) { String rootUri = package['rootUri']; if (!rootUri.endsWith('/')) rootUri += '/'; final String packageName = package['name']; - final String packageUri = package['packageUri']; + final String? packageUri = package['packageUri']; final Uri resolvedRootUri = packageConfig.resolve(rootUri); final Uri resolvedPackageUri = packageUri != null ? resolvedRootUri.resolve(packageUri) @@ -439,7 +438,7 @@ _handlePackagesRequest(bool traceLoading, int tag, Uri resource) { if (traceLoading) { _log("Handling load of packages map: '$resource'."); } - Uint8List bytes; + late Uint8List bytes; if (resource.scheme == '' || resource.scheme == 'file') { final file = File.fromUri(resource); if (!file.existsSync()) { @@ -447,7 +446,7 @@ _handlePackagesRequest(bool traceLoading, int tag, Uri resource) { } bytes = file.readAsBytesSync(); } else if (resource.scheme == 'data') { - final uriData = resource.data; + final uriData = resource.data!; if (!_isValidUtf8DataUrl(uriData)) { return "The data resource '$resource' must have a 'text/plain' mime " "type and a 'utf-8' or 'US-ASCII' charset."; @@ -561,7 +560,7 @@ _setupHooks() { VMLibraryHooks.resolvePackageUriFuture = _resolvePackageUriFuture; } -Future _getPackageConfigFuture() { +Future _getPackageConfigFuture() { if (_traceLoading) { _log("Request for package config from user code."); } @@ -572,7 +571,7 @@ Future _getPackageConfigFuture() { return Future.value(_packageConfig); } -Future _resolvePackageUriFuture(Uri packageUri) { +Future _resolvePackageUriFuture(Uri packageUri) { if (_traceLoading) { _log("Request for package Uri resolution from user code: $packageUri"); } @@ -586,7 +585,7 @@ Future _resolvePackageUriFuture(Uri packageUri) { if (!_packagesReady) { _requestPackagesMap(_packagesConfigUri); } - Uri resolvedUri; + Uri? resolvedUri; try { resolvedUri = _resolvePackageUri(packageUri); } catch (e, s) { diff --git a/sdk/lib/_internal/vm/bin/cli_patch.dart b/sdk/lib/_internal/vm/bin/cli_patch.dart index 0ccae81624e..504a0dbdbe5 100644 --- a/sdk/lib/_internal/vm/bin/cli_patch.dart +++ b/sdk/lib/_internal/vm/bin/cli_patch.dart @@ -2,8 +2,6 @@ // 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.6 - import "dart:_internal" show patch; @patch diff --git a/sdk/lib/_internal/vm/bin/common_patch.dart b/sdk/lib/_internal/vm/bin/common_patch.dart index ee3f1c99c9d..9899f2e4a5a 100644 --- a/sdk/lib/_internal/vm/bin/common_patch.dart +++ b/sdk/lib/_internal/vm/bin/common_patch.dart @@ -2,14 +2,12 @@ // 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.6 - /// Note: the VM concatenates all patch files into a single patch file. This /// file is the first patch in "dart:io" which contains all the imports used by /// patches of that library. We plan to change this when we have a shared front /// end and simply use parts. -import "dart:_internal" show VMLibraryHooks, patch, ClassID; +import "dart:_internal" show VMLibraryHooks, patch, checkNotNullable, ClassID; import "dart:async" show diff --git a/sdk/lib/_internal/vm/bin/directory_patch.dart b/sdk/lib/_internal/vm/bin/directory_patch.dart index c6b78065bf3..7549f72abb4 100644 --- a/sdk/lib/_internal/vm/bin/directory_patch.dart +++ b/sdk/lib/_internal/vm/bin/directory_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "common_patch.dart"; @patch diff --git a/sdk/lib/_internal/vm/bin/eventhandler_patch.dart b/sdk/lib/_internal/vm/bin/eventhandler_patch.dart index 1b5c5c86d62..072d9958b2c 100644 --- a/sdk/lib/_internal/vm/bin/eventhandler_patch.dart +++ b/sdk/lib/_internal/vm/bin/eventhandler_patch.dart @@ -2,14 +2,12 @@ // 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.6 - // part of "common_patch.dart"; @patch class _EventHandler { @patch - static void _sendData(Object sender, SendPort sendPort, int data) + static void _sendData(Object? sender, SendPort sendPort, int data) native "EventHandler_SendData"; static int _timerMillisecondClock() diff --git a/sdk/lib/_internal/vm/bin/file_patch.dart b/sdk/lib/_internal/vm/bin/file_patch.dart index 73fe2dcaa1c..033abea6211 100644 --- a/sdk/lib/_internal/vm/bin/file_patch.dart +++ b/sdk/lib/_internal/vm/bin/file_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "common_patch.dart"; @patch @@ -76,9 +74,9 @@ class _RandomAccessFileOpsImpl extends NativeFieldWrapperClass1 int close() native "File_Close"; readByte() native "File_ReadByte"; read(int bytes) native "File_Read"; - readInto(List buffer, int start, int end) native "File_ReadInto"; + readInto(List buffer, int start, int? end) native "File_ReadInto"; writeByte(int value) native "File_WriteByte"; - writeFrom(List buffer, int start, int end) native "File_WriteFrom"; + writeFrom(List buffer, int start, int? end) native "File_WriteFrom"; position() native "File_Position"; setPosition(int position) native "File_SetPosition"; truncate(int length) native "File_Truncate"; @@ -96,19 +94,20 @@ class _WatcherPath { } @patch -class _FileSystemWatcher { +abstract class _FileSystemWatcher { void _pathWatchedEnd(); - static int _id; + static int? _id; static final Map _idMap = {}; final String _path; final int _events; final bool _recursive; - _WatcherPath _watcherPath; + _WatcherPath? _watcherPath; - StreamController _broadcastController; + final StreamController _broadcastController = + new StreamController.broadcast(); @patch static Stream _watch( @@ -132,8 +131,9 @@ class _FileSystemWatcher { throw new FileSystemException( "File system watching is not supported on this platform", _path); } - _broadcastController = new StreamController.broadcast( - onListen: _listen, onCancel: _cancel); + _broadcastController + ..onListen = _listen + ..onCancel = _cancel; } Stream get _stream => _broadcastController.stream; @@ -143,7 +143,7 @@ class _FileSystemWatcher { try { _id = _initWatcher(); _newWatcher(); - } catch (e) { + } on dynamic catch (e) { _broadcastController.addError(new FileSystemException( "Failed to initialize file system entity watcher", null, e)); _broadcastController.close(); @@ -153,8 +153,8 @@ class _FileSystemWatcher { var pathId; try { pathId = - _watchPath(_id, _Namespace._namespace, _path, _events, _recursive); - } catch (e) { + _watchPath(_id!, _Namespace._namespace, _path, _events, _recursive); + } on dynamic catch (e) { _broadcastController .addError(new FileSystemException("Failed to watch path", _path, e)); _broadcastController.close(); @@ -164,25 +164,25 @@ class _FileSystemWatcher { _idMap[pathId] = new _WatcherPath(pathId, _path, _events); } _watcherPath = _idMap[pathId]; - _watcherPath.count++; + _watcherPath!.count++; _pathWatched().pipe(_broadcastController); } void _cancel() { - if (_watcherPath != null) { - assert(_watcherPath.count > 0); - _watcherPath.count--; - if (_watcherPath.count == 0) { - if (_idMap.containsKey(_watcherPath.pathId)) { - _unwatchPath(_id, _watcherPath.pathId); - _pathWatchedEnd(); - _idMap.remove(_watcherPath.pathId); - } + final watcherPath = _watcherPath; + if (watcherPath != null) { + assert(watcherPath.count > 0); + watcherPath.count--; + if (watcherPath.count == 0) { + _unwatchPath(_id!, watcherPath.pathId); + _pathWatchedEnd(); + _idMap.remove(watcherPath.pathId); } _watcherPath = null; } - if (_idMap.isEmpty && _id != null) { - _closeWatcher(_id); + final id = _id; + if (_idMap.isEmpty && id != null) { + _closeWatcher(id); _doneWatcher(); _id = null; } @@ -193,12 +193,12 @@ class _FileSystemWatcher { // Called when a watcher is no longer needed. void _doneWatcher() {} // Called when a new path is being watched. - Stream _pathWatched() {} + Stream _pathWatched(); // Called when a path is no longer being watched. void _donePathWatched() {} static _WatcherPath _pathFromPathId(int pathId) { - return _idMap[pathId]; + return _idMap[pathId]!; } static Stream _listenOnSocket(int socketId, int id, int pathId) { @@ -299,15 +299,6 @@ class _FileSystemWatcher { } } } else if (event == RawSocketEvent.closed) { - // After this point we should not try to do anything with pathId as - // the handle it represented is closed and gone now. - if (_idMap.containsKey(pathId)) { - _idMap.remove(pathId); - if (_idMap.isEmpty && _id != null) { - _closeWatcher(_id); - _id = null; - } - } } else if (event == RawSocketEvent.readClosed) { // If Directory watcher buffer overflows, it will send an readClosed event. // Normal closing will cancel stream subscription so that path is @@ -316,7 +307,7 @@ class _FileSystemWatcher { var path = _pathFromPathId(pathId).path; _idMap.remove(pathId); if (_idMap.isEmpty && _id != null) { - _closeWatcher(_id); + _closeWatcher(_id!); _id = null; } throw FileSystemException( @@ -348,20 +339,20 @@ class _FileSystemWatcher { class _InotifyFileSystemWatcher extends _FileSystemWatcher { static final Map _idMap = {}; - static StreamSubscription _subscription; + static late StreamSubscription _subscription; _InotifyFileSystemWatcher(path, events, recursive) : super._(path, events, recursive); void _newWatcher() { - int id = _FileSystemWatcher._id; + int id = _FileSystemWatcher._id!; _subscription = _FileSystemWatcher._listenOnSocket(id, id, 0).listen((event) { if (_idMap.containsKey(event[0])) { if (event[1] != null) { - _idMap[event[0]].add(event[1]); + _idMap[event[0]]!.add(event[1]); } else { - _idMap[event[0]].close(); + _idMap[event[0]]!.close(); } } }); @@ -372,30 +363,30 @@ class _InotifyFileSystemWatcher extends _FileSystemWatcher { } Stream _pathWatched() { - var pathId = _watcherPath.pathId; + var pathId = _watcherPath!.pathId; if (!_idMap.containsKey(pathId)) { _idMap[pathId] = new StreamController.broadcast(); } - return _idMap[pathId].stream; + return _idMap[pathId]!.stream; } void _pathWatchedEnd() { - var pathId = _watcherPath.pathId; + var pathId = _watcherPath!.pathId; if (!_idMap.containsKey(pathId)) return; - _idMap[pathId].close(); + _idMap[pathId]!.close(); _idMap.remove(pathId); } } class _Win32FileSystemWatcher extends _FileSystemWatcher { - StreamSubscription _subscription; - StreamController _controller; + late StreamSubscription _subscription; + late StreamController _controller; _Win32FileSystemWatcher(path, events, recursive) : super._(path, events, recursive); Stream _pathWatched() { - var pathId = _watcherPath.pathId; + var pathId = _watcherPath!.pathId; _controller = new StreamController(); _subscription = _FileSystemWatcher._listenOnSocket(pathId, 0, pathId).listen((event) { @@ -416,14 +407,14 @@ class _Win32FileSystemWatcher extends _FileSystemWatcher { } class _FSEventStreamFileSystemWatcher extends _FileSystemWatcher { - StreamSubscription _subscription; - StreamController _controller; + late StreamSubscription _subscription; + late StreamController _controller; _FSEventStreamFileSystemWatcher(path, events, recursive) : super._(path, events, recursive); Stream _pathWatched() { - var pathId = _watcherPath.pathId; + var pathId = _watcherPath!.pathId; var socketId = _FileSystemWatcher._getSocketId(0, pathId); _controller = new StreamController(); _subscription = diff --git a/sdk/lib/_internal/vm/bin/file_system_entity_patch.dart b/sdk/lib/_internal/vm/bin/file_system_entity_patch.dart index 1f081c7cc24..973e6b67579 100644 --- a/sdk/lib/_internal/vm/bin/file_system_entity_patch.dart +++ b/sdk/lib/_internal/vm/bin/file_system_entity_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "common_patch.dart"; @patch diff --git a/sdk/lib/_internal/vm/bin/filter_patch.dart b/sdk/lib/_internal/vm/bin/filter_patch.dart index 0594b6b3f97..06898f4851b 100644 --- a/sdk/lib/_internal/vm/bin/filter_patch.dart +++ b/sdk/lib/_internal/vm/bin/filter_patch.dart @@ -2,32 +2,30 @@ // 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.6 - // part of "common_patch.dart"; class _FilterImpl extends NativeFieldWrapperClass1 implements RawZLibFilter { void process(List data, int start, int end) native "Filter_Process"; - List processed({bool flush: true, bool end: false}) + List? processed({bool flush: true, bool end: false}) native "Filter_Processed"; } class _ZLibInflateFilter extends _FilterImpl { - _ZLibInflateFilter(int windowBits, List dictionary, bool raw) { + _ZLibInflateFilter(int windowBits, List? dictionary, bool raw) { _init(windowBits, dictionary, raw); } - void _init(int windowBits, List dictionary, bool raw) + void _init(int windowBits, List? dictionary, bool raw) native "Filter_CreateZLibInflate"; } class _ZLibDeflateFilter extends _FilterImpl { _ZLibDeflateFilter(bool gzip, int level, int windowBits, int memLevel, - int strategy, List dictionary, bool raw) { + int strategy, List? dictionary, bool raw) { _init(gzip, level, windowBits, memLevel, strategy, dictionary, raw); } void _init(bool gzip, int level, int windowBits, int memLevel, int strategy, - List dictionary, bool raw) native "Filter_CreateZLibDeflate"; + List? dictionary, bool raw) native "Filter_CreateZLibDeflate"; } @patch @@ -39,12 +37,12 @@ class RawZLibFilter { int windowBits, int memLevel, int strategy, - List dictionary, + List? dictionary, bool raw) => new _ZLibDeflateFilter( gzip, level, windowBits, memLevel, strategy, dictionary, raw); @patch static RawZLibFilter _makeZLibInflateFilter( - int windowBits, List dictionary, bool raw) => + int windowBits, List? dictionary, bool raw) => new _ZLibInflateFilter(windowBits, dictionary, raw); } diff --git a/sdk/lib/_internal/vm/bin/io_service_patch.dart b/sdk/lib/_internal/vm/bin/io_service_patch.dart index d98df90ebe7..d54bbf2371a 100644 --- a/sdk/lib/_internal/vm/bin/io_service_patch.dart +++ b/sdk/lib/_internal/vm/bin/io_service_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "common_patch.dart"; class _IOServicePorts { @@ -36,7 +34,7 @@ class _IOServicePorts { } void _returnPort(int forRequestId) { - final SendPort port = _usedPorts.remove(forRequestId); + final SendPort port = _usedPorts.remove(forRequestId)!; if (!_usedPorts.values.contains(port)) { _freePorts.add(port); } @@ -48,8 +46,8 @@ class _IOServicePorts { @patch class _IOService { static _IOServicePorts _servicePorts = new _IOServicePorts(); - static RawReceivePort _receivePort; - static SendPort _replyToPort; + static RawReceivePort? _receivePort; + static late SendPort _replyToPort; static HashMap _messageMap = new HashMap(); static int _id = 0; @@ -66,7 +64,7 @@ class _IOService { try { servicePort.send([id, _replyToPort, request, data]); } catch (error) { - _messageMap.remove(id).complete(error); + _messageMap.remove(id)!.complete(error); if (_messageMap.length == 0) { _finalize(); } @@ -77,10 +75,10 @@ class _IOService { static void _ensureInitialize() { if (_receivePort == null) { _receivePort = new RawReceivePort(); - _replyToPort = _receivePort.sendPort; - _receivePort.handler = (data) { + _replyToPort = _receivePort!.sendPort; + _receivePort!.handler = (data) { assert(data is List && data.length == 2); - _messageMap.remove(data[0]).complete(data[1]); + _messageMap.remove(data[0])!.complete(data[1]); _servicePorts._returnPort(data[0]); if (_messageMap.length == 0) { _finalize(); @@ -91,7 +89,7 @@ class _IOService { static void _finalize() { _id = 0; - _receivePort.close(); + _receivePort!.close(); _receivePort = null; } diff --git a/sdk/lib/_internal/vm/bin/namespace_patch.dart b/sdk/lib/_internal/vm/bin/namespace_patch.dart index 60bbb5ecc0c..2cf329f2f43 100644 --- a/sdk/lib/_internal/vm/bin/namespace_patch.dart +++ b/sdk/lib/_internal/vm/bin/namespace_patch.dart @@ -2,8 +2,6 @@ // 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.6 - @pragma("vm:entry-point") class _NamespaceImpl extends NativeFieldWrapperClass1 implements _Namespace { _NamespaceImpl._(); @@ -16,7 +14,7 @@ class _NamespaceImpl extends NativeFieldWrapperClass1 implements _Namespace { // If the platform supports "namespaces", this method is called by the // embedder with the platform-specific namespace information. - static _NamespaceImpl _cachedNamespace = null; + static _NamespaceImpl? _cachedNamespace = null; static void _setupNamespace(var namespace) { _cachedNamespace = _create(new _NamespaceImpl._(), namespace); } @@ -27,7 +25,7 @@ class _NamespaceImpl extends NativeFieldWrapperClass1 implements _Namespace { // instead use a safe-ish default value. _cachedNamespace = _create(new _NamespaceImpl._(), _getDefault()); } - return _cachedNamespace; + return _cachedNamespace!; } static int get _namespacePointer => _getPointer(_namespace); diff --git a/sdk/lib/_internal/vm/bin/platform_patch.dart b/sdk/lib/_internal/vm/bin/platform_patch.dart index a9c1040ebde..d187101b2ce 100644 --- a/sdk/lib/_internal/vm/bin/platform_patch.dart +++ b/sdk/lib/_internal/vm/bin/platform_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "common_patch.dart"; @patch @@ -35,9 +33,9 @@ class _Platform { static String _localeName() native "Platform_LocaleName"; @patch - static String _packageRoot() => VMLibraryHooks.packageRootString; + static String? _packageRoot() => VMLibraryHooks.packageRootString; @patch - static String _packageConfig() => VMLibraryHooks.packageConfigString; + static String? _packageConfig() => VMLibraryHooks.packageConfigString; @patch static Uri _script() => VMLibraryHooks.platformScript; diff --git a/sdk/lib/_internal/vm/bin/process_patch.dart b/sdk/lib/_internal/vm/bin/process_patch.dart index 89e7c14dd6a..bb86a0d9647 100644 --- a/sdk/lib/_internal/vm/bin/process_patch.dart +++ b/sdk/lib/_internal/vm/bin/process_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "common_patch.dart"; @patch @@ -22,8 +20,8 @@ class _WindowsCodePageEncoder { class Process { @patch static Future start(String executable, List arguments, - {String workingDirectory, - Map environment, + {String? workingDirectory, + Map? environment, bool includeParentEnvironment: true, bool runInShell: false, ProcessStartMode mode: ProcessStartMode.normal}) { @@ -40,12 +38,12 @@ class Process { @patch static Future run(String executable, List arguments, - {String workingDirectory, - Map environment, + {String? workingDirectory, + Map? environment, bool includeParentEnvironment: true, bool runInShell: false, - Encoding stdoutEncoding: systemEncoding, - Encoding stderrEncoding: systemEncoding}) { + Encoding? stdoutEncoding: systemEncoding, + Encoding? stderrEncoding: systemEncoding}) { return _runNonInteractiveProcess( executable, arguments, @@ -59,12 +57,12 @@ class Process { @patch static ProcessResult runSync(String executable, List arguments, - {String workingDirectory, - Map environment, + {String? workingDirectory, + Map? environment, bool includeParentEnvironment: true, bool runInShell: false, - Encoding stdoutEncoding: systemEncoding, - Encoding stderrEncoding: systemEncoding}) { + Encoding? stdoutEncoding: systemEncoding, + Encoding? stderrEncoding: systemEncoding}) { return _runNonInteractiveProcessSync( executable, arguments, @@ -78,24 +76,24 @@ class Process { @patch static bool killPid(int pid, [ProcessSignal signal = ProcessSignal.sigterm]) { - if (signal is! ProcessSignal) { - throw new ArgumentError("Argument 'signal' must be a ProcessSignal"); - } + // TODO(40614): Remove once non-nullability is sound. + ArgumentError.checkNotNull(signal, "signal"); return _ProcessUtils._killPid(pid, signal._signalNumber); } } -List<_SignalController> _signalControllers = new List(32); +List<_SignalController?> _signalControllers = new List.filled(32, null); class _SignalController { final ProcessSignal signal; - StreamController _controller; + final _controller = new StreamController.broadcast(); var _id; _SignalController(this.signal) { - _controller = new StreamController.broadcast( - onListen: _listen, onCancel: _cancel); + _controller + ..onListen = _listen + ..onCancel = _cancel; } Stream get stream => _controller.stream; @@ -111,7 +109,7 @@ class _SignalController { var socket = new _RawSocket(new _NativeSocket.watchSignal(id)); socket.listen((event) { if (event == RawSocketEvent.read) { - var bytes = socket.read(); + var bytes = socket.read()!; for (int i = 0; i < bytes.length; i++) { _controller.add(signal); } @@ -137,7 +135,7 @@ Function _getWatchSignalInternal() => _ProcessUtils._watchSignalInternal; @patch class _ProcessUtils { @patch - static void _exit(int status) native "Process_Exit"; + static Never _exit(int status) native "Process_Exit"; @patch static void _setExitCode(int status) native "Process_SetExitCode"; @patch @@ -145,7 +143,7 @@ class _ProcessUtils { @patch static void _sleep(int millis) native "Process_Sleep"; @patch - static int _pid(Process process) native "Process_Pid"; + static int _pid(Process? process) native "Process_Pid"; static bool _killPid(int pid, int signal) native "Process_KillPid"; @patch static Stream _watchSignal(ProcessSignal signal) { @@ -166,7 +164,7 @@ class _ProcessUtils { if (_signalControllers[signal._signalNumber] == null) { _signalControllers[signal._signalNumber] = new _SignalController(signal); } - return _signalControllers[signal._signalNumber].stream; + return _signalControllers[signal._signalNumber]!.stream; } } @@ -197,9 +195,9 @@ class ProcessInfo { @pragma("vm:entry-point") class _ProcessStartStatus { @pragma("vm:entry-point", "set") - int _errorCode; // Set to OS error code if process start failed. + int? _errorCode; // Set to OS error code if process start failed. @pragma("vm:entry-point", "set") - String _errorMessage; // Set to OS error message if process start failed. + String? _errorMessage; // Set to OS error message if process start failed. } // The NativeFieldWrapperClass1 can not be used with a mixin, due to missing @@ -207,18 +205,25 @@ class _ProcessStartStatus { class _ProcessImplNativeWrapper extends NativeFieldWrapperClass1 {} class _ProcessImpl extends _ProcessImplNativeWrapper implements Process { - _ProcessResourceInfo _resourceInfo; static bool connectedResourceHandler = false; _ProcessImpl( String path, List arguments, this._workingDirectory, - Map environment, + Map? environment, bool includeParentEnvironment, bool runInShell, - ProcessStartMode mode) + this._mode) : super() { + // TODO(40614): Remove once non-nullability is sound. + ArgumentError.checkNotNull(path, "path"); + ArgumentError.checkNotNull(arguments, "arguments"); + for (int i = 0; i < arguments.length; i++) { + ArgumentError.checkNotNull(arguments[i], "arguments[]"); + } + ArgumentError.checkNotNull(_mode, "mode"); + if (!connectedResourceHandler) { registerExtension( 'ext.dart.io.getProcesses', _ProcessResourceInfo.getStartedProcesses); @@ -232,10 +237,6 @@ class _ProcessImpl extends _ProcessImplNativeWrapper implements Process { path = _getShellCommand(); } - if (path is! String) { - throw new ArgumentError("Path is not a String: $path"); - } - if (Platform.isWindows && path.contains(' ') && !path.contains('"')) { // Escape paths that may contain spaces // Bug: https://github.com/dart-lang/sdk/issues/37751 @@ -244,57 +245,29 @@ class _ProcessImpl extends _ProcessImplNativeWrapper implements Process { _path = path; } - if (arguments is! List) { - throw new ArgumentError("Arguments is not a List: $arguments"); - } - int len = arguments.length; - _arguments = new List(len); - for (int i = 0; i < len; i++) { - var arg = arguments[i]; - if (arg is! String) { - throw new ArgumentError("Non-string argument: $arg"); - } - _arguments[i] = arguments[i]; - if (Platform.isWindows) { - _arguments[i] = _windowsArgumentEscape(_arguments[i]); - } - } - - if (_workingDirectory != null && _workingDirectory is! String) { - throw new ArgumentError( - "WorkingDirectory is not a String: $_workingDirectory"); - } + _arguments = [ + for (int i = 0; i < arguments.length; i++) + Platform.isWindows + ? _windowsArgumentEscape(arguments[i]) + : arguments[i], + ]; _environment = []; // Ensure that we have a non-null environment. - environment = (environment == null) ? (const {}) : environment; - if (environment is! Map) { - throw new ArgumentError("Environment is not a map: $environment"); - } + environment ??= const {}; environment.forEach((key, value) { - if (key is! String || value is! String) { - throw new ArgumentError( - "Environment key or value is not a string: ($key, $value)"); - } _environment.add('$key=$value'); }); if (includeParentEnvironment) { Platform.environment.forEach((key, value) { - assert(key is String); - assert(value is String); // Do not override keys already set as part of environment. - if (!environment.containsKey(key)) { + if (!environment!.containsKey(key)) { _environment.add('$key=$value'); } }); } - if (mode is! ProcessStartMode) { - throw new ArgumentError("Mode is not a ProcessStartMode: $mode"); - } - _mode = mode; - - if (_modeHasStdio(mode)) { + if (_modeHasStdio(_mode)) { // stdin going to process. _stdin = new _StdSink(new _Socket._writePipe().._owner = this); // stdout coming from process. @@ -302,19 +275,17 @@ class _ProcessImpl extends _ProcessImplNativeWrapper implements Process { // stderr coming from process. _stderr = new _StdStream(new _Socket._readPipe().._owner = this); } - if (_modeIsAttached(mode)) { + if (_modeIsAttached(_mode)) { _exitHandler = new _Socket._readPipe(); } - _ended = false; - _started = false; } _NativeSocket get _stdinNativeSocket => - (_stdin._sink as _Socket)._nativeSocket; + (_stdin!._sink as _Socket)._nativeSocket; _NativeSocket get _stdoutNativeSocket => - (_stdout._stream as _Socket)._nativeSocket; + (_stdout!._stream as _Socket)._nativeSocket; _NativeSocket get _stderrNativeSocket => - (_stderr._stream as _Socket)._nativeSocket; + (_stderr!._stream as _Socket)._nativeSocket; static bool _modeIsAttached(ProcessStartMode mode) { return (mode == ProcessStartMode.normal) || @@ -437,19 +408,19 @@ class _ProcessImpl extends _ProcessImplNativeWrapper implements Process { status); if (!success) { completer.completeError(new ProcessException( - _path, _arguments, status._errorMessage, status._errorCode)); + _path, _arguments, status._errorMessage!, status._errorCode!)); return; } _started = true; - _resourceInfo = new _ProcessResourceInfo(this); + final resourceInfo = new _ProcessResourceInfo(this); // Setup an exit handler to handle internal cleanup and possible // callback when a process terminates. if (_modeIsAttached(_mode)) { int exitDataRead = 0; final int EXIT_DATA_SIZE = 8; - List exitDataBuffer = new List(EXIT_DATA_SIZE); + List exitDataBuffer = new List.filled(EXIT_DATA_SIZE, 0); _exitHandler.listen((data) { int exitCode(List ints) { var code = _intFromBytes(ints, 0); @@ -460,12 +431,12 @@ class _ProcessImpl extends _ProcessImplNativeWrapper implements Process { void handleExit() { _ended = true; - _exitCode.complete(exitCode(exitDataBuffer)); + _exitCode!.complete(exitCode(exitDataBuffer)); // Kill stdin, helping hand if the user forgot to do it. if (_modeHasStdio(_mode)) { - (_stdin._sink as _Socket).destroy(); + (_stdin!._sink as _Socket).destroy(); } - _resourceInfo.stopped(); + resourceInfo.stopped(); } exitDataBuffer.setRange( @@ -482,7 +453,8 @@ class _ProcessImpl extends _ProcessImplNativeWrapper implements Process { return completer.future; } - ProcessResult _runAndWait(Encoding stdoutEncoding, Encoding stderrEncoding) { + ProcessResult _runAndWait( + Encoding? stdoutEncoding, Encoding? stderrEncoding) { var status = new _ProcessStartStatus(); _exitCode = new Completer(); bool success = _startNative( @@ -499,10 +471,10 @@ class _ProcessImpl extends _ProcessImplNativeWrapper implements Process { status); if (!success) { throw new ProcessException( - _path, _arguments, status._errorMessage, status._errorCode); + _path, _arguments, status._errorMessage!, status._errorCode!); } - _resourceInfo = new _ProcessResourceInfo(this); + final resourceInfo = new _ProcessResourceInfo(this); var result = _wait(_stdinNativeSocket, _stdoutNativeSocket, _stderrNativeSocket, _exitHandler._nativeSocket); @@ -512,7 +484,7 @@ class _ProcessImpl extends _ProcessImplNativeWrapper implements Process { return encoding.decode(output); } - _resourceInfo.stopped(); + resourceInfo.stopped(); return new ProcessResult( result[0], @@ -525,16 +497,16 @@ class _ProcessImpl extends _ProcessImplNativeWrapper implements Process { _Namespace namespace, String path, List arguments, - String workingDirectory, + String? workingDirectory, List environment, int mode, - _NativeSocket stdin, - _NativeSocket stdout, - _NativeSocket stderr, - _NativeSocket exitHandler, + _NativeSocket? stdin, + _NativeSocket? stdout, + _NativeSocket? stderr, + _NativeSocket? exitHandler, _ProcessStartStatus status) native "Process_Start"; - _wait(_NativeSocket stdin, _NativeSocket stdout, _NativeSocket stderr, + _wait(_NativeSocket? stdin, _NativeSocket? stdout, _NativeSocket? stderr, _NativeSocket exitHandler) native "Process_Wait"; Stream> get stdout => @@ -549,9 +521,8 @@ class _ProcessImpl extends _ProcessImplNativeWrapper implements Process { _exitCode?.future ?? (throw StateError("Process is detached")); bool kill([ProcessSignal signal = ProcessSignal.sigterm]) { - if (signal is! ProcessSignal) { - throw new ArgumentError("Argument 'signal' must be a ProcessSignal"); - } + // TODO(40614): Remove once non-nullability is sound. + ArgumentError.checkNotNull(kill, "kill"); assert(_started); if (_ended) return false; return _ProcessUtils._killPid(pid, signal._signalNumber); @@ -559,19 +530,19 @@ class _ProcessImpl extends _ProcessImplNativeWrapper implements Process { int get pid => _ProcessUtils._pid(this); - String _path; - List _arguments; - String _workingDirectory; - List _environment; - ProcessStartMode _mode; + late String _path; + late List _arguments; + String? _workingDirectory; + late List _environment; + final ProcessStartMode _mode; // Private methods of Socket are used by _in, _out, and _err. - _StdSink _stdin; - _StdStream _stdout; - _StdStream _stderr; - _Socket _exitHandler; - bool _ended; - bool _started; - Completer _exitCode; + _StdSink? _stdin; + _StdStream? _stdout; + _StdStream? _stderr; + late _Socket _exitHandler; + bool _ended = false; + bool _started = false; + Completer? _exitCode; } // _NonInteractiveProcess is a wrapper around an interactive process @@ -581,12 +552,12 @@ class _ProcessImpl extends _ProcessImplNativeWrapper implements Process { Future _runNonInteractiveProcess( String path, List arguments, - String workingDirectory, - Map environment, + String? workingDirectory, + Map? environment, bool includeParentEnvironment, bool runInShell, - Encoding stdoutEncoding, - Encoding stderrEncoding) { + Encoding? stdoutEncoding, + Encoding? stderrEncoding) { // Start the underlying process. return Process.start(path, arguments, workingDirectory: workingDirectory, @@ -600,14 +571,16 @@ Future _runNonInteractiveProcess( p.stdin.close(); // Setup stdout and stderr handling. - Future foldStream(Stream> stream, Encoding encoding) { + Future foldStream(Stream> stream, Encoding? encoding) { if (encoding == null) { return stream - .fold(new BytesBuilder(), (builder, data) => builder..add(data)) + .fold( + new BytesBuilder(), (builder, data) => builder..add(data)) .then((builder) => builder.takeBytes()); } else { - return stream.transform(encoding.decoder).fold(new StringBuffer(), - (buf, data) { + return stream + .transform(encoding.decoder) + .fold(new StringBuffer(), (buf, data) { buf.write(data); return buf; }).then((sb) => sb.toString()); @@ -626,12 +599,12 @@ Future _runNonInteractiveProcess( ProcessResult _runNonInteractiveProcessSync( String executable, List arguments, - String workingDirectory, - Map environment, + String? workingDirectory, + Map? environment, bool includeParentEnvironment, bool runInShell, - Encoding stdoutEncoding, - Encoding stderrEncoding) { + Encoding? stdoutEncoding, + Encoding? stderrEncoding) { var process = new _ProcessImpl( executable, arguments, diff --git a/sdk/lib/_internal/vm/bin/secure_socket_patch.dart b/sdk/lib/_internal/vm/bin/secure_socket_patch.dart index 117f90f0002..9a0586d6d6c 100644 --- a/sdk/lib/_internal/vm/bin/secure_socket_patch.dart +++ b/sdk/lib/_internal/vm/bin/secure_socket_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "common_patch.dart"; @patch @@ -28,7 +26,7 @@ class X509Certificate { } class _SecureSocket extends _Socket implements SecureSocket { - _RawSecureSocket get _raw => super._raw as _RawSecureSocket; + _RawSecureSocket? get _raw => super._raw as _RawSecureSocket?; _SecureSocket(RawSecureSocket raw) : super(raw); @@ -36,24 +34,24 @@ class _SecureSocket extends _Socket implements SecureSocket { {bool useSessionCache: true, bool requestClientCertificate: false, bool requireClientCertificate: false}) { - _raw.renegotiate( + _raw!.renegotiate( useSessionCache: useSessionCache, requestClientCertificate: requestClientCertificate, requireClientCertificate: requireClientCertificate); } - X509Certificate get peerCertificate { + X509Certificate? get peerCertificate { if (_raw == null) { throw new StateError("peerCertificate called on destroyed SecureSocket"); } - return _raw.peerCertificate; + return _raw!.peerCertificate; } - String get selectedProtocol { + String? get selectedProtocol { if (_raw == null) { throw new StateError("selectedProtocol called on destroyed SecureSocket"); } - return _raw.selectedProtocol; + return _raw!.selectedProtocol; } } @@ -78,17 +76,17 @@ class _SecureFilterImpl extends NativeFieldWrapperClass1 static final int ENCRYPTED_SIZE = 10 * 1024; _SecureFilterImpl._() { - buffers = new List<_ExternalBuffer>(_RawSecureSocket.bufferCount); - for (int i = 0; i < _RawSecureSocket.bufferCount; ++i) { - buffers[i] = new _ExternalBuffer( - _RawSecureSocket._isBufferEncrypted(i) ? ENCRYPTED_SIZE : SIZE); - } + buffers = <_ExternalBuffer>[ + for (int i = 0; i < _RawSecureSocket.bufferCount; ++i) + new _ExternalBuffer( + _RawSecureSocket._isBufferEncrypted(i) ? ENCRYPTED_SIZE : SIZE), + ]; } void connect( String hostName, SecurityContext context, - bool is_server, + bool isServer, bool requestClientCertificate, bool requireClientCertificate, Uint8List protocols) native "SecureSocket_Connect"; @@ -106,14 +104,14 @@ class _SecureFilterImpl extends NativeFieldWrapperClass1 int processBuffer(int bufferIndex) => throw new UnimplementedError(); - String selectedProtocol() native "SecureSocket_GetSelectedProtocol"; + String? selectedProtocol() native "SecureSocket_GetSelectedProtocol"; void renegotiate(bool useSessionCache, bool requestClientCertificate, bool requireClientCertificate) native "SecureSocket_Renegotiate"; void init() native "SecureSocket_Init"; - X509Certificate get peerCertificate native "SecureSocket_PeerCertificate"; + X509Certificate? get peerCertificate native "SecureSocket_PeerCertificate"; void registerBadCertificateCallback(Function callback) native "SecureSocket_RegisterBadCertificateCallback"; @@ -125,7 +123,7 @@ class _SecureFilterImpl extends NativeFieldWrapperClass1 int _pointer() native "SecureSocket_FilterPointer"; @pragma("vm:entry-point", "get") - List<_ExternalBuffer> buffers; + List<_ExternalBuffer>? buffers; } @patch @@ -157,36 +155,36 @@ class _SecurityContext extends NativeFieldWrapperClass1 static final SecurityContext defaultContext = new _SecurityContext(true); - void usePrivateKey(String file, {String password}) { + void usePrivateKey(String file, {String? password}) { List bytes = (new File(file)).readAsBytesSync(); usePrivateKeyBytes(bytes, password: password); } - void usePrivateKeyBytes(List keyBytes, {String password}) + void usePrivateKeyBytes(List keyBytes, {String? password}) native "SecurityContext_UsePrivateKeyBytes"; - void setTrustedCertificates(String file, {String password}) { + void setTrustedCertificates(String file, {String? password}) { List bytes = (new File(file)).readAsBytesSync(); setTrustedCertificatesBytes(bytes, password: password); } - void setTrustedCertificatesBytes(List certBytes, {String password}) + void setTrustedCertificatesBytes(List certBytes, {String? password}) native "SecurityContext_SetTrustedCertificatesBytes"; - void useCertificateChain(String file, {String password}) { + void useCertificateChain(String file, {String? password}) { List bytes = (new File(file)).readAsBytesSync(); useCertificateChainBytes(bytes, password: password); } - void useCertificateChainBytes(List chainBytes, {String password}) + void useCertificateChainBytes(List chainBytes, {String? password}) native "SecurityContext_UseCertificateChainBytes"; - void setClientAuthorities(String file, {String password}) { + void setClientAuthorities(String file, {String? password}) { List bytes = (new File(file)).readAsBytesSync(); setClientAuthoritiesBytes(bytes, password: password); } - void setClientAuthoritiesBytes(List authCertBytes, {String password}) + void setClientAuthoritiesBytes(List authCertBytes, {String? password}) native "SecurityContext_SetClientAuthoritiesBytes"; void setAlpnProtocols(List protocols, bool isServer) { @@ -210,32 +208,14 @@ class _X509CertificateImpl extends NativeFieldWrapperClass1 // This is done by WrappedX509 in secure_socket.cc. _X509CertificateImpl._(); - Uint8List _cachedDer; Uint8List get _der native "X509_Der"; - Uint8List get der { - if (_cachedDer == null) { - _cachedDer = _der; - } - return _cachedDer; - } + late final Uint8List der = _der; - String _cachedPem; String get _pem native "X509_Pem"; - String get pem { - if (_cachedPem == null) { - _cachedPem = _pem; - } - return _cachedPem; - } + late final String pem = _pem; - Uint8List _cachedSha1; Uint8List get _sha1 native "X509_Sha1"; - Uint8List get sha1 { - if (_cachedSha1 == null) { - _cachedSha1 = _sha1; - } - return _cachedSha1; - } + late final Uint8List sha1 = _sha1; String get subject native "X509_Subject"; String get issuer native "X509_Issuer"; diff --git a/sdk/lib/_internal/vm/bin/socket_patch.dart b/sdk/lib/_internal/vm/bin/socket_patch.dart index 8d2e06c31da..e2bff2fb777 100644 --- a/sdk/lib/_internal/vm/bin/socket_patch.dart +++ b/sdk/lib/_internal/vm/bin/socket_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "common_patch.dart"; @patch @@ -18,30 +16,29 @@ class RawServerSocket { @patch class RawSocket { @patch - static Future connect(host, int port, - {sourceAddress, Duration timeout}) { + static Future connect(dynamic host, int port, + {dynamic sourceAddress, Duration? timeout}) { return _RawSocket.connect(host, port, sourceAddress, timeout); } @patch - static Future> startConnect(host, int port, - {sourceAddress}) { + static Future> startConnect(dynamic host, int port, + {dynamic sourceAddress}) { return _RawSocket.startConnect(host, port, sourceAddress); } } @patch class RawSocketOption { - static final List _optionsCache = - List(_RawSocketOptions.values.length); + static final List _optionsCache = + List.filled(_RawSocketOptions.values.length, null); @patch static int _getOptionValue(int key) { if (key > _RawSocketOptions.values.length) { throw ArgumentError.value(key, 'key'); } - _optionsCache[key] ??= _getNativeOptionValue(key); - return _optionsCache[key]; + return _optionsCache[key] ??= _getNativeOptionValue(key); } static int _getNativeOptionValue(int key) @@ -71,13 +68,13 @@ class InternetAddress { } @patch - factory InternetAddress(String address, {InternetAddressType type}) { + factory InternetAddress(String address, {InternetAddressType? type}) { return _InternetAddress.fromString(address, type: type); } @patch factory InternetAddress.fromRawAddress(Uint8List rawAddress, - {InternetAddressType type}) { + {InternetAddressType? type}) { return _InternetAddress.fromRawAddress(rawAddress, type: type); } @@ -94,7 +91,7 @@ class InternetAddress { } @patch - static InternetAddress tryParse(String address) { + static InternetAddress? tryParse(String address) { return _InternetAddress.tryParse(address); } } @@ -121,13 +118,17 @@ class NetworkInterface { } void _throwOnBadPort(int port) { - if ((port == null) || (port < 0) || (port > 0xFFFF)) { + // TODO(40614): Remove once non-nullability is sound. + ArgumentError.checkNotNull(port, "port"); + if ((port < 0) || (port > 0xFFFF)) { throw new ArgumentError("Invalid port $port"); } } void _throwOnBadTtl(int ttl) { - if (ttl == null || ttl < 1 || ttl > 255) { + // TODO(40614): Remove once non-nullability is sound. + ArgumentError.checkNotNull(ttl, "ttl"); + if (ttl < 1 || ttl > 255) { throw new ArgumentError('Invalid ttl $ttl'); } } @@ -148,12 +149,12 @@ class _InternetAddress implements InternetAddress { static _InternetAddress anyIPv6 = _InternetAddress.fixed(_addressAnyIPv6); final String address; - final String _host; + final String? _host; final Uint8List _in_addr; final int _scope_id; final InternetAddressType type; - String get host => _host != null ? _host : address; + String get host => _host ?? address; Uint8List get rawAddress => new Uint8List.fromList(_in_addr); @@ -171,6 +172,7 @@ class _InternetAddress implements InternetAddress { case InternetAddressType.unix: return false; } + throw new UnsupportedError("Unexpected address type $type"); } bool get isLinkLocal { @@ -186,6 +188,7 @@ class _InternetAddress implements InternetAddress { case InternetAddressType.unix: return false; } + throw new UnsupportedError("Unexpected address type $type"); } bool get isMulticast { @@ -201,6 +204,7 @@ class _InternetAddress implements InternetAddress { case InternetAddressType.unix: return false; } + throw new UnsupportedError("Unexpected address type $type"); } Future reverse() { @@ -214,16 +218,14 @@ class _InternetAddress implements InternetAddress { [this._scope_id = 0]); factory _InternetAddress.fromString(String address, - {InternetAddressType type}) { + {InternetAddressType? type}) { + // TODO(40614): Remove once non-nullability is sound. + ArgumentError.checkNotNull(address, 'address'); if (type == InternetAddressType.unix) { - ArgumentError.checkNotNull(address, 'address'); var rawAddress = FileSystemEntity._toUtf8Array(address); return _InternetAddress( InternetAddressType.unix, address, null, rawAddress); } else { - if (address is! String) { - throw ArgumentError("Invalid internet address $address"); - } var in_addr = _parse(address); if (in_addr == null) { throw ArgumentError("Invalid internet address $address"); @@ -236,7 +238,7 @@ class _InternetAddress implements InternetAddress { } factory _InternetAddress.fromRawAddress(Uint8List rawAddress, - {InternetAddressType type}) { + {InternetAddressType? type}) { if (type == InternetAddressType.unix) { ArgumentError.checkNotNull(rawAddress, 'rawAddress'); var rawPath = FileSystemEntity._toNullTerminatedUtf8Array(rawAddress); @@ -258,10 +260,8 @@ class _InternetAddress implements InternetAddress { } } - static _InternetAddress tryParse(String address) { - if (address == null) { - throw ArgumentError("Invalid internet address $address"); - } + static _InternetAddress? tryParse(String address) { + checkNotNullable(address, "address"); var addressBytes = _parse(address); if (addressBytes == null) return null; var type = addressBytes.length == _IPv4AddrLength @@ -331,7 +331,7 @@ class _InternetAddress implements InternetAddress { static String _rawAddrToString(Uint8List address) native "InternetAddress_RawAddrToString"; - static Uint8List _parse(String address) native "InternetAddress_Parse"; + static Uint8List? _parse(String address) native "InternetAddress_Parse"; } class _NetworkInterface implements NetworkInterface { @@ -429,8 +429,8 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { Completer closeCompleter = new Completer.sync(); // Handlers and receive port for socket events from the event handler. - final List eventHandlers = new List(eventCount + 1); - RawReceivePort eventPort; + final List eventHandlers = new List.filled(eventCount + 1, null); + RawReceivePort? eventPort; bool flagsSent = false; // The type flags for this socket. @@ -440,7 +440,7 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { int localPort = 0; // Holds the address used to connect or bind the socket. - InternetAddress localAddress; + late InternetAddress localAddress; // The size of data that is ready to be read, for TCP sockets. // This might be out-of-date when Read is called. @@ -464,11 +464,11 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { bool writeAvailable = false; static bool connectedResourceHandler = false; - _ReadWriteResourceInfo resourceInfo; + _SocketResourceInfo? resourceInfo; // The owner object is the object that the Socket is being used by, e.g. // a HttpServer, a WebSocket connection, a process pipe, etc. - Object owner; + Object? owner; static Future> lookup(String host, {InternetAddressType type: InternetAddressType.any}) { @@ -552,7 +552,7 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { } static Future> startConnect( - host, int port, sourceAddress) { + dynamic host, int port, dynamic sourceAddress) { if (host is String) { host = escapeLinkLocalAddress(host); } @@ -584,9 +584,8 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { } return; } - final _InternetAddress address = it.current; - var socket = new _NativeSocket.normal(); - socket.localAddress = address; + final _InternetAddress address = it.current as _InternetAddress; + var socket = new _NativeSocket.normal(address); var result; if (sourceAddress == null) { if (address.type == InternetAddressType.unix) { @@ -694,13 +693,12 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { } connectNext(); - return new ConnectionTask<_NativeSocket>._( - socket: completer.future, onCancel: onCancel); + return new ConnectionTask<_NativeSocket>._(completer.future, onCancel); }); } static Future<_NativeSocket> connect( - host, int port, sourceAddress, Duration timeout) { + dynamic host, int port, dynamic sourceAddress, Duration? timeout) { return startConnect(host, port, sourceAddress) .then((ConnectionTask<_NativeSocket> task) { Future<_NativeSocket> socketFuture = task.socket; @@ -715,7 +713,7 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { }); } - static Future<_InternetAddress> _resolveHost(host) async { + static Future<_InternetAddress> _resolveHost(dynamic host) async { if (host is _InternetAddress) { return host; } else { @@ -735,8 +733,7 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { } final address = await _resolveHost(host); - var socket = new _NativeSocket.listen(); - socket.localAddress = address; + var socket = new _NativeSocket.listen(address); var result; if (address.type == InternetAddressType.unix) { var path = address.address; @@ -785,9 +782,11 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { _NativeSocket.datagram(this.localAddress) : typeFlags = typeNormalSocket | typeUdpSocket; - _NativeSocket.normal() : typeFlags = typeNormalSocket | typeTcpSocket; + _NativeSocket.normal(this.localAddress) + : typeFlags = typeNormalSocket | typeTcpSocket; - _NativeSocket.listen() : typeFlags = typeListeningSocket | typeTcpSocket { + _NativeSocket.listen(this.localAddress) + : typeFlags = typeListeningSocket | typeTcpSocket { isClosedWrite = true; } @@ -815,13 +814,13 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { String get _serviceTypePath => throw new UnimplementedError(); String get _serviceTypeName => throw new UnimplementedError(); - Uint8List read(int count) { + Uint8List? read(int? count) { if (count != null && count <= 0) { throw ArgumentError("Illegal length $count"); } if (isClosing || isClosed) return null; try { - var list; + Uint8List? list; if (count != null) { list = nativeRead(count); available = nativeAvailable(); @@ -845,13 +844,18 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { list = builder.toBytes(); } } + final resourceInformation = resourceInfo; + assert(resourceInformation != null || + isPipe || + isInternal || + isInternalSignal); if (list != null) { - if (resourceInfo != null) { - resourceInfo.totalRead += list.length; + if (resourceInformation != null) { + resourceInformation.totalRead += list.length; } } - if (resourceInfo != null) { - resourceInfo.didRead(); + if (resourceInformation != null) { + resourceInformation.didRead(); } if (!const bool.fromEnvironment("dart.vm.product")) { _SocketProfile.collectStatistic( @@ -860,24 +864,27 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { return list; } catch (e) { reportError(e, StackTrace.current, "Read failed"); + return null; } } - Datagram receive() { + Datagram? receive() { if (isClosing || isClosed) return null; try { - Datagram result = nativeRecvFrom(); + Datagram? result = nativeRecvFrom(); if (result != null) { - if (resourceInfo != null) { - resourceInfo.totalRead += result.data.length; + final resourceInformation = resourceInfo; + if (resourceInformation != null) { + resourceInformation.totalRead += result.data.length; } } - if (resourceInfo != null) { - resourceInfo.didRead(); + final resourceInformation = resourceInfo; + if (resourceInformation != null) { + resourceInformation.didRead(); } if (!const bool.fromEnvironment("dart.vm.product")) { _SocketProfile.collectStatistic(nativeGetSocketId(), - _SocketProfileType.readBytes, result?.data?.length); + _SocketProfileType.readBytes, result?.data.length); } _availableDatagram = nativeAvailableDatagram(); return result; @@ -887,9 +894,11 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { } } - int write(List buffer, int offset, int bytes) { - if (buffer is! List) throw new ArgumentError(); - if (offset == null) offset = 0; + static int _fixOffset(int? offset) => offset ?? 0; + + int write(List buffer, int offset, int? bytes) { + // TODO(40614): Remove once non-nullability is sound. + offset = _fixOffset(offset); if (bytes == null) { if (offset > buffer.length) { throw new RangeError.value(offset); @@ -901,9 +910,6 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { if ((offset + bytes) > buffer.length) { throw new RangeError.value(offset + bytes); } - if (offset is! int || bytes is! int) { - throw new ArgumentError("Invalid arguments to write on Socket"); - } if (isClosing || isClosed) return 0; if (bytes == 0) return 0; try { @@ -925,10 +931,13 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { } // Negate the result, as stated above. if (result < 0) result = -result; - // TODO(ricow): Remove when we track internal and pipe uses. - assert(resourceInfo != null || isPipe || isInternal || isInternalSignal); - if (resourceInfo != null) { - resourceInfo.addWrite(result); + final resourceInformation = resourceInfo; + assert(resourceInformation != null || + isPipe || + isInternal || + isInternalSignal); + if (resourceInformation != null) { + resourceInformation.addWrite(result); } return result; } catch (e) { @@ -953,8 +962,13 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { } int result = nativeSendTo(bufferAndStart.buffer, bufferAndStart.start, bytes, (address as _InternetAddress)._in_addr, port); - if (resourceInfo != null) { - resourceInfo.addWrite(result); + final resourceInformation = resourceInfo; + assert(resourceInformation != null || + isPipe || + isInternal || + isInternalSignal); + if (resourceInformation != null) { + resourceInformation.addWrite(result); } return result; } catch (e) { @@ -964,23 +978,25 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { } } - _NativeSocket accept() { + _NativeSocket? accept() { // Don't issue accept if we're closing. if (isClosing || isClosed) return null; assert(connections > 0); connections--; tokens++; returnTokens(listeningTokenBatchSize); - var socket = new _NativeSocket.normal(); + var socket = new _NativeSocket.normal(address); if (nativeAccept(socket) != true) return null; socket.localPort = localPort; - socket.localAddress = address; setupResourceInfo(socket); - // TODO(ricow): Remove when we track internal and pipe uses. - assert(resourceInfo != null || isPipe || isInternal || isInternalSignal); - if (resourceInfo != null) { + final resourceInformation = resourceInfo; + assert(resourceInformation != null || + isPipe || + isInternal || + isInternalSignal); + if (resourceInformation != null) { // We track this as read one byte. - resourceInfo.addRead(1); + resourceInformation.addRead(1); } return socket; } @@ -1074,7 +1090,7 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { void multiplex(Object eventsObj) { // TODO(paulberry): when issue #31305 is fixed, we should be able to simply // declare `events` as a `covariant int` parameter. - int events = eventsObj; + int events = eventsObj as int; for (int i = firstEvent; i <= lastEvent; i++) { if (((events & (1 << i)) != 0)) { if ((i == closedEvent || i == readEvent) && isClosedRead) continue; @@ -1109,11 +1125,13 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { if (i == destroyedEvent) { assert(isClosing); assert(!isClosed); - // TODO(ricow): Remove/update when we track internal and pipe uses. - assert( - resourceInfo != null || isPipe || isInternal || isInternalSignal); - if (resourceInfo != null) { - _SocketResourceInfo.SocketClosed(resourceInfo); + final resourceInformation = resourceInfo; + assert(resourceInformation != null || + isPipe || + isInternal || + isInternalSignal); + if (resourceInformation != null) { + _SocketResourceInfo.SocketClosed(resourceInformation); } isClosed = true; closeCompleter.complete(); @@ -1159,7 +1177,7 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { eventHandlers[destroyedEvent] = destroyed; } - void setListening({read: true, write: true}) { + void setListening({bool read: true, bool write: true}) { sendReadEvents = read; sendWriteEvents = write; if (read) issueReadEvent(); @@ -1225,7 +1243,7 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { int fullData = (typeFlags & typeTypeMask) | data; assert(!isClosing); connectToEventHandler(); - _EventHandler._sendData(this, eventPort.sendPort, fullData); + _EventHandler._sendData(this, eventPort!.sendPort, fullData); } void connectToEventHandler() { @@ -1244,8 +1262,7 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { } void disconnectFromEventHandler() { - assert(eventPort != null); - eventPort.close(); + eventPort!.close(); eventPort = null; // Now that we don't track this Socket anymore, we can clear the owner // field. @@ -1260,7 +1277,7 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { // Create the appropriate error/exception from different returned // error objects. static createError(error, String message, - [InternetAddress address, int port]) { + [InternetAddress? address, int? port]) { if (error is OSError) { return new SocketException(message, osError: error, address: address, port: port); @@ -1282,8 +1299,9 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { } } - void reportError(error, StackTrace st, String message) { - var e = createError(error, message, address, localPort); + void reportError(error, StackTrace? st, String message) { + var e = + createError(error, message, isUdp || isTcp ? address : null, localPort); // Invoke the error handler if any. if (eventHandlers[errorEvent] != null) { eventHandlers[errorEvent](e, st); @@ -1292,34 +1310,38 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { close(); } - getOption(SocketOption option) { - if (option == null) throw new ArgumentError.notNull("option"); - return nativeGetOption(option._value, address.type._value); + dynamic getOption(SocketOption option) { + // TODO(40614): Remove once non-nullability is sound. + ArgumentError.checkNotNull(option, "option"); + var result = nativeGetOption(option._value, address.type._value); + if (result is OSError) throw result; + return result; } bool setOption(SocketOption option, value) { - if (option == null) throw new ArgumentError.notNull("option"); + // TODO(40614): Remove once non-nullability is sound. + ArgumentError.checkNotNull(option, "option"); nativeSetOption(option._value, address.type._value, value); return true; } Uint8List getRawOption(RawSocketOption option) { - if (option == null) throw new ArgumentError.notNull("option"); - if (option.value == null) throw new ArgumentError.notNull("option.value"); - + // TODO(40614): Remove once non-nullability is sound. + ArgumentError.checkNotNull(option, "option"); + ArgumentError.checkNotNull(option.value, "option.value"); nativeGetRawOption(option.level, option.option, option.value); return option.value; } void setRawOption(RawSocketOption option) { - if (option == null) throw new ArgumentError.notNull("option"); - if (option.value == null) throw new ArgumentError.notNull("option.value"); - + // TODO(40614): Remove once non-nullability is sound. + ArgumentError.checkNotNull(option, "option"); + ArgumentError.checkNotNull(option.value, "option.value"); nativeSetRawOption(option.level, option.option, option.value); } - InternetAddress multicastAddress( - InternetAddress addr, NetworkInterface interface) { + InternetAddress? multicastAddress( + InternetAddress addr, NetworkInterface? interface) { // On Mac OS using the interface index for joining IPv4 multicast groups // is not supported. Here the IP address of the interface is needed. if (Platform.isMacOS && addr.type == InternetAddressType.IPv4) { @@ -1342,15 +1364,17 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { } } - void joinMulticast(InternetAddress addr, NetworkInterface interface) { - _InternetAddress interfaceAddr = multicastAddress(addr, interface); + void joinMulticast(InternetAddress addr, NetworkInterface? interface) { + final interfaceAddr = + multicastAddress(addr, interface) as _InternetAddress?; var interfaceIndex = interface == null ? 0 : interface.index; nativeJoinMulticast((addr as _InternetAddress)._in_addr, interfaceAddr?._in_addr, interfaceIndex); } - void leaveMulticast(InternetAddress addr, NetworkInterface interface) { - _InternetAddress interfaceAddr = multicastAddress(addr, interface); + void leaveMulticast(InternetAddress addr, NetworkInterface? interface) { + final interfaceAddr = + multicastAddress(addr, interface) as _InternetAddress?; var interfaceIndex = interface == null ? 0 : interface.index; nativeLeaveMulticast((addr as _InternetAddress)._in_addr, interfaceAddr?._in_addr, interfaceIndex); @@ -1359,8 +1383,8 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { void nativeSetSocketId(int id, int typeFlags) native "Socket_SetSocketId"; int nativeAvailable() native "Socket_Available"; bool nativeAvailableDatagram() native "Socket_AvailableDatagram"; - Uint8List nativeRead(int len) native "Socket_Read"; - Datagram nativeRecvFrom() native "Socket_RecvFrom"; + Uint8List? nativeRead(int len) native "Socket_Read"; + Datagram? nativeRecvFrom() native "Socket_RecvFrom"; int nativeWrite(List buffer, int offset, int bytes) native "Socket_WriteList"; int nativeSendTo(List buffer, int offset, int bytes, Uint8List address, @@ -1392,15 +1416,15 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { native "Socket_SetOption"; void nativeSetRawOption(int level, int option, Uint8List data) native "Socket_SetRawOption"; - void nativeJoinMulticast(Uint8List addr, Uint8List interfaceAddr, + void nativeJoinMulticast(Uint8List addr, Uint8List? interfaceAddr, int interfaceIndex) native "Socket_JoinMulticast"; - void nativeLeaveMulticast(Uint8List addr, Uint8List interfaceAddr, + void nativeLeaveMulticast(Uint8List addr, Uint8List? interfaceAddr, int interfaceIndex) native "Socket_LeaveMulticast"; } class _RawServerSocket extends Stream implements RawServerSocket { final _NativeSocket _socket; - StreamController _controller; + StreamController? _controller; bool _v6Only; static Future<_RawServerSocket> bind( @@ -1413,13 +1437,13 @@ class _RawServerSocket extends Stream implements RawServerSocket { _RawServerSocket(this._socket, this._v6Only); - StreamSubscription listen(void onData(RawSocket event), - {Function onError, void onDone(), bool cancelOnError}) { + StreamSubscription listen(void onData(RawSocket event)?, + {Function? onError, void onDone()?, bool? cancelOnError}) { if (_controller != null) { throw new StateError("Stream was already listened to"); } var zone = Zone.current; - _controller = new StreamController( + final controller = _controller = new StreamController( sync: true, onListen: _onSubscriptionStateChange, onCancel: _onSubscriptionStateChange, @@ -1434,16 +1458,16 @@ class _RawServerSocket extends Stream implements RawServerSocket { _SocketProfile.collectNewSocket(socket.nativeGetSocketId(), _tcpSocket, socket.address, socket.port); } - _controller.add(_RawSocket(socket)); - if (_controller.isPaused) return; + controller.add(_RawSocket(socket)); + if (controller.isPaused) return; } }), - error: zone.bindBinaryCallbackGuarded((e, st) { - _controller.addError(e, st); - _controller.close(); + error: zone.bindBinaryCallbackGuarded((Object e, StackTrace? st) { + controller.addError(e, st); + controller.close(); }), - destroyed: () => _controller.close()); - return _controller.stream.listen(onData, + destroyed: () => controller.close()); + return controller.stream.listen(onData, onError: onError, onDone: onDone, cancelOnError: cancelOnError); } @@ -1464,7 +1488,7 @@ class _RawServerSocket extends Stream implements RawServerSocket { } void _onSubscriptionStateChange() { - if (_controller.hasListener) { + if (_controller!.hasListener) { _resume(); } else { _socket.close(); @@ -1472,7 +1496,7 @@ class _RawServerSocket extends Stream implements RawServerSocket { } void _onPauseStateChange() { - if (_controller.isPaused) { + if (_controller!.isPaused) { _pause(); } else { _resume(); @@ -1486,7 +1510,7 @@ class _RawServerSocket extends Stream implements RawServerSocket { class _RawSocket extends Stream implements RawSocket { final _NativeSocket _socket; - StreamController _controller; + final _controller = new StreamController(sync: true); bool _readEventsEnabled = true; bool _writeEventsEnabled = true; @@ -1494,7 +1518,7 @@ class _RawSocket extends Stream implements RawSocket { bool _isMacOSTerminalInput = false; static Future connect( - host, int port, sourceAddress, Duration timeout) { + dynamic host, int port, dynamic sourceAddress, Duration? timeout) { return _NativeSocket.connect(host, port, sourceAddress, timeout) .then((socket) { if (!const bool.fromEnvironment("dart.vm.product")) { @@ -1506,7 +1530,7 @@ class _RawSocket extends Stream implements RawSocket { } static Future> startConnect( - host, int port, sourceAddress) { + dynamic host, int port, dynamic sourceAddress) { return _NativeSocket.startConnect(host, port, sourceAddress) .then((ConnectionTask<_NativeSocket> nativeTask) { final Future<_RawSocket> raw = @@ -1517,19 +1541,17 @@ class _RawSocket extends Stream implements RawSocket { } return _RawSocket(nativeSocket); }); - return ConnectionTask<_RawSocket>._( - socket: raw, onCancel: nativeTask._onCancel); + return ConnectionTask<_RawSocket>._(raw, nativeTask._onCancel); }); } _RawSocket(this._socket) { var zone = Zone.current; - _controller = new StreamController( - sync: true, - onListen: _onSubscriptionStateChange, - onCancel: _onSubscriptionStateChange, - onPause: _onPauseStateChange, - onResume: _onPauseStateChange); + _controller + ..onListen = _onSubscriptionStateChange + ..onCancel = _onSubscriptionStateChange + ..onPause = _onPauseStateChange + ..onResume = _onPauseStateChange; _socket.setHandlers( read: () => _controller.add(RawSocketEvent.read), write: () { @@ -1543,7 +1565,7 @@ class _RawSocket extends Stream implements RawSocket { _controller.add(RawSocketEvent.closed); _controller.close(); }, - error: zone.bindBinaryCallbackGuarded((e, st) { + error: zone.bindBinaryCallbackGuarded((Object e, StackTrace? st) { _controller.addError(e, st); _socket.close(); })); @@ -1556,7 +1578,7 @@ class _RawSocket extends Stream implements RawSocket { return new _RawSocket(native); } - factory _RawSocket._readPipe(int fd) { + factory _RawSocket._readPipe(int? fd) { var native = new _NativeSocket.pipe(); native.isClosedWrite = true; if (fd != null) _getStdioHandle(native, fd); @@ -1569,15 +1591,15 @@ class _RawSocket extends Stream implements RawSocket { return result; } - StreamSubscription listen(void onData(RawSocketEvent event), - {Function onError, void onDone(), bool cancelOnError}) { + StreamSubscription listen(void onData(RawSocketEvent event)?, + {Function? onError, void onDone()?, bool? cancelOnError}) { return _controller.stream.listen(onData, onError: onError, onDone: onDone, cancelOnError: cancelOnError); } int available() => _socket.available; - Uint8List read([int len]) { + Uint8List? read([int? len]) { if (_isMacOSTerminalInput) { var available = this.available(); if (available == 0) return null; @@ -1593,7 +1615,7 @@ class _RawSocket extends Stream implements RawSocket { } } - int write(List buffer, [int offset, int count]) => + int write(List buffer, [int offset = 0, int? count]) => _socket.write(buffer, offset, count); Future close() => _socket.close().then((_) { @@ -1686,8 +1708,8 @@ class _ServerSocket extends Stream implements ServerSocket { _ServerSocket(this._socket); - StreamSubscription listen(void onData(Socket event), - {Function onError, void onDone(), bool cancelOnError}) { + StreamSubscription listen(void onData(Socket event)?, + {Function? onError, void onDone()?, bool? cancelOnError}) { return _socket.map((rawSocket) => new _Socket(rawSocket)).listen( onData, onError: onError, @@ -1710,39 +1732,38 @@ class _ServerSocket extends Stream implements ServerSocket { @patch class Socket { @patch - static Future _connect(host, int port, - {sourceAddress, Duration timeout}) { + static Future _connect(dynamic host, int port, + {dynamic sourceAddress, Duration? timeout}) { return RawSocket.connect(host, port, sourceAddress: sourceAddress, timeout: timeout) .then((socket) => new _Socket(socket)); } @patch - static Future> _startConnect(host, int port, - {sourceAddress}) { + static Future> _startConnect(dynamic host, int port, + {dynamic sourceAddress}) { return RawSocket.startConnect(host, port, sourceAddress: sourceAddress) .then((rawTask) { Future socket = rawTask.socket.then((rawSocket) => new _Socket(rawSocket)); - return new ConnectionTask._( - socket: socket, onCancel: rawTask._onCancel); + return new ConnectionTask._(socket, rawTask._onCancel); }); } } class _SocketStreamConsumer extends StreamConsumer> { - StreamSubscription subscription; + StreamSubscription? subscription; final _Socket socket; - int offset; - List buffer; + int? offset; + List? buffer; bool paused = false; - Completer streamCompleter; + Completer? streamCompleter; _SocketStreamConsumer(this.socket); Future addStream(Stream> stream) { socket._ensureRawSocketSubscription(); - streamCompleter = new Completer(); + final completer = streamCompleter = new Completer(); if (socket._raw != null) { subscription = stream.listen((data) { assert(!paused); @@ -1763,7 +1784,7 @@ class _SocketStreamConsumer extends StreamConsumer> { done(); }, cancelOnError: true); } - return streamCompleter.future; + return completer.future; } Future close() { @@ -1772,39 +1793,42 @@ class _SocketStreamConsumer extends StreamConsumer> { } void write() { - if (subscription == null) return; - assert(buffer != null); + final sub = subscription; + if (sub == null) return; // Write as much as possible. - offset += socket._write(buffer, offset, buffer.length - offset); - if (offset < buffer.length) { + offset = + offset! + socket._write(buffer!, offset!, buffer!.length - offset!); + if (offset! < buffer!.length) { if (!paused) { paused = true; - subscription.pause(); + sub.pause(); } socket._enableWriteEvent(); } else { buffer = null; if (paused) { paused = false; - subscription.resume(); + sub.resume(); } } } void done([error, stackTrace]) { - if (streamCompleter != null) { + final completer = streamCompleter; + if (completer != null) { if (error != null) { - streamCompleter.completeError(error, stackTrace); + completer.completeError(error, stackTrace); } else { - streamCompleter.complete(socket); + completer.complete(socket); } streamCompleter = null; } } void stop() { - if (subscription == null) return; - subscription.cancel(); + final sub = subscription; + if (sub == null) return; + sub.cancel(); subscription = null; paused = false; socket._disableWriteEvent(); @@ -1812,37 +1836,36 @@ class _SocketStreamConsumer extends StreamConsumer> { } class _Socket extends Stream implements Socket { - RawSocket _raw; // Set to null when the raw socket is closed. + RawSocket? _raw; // Set to null when the raw socket is closed. bool _closed = false; // Set to true when the raw socket is closed. - StreamController _controller; + final _controller = new StreamController(sync: true); bool _controllerClosed = false; - _SocketStreamConsumer _consumer; - IOSink _sink; - var _subscription; + late _SocketStreamConsumer _consumer; + late IOSink _sink; + StreamSubscription? _subscription; var _detachReady; - _Socket(this._raw) { - _controller = new StreamController( - sync: true, - onListen: _onSubscriptionStateChange, - onCancel: _onSubscriptionStateChange, - onPause: _onPauseStateChange, - onResume: _onPauseStateChange); + _Socket(RawSocket raw) : _raw = raw { + _controller + ..onListen = _onSubscriptionStateChange + ..onCancel = _onSubscriptionStateChange + ..onPause = _onPauseStateChange + ..onResume = _onPauseStateChange; _consumer = new _SocketStreamConsumer(this); _sink = new IOSink(_consumer); // Disable read events until there is a subscription. - _raw.readEventsEnabled = false; + raw.readEventsEnabled = false; // Disable write events until the consumer needs it for pending writes. - _raw.writeEventsEnabled = false; + raw.writeEventsEnabled = false; } factory _Socket._writePipe() { return new _Socket(new _RawSocket._writePipe()); } - factory _Socket._readPipe([int fd]) { + factory _Socket._readPipe([int? fd]) { return new _Socket(new _RawSocket._readPipe(fd)); } @@ -1852,8 +1875,8 @@ class _Socket extends Stream implements Socket { // is Socket and not _NativeSocket. _NativeSocket get _nativeSocket => (_raw as _RawSocket)._socket; - StreamSubscription listen(void onData(Uint8List event), - {Function onError, void onDone(), bool cancelOnError}) { + StreamSubscription listen(void onData(Uint8List event)?, + {Function? onError, void onDone()?, bool? cancelOnError}) { return _controller.stream.listen(onData, onError: onError, onDone: onDone, cancelOnError: cancelOnError); } @@ -1864,17 +1887,18 @@ class _Socket extends Stream implements Socket { _sink.encoding = value; } - void write(Object obj) => _sink.write(obj); + void write(Object? obj) => _sink.write(obj); - void writeln([Object obj = ""]) => _sink.writeln(obj); + void writeln([Object? obj = ""]) => _sink.writeln(obj); void writeCharCode(int charCode) => _sink.writeCharCode(charCode); - void writeAll(Iterable objects, [sep = ""]) => _sink.writeAll(objects, sep); + void writeAll(Iterable objects, [String sep = ""]) => + _sink.writeAll(objects, sep); void add(List bytes) => _sink.add(bytes); - void addError(Object error, [StackTrace stackTrace]) { + void addError(Object error, [StackTrace? stackTrace]) { throw new UnsupportedError("Cannot send errors on sockets"); } @@ -1898,38 +1922,45 @@ class _Socket extends Stream implements Socket { } bool setOption(SocketOption option, bool enabled) { - if (_raw == null) throw const SocketException.closed(); - return _raw.setOption(option, enabled); + final raw = _raw; + if (raw == null) throw const SocketException.closed(); + return raw.setOption(option, enabled); } Uint8List getRawOption(RawSocketOption option) { - if (_raw == null) throw const SocketException.closed(); - return _raw.getRawOption(option); + final raw = _raw; + if (raw == null) throw const SocketException.closed(); + return raw.getRawOption(option); } void setRawOption(RawSocketOption option) { - if (_raw == null) throw const SocketException.closed(); - _raw.setRawOption(option); + final raw = _raw; + if (raw == null) throw const SocketException.closed(); + raw.setRawOption(option); } int get port { - if (_raw == null) throw const SocketException.closed(); - return _raw.port; + final raw = _raw; + if (raw == null) throw const SocketException.closed(); + return raw.port; } InternetAddress get address { - if (_raw == null) throw const SocketException.closed(); - return _raw.address; + final raw = _raw; + if (raw == null) throw const SocketException.closed(); + return raw.address; } int get remotePort { - if (_raw == null) throw const SocketException.closed(); - return _raw.remotePort; + final raw = _raw; + if (raw == null) throw const SocketException.closed(); + return raw.remotePort; } InternetAddress get remoteAddress { - if (_raw == null) throw const SocketException.closed(); - return _raw.remoteAddress; + final raw = _raw; + if (raw == null) throw const SocketException.closed(); + return raw.remoteAddress; } Future _detachRaw() { @@ -1947,45 +1978,45 @@ class _Socket extends Stream implements Socket { // consumer needs a subscription as they share the error and done // events from the raw socket. void _ensureRawSocketSubscription() { - if (_subscription == null && _raw != null) { - _subscription = _raw.listen(_onData, + final raw = _raw; + if (_subscription == null && raw != null) { + _subscription = raw.listen(_onData, onError: _onError, onDone: _onDone, cancelOnError: true); } } _closeRawSocket() { - var tmp = _raw; + var raw = _raw!; _raw = null; _closed = true; - tmp.close(); + raw.close(); } void _onSubscriptionStateChange() { + final raw = _raw; if (_controller.hasListener) { _ensureRawSocketSubscription(); // Enable read events for providing data to subscription. - if (_raw != null) { - _raw.readEventsEnabled = true; + if (raw != null) { + raw.readEventsEnabled = true; } } else { _controllerClosed = true; - if (_raw != null) { - _raw.shutdown(SocketDirection.receive); + if (raw != null) { + raw.shutdown(SocketDirection.receive); } } } void _onPauseStateChange() { - if (_raw != null) { - _raw.readEventsEnabled = !_controller.isPaused; - } + _raw?.readEventsEnabled = !_controller.isPaused; } void _onData(event) { switch (event) { case RawSocketEvent.read: if (_raw == null) break; - var buffer = _raw.read(); + var buffer = _raw!.read(); if (buffer != null) _controller.add(buffer); break; case RawSocketEvent.write: @@ -2016,30 +2047,28 @@ class _Socket extends Stream implements Socket { } int _write(List data, int offset, int length) { - if (_raw != null) { - return _raw.write(data, offset, length); + final raw = _raw; + if (raw != null) { + return raw.write(data, offset, length); } return 0; } void _enableWriteEvent() { - if (_raw != null) { - _raw.writeEventsEnabled = true; - } + _raw?.writeEventsEnabled = true; } void _disableWriteEvent() { - if (_raw != null) { - _raw.writeEventsEnabled = false; - } + _raw?.writeEventsEnabled = false; } void _consumerDone() { if (_detachReady != null) { _detachReady.complete(null); } else { - if (_raw != null) { - _raw.shutdown(SocketDirection.send); + final raw = _raw; + if (raw != null) { + raw.shutdown(SocketDirection.send); _disableWriteEvent(); } } @@ -2064,7 +2093,7 @@ class RawDatagramSocket { class _RawDatagramSocket extends Stream implements RawDatagramSocket { _NativeSocket _socket; - StreamController _controller; + late StreamController _controller; bool _readEventsEnabled = true; bool _writeEventsEnabled = true; @@ -2089,7 +2118,7 @@ class _RawDatagramSocket extends Stream _controller.add(RawSocketEvent.closed); _controller.close(); }, - error: zone.bindBinaryCallbackGuarded((e, st) { + error: zone.bindBinaryCallbackGuarded((Object e, StackTrace? st) { _controller.addError(e, st); _socket.close(); })); @@ -2109,8 +2138,8 @@ class _RawDatagramSocket extends Stream }); } - StreamSubscription listen(void onData(RawSocketEvent event), - {Function onError, void onDone(), bool cancelOnError}) { + StreamSubscription listen(void onData(RawSocketEvent event)?, + {Function? onError, void onDone()?, bool? cancelOnError}) { return _controller.stream.listen(onData, onError: onError, onDone: onDone, cancelOnError: cancelOnError); } @@ -2126,15 +2155,15 @@ class _RawDatagramSocket extends Stream int send(List buffer, InternetAddress address, int port) => _socket.send(buffer, 0, buffer.length, address, port); - Datagram receive() { + Datagram? receive() { return _socket.receive(); } - void joinMulticast(InternetAddress group, [NetworkInterface interface]) { + void joinMulticast(InternetAddress group, [NetworkInterface? interface]) { _socket.joinMulticast(group, interface); } - void leaveMulticast(InternetAddress group, [NetworkInterface interface]) { + void leaveMulticast(InternetAddress group, [NetworkInterface? interface]) { _socket.leaveMulticast(group, interface); } @@ -2164,7 +2193,7 @@ class _RawDatagramSocket extends Stream _socket.setOption(SocketOption._ipMulticastHops, value); NetworkInterface get multicastInterface => throw UnimplementedError(); - void set multicastInterface(NetworkInterface value) => + void set multicastInterface(NetworkInterface? value) => throw UnimplementedError(); bool get broadcastEnabled => _socket.getOption(SocketOption._ipBroadcast); diff --git a/sdk/lib/_internal/vm/bin/stdio_patch.dart b/sdk/lib/_internal/vm/bin/stdio_patch.dart index 217f3a3e8ea..bc3222151a8 100644 --- a/sdk/lib/_internal/vm/bin/stdio_patch.dart +++ b/sdk/lib/_internal/vm/bin/stdio_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "common_patch.dart"; @patch @@ -24,6 +22,7 @@ class _StdIOUtils { case _stdioHandleTypeFile: return new Stdin._(new _FileStream.forStdin(), fd); } + throw new UnsupportedError("Unexpected handle type $type"); } @patch @@ -37,7 +36,7 @@ class _StdIOUtils { } @patch - static int _socketType(Socket socket) { + static int? _socketType(Socket socket) { if (socket is _Socket) return _nativeSocketType(socket._nativeSocket); return null; } diff --git a/sdk/lib/_internal/vm/bin/sync_socket_patch.dart b/sdk/lib/_internal/vm/bin/sync_socket_patch.dart index bccdd4fce0a..f60244944af 100644 --- a/sdk/lib/_internal/vm/bin/sync_socket_patch.dart +++ b/sdk/lib/_internal/vm/bin/sync_socket_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "common_patch.dart"; @patch @@ -34,14 +32,14 @@ class _RawSynchronousSocket implements RawSynchronousSocket { void closeSync() => _socket.closeSync(); - int readIntoSync(List buffer, [int start = 0, int end]) => + int readIntoSync(List buffer, [int start = 0, int? end]) => _socket.readIntoSync(buffer, start, end); - List readSync(int bytes) => _socket.readSync(bytes); + List? readSync(int bytes) => _socket.readSync(bytes); void shutdown(SocketDirection direction) => _socket.shutdown(direction); - void writeFromSync(List buffer, [int start = 0, int end]) => + void writeFromSync(List buffer, [int start = 0, int? end]) => _socket.writeFromSync(buffer, start, end); } @@ -57,18 +55,19 @@ class _NativeSynchronousSocket extends _NativeSynchronousSocketNativeWrapper { bool isClosedWrite = false; // Holds the address used to connect the socket. - InternetAddress localAddress; + late InternetAddress localAddress; // Holds the port of the socket, 0 if not known. int localPort = 0; - _ReadWriteResourceInfo resourceInfo; + // Always set by setupResourceInfo called by connectSync. + late _SocketResourceInfo resourceInfo; static _NativeSynchronousSocket connectSync(host, int port) { if (host == null) { throw new ArgumentError("Parameter host cannot be null"); } - List<_InternetAddress> addresses = null; + late List<_InternetAddress> addresses; var error = null; if (host is _InternetAddress) { addresses = [host]; @@ -82,7 +81,6 @@ class _NativeSynchronousSocket extends _NativeSynchronousSocketNativeWrapper { throw createError(error, "Failed host lookup: '$host'"); } } - assert(addresses is List); var it = addresses.iterator; _NativeSynchronousSocket connectNext() { if (!it.moveNext()) { @@ -174,7 +172,7 @@ class _NativeSynchronousSocket extends _NativeSynchronousSocketNativeWrapper { // Create the appropriate error/exception from different returned // error objects. static createError(error, String message, - [InternetAddress address, int port]) { + [InternetAddress? address, int? port]) { if (error is OSError) { return new SocketException(message, osError: error, address: address, port: port); @@ -189,35 +187,26 @@ class _NativeSynchronousSocket extends _NativeSynchronousSocketNativeWrapper { if (response is OSError) { throw response; } - List<_InternetAddress> addresses = - new List<_InternetAddress>(response.length); - for (int i = 0; i < response.length; ++i) { - var result = response[i]; - var type = InternetAddressType._from(result[0]); - addresses[i] = _InternetAddress(type, result[1], host, result[2]); - } - return addresses; + return <_InternetAddress>[ + for (int i = 0; i < response.length; ++i) + new _InternetAddress(InternetAddressType._from(response[i][0]), + response[i][1], host, response[i][2]), + ]; } - int readIntoSync(List buffer, int start, int end) { + int readIntoSync(List buffer, int start, int? end) { + // TODO(40614): Remove once non-nullability is sound. + ArgumentError.checkNotNull(buffer, "buffer"); + ArgumentError.checkNotNull(start, "start"); _checkAvailable(); if (isClosedRead) { throw new SocketException("Socket is closed for reading"); } - - if ((buffer is! List) || - ((start != null) && (start is! int)) || - ((end != null) && (end is! int))) { - throw new ArgumentError("Invalid arguments to readIntoSync"); - } - if (start == null) { - throw new ArgumentError("start cannot be null"); - } end = RangeError.checkValidRange(start, end, buffer.length); if (end == start) { return 0; } - var result = _nativeReadInto(buffer, start, (end - start)); + var result = _nativeReadInto(buffer, start, end - start); if (result is OSError) { throw new SocketException("readIntoSync failed", osError: result); } @@ -225,7 +214,7 @@ class _NativeSynchronousSocket extends _NativeSynchronousSocketNativeWrapper { return result; } - List readSync(int len) { + List? readSync(int len) { _checkAvailable(); if (isClosedRead) { throw new SocketException("Socket is closed for reading"); @@ -241,15 +230,10 @@ class _NativeSynchronousSocket extends _NativeSynchronousSocketNativeWrapper { if (result is OSError) { throw result; } - assert(resourceInfo != null); - if (result != null) { - if (resourceInfo != null) { - resourceInfo.totalRead += result.length; - } - } - if (resourceInfo != null) { - resourceInfo.didRead(); + if (result is List) { + resourceInfo.totalRead += result.length; } + resourceInfo.didRead(); return result; } @@ -300,25 +284,18 @@ class _NativeSynchronousSocket extends _NativeSynchronousSocketNativeWrapper { isClosedWrite = true; } - void writeFromSync(List buffer, int start, int end) { + void writeFromSync(List buffer, int start, int? end) { + // TODO(40614): Remove once non-nullability is sound. + ArgumentError.checkNotNull(buffer, "buffer"); + ArgumentError.checkNotNull(start, "start"); _checkAvailable(); if (isClosedWrite) { throw new SocketException("Socket is closed for writing"); } - if ((buffer is! List) || - ((start != null) && (start is! int)) || - ((end != null) && (end is! int))) { - throw new ArgumentError("Invalid arguments to writeFromSync"); - } - if (start == null) { - throw new ArgumentError("start cannot be equal to null"); - } - end = RangeError.checkValidRange(start, end, buffer.length); if (end == start) { return; } - _BufferAndStart bufferAndStart = _ensureFastAndSerializableByteData(buffer, start, end); var result = _nativeWrite(bufferAndStart.buffer, bufferAndStart.start, @@ -326,10 +303,7 @@ class _NativeSynchronousSocket extends _NativeSynchronousSocketNativeWrapper { if (result is OSError) { throw new SocketException("writeFromSync failed", osError: result); } - assert(resourceInfo != null); - if (resourceInfo != null) { - resourceInfo.addWrite(result); - } + resourceInfo.addWrite(result); } void _checkAvailable() { diff --git a/sdk/lib/_internal/vm/bin/vmservice_io.dart b/sdk/lib/_internal/vm/bin/vmservice_io.dart index 06564f5db6e..aea026bebfc 100644 --- a/sdk/lib/_internal/vm/bin/vmservice_io.dart +++ b/sdk/lib/_internal/vm/bin/vmservice_io.dart @@ -2,8 +2,6 @@ // 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.6 - library vmservice_io; import 'dart:async'; @@ -14,45 +12,48 @@ import 'dart:_vmservice'; part 'vmservice_server.dart'; // The TCP ip/port that the HTTP server listens on. -@pragma("vm:entry-point") -int _port; -@pragma("vm:entry-point") -String _ip; +@pragma('vm:entry-point') +int _port = 0; +@pragma('vm:entry-point') +String _ip = ''; // Should the HTTP server auto start? -@pragma("vm:entry-point") -bool _autoStart; +@pragma('vm:entry-point') +bool _autoStart = false; // Should the HTTP server require an auth code? -@pragma("vm:entry-point") -bool _authCodesDisabled; +@pragma('vm:entry-point') +bool _authCodesDisabled = false; // Should the HTTP server run in devmode? -@pragma("vm:entry-point") -bool _originCheckDisabled; +@pragma('vm:entry-point') +bool _originCheckDisabled = false; // Location of file to output VM service connection info. -@pragma("vm:entry-point") -String _serviceInfoFilename; -@pragma("vm:entry-point") +@pragma('vm:entry-point') +String? _serviceInfoFilename; +@pragma('vm:entry-point') bool _isWindows = false; -@pragma("vm:entry-point") +@pragma('vm:entry-point') bool _isFuchsia = false; -@pragma("vm:entry-point") -var _signalWatch; +@pragma('vm:entry-point') +var _signalWatch = null; var _signalSubscription; @pragma("vm:entry-point") bool _enableServicePortFallback = false; // HTTP server. -Server server; -Future serverFuture; +Server? server; +Future? serverFuture; -_lazyServerBoot() { - if (server != null) { - return; +Server _lazyServerBoot() { + var localServer = server; + if (localServer != null) { + return localServer; } // Lazily create service. - var service = new VMService(); + final service = VMService(); // Lazily create server. - server = new Server(service, _ip, _port, _originCheckDisabled, + localServer = Server(service, _ip, _port, _originCheckDisabled, _authCodesDisabled, _serviceInfoFilename, _enableServicePortFallback); + server = localServer; + return localServer; } Future cleanupCallback() async { @@ -61,15 +62,16 @@ Future cleanupCallback() async { await _signalSubscription.cancel(); _signalSubscription = null; } - if (server != null) { + final localServer = server; + if (localServer != null) { try { - await server.cleanup(true); + await localServer.cleanup(true); } catch (e, st) { - print("Error in vm-service shutdown: $e\n$st\n"); + print('Error in vm-service shutdown: $e\n$st\n'); } } if (_registerSignalHandlerTimer != null) { - _registerSignalHandlerTimer.cancel(); + _registerSignalHandlerTimer!.cancel(); _registerSignalHandlerTimer = null; } // Call out to embedder's shutdown callback. @@ -77,40 +79,38 @@ Future cleanupCallback() async { } Future createTempDirCallback(String base) async { - Directory temp = await Directory.systemTemp.createTemp(base); + final temp = await Directory.systemTemp.createTemp(base); // Underneath the temporary directory, create a directory with the // same name as the DevFS name [base]. - var fsUri = temp.uri.resolveUri(new Uri.directory(base)); - await new Directory.fromUri(fsUri).create(); + final fsUri = temp.uri.resolveUri(Uri.directory(base)); + await Directory.fromUri(fsUri).create(); return fsUri; } -Future deleteDirCallback(Uri path) async { - Directory dir = new Directory.fromUri(path); - await dir.delete(recursive: true); -} +Future deleteDirCallback(Uri path) async => + await Directory.fromUri(path).delete(recursive: true); class PendingWrite { PendingWrite(this.uri, this.bytes); - final Completer completer = new Completer(); + final completer = Completer(); final Uri uri; final List bytes; Future write() async { - var file = new File.fromUri(uri); - var parent_directory = file.parent; + final file = File.fromUri(uri); + final parent_directory = file.parent; await parent_directory.create(recursive: true); if (await file.exists()) { await file.delete(); } - var result = await file.writeAsBytes(bytes); - completer.complete(null); + await file.writeAsBytes(bytes); + completer.complete(); WriteLimiter._writeCompleted(); } } class WriteLimiter { - static final List pendingWrites = new List(); + static final pendingWrites = []; // non-rooted Android devices have a very low limit for the number of // open files. Artificially cap ourselves to 16. @@ -119,7 +119,7 @@ class WriteLimiter { static Future scheduleWrite(Uri path, List bytes) async { // Create a new pending write. - PendingWrite pw = new PendingWrite(path, bytes); + final pw = PendingWrite(path, bytes); pendingWrites.add(pw); _maybeWriteFiles(); return pw.completer.future; @@ -128,7 +128,7 @@ class WriteLimiter { static _maybeWriteFiles() { while (openWrites < kMaxOpenWrites) { if (pendingWrites.length > 0) { - PendingWrite pw = pendingWrites.removeLast(); + final pw = pendingWrites.removeLast(); pw.write(); openWrites++; } else { @@ -144,38 +144,35 @@ class WriteLimiter { } } -Future writeFileCallback(Uri path, List bytes) async { - return WriteLimiter.scheduleWrite(path, bytes); -} +Future writeFileCallback(Uri path, List bytes) async => + WriteLimiter.scheduleWrite(path, bytes); -Future writeStreamFileCallback(Uri path, Stream> bytes) async { - var file = new File.fromUri(path); - var parent_directory = file.parent; +Future writeStreamFileCallback(Uri path, Stream> bytes) async { + final file = File.fromUri(path); + final parent_directory = file.parent; await parent_directory.create(recursive: true); if (await file.exists()) { await file.delete(); } - IOSink sink = await file.openWrite(); + final sink = await file.openWrite(); await sink.addStream(bytes); await sink.close(); } -Future> readFileCallback(Uri path) async { - var file = new File.fromUri(path); - return await file.readAsBytes(); -} +Future> readFileCallback(Uri path) async => + await File.fromUri(path).readAsBytes(); Future>> listFilesCallback(Uri dirPath) async { - var dir = new Directory.fromUri(dirPath); - var dirPathStr = dirPath.path; - var stream = dir.list(recursive: true); - var result = >[]; + final dir = Directory.fromUri(dirPath); + final dirPathStr = dirPath.path; + final stream = dir.list(recursive: true); + final result = >[]; await for (var fileEntity in stream) { - var filePath = new Uri.file(fileEntity.path).path; - var stat = await fileEntity.stat(); - if (stat.type == FileSystemEntityType.FILE && + final filePath = Uri.file(fileEntity.path).path; + final stat = await fileEntity.stat(); + if (stat.type == FileSystemEntityType.file && filePath.startsWith(dirPathStr)) { - var map = {}; + final map = {}; map['name'] = '/' + filePath.substring(dirPathStr.length); map['size'] = stat.size; map['modified'] = stat.modified.millisecondsSinceEpoch; @@ -185,33 +182,26 @@ Future>> listFilesCallback(Uri dirPath) async { return result; } -Future serverInformationCallback() async { - _lazyServerBoot(); - return server.serverAddress; -} +Uri? serverInformationCallback() => _lazyServerBoot().serverAddress; -Future webServerControlCallback(bool enable) async { - _lazyServerBoot(); - if (server.running == enable) { - // No change. - return server.serverAddress; - } - - if (enable) { - await server.startup(); - return server.serverAddress; - } else { - await server.shutdown(true); - return server.serverAddress; +Future webServerControlCallback(bool enable) async { + final _server = _lazyServerBoot(); + if (_server.running != enable) { + if (enable) { + await _server.startup(); + } else { + await _server.shutdown(true); + } } + return _server.serverAddress; } void webServerAcceptNewWebSocketConnections(bool enable) { - _lazyServerBoot(); - server.acceptNewWebSocketConnections = enable; + final _server = _lazyServerBoot(); + _server.acceptNewWebSocketConnections = enable; } -Null _clearFuture(_) { +void _clearFuture(_) { serverFuture = null; } @@ -220,16 +210,16 @@ _onSignal(ProcessSignal signal) { // Still waiting. return; } - _lazyServerBoot(); + final _server = _lazyServerBoot(); // Toggle HTTP server. - if (server.running) { - serverFuture = server.shutdown(true).then(_clearFuture); + if (_server.running) { + _server.shutdown(true).then(_clearFuture); } else { - serverFuture = server.startup().then(_clearFuture); + _server.startup().then(_clearFuture); } } -Timer _registerSignalHandlerTimer; +Timer? _registerSignalHandlerTimer; _registerSignalHandler() { _registerSignalHandlerTimer = null; @@ -241,10 +231,10 @@ _registerSignalHandler() { // Cannot register for signals on Windows or Fuchsia. return; } - _signalSubscription = _signalWatch(ProcessSignal.SIGQUIT).listen(_onSignal); + _signalSubscription = _signalWatch(ProcessSignal.sigquit).listen(_onSignal); } -@pragma("vm:entry-point", !const bool.fromEnvironment("dart.vm.product")) +@pragma('vm:entry-point', !const bool.fromEnvironment('dart.vm.product')) main() { // Set embedder hooks. VMServiceEmbedderHooks.cleanup = cleanupCallback; @@ -260,17 +250,17 @@ main() { webServerAcceptNewWebSocketConnections; // Always instantiate the vmservice object so that the exit message // can be delivered and waiting loaders can be cancelled. - new VMService(); + VMService(); if (_autoStart) { - _lazyServerBoot(); - server.startup(); + final _server = _lazyServerBoot(); + _server.startup(); // It's just here to push an event on the event loop so that we invoke the // scheduled microtasks. Timer.run(() {}); } // Register signal handler after a small delay to avoid stalling main // isolate startup. - _registerSignalHandlerTimer = new Timer(shortDelay, _registerSignalHandler); + _registerSignalHandlerTimer = Timer(shortDelay, _registerSignalHandler); } -_shutdown() native "VMServiceIO_Shutdown"; +_shutdown() native 'VMServiceIO_Shutdown'; diff --git a/sdk/lib/_internal/vm/bin/vmservice_server.dart b/sdk/lib/_internal/vm/bin/vmservice_server.dart index efc87eb5513..26f1bfa86aa 100644 --- a/sdk/lib/_internal/vm/bin/vmservice_server.dart +++ b/sdk/lib/_internal/vm/bin/vmservice_server.dart @@ -2,11 +2,9 @@ // 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.6 - part of vmservice_io; -final bool silentObservatory = new bool.fromEnvironment('SILENT_OBSERVATORY'); +final bool silentObservatory = bool.fromEnvironment('SILENT_OBSERVATORY'); void serverPrint(String s) { if (silentObservatory) { @@ -17,10 +15,10 @@ void serverPrint(String s) { } class WebSocketClient extends Client { - static const int PARSE_ERROR_CODE = 4000; - static const int BINARY_MESSAGE_ERROR_CODE = 4001; - static const int NOT_MAP_ERROR_CODE = 4002; - static const int ID_ERROR_CODE = 4003; + static const int parseErrorCode = 4000; + static const int binaryMessageErrorCode = 4001; + static const int notMapErrorCode = 4002; + static const int idErrorCode = 4003; final WebSocket socket; WebSocketClient(this.socket, VMService service) : super(service) { @@ -36,19 +34,19 @@ class WebSocketClient extends Client { void onWebSocketMessage(message) { if (message is String) { - var map; + Map map; try { map = json.decode(message); } catch (e) { - socket.close(PARSE_ERROR_CODE, 'Message parse error: $e'); + socket.close(parseErrorCode, 'Message parse error: $e'); return; } if (map is! Map) { - socket.close(NOT_MAP_ERROR_CODE, 'Message must be a JSON map.'); + socket.close(notMapErrorCode, 'Message must be a JSON map.'); return; } try { - final rpc = new Message.fromJsonRpc(this, map); + final rpc = Message.fromJsonRpc(this, map); switch (rpc.type) { case MessageType.Request: onRequest(rpc); @@ -60,17 +58,17 @@ class WebSocketClient extends Client { onResponse(rpc); break; } - } catch (e) { - socket.close(ID_ERROR_CODE, e.message); + } on dynamic catch (e) { + socket.close(idErrorCode, e.message); } } else { - socket.close(BINARY_MESSAGE_ERROR_CODE, 'Message must be a string.'); + socket.close(binaryMessageErrorCode, 'Message must be a string.'); } } - void post(Response result) { + void post(Response? result) { if (result == null) { - // Do nothing. + // The result of a notification event. Do nothing. return; } try { @@ -89,17 +87,16 @@ class WebSocketClient extends Client { } } - dynamic toJson() { - Map map = super.toJson(); - map['type'] = 'WebSocketClient'; - map['socket'] = '$socket'; - return map; - } + Map toJson() => { + ...super.toJson(), + 'type': 'WebSocketClient', + 'socket': '$socket', + }; } class HttpRequestClient extends Client { - static ContentType jsonContentType = - new ContentType("application", "json", charset: "utf-8"); + static final jsonContentType = + ContentType('application', 'json', charset: 'utf-8'); final HttpRequest request; HttpRequestClient(this.request, VMService service) @@ -110,11 +107,14 @@ class HttpRequestClient extends Client { close(); } - void post(Response result) { + void post(Response? result) { if (result == null) { + // The result of a notification event. Nothing to do other than close the + // connection. close(); return; } + HttpResponse response = request.response; // We closed the connection for bad origins earlier. response.headers.add('Access-Control-Allow-Origin', '*'); @@ -133,8 +133,8 @@ class HttpRequestClient extends Client { close(); } - dynamic toJson() { - Map map = super.toJson(); + Map toJson() { + final map = super.toJson(); map['type'] = 'HttpRequestClient'; map['request'] = '$request'; return map; @@ -150,21 +150,22 @@ class Server { final bool _originCheckDisabled; final bool _authCodesDisabled; final bool _enableServicePortFallback; - final String _serviceInfoFilename; - HttpServer _server; + final String? _serviceInfoFilename; + HttpServer? _server; bool get running => _server != null; bool acceptNewWebSocketConnections = true; int _port = -1; /// Returns the server address including the auth token. - Uri get serverAddress { + Uri? get serverAddress { if (!running) { return null; } - var ip = _server.address.address; - var port = _server.port; - var path = !_authCodesDisabled ? "$serviceAuthToken/" : "/"; - return new Uri(scheme: 'http', host: ip, port: port, path: path); + final server = _server!; + final ip = server.address.address; + final port = server.port; + final path = !_authCodesDisabled ? '$serviceAuthToken/' : '/'; + return Uri(scheme: 'http', host: ip, port: port, path: path); } // On Fuchsia, authentication codes are disabled by default. To enable, the authentication token @@ -195,9 +196,10 @@ class Server { return true; } - if ((uri.port == _server.port) && - ((uri.host == _server.address.address) || - (uri.host == _server.address.host))) { + final server = _server!; + if ((uri.port == server.port) && + ((uri.host == server.address.address) || + (uri.host == server.address.host))) { return true; } @@ -210,16 +212,16 @@ class Server { return true; } // First check the web-socket specific origin. - List origins = request.headers["Sec-WebSocket-Origin"]; + List? origins = request.headers['Sec-WebSocket-Origin']; if (origins == null) { // Fall back to the general Origin field. - origins = request.headers["Origin"]; + origins = request.headers['Origin']; } if (origins == null) { // No origin sent. This is a non-browser client or a same-origin request. return true; } - for (String origin in origins) { + for (final origin in origins) { if (_isAllowedOrigin(origin)) { return true; } @@ -240,7 +242,7 @@ class Server { return null; } // Check that we were given the auth token. - final String authToken = requestPathSegments[0]; + final authToken = requestPathSegments[0]; if (authToken != serviceAuthToken) { // Malformed. return null; @@ -249,7 +251,7 @@ class Server { // ROOT_REDIRECT_PATH correctly, otherwise the response is misinterpreted. if (requestPathSegments.length == 1) { // requestPathSegments is unmodifiable. Copy it. - final List pathSegments = []..addAll(requestPathSegments); + final pathSegments = List.from(requestPathSegments); // Adding an empty string to the path segments results in the path having // a trailing '/'. @@ -267,7 +269,7 @@ class Server { if (!_originCheck(request)) { // This is a cross origin attempt to connect request.response.statusCode = HttpStatus.forbidden; - request.response.write("forbidden origin"); + request.response.write('forbidden origin'); request.response.close(); return; } @@ -275,22 +277,22 @@ class Server { // PUT requests are forwarded to DevFS for processing. List fsNameList; - List fsPathList; - List fsPathBase64List; - List fsUriBase64List; - Object fsName; - Object fsPath; - Object fsUri; + List? fsPathList; + List? fsPathBase64List; + List? fsUriBase64List; + Object? fsName; + Object? fsPath; + Uri? fsUri; try { // Extract the fs name and fs path from the request headers. - fsNameList = request.headers['dev_fs_name']; + fsNameList = request.headers['dev_fs_name']!; fsName = fsNameList[0]; // Prefer Uri encoding first. fsUriBase64List = request.headers['dev_fs_uri_b64']; if ((fsUriBase64List != null) && (fsUriBase64List.length > 0)) { - String decodedFsUri = utf8.decode(base64.decode(fsUriBase64List[0])); + final decodedFsUri = utf8.decode(base64.decode(fsUriBase64List[0])); fsUri = Uri.parse(decodedFsUri); } @@ -299,9 +301,9 @@ class Server { fsPathList = request.headers['dev_fs_path']; fsPathBase64List = request.headers['dev_fs_path_b64']; // If the 'dev_fs_path_b64' header field was sent, use that instead. - if ((fsPathBase64List != null) && (fsPathBase64List.length > 0)) { + if ((fsPathBase64List != null) && fsPathBase64List.isNotEmpty) { fsPath = utf8.decode(base64.decode(fsPathBase64List[0])); - } else { + } else if (fsPathList != null && fsPathList.isNotEmpty) { fsPath = fsPathList[0]; } } @@ -310,7 +312,7 @@ class Server { String result; try { result = await _service.devfs.handlePutStream(fsName, fsPath, fsUri, - request.cast>().transform(GZIP.decoder)); + request.cast>().transform(gzip.decoder)); } catch (e) { request.response.statusCode = HttpStatus.internalServerError; request.response.write(e); @@ -329,24 +331,24 @@ class Server { if (request.method != 'GET') { // Not a GET request. Do nothing. request.response.statusCode = HttpStatus.methodNotAllowed; - request.response.write("method not allowed"); + request.response.write('method not allowed'); request.response.close(); return; } - final dynamic result = _checkAuthTokenAndGetPath(request.uri); + final result = _checkAuthTokenAndGetPath(request.uri); if (result == null) { // Either no authentication code was provided when one was expected or an // incorrect authentication code was provided. request.response.statusCode = HttpStatus.forbidden; - request.response.write("missing or invalid authentication code"); + request.response.write('missing or invalid authentication code'); request.response.close(); return; } else if (result is Uri) { // The URI contains the valid auth token but is missing a trailing '/'. // Redirect to the same URI with the trailing '/' to correctly serve // index.html. - request.response.redirect(result as Uri); + request.response.redirect(result); return; } @@ -356,22 +358,22 @@ class Server { WebSocketTransformer.upgrade(request, compression: CompressionOptions.compressionOff) .then((WebSocket webSocket) { - new WebSocketClient(webSocket, _service); + WebSocketClient(webSocket, _service); }); } else { // Forward the websocket connection request to DDS. - request.response.redirect(_service.ddsUri); + request.response.redirect(_service.ddsUri!); } return; } if (assets == null) { - request.response.headers.contentType = ContentType.TEXT; - request.response.write("This VM was built without the Observatory UI."); + request.response.headers.contentType = ContentType.text; + request.response.write('This VM was built without the Observatory UI.'); request.response.close(); return; } - Asset asset = assets[path]; + final asset = assets[path]; if (asset != null) { // Serving up a static asset (e.g. .css, .html, .png). request.response.headers.contentType = ContentType.parse(asset.mimeType); @@ -380,21 +382,21 @@ class Server { return; } // HTTP based service request. - final client = new HttpRequestClient(request, _service); - final message = new Message.fromUri( + final client = HttpRequestClient(request, _service); + final message = Message.fromUri( client, Uri(path: path, queryParameters: request.uri.queryParameters)); client.onRequest(message); // exception free, no need to try catch } - Future _dumpServiceInfoToFile() async { + Future _dumpServiceInfoToFile(String serviceInfoFilenameLocal) async { final serviceInfo = { 'uri': serverAddress.toString(), }; - final file = File.fromUri(Uri.parse(_serviceInfoFilename)); + final file = File.fromUri(Uri.parse(serviceInfoFilenameLocal)); return file.writeAsString(json.encode(serviceInfo)); } - Future startup() async { + Future startup() async { if (_server != null) { // Already running. return this; @@ -408,9 +410,9 @@ class Server { var address; var addresses = await InternetAddress.lookup(_ip); // Prefer IPv4 addresses. - for (var i = 0; i < addresses.length; i++) { + for (int i = 0; i < addresses.length; i++) { address = addresses[i]; - if (address.type == InternetAddressType.IP_V4) break; + if (address.type == InternetAddressType.IPv4) break; } _server = await HttpServer.bind(address, _port); return true; @@ -423,14 +425,14 @@ class Server { // poll for the network for ~10 seconds. int attempts = 0; - final int maxAttempts = 10; + final maxAttempts = 10; while (!await poll()) { attempts++; - serverPrint("Observatory server failed to start after $attempts tries"); + serverPrint('Observatory server failed to start after $attempts tries'); if (attempts > maxAttempts) { serverPrint('Could not start Observatory HTTP server:\n' '$pollError\n$pollStack\n'); - _notifyServerState(""); + _notifyServerState(''); onServerAddressChange(null); return this; } @@ -438,7 +440,7 @@ class Server { _port = 0; serverPrint('Falling back to automatic port selection'); } - await new Future.delayed(const Duration(seconds: 1)); + await Future.delayed(const Duration(seconds: 1)); } if (_service.isExiting) { serverPrint('Observatory HTTP server exiting before listening as ' @@ -446,17 +448,20 @@ class Server { await shutdown(true); return this; } - _server.listen(_requestHandler, cancelOnError: true); + final server = _server!; + server.listen(_requestHandler, cancelOnError: true); serverPrint('Observatory listening on $serverAddress'); if (Platform.isFuchsia) { // Create a file with the port number. - String tmp = Directory.systemTemp.path; - String path = "$tmp/dart.services/${_server.port}"; - serverPrint("Creating $path"); - new File(path)..createSync(recursive: true); + final tmp = Directory.systemTemp.path; + final path = '$tmp/dart.services/${server.port}'; + serverPrint('Creating $path'); + File(path)..createSync(recursive: true); } - if (_serviceInfoFilename != null && _serviceInfoFilename.isNotEmpty) { - await _dumpServiceInfoToFile(); + final serviceInfoFilenameLocal = _serviceInfoFilename; + if (serviceInfoFilenameLocal != null && + serviceInfoFilenameLocal.isNotEmpty) { + await _dumpServiceInfoToFile(serviceInfoFilenameLocal); } // Server is up and running. _notifyServerState(serverAddress.toString()); @@ -464,42 +469,43 @@ class Server { return this; } - Future cleanup(bool force) { - if (_server == null) { - return new Future.value(null); + Future cleanup(bool force) { + final serverLocal = _server; + if (serverLocal == null) { + return Future.value(); } if (Platform.isFuchsia) { // Remove the file with the port number. - String tmp = Directory.systemTemp.path; - String path = "$tmp/dart.services/${_server.port}"; - serverPrint("Deleting $path"); - new File(path)..deleteSync(); + final tmp = Directory.systemTemp.path; + final path = '$tmp/dart.services/${serverLocal.port}'; + serverPrint('Deleting $path'); + File(path)..deleteSync(); } - return _server.close(force: force); + return serverLocal.close(force: force); } - Future shutdown(bool forced) { + Future shutdown(bool forced) { if (_server == null) { // Not started. - return new Future.value(this); + return Future.value(this); } // Shutdown HTTP server and subscription. - Uri oldServerAddress = serverAddress; + Uri oldServerAddress = serverAddress!; return cleanup(forced).then((_) { serverPrint('Observatory no longer listening on $oldServerAddress'); _server = null; - _notifyServerState(""); + _notifyServerState(''); onServerAddressChange(null); return this; }).catchError((e, st) { _server = null; serverPrint('Could not shutdown Observatory HTTP server:\n$e\n$st\n'); - _notifyServerState(""); + _notifyServerState(''); onServerAddressChange(null); return this; }); } } -void _notifyServerState(String uri) native "VMServiceIO_NotifyServerState"; +void _notifyServerState(String uri) native 'VMServiceIO_NotifyServerState'; diff --git a/sdk/lib/_internal/vm/lib/array.dart b/sdk/lib/_internal/vm/lib/array.dart index 5fb151757af..53048413284 100644 --- a/sdk/lib/_internal/vm/lib/array.dart +++ b/sdk/lib/_internal/vm/lib/array.dart @@ -2,14 +2,12 @@ // 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.6 - // part of "core_patch.dart"; @pragma("vm:entry-point") class _List extends FixedLengthListBase { - @pragma( - "vm:exact-result-type", [_List, "result-type-uses-passed-type-arguments"]) + @pragma("vm:exact-result-type", + [_List, "result-type-uses-passed-type-arguments"]) @pragma("vm:prefer-inline") factory _List(length) native "List_allocate"; @@ -26,7 +24,7 @@ class _List extends FixedLengthListBase { int get length native "List_getLength"; @pragma("vm:prefer-inline") - List _slice(int start, int count, bool needsTypeArgument) { + _List _slice(int start, int count, bool needsTypeArgument) { if (count <= 64) { final result = needsTypeArgument ? new _List(count) : new _List(count); for (int i = 0; i < result.length; i++) { @@ -38,7 +36,7 @@ class _List extends FixedLengthListBase { } } - List _sliceInternal(int start, int count, bool needsTypeArgument) + _List _sliceInternal(int start, int count, bool needsTypeArgument) native "List_slice"; // List interface. @@ -54,12 +52,12 @@ class _List extends FixedLengthListBase { if (identical(this, iterable)) { Lists.copy(this, skipCount, this, start, length); } else if (ClassID.getID(iterable) == ClassID.cidArray) { - final _List iterableAsList = iterable; + final _List iterableAsList = unsafeCast<_List>(iterable); Lists.copy(iterableAsList, skipCount, this, start, length); } else if (iterable is List) { Lists.copy(iterable, skipCount, this, start, length); } else { - Iterator it = iterable.iterator; + Iterator it = iterable.iterator; while (skipCount > 0) { if (!it.moveNext()) return; skipCount--; @@ -79,7 +77,7 @@ class _List extends FixedLengthListBase { if (identical(this, iterable)) { iterableAsList = this; } else if (ClassID.getID(iterable) == ClassID.cidArray) { - iterableAsList = iterable; + iterableAsList = unsafeCast<_List>(iterable); } else if (iterable is List) { iterableAsList = iterable; } else { @@ -95,9 +93,10 @@ class _List extends FixedLengthListBase { Lists.copy(iterableAsList, 0, this, index, length); } - List sublist(int start, [int end]) { - end = RangeError.checkValidRange(start, end, this.length); - int length = end - start; + List sublist(int start, [int? end]) { + final int listLength = this.length; + final int actualEnd = RangeError.checkValidRange(start, end, listLength); + int length = actualEnd - start; if (length == 0) return []; var result = new _GrowableList._withData(_slice(start, length, false)); result._setLength(length); @@ -138,11 +137,11 @@ class _List extends FixedLengthListBase { List toList({bool growable: true}) { var length = this.length; if (length > 0) { - var result = _slice(0, length, !growable); + _List result = _slice(0, length, !growable); if (growable) { - result = new _GrowableList._withData(result).._setLength(length); + return new _GrowableList._withData(result).._setLength(length); } - return result; + return unsafeCast<_List>(result); } // _GrowableList._withData must not be called with empty list. return growable ? [] : new _List(0); @@ -172,15 +171,15 @@ class _ImmutableList extends UnmodifiableListBase { @pragma("vm:prefer-inline") int get length native "List_getLength"; - List sublist(int start, [int end]) { - end = RangeError.checkValidRange(start, end, this.length); - int length = end - start; + List sublist(int start, [int? end]) { + final int actualEnd = RangeError.checkValidRange(start, end, this.length); + int length = actualEnd - start; if (length == 0) return []; - List list = new _List(length); + final list = new _List(length); for (int i = 0; i < length; i++) { list[i] = this[start + i]; } - var result = new _GrowableList._withData(list); + final result = new _GrowableList._withData(list); result._setLength(length); return result; } @@ -217,16 +216,21 @@ class _ImmutableList extends UnmodifiableListBase { } List toList({bool growable: true}) { - var length = this.length; + final int length = this.length; if (length > 0) { - List list = growable ? new _List(length) : new _List(length); - for (int i = 0; i < length; i++) { - list[i] = this[i]; + if (growable) { + final list = new _List(length); + for (int i = 0; i < length; i++) { + list[i] = this[i]; + } + return _GrowableList._withData(list).._setLength(length); + } else { + final list = new _List(length); + for (int i = 0; i < length; i++) { + list[i] = this[i]; + } + return list; } - if (!growable) return list; - var result = new _GrowableList._withData(list); - result._setLength(length); - return result; } return growable ? [] : new _List(0); } @@ -237,7 +241,7 @@ class _FixedSizeArrayIterator implements Iterator { final List _array; final int _length; // Cache array length for faster access. int _index; - E _current; + E? _current; _FixedSizeArrayIterator(List array) : _array = array, @@ -246,7 +250,10 @@ class _FixedSizeArrayIterator implements Iterator { assert(array is _List || array is _ImmutableList); } - E get current => _current; + E get current { + final cur = _current; + return (cur != null) ? cur : cur as E; + } @pragma("vm:prefer-inline") bool moveNext() { diff --git a/sdk/lib/_internal/vm/lib/array_patch.dart b/sdk/lib/_internal/vm/lib/array_patch.dart index fff049099bb..ef181bee908 100644 --- a/sdk/lib/_internal/vm/lib/array_patch.dart +++ b/sdk/lib/_internal/vm/lib/array_patch.dart @@ -2,14 +2,17 @@ // 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.6 - // part of "core_patch.dart"; @patch class List { @patch - factory List([int length]) native "List_new"; + factory List.empty({bool growable = false}) { + return growable ? [] : _List(0); + } + + @patch + factory List([int? length]) native "List_new"; @patch factory List.filled(int length, E fill, {bool growable: false}) { @@ -65,6 +68,18 @@ class List { return List.from(elements, growable: growable); } + @patch + @pragma("vm:prefer-inline") + factory List.generate(int length, E generator(int index), + {bool growable = true}) { + final List result = + growable ? new _GrowableList(length) : new _List(length); + for (int i = 0; i < result.length; ++i) { + result[i] = generator(i); + } + return result; + } + @patch factory List.unmodifiable(Iterable elements) { final result = new List.from(elements, growable: false); @@ -78,7 +93,7 @@ class List { if (elements.isEmpty) { return new _GrowableList(0); } - var result = new _GrowableList._withData(elements); + final result = new _GrowableList._withData(unsafeCast<_List>(elements)); result._setLength(elements.length); return result; } diff --git a/sdk/lib/_internal/vm/lib/async_patch.dart b/sdk/lib/_internal/vm/lib/async_patch.dart index 3c111f47ad3..c3201d3a13a 100644 --- a/sdk/lib/_internal/vm/lib/async_patch.dart +++ b/sdk/lib/_internal/vm/lib/async_patch.dart @@ -2,8 +2,6 @@ // 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.6 - /// Note: the VM concatenates all patch files into a single patch file. This /// file is the first patch in "dart:async" which contains all the imports used /// by patches of that library. We plan to change this when we have a shared @@ -29,15 +27,21 @@ class _AsyncAwaitCompleter implements Completer { _AsyncAwaitCompleter() : isSync = false; @pragma("vm:entry-point") - void complete([FutureOr value]) { - if (!isSync || value is Future) { + void complete([FutureOr? value]) { + // All paths require that if value is null, null as T succeeds. + value = (value == null) ? value as T : value; + if (!isSync) { _future._asyncComplete(value); + } else if (value is Future) { + assert(!_future._isComplete); + _future._chainFuture(value); } else { - _future._completeWithValue(value); + // TODO(40014): Remove cast when type promotion works. + _future._completeWithValue(value as T); } } - void completeError(Object e, [StackTrace st]) { + void completeError(Object e, [StackTrace? st]) { st ??= AsyncError.defaultStackTrace(e); if (isSync) { _future._completeError(e, st); @@ -97,7 +101,7 @@ dynamic Function(Object, StackTrace) _asyncErrorWrapperHelper( /// Returns the result of registering with `.then`. Future _awaitHelper(var object, dynamic Function(dynamic) thenCallback, dynamic Function(dynamic, StackTrace) errorCallback, Function awaiter) { - _Future future; + late _Future future; if (object is! Future) { future = new _Future().._setValue(object); } else if (object is _Future) { @@ -133,11 +137,12 @@ void _asyncStarMoveNextHelper(var stream) { return; } // stream is a _StreamImpl. - if (stream._generator == null) { + final generator = stream._generator; + if (generator == null) { // No generator registered, this isn't an async* Stream. return; } - _moveNextDebuggerStepCheck(stream._generator); + _moveNextDebuggerStepCheck(generator); } // _AsyncStarStreamController is used by the compiler to implement @@ -151,7 +156,7 @@ class _AsyncStarStreamController { bool onListenReceived = false; bool isScheduled = false; bool isSuspendedAtYield = false; - _Future cancellationFuture = null; + _Future? cancellationFuture = null; Stream get stream { final Stream local = controller.stream; @@ -218,11 +223,13 @@ class _AsyncStarStreamController { } void addError(Object error, StackTrace stackTrace) { + // TODO(40614): Remove once non-nullability is sound. ArgumentError.checkNotNull(error, "error"); - if ((cancellationFuture != null) && cancellationFuture._mayComplete) { + final future = cancellationFuture; + if ((future != null) && future._mayComplete) { // If the stream has been cancelled, complete the cancellation future // with the error. - cancellationFuture._completeError(error, stackTrace); + future._completeError(error, stackTrace); return; } // If stream is cancelled, tell caller to exit the async generator. @@ -235,19 +242,20 @@ class _AsyncStarStreamController { } close() { - if ((cancellationFuture != null) && cancellationFuture._mayComplete) { + final future = cancellationFuture; + if ((future != null) && future._mayComplete) { // If the stream has been cancelled, complete the cancellation future // with the error. - cancellationFuture._completeWithValue(null); + future._completeWithValue(null); } controller.close(); } - _AsyncStarStreamController(this.asyncStarBody) { - controller = new StreamController( - onListen: this.onListen, - onResume: this.onResume, - onCancel: this.onCancel); + _AsyncStarStreamController(this.asyncStarBody) + : controller = new StreamController() { + controller.onListen = this.onListen; + controller.onResume = this.onResume; + controller.onCancel = this.onCancel; } onListen() { @@ -285,17 +293,17 @@ void _rethrow(Object error, StackTrace stackTrace) native "Async_rethrow"; @patch class _Future { /// The closure implementing the async[*]-body that is `await`ing this future. - Function _awaiter; + Function? _awaiter; } @patch class _StreamImpl { /// The closure implementing the async[*]-body that is `await`ing this future. - Function _awaiter; + Function? _awaiter; /// The closure implementing the async-generator body that is creating events /// for this stream. - Function _generator; + Function? _generator; } @pragma("vm:entry-point", "call") diff --git a/sdk/lib/_internal/vm/lib/bigint_patch.dart b/sdk/lib/_internal/vm/lib/bigint_patch.dart index 0712115c072..5cc0befd8ee 100644 --- a/sdk/lib/_internal/vm/lib/bigint_patch.dart +++ b/sdk/lib/_internal/vm/lib/bigint_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // part of dart.core; // Copyright 2009 The Go Authors. All rights reserved. @@ -52,11 +50,11 @@ class BigInt implements Comparable { static BigInt get two => _BigIntImpl.two; @patch - static BigInt parse(String source, {int radix}) => + static BigInt parse(String source, {int? radix}) => _BigIntImpl.parse(source, radix: radix); @patch - static BigInt tryParse(String source, {int radix}) => + static BigInt? tryParse(String source, {int? radix}) => _BigIntImpl._tryParse(source, radix: radix); @patch @@ -109,15 +107,14 @@ class _BigIntImpl implements BigInt { new bool.fromEnvironment('dart.vm.not.a.compile.time.constant'); // Result cache for last _divRem call. - // Result cache for last _divRem call. - static Uint32List _lastDividendDigits; - static int _lastDividendUsed; - static Uint32List _lastDivisorDigits; - static int _lastDivisorUsed; - static Uint32List _lastQuoRemDigits; - static int _lastQuoRemUsed; - static int _lastRemUsed; - static int _lastRem_nsh; + static Uint32List? _lastDividendDigits; + static int? _lastDividendUsed; + static Uint32List? _lastDivisorDigits; + static int? _lastDivisorUsed; + static late Uint32List _lastQuoRemDigits; + static late int _lastQuoRemUsed; + static late int _lastRemUsed; + static late int _lastRem_nsh; /// Whether this bigint is negative. final bool _isNegative; @@ -168,7 +165,7 @@ class _BigIntImpl implements BigInt { * Throws a [FormatException] if the [source] is not a valid integer literal, * optionally prefixed by a sign. */ - static _BigIntImpl parse(String source, {int radix}) { + static _BigIntImpl parse(String source, {int? radix}) { var result = _tryParse(source, radix: radix); if (result == null) { throw new FormatException("Could not parse BigInt", source); @@ -187,7 +184,7 @@ class _BigIntImpl implements BigInt { // Read in the source 9 digits at a time. // The first part may have a few leading virtual '0's to make the remaining // parts all have exactly 9 digits. - int digitInPartCount = 9 - source.length.remainder(9); + int digitInPartCount = 9 - unsafeCast(source.length.remainder(9)); if (digitInPartCount == 9) digitInPartCount = 0; for (int i = 0; i < source.length; i++) { part = part * 10 + source.codeUnitAt(i) - _0; @@ -229,7 +226,7 @@ class _BigIntImpl implements BigInt { /// If [isNegative] is true, negates the result before returning it. /// /// The [source] (substring) must be a valid hex literal. - static _BigIntImpl _parseHex(String source, int startPos, bool isNegative) { + static _BigIntImpl? _parseHex(String source, int startPos, bool isNegative) { int hexCharsPerDigit = _digitBits ~/ 4; int sourceLength = source.length - startPos; int used = (sourceLength + hexCharsPerDigit - 1) ~/ hexCharsPerDigit; @@ -263,7 +260,7 @@ class _BigIntImpl implements BigInt { /// /// The [source] will be checked for invalid characters. If it is invalid, /// this function returns `null`. - static _BigIntImpl _parseRadix(String source, int radix, bool isNegative) { + static _BigIntImpl? _parseRadix(String source, int radix, bool isNegative) { var result = zero; var base = new _BigIntImpl._fromInt(radix); for (int i = 0; i < source.length; i++) { @@ -280,21 +277,21 @@ class _BigIntImpl implements BigInt { /// Returns the parsed big integer, or `null` if it failed. /// /// If the [radix] is `null` accepts decimal literals or `0x` hex literals. - static _BigIntImpl _tryParse(String source, {int radix}) { + static _BigIntImpl? _tryParse(String source, {int? radix}) { if (source == "") return null; - var match = _parseRE.firstMatch(source); + final match = _parseRE.firstMatch(source); int signIndex = 1; int hexIndex = 3; int decimalIndex = 4; int nonDecimalHexIndex = 5; if (match == null) return null; - bool isNegative = match[signIndex] == "-"; + final bool isNegative = match[signIndex] == "-"; - String decimalMatch = match[decimalIndex]; - String hexMatch = match[hexIndex]; - String nonDecimalMatch = match[nonDecimalHexIndex]; + final String? decimalMatch = match[decimalIndex]; + final String? hexMatch = match[hexIndex]; + final String? nonDecimalMatch = match[nonDecimalHexIndex]; if (radix == null) { if (decimalMatch != null) { @@ -314,12 +311,16 @@ class _BigIntImpl implements BigInt { if (radix == 10 && decimalMatch != null) { return _parseDecimal(decimalMatch, isNegative); } - if (radix == 16 && (decimalMatch != null || nonDecimalMatch != null)) { - return _parseHex(decimalMatch ?? nonDecimalMatch, 0, isNegative); + if (radix == 16) { + final match = decimalMatch ?? nonDecimalMatch; + if (match != null) { + return _parseHex(match, 0, isNegative); + } } - return _parseRadix( - decimalMatch ?? nonDecimalMatch ?? hexMatch, radix, isNegative); + // The RegExp guarantees that one of the 3 matches is non-null. + final nonNullMatch = (decimalMatch ?? nonDecimalMatch ?? hexMatch)!; + return _parseRadix(nonNullMatch, radix, isNegative); } static RegExp _parseRE = RegExp( @@ -366,10 +367,13 @@ class _BigIntImpl implements BigInt { if (value == 1) return one; if (value == 2) return two; - if (value.abs() < 0x100000000) + if (value.abs() < 0x100000000) { return new _BigIntImpl._fromInt(value.toInt()); - if (value is double) return new _BigIntImpl._fromDouble(value); - return new _BigIntImpl._fromInt(value); + } + if (value is double) { + return new _BigIntImpl._fromDouble(value); + } + return new _BigIntImpl._fromInt(value as int); } factory _BigIntImpl._fromInt(int value) { @@ -719,7 +723,7 @@ class _BigIntImpl implements BigInt { /// Returns 0 if abs(this) == abs(other); a positive number if /// abs(this) > abs(other); and a negative number if abs(this) < abs(other). int _absCompare(BigInt bigInt) { - _BigIntImpl other = bigInt; + final other = _ensureSystemBigInt(bigInt, 'bigInt'); return _compareDigits(_digits, _used, other._digits, other._used); } @@ -730,7 +734,7 @@ class _BigIntImpl implements BigInt { * equal, and a positive number if `this` is greater than `other`. */ int compareTo(BigInt bigInt) { - _BigIntImpl other = bigInt; + final other = _ensureSystemBigInt(bigInt, 'bigInt'); if (_isNegative == other._isNegative) { var result = _absCompare(other); // Use 0 - result to avoid negative zero in JavaScript. @@ -928,7 +932,7 @@ class _BigIntImpl implements BigInt { * the result is non-negative. */ _BigIntImpl operator &(BigInt bigInt) { - _BigIntImpl other = bigInt; + final other = _ensureSystemBigInt(bigInt, 'bigInt'); if (_isZero || other._isZero) return zero; if (_isNegative == other._isNegative) { if (_isNegative) { @@ -968,7 +972,7 @@ class _BigIntImpl implements BigInt { * otherwise the result us negative. */ _BigIntImpl operator |(BigInt bigInt) { - _BigIntImpl other = bigInt; + final other = _ensureSystemBigInt(bigInt, 'bigInt'); if (_isZero) return other; if (other._isZero) return this; if (_isNegative == other._isNegative) { @@ -1010,7 +1014,7 @@ class _BigIntImpl implements BigInt { * otherwise the result is negative. */ _BigIntImpl operator ^(BigInt bigInt) { - _BigIntImpl other = bigInt; + final other = _ensureSystemBigInt(bigInt, 'bigInt'); if (_isZero) return other; if (other._isZero) return this; if (_isNegative == other._isNegative) { @@ -1059,7 +1063,7 @@ class _BigIntImpl implements BigInt { /// Addition operator. _BigIntImpl operator +(BigInt bigInt) { - _BigIntImpl other = bigInt; + final other = _ensureSystemBigInt(bigInt, 'bigInt'); if (_isZero) return other; if (other._isZero) return this; var isNegative = _isNegative; @@ -1078,7 +1082,7 @@ class _BigIntImpl implements BigInt { /// Subtraction operator. _BigIntImpl operator -(BigInt bigInt) { - _BigIntImpl other = bigInt; + final other = _ensureSystemBigInt(bigInt, 'bigInt'); if (_isZero) return -other; if (other._isZero) return this; var isNegative = _isNegative; @@ -1207,7 +1211,7 @@ class _BigIntImpl implements BigInt { /// Multiplication operator. _BigIntImpl operator *(BigInt bigInt) { - _BigIntImpl other = bigInt; + final other = _ensureSystemBigInt(bigInt, 'bigInt'); var used = _used; var otherUsed = other._used; if (used == 0 || otherUsed == 0) { @@ -1307,7 +1311,7 @@ class _BigIntImpl implements BigInt { /// Returns `trunc(this / other)`, with `other != 0`. _BigIntImpl _div(BigInt bigInt) { - _BigIntImpl other = bigInt; + final other = _ensureSystemBigInt(bigInt, 'bigInt'); assert(other._used > 0); if (_used < other._used) { return zero; @@ -1327,7 +1331,7 @@ class _BigIntImpl implements BigInt { /// Returns `this - other * trunc(this / other)`, with `other != 0`. _BigIntImpl _rem(BigInt bigInt) { - _BigIntImpl other = bigInt; + final other = _ensureSystemBigInt(bigInt, 'bigInt'); assert(other._used > 0); if (_used < other._used) { return this; @@ -1670,7 +1674,7 @@ class _BigIntImpl implements BigInt { * ``` */ _BigIntImpl operator ~/(BigInt bigInt) { - _BigIntImpl other = bigInt; + final other = _ensureSystemBigInt(bigInt, 'bigInt'); if (other._used == 0) { throw const IntegerDivisionByZeroException(); } @@ -1685,7 +1689,7 @@ class _BigIntImpl implements BigInt { * As a consequence the remainder `r` has the same sign as the divider `this`. */ _BigIntImpl remainder(BigInt bigInt) { - _BigIntImpl other = bigInt; + final other = _ensureSystemBigInt(bigInt, 'bigInt'); if (other._used == 0) { throw const IntegerDivisionByZeroException(); } @@ -1719,7 +1723,7 @@ class _BigIntImpl implements BigInt { * See [remainder] for the remainder of the truncating division. */ _BigIntImpl operator %(BigInt bigInt) { - _BigIntImpl other = bigInt; + final other = _ensureSystemBigInt(bigInt, 'bigInt'); if (other._used == 0) { throw const IntegerDivisionByZeroException(); } @@ -1783,8 +1787,8 @@ class _BigIntImpl implements BigInt { * positive. */ _BigIntImpl modPow(BigInt bigExponent, BigInt bigModulus) { - _BigIntImpl exponent = bigExponent; - _BigIntImpl modulus = bigModulus; + final exponent = _ensureSystemBigInt(bigExponent, 'bigExponent'); + final modulus = _ensureSystemBigInt(bigModulus, 'bigModulus'); if (exponent._isNegative) { throw new ArgumentError("exponent must be positive: $exponent"); } @@ -1828,7 +1832,7 @@ class _BigIntImpl implements BigInt { } return z._revert(resultDigits, resultUsed); } - var k; + late int k; if (exponentBitlen < 18) k = 1; else if (exponentBitlen < 48) @@ -1841,10 +1845,10 @@ class _BigIntImpl implements BigInt { k = 6; _BigIntReduction z = new _BigIntMontgomeryReduction(modulus); var n = 3; - final k1 = k - 1; + final int k1 = k - 1; final km = (1 << k) - 1; - List gDigits = new List(km + 1); - List gUsed = new List(km + 1); + List gDigits = new List.filled(km + 1, null); + List gUsed = new List.filled(km + 1, null); gDigits[1] = _newDigits(z._normModulusUsed); gUsed[1] = z._convert(this, gDigits[1]); if (k > 1) { @@ -1865,7 +1869,7 @@ class _BigIntImpl implements BigInt { var result2Used; var exponentDigits = exponent._digits; var j = exponent._used - 1; - var i = exponentDigits[j].bitLength - 1; + int i = exponentDigits[j].bitLength - 1; while (j >= 0) { if (i >= k1) { w = (exponentDigits[j] >> (i - k1)) & km; @@ -1986,19 +1990,19 @@ class _BigIntImpl implements BigInt { // Variables a, b, c, and d require one more digit. final abcdUsed = maxUsed + 1; final abcdLen = abcdUsed + (abcdUsed & 1) + 2; // +2 to satisfy _absAdd. - var aDigits, bDigits, cDigits, dDigits; - bool aIsNegative, bIsNegative, cIsNegative, dIsNegative; + + bool aIsNegative = false; + bool cIsNegative = false; + late final Uint32List aDigits, cDigits; if (ac) { aDigits = _newDigits(abcdLen); - aIsNegative = false; aDigits[0] = 1; cDigits = _newDigits(abcdLen); - cIsNegative = false; } - bDigits = _newDigits(abcdLen); - bIsNegative = false; - dDigits = _newDigits(abcdLen); - dIsNegative = false; + final Uint32List bDigits = _newDigits(abcdLen); + final Uint32List dDigits = _newDigits(abcdLen); + bool bIsNegative = false; + bool dIsNegative = false; dDigits[0] = 1; while (true) { @@ -2192,7 +2196,7 @@ class _BigIntImpl implements BigInt { */ // Returns 1/this % modulus, with modulus > 0. _BigIntImpl modInverse(BigInt bigInt) { - _BigIntImpl modulus = bigInt; + final modulus = _ensureSystemBigInt(bigInt, 'bigInt'); if (modulus <= zero) { throw new ArgumentError("Modulus must be strictly positive: $modulus"); } @@ -2218,7 +2222,7 @@ class _BigIntImpl implements BigInt { * If both `this` and `other` is zero, the result is also zero. */ _BigIntImpl gcd(BigInt bigInt) { - _BigIntImpl other = bigInt; + final other = _ensureSystemBigInt(bigInt, 'bigInt'); if (_isZero) return other.abs(); if (other._isZero) return this.abs(); return _binaryGcd(this, other, false); @@ -2526,6 +2530,12 @@ class _BigIntImpl implements BigInt { } return new String.fromCharCodes(chars.reversed); } + + static _BigIntImpl _ensureSystemBigInt(BigInt bigInt, String parameterName) { + if (bigInt is _BigIntImpl) return bigInt; + throw ArgumentError.value( + bigInt, parameterName, "Must be a platform BigInt"); + } } // Interface for modular reduction. @@ -2544,10 +2554,10 @@ abstract class _BigIntReduction { // Montgomery reduction on _BigIntImpl. class _BigIntMontgomeryReduction implements _BigIntReduction { final _BigIntImpl _modulus; - int _normModulusUsed; // Even if processing 64-bit (digit pairs). - Uint32List _modulusDigits; - Uint32List _args; - int _digitsPerStep; // Number of digits processed in one step. 1 or 2. + final int _normModulusUsed; // Even if processing 64-bit (digit pairs). + final Uint32List _modulusDigits; + final Uint32List _args; + final int _digitsPerStep; // Number of digits processed in one step. 1 or 2. static const int _xDigit = 0; // Index of digit of x. static const int _xHighDigit = 1; // Index of high digit of x (64-bit only). static const int _rhoDigit = 2; // Index of digit of rho. @@ -2555,23 +2565,30 @@ class _BigIntMontgomeryReduction implements _BigIntReduction { static const int _muDigit = 4; // Index of mu. static const int _muHighDigit = 5; // Index of high 32-bits of mu (64-bit). - _BigIntMontgomeryReduction(this._modulus) { - _modulusDigits = _modulus._digits; - _args = _newDigits(6); + factory _BigIntMontgomeryReduction(_BigIntImpl modulus) { + final Uint32List modulusDigits = modulus._digits; + final Uint32List args = _newDigits(6); + // Determine if we can process digit pairs by calling an intrinsic. - _digitsPerStep = _mulMod(_args, _args, 0); - _args[_xDigit] = _modulusDigits[0]; - if (_digitsPerStep == 1) { - _normModulusUsed = _modulus._used; - _invDigit(_args); + final int digitsPerStep = _mulMod(args, args, 0); + args[_xDigit] = modulusDigits[0]; + + int normModulusUsed = modulus._used; + if (digitsPerStep == 1) { + _invDigit(args); } else { - assert(_digitsPerStep == 2); - _normModulusUsed = _modulus._used + (_modulus._used & 1); - _args[_xHighDigit] = _modulusDigits[1]; - _invDigitPair(_args); + assert(digitsPerStep == 2); + normModulusUsed += modulus._used & 1; + args[_xHighDigit] = modulusDigits[1]; + _invDigitPair(args); } + return _BigIntMontgomeryReduction._( + modulus, normModulusUsed, modulusDigits, args, digitsPerStep); } + _BigIntMontgomeryReduction._(this._modulus, this._normModulusUsed, + this._modulusDigits, this._args, this._digitsPerStep); + // Calculates -1/x % _digitBase, x is 32-bit digit. // xy == 1 (mod m) // xy = 1+km @@ -2728,41 +2745,54 @@ class _BigIntClassicReduction implements _BigIntReduction { // quotient digit(s). Uint32List _tmpDigits; // Temporary digits used during reduction. - _BigIntClassicReduction(this._modulus) { + factory _BigIntClassicReduction(_BigIntImpl modulus) { // Preprocess arguments to _remDigits. - var nsh = - _BigIntImpl._digitBits - _modulus._digits[_modulus._used - 1].bitLength; + int nsh = + _BigIntImpl._digitBits - modulus._digits[modulus._used - 1].bitLength; // For 64-bit processing, make sure _negNormModulusDigits has an even number // of digits. - if (_modulus._used.isOdd) { + if (modulus._used.isOdd) { nsh += _BigIntImpl._digitBits; } - _modulusNsh = nsh; - _normModulus = _modulus << nsh; - _normModulusUsed = _normModulus._used; - _normModulusDigits = _normModulus._digits; - assert(_normModulusUsed.isEven); - _args = _newDigits(4); - _args[_BigIntImpl._divisorLowTopDigit] = - _normModulusDigits[_normModulusUsed - 2]; - _args[_BigIntImpl._divisorTopDigit] = - _normModulusDigits[_normModulusUsed - 1]; - // Negate _normModulus so we can use _mulAdd instead of + final _BigIntImpl normModulus = modulus << nsh; + final int normModulusUsed = normModulus._used; + final Uint32List normModulusDigits = normModulus._digits; + assert(normModulusUsed.isEven); + + final Uint32List args = _newDigits(4); + args[_BigIntImpl._divisorLowTopDigit] = + normModulusDigits[normModulusUsed - 2]; + args[_BigIntImpl._divisorTopDigit] = normModulusDigits[normModulusUsed - 1]; + // Negate normModulus so we can use _mulAdd instead of // unimplemented _mulSub. - var negNormModulus = - _BigIntImpl.one._dlShift(_normModulusUsed) - _normModulus; - if (negNormModulus._used < _normModulusUsed) { - _negNormModulusDigits = _BigIntImpl._cloneDigits( - negNormModulus._digits, 0, _normModulusUsed, _normModulusUsed); + final _BigIntImpl negNormModulus = + _BigIntImpl.one._dlShift(normModulusUsed) - normModulus; + late Uint32List negNormModulusDigits; + if (negNormModulus._used < normModulusUsed) { + negNormModulusDigits = _BigIntImpl._cloneDigits( + negNormModulus._digits, 0, normModulusUsed, normModulusUsed); } else { - _negNormModulusDigits = negNormModulus._digits; + negNormModulusDigits = negNormModulus._digits; } - // _negNormModulusDigits is read-only and has _normModulusUsed digits (possibly + // negNormModulusDigits is read-only and has normModulusUsed digits (possibly // including several leading zeros) plus a leading zero for 64-bit // processing. - _tmpDigits = _newDigits(2 * _normModulusUsed); + final Uint32List tmpDigits = _newDigits(2 * normModulusUsed); + + return _BigIntClassicReduction._(modulus, normModulusUsed, normModulus, + normModulusDigits, negNormModulusDigits, nsh, args, tmpDigits); } + _BigIntClassicReduction._( + this._modulus, + this._normModulusUsed, + this._normModulus, + this._normModulusDigits, + this._negNormModulusDigits, + this._modulusNsh, + this._args, + this._tmpDigits); + int _convert(_BigIntImpl x, Uint32List resultDigits) { var digits; var used; diff --git a/sdk/lib/_internal/vm/lib/bool_patch.dart b/sdk/lib/_internal/vm/lib/bool_patch.dart index 56098da69e3..d627d467125 100644 --- a/sdk/lib/_internal/vm/lib/bool_patch.dart +++ b/sdk/lib/_internal/vm/lib/bool_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "core_patch.dart"; @patch diff --git a/sdk/lib/_internal/vm/lib/class_id.dart b/sdk/lib/_internal/vm/lib/class_id.dart index c1e86218994..ff9d0b6d329 100644 --- a/sdk/lib/_internal/vm/lib/class_id.dart +++ b/sdk/lib/_internal/vm/lib/class_id.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "internal_patch.dart"; @pragma("vm:entry-point") diff --git a/sdk/lib/_internal/vm/lib/class_id_fasta.dart b/sdk/lib/_internal/vm/lib/class_id_fasta.dart index 8b7064e2dd6..c81bd60f69a 100644 --- a/sdk/lib/_internal/vm/lib/class_id_fasta.dart +++ b/sdk/lib/_internal/vm/lib/class_id_fasta.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "internal_patch.dart"; @pragma("vm:entry-point") diff --git a/sdk/lib/_internal/vm/lib/collection_patch.dart b/sdk/lib/_internal/vm/lib/collection_patch.dart index 0960adcc31c..1307fb71b83 100644 --- a/sdk/lib/_internal/vm/lib/collection_patch.dart +++ b/sdk/lib/_internal/vm/lib/collection_patch.dart @@ -2,8 +2,6 @@ // 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.6 - /// Note: the VM concatenates all patch files into a single patch file. This /// file is the first patch in "dart:collection" which contains all the imports /// used by patches of that library. We plan to change this when we have a @@ -15,6 +13,10 @@ import "dart:_internal" show patch, IterableElementError; import "dart:typed_data" show Uint32List; +class _TypeTest { + bool test(v) => v is T; +} + /// These are the additional parts of this patch library: // part "compact_hash.dart"; @@ -22,9 +24,9 @@ import "dart:typed_data" show Uint32List; class HashMap { @patch factory HashMap( - {bool equals(K key1, K key2), - int hashCode(K key), - bool isValidKey(potentialKey)}) { + {bool equals(K key1, K key2)?, + int hashCode(K key)?, + bool isValidKey(potentialKey)?}) { if (isValidKey == null) { if (hashCode == null) { if (equals == null) { @@ -57,8 +59,7 @@ class _HashMap extends MapBase implements HashMap { static const int _INITIAL_CAPACITY = 8; int _elementCount = 0; - List<_HashMapEntry> _buckets = - new List<_HashMapEntry>(_INITIAL_CAPACITY); + var _buckets = List<_HashMapEntry?>.filled(_INITIAL_CAPACITY, null); int _modificationCount = 0; int get length => _elementCount; @@ -68,7 +69,7 @@ class _HashMap extends MapBase implements HashMap { Iterable get keys => new _HashMapKeyIterable(this); Iterable get values => new _HashMapValueIterable(this); - bool containsKey(Object key) { + bool containsKey(Object? key) { final hashCode = key.hashCode; final buckets = _buckets; final index = hashCode & (buckets.length - 1); @@ -80,7 +81,7 @@ class _HashMap extends MapBase implements HashMap { return false; } - bool containsValue(Object value) { + bool containsValue(Object? value) { final buckets = _buckets; final length = buckets.length; for (int i = 0; i < length; i++) { @@ -93,7 +94,7 @@ class _HashMap extends MapBase implements HashMap { return false; } - V operator [](Object key) { + V? operator [](Object? key) { final hashCode = key.hashCode; final buckets = _buckets; final index = hashCode & (buckets.length - 1); @@ -167,12 +168,12 @@ class _HashMap extends MapBase implements HashMap { } } - V remove(Object key) { + V? remove(Object? key) { final hashCode = key.hashCode; final buckets = _buckets; final index = hashCode & (buckets.length - 1); var entry = buckets[index]; - _HashMapEntry previous = null; + _HashMapEntry? previous = null; while (entry != null) { final next = entry.next; if (hashCode == entry.hashCode && entry.key == key) { @@ -189,7 +190,7 @@ class _HashMap extends MapBase implements HashMap { } void clear() { - _buckets = new List(_INITIAL_CAPACITY); + _buckets = new List.filled(_INITIAL_CAPACITY, null); if (_elementCount > 0) { _elementCount = 0; _modificationCount = (_modificationCount + 1) & _MODIFICATION_COUNT_MASK; @@ -197,7 +198,7 @@ class _HashMap extends MapBase implements HashMap { } void _removeEntry(_HashMapEntry entry, - _HashMapEntry previousInBucket, int bucketIndex) { + _HashMapEntry? previousInBucket, int bucketIndex) { if (previousInBucket == null) { _buckets[bucketIndex] = entry.next; } else { @@ -205,7 +206,7 @@ class _HashMap extends MapBase implements HashMap { } } - void _addEntry(List<_HashMapEntry> buckets, int index, int length, + void _addEntry(List<_HashMapEntry?> buckets, int index, int length, K key, V value, int hashCode) { final entry = new _HashMapEntry(key, value, hashCode, buckets[index]); buckets[index] = entry; @@ -221,7 +222,7 @@ class _HashMap extends MapBase implements HashMap { final oldBuckets = _buckets; final oldLength = oldBuckets.length; final newLength = oldLength << 1; - final newBuckets = new List<_HashMapEntry>(newLength); + final newBuckets = new List<_HashMapEntry?>.filled(newLength, null); for (int i = 0; i < oldLength; i++) { var entry = oldBuckets[i]; while (entry != null) { @@ -243,30 +244,32 @@ class _CustomHashMap extends _HashMap { final _Equality _equals; final _Hasher _hashCode; final _Predicate _validKey; - _CustomHashMap(this._equals, this._hashCode, validKey) + _CustomHashMap(this._equals, this._hashCode, _Predicate? validKey) : _validKey = (validKey != null) ? validKey : new _TypeTest().test; - bool containsKey(Object key) { + bool containsKey(Object? key) { if (!_validKey(key)) return false; - final hashCode = _hashCode(key); + K lkey = key as K; + final hashCode = _hashCode(lkey); final buckets = _buckets; final index = hashCode & (buckets.length - 1); var entry = buckets[index]; while (entry != null) { - if (hashCode == entry.hashCode && _equals(entry.key, key)) return true; + if (hashCode == entry.hashCode && _equals(entry.key, lkey)) return true; entry = entry.next; } return false; } - V operator [](Object key) { + V? operator [](Object? key) { if (!_validKey(key)) return null; - final hashCode = _hashCode(key); + K lkey = key as K; + final hashCode = _hashCode(lkey); final buckets = _buckets; final index = hashCode & (buckets.length - 1); var entry = buckets[index]; while (entry != null) { - if (hashCode == entry.hashCode && _equals(entry.key, key)) { + if (hashCode == entry.hashCode && _equals(entry.key, lkey)) { return entry.value; } entry = entry.next; @@ -312,16 +315,17 @@ class _CustomHashMap extends _HashMap { return value; } - V remove(Object key) { + V? remove(Object? key) { if (!_validKey(key)) return null; - final hashCode = _hashCode(key); + K lkey = key as K; + final hashCode = _hashCode(lkey); final buckets = _buckets; final index = hashCode & (buckets.length - 1); var entry = buckets[index]; - _HashMapEntry previous = null; + _HashMapEntry? previous = null; while (entry != null) { final next = entry.next; - if (hashCode == entry.hashCode && _equals(entry.key, key)) { + if (hashCode == entry.hashCode && _equals(entry.key, lkey)) { _removeEntry(entry, previous, index); _elementCount--; _modificationCount = @@ -338,7 +342,7 @@ class _CustomHashMap extends _HashMap { } class _IdentityHashMap extends _HashMap { - bool containsKey(Object key) { + bool containsKey(Object? key) { final hashCode = identityHashCode(key); final buckets = _buckets; final index = hashCode & (buckets.length - 1); @@ -350,7 +354,7 @@ class _IdentityHashMap extends _HashMap { return false; } - V operator [](Object key) { + V? operator [](Object? key) { final hashCode = identityHashCode(key); final buckets = _buckets; final index = hashCode & (buckets.length - 1); @@ -402,12 +406,12 @@ class _IdentityHashMap extends _HashMap { return value; } - V remove(Object key) { + V? remove(Object? key) { final hashCode = identityHashCode(key); final buckets = _buckets; final index = hashCode & (buckets.length - 1); var entry = buckets[index]; - _HashMapEntry previous = null; + _HashMapEntry? previous = null; while (entry != null) { final next = entry.next; if (hashCode == entry.hashCode && identical(entry.key, key)) { @@ -430,7 +434,7 @@ class _HashMapEntry { final K key; V value; final int hashCode; - _HashMapEntry next; + _HashMapEntry? next; _HashMapEntry(this.key, this.value, this.hashCode, this.next); } @@ -446,7 +450,7 @@ abstract class _HashMapIterable class _HashMapKeyIterable extends _HashMapIterable { _HashMapKeyIterable(_HashMap map) : super(map); Iterator get iterator => new _HashMapKeyIterator(_map); - bool contains(Object key) => _map.containsKey(key); + bool contains(Object? key) => _map.containsKey(key); void forEach(void action(K key)) { _map.forEach((K key, _) { action(key); @@ -459,7 +463,7 @@ class _HashMapKeyIterable extends _HashMapIterable { class _HashMapValueIterable extends _HashMapIterable { _HashMapValueIterable(_HashMap map) : super(map); Iterator get iterator => new _HashMapValueIterator(_map); - bool contains(Object value) => _map.containsValue(value); + bool contains(Object? value) => _map.containsValue(value); void forEach(void action(V value)) { _map.forEach((_, V value) { action(value); @@ -472,7 +476,7 @@ abstract class _HashMapIterator implements Iterator { final int _stamp; int _index = 0; - _HashMapEntry _entry; + _HashMapEntry? _entry; _HashMapIterator(this._map) : _stamp = _map._modificationCount; @@ -506,21 +510,21 @@ abstract class _HashMapIterator implements Iterator { class _HashMapKeyIterator extends _HashMapIterator { _HashMapKeyIterator(_HashMap map) : super(map); - K get current => _entry?.key; + K get current => _entry!.key; } class _HashMapValueIterator extends _HashMapIterator { _HashMapValueIterator(_HashMap map) : super(map); - V get current => _entry?.value; + V get current => _entry!.value; } @patch class HashSet { @patch factory HashSet( - {bool equals(E e1, E e2), - int hashCode(E e), - bool isValidKey(potentialKey)}) { + {bool equals(E e1, E e2)?, + int hashCode(E e)?, + bool isValidKey(potentialKey)?}) { if (isValidKey == null) { if (hashCode == null) { if (equals == null) { @@ -548,13 +552,12 @@ class HashSet { class _HashSet extends _SetBase implements HashSet { static const int _INITIAL_CAPACITY = 8; - List<_HashSetEntry> _buckets = - new List<_HashSetEntry>(_INITIAL_CAPACITY); + var _buckets = List<_HashSetEntry?>.filled(_INITIAL_CAPACITY, null); int _elementCount = 0; int _modificationCount = 0; - bool _equals(e1, e2) => e1 == e2; - int _hashCode(e) => e.hashCode; + bool _equals(Object? e1, Object? e2) => e1 == e2; + int _hashCode(Object? e) => e.hashCode; static Set _newEmpty() => new _HashSet(); @@ -568,9 +571,9 @@ class _HashSet extends _SetBase implements HashSet { bool get isNotEmpty => _elementCount != 0; - bool contains(Object object) { + bool contains(Object? object) { int index = _hashCode(object) & (_buckets.length - 1); - _HashSetEntry entry = _buckets[index]; + var entry = _buckets[index]; while (entry != null) { if (_equals(entry.key, object)) return true; entry = entry.next; @@ -578,9 +581,9 @@ class _HashSet extends _SetBase implements HashSet { return false; } - E lookup(Object object) { + E? lookup(Object? object) { int index = _hashCode(object) & (_buckets.length - 1); - _HashSetEntry entry = _buckets[index]; + var entry = _buckets[index]; while (entry != null) { var key = entry.key; if (_equals(key, object)) return key; @@ -608,7 +611,7 @@ class _HashSet extends _SetBase implements HashSet { entry = nextEntry; nextEntry = nextEntry.next; } - return entry.key; + return entry!.key; } } throw IterableElementError.noElement(); @@ -619,7 +622,7 @@ class _HashSet extends _SetBase implements HashSet { bool add(E element) { final hashCode = _hashCode(element); final index = hashCode & (_buckets.length - 1); - _HashSetEntry entry = _buckets[index]; + var entry = _buckets[index]; while (entry != null) { if (_equals(entry.key, element)) return false; entry = entry.next; @@ -634,13 +637,13 @@ class _HashSet extends _SetBase implements HashSet { } } - bool _remove(Object object, int hashCode) { + bool _remove(Object? object, int hashCode) { final index = hashCode & (_buckets.length - 1); - _HashSetEntry entry = _buckets[index]; - _HashSetEntry previous = null; + var entry = _buckets[index]; + _HashSetEntry? previous = null; while (entry != null) { if (_equals(entry.key, object)) { - _HashSetEntry next = entry.remove(); + final next = entry.remove(); if (previous == null) { _buckets[index] = next; } else { @@ -657,10 +660,10 @@ class _HashSet extends _SetBase implements HashSet { return false; } - bool remove(Object object) => _remove(object, _hashCode(object)); + bool remove(Object? object) => _remove(object, _hashCode(object)); - void removeAll(Iterable objectsToRemove) { - for (Object object in objectsToRemove) { + void removeAll(Iterable objectsToRemove) { + for (Object? object in objectsToRemove) { _remove(object, _hashCode(object)); } } @@ -668,8 +671,8 @@ class _HashSet extends _SetBase implements HashSet { void _filterWhere(bool test(E element), bool removeMatching) { int length = _buckets.length; for (int index = 0; index < length; index++) { - _HashSetEntry entry = _buckets[index]; - _HashSetEntry previous = null; + var entry = _buckets[index]; + _HashSetEntry? previous = null; while (entry != null) { int modificationCount = _modificationCount; bool testResult = test(entry.key); @@ -677,7 +680,7 @@ class _HashSet extends _SetBase implements HashSet { throw new ConcurrentModificationError(this); } if (testResult == removeMatching) { - _HashSetEntry next = entry.remove(); + final next = entry.remove(); if (previous == null) { _buckets[index] = next; } else { @@ -704,7 +707,7 @@ class _HashSet extends _SetBase implements HashSet { } void clear() { - _buckets = new List(_INITIAL_CAPACITY); + _buckets = List<_HashSetEntry?>.filled(_INITIAL_CAPACITY, null); if (_elementCount > 0) { _elementCount = 0; _modificationCount = (_modificationCount + 1) & _MODIFICATION_COUNT_MASK; @@ -723,14 +726,14 @@ class _HashSet extends _SetBase implements HashSet { } void _resize() { - int oldLength = _buckets.length; - int newLength = oldLength << 1; - List oldBuckets = _buckets; - List newBuckets = new List<_HashSetEntry>(newLength); + final oldLength = _buckets.length; + final newLength = oldLength << 1; + final oldBuckets = _buckets; + final newBuckets = List<_HashSetEntry?>.filled(newLength, null); for (int i = 0; i < oldLength; i++) { - _HashSetEntry entry = oldBuckets[i]; + var entry = oldBuckets[i]; while (entry != null) { - _HashSetEntry next = entry.next; + final next = entry.next; int newIndex = entry.hashCode & (newLength - 1); entry.next = newBuckets[newIndex]; newBuckets[newIndex] = entry; @@ -745,8 +748,8 @@ class _HashSet extends _SetBase implements HashSet { } class _IdentityHashSet extends _HashSet { - int _hashCode(e) => identityHashCode(e); - bool _equals(e1, e2) => identical(e1, e2); + int _hashCode(Object? e) => identityHashCode(e); + bool _equals(Object? e1, Object? e2) => identical(e1, e2); HashSet _newSet() => new _IdentityHashSet(); HashSet _newSimilarSet() => new _IdentityHashSet(); @@ -756,41 +759,41 @@ class _CustomHashSet extends _HashSet { final _Equality _equality; final _Hasher _hasher; final _Predicate _validKey; - _CustomHashSet(this._equality, this._hasher, bool validKey(Object o)) + _CustomHashSet(this._equality, this._hasher, _Predicate? validKey) : _validKey = (validKey != null) ? validKey : new _TypeTest().test; - bool remove(Object element) { + bool remove(Object? element) { if (!_validKey(element)) return false; return super.remove(element); } - bool contains(Object element) { + bool contains(Object? element) { if (!_validKey(element)) return false; return super.contains(element); } - E lookup(Object element) { + E? lookup(Object? element) { if (!_validKey(element)) return null; return super.lookup(element); } - bool containsAll(Iterable elements) { - for (Object element in elements) { + bool containsAll(Iterable elements) { + for (Object? element in elements) { if (!_validKey(element) || !this.contains(element)) return false; } return true; } - void removeAll(Iterable elements) { - for (Object element in elements) { + void removeAll(Iterable elements) { + for (Object? element in elements) { if (_validKey(element)) { - super._remove(element, _hasher(element)); + super._remove(element, _hashCode(element)); } } } - bool _equals(e1, e2) => _equality(e1, e2); - int _hashCode(e) => _hasher(e); + bool _equals(Object? e1, Object? e2) => _equality(e1 as E, e2 as E); + int _hashCode(Object? e) => _hasher(e as E); HashSet _newSet() => new _CustomHashSet(_equality, _hasher, _validKey); HashSet _newSimilarSet() => new _HashSet(); @@ -799,10 +802,10 @@ class _CustomHashSet extends _HashSet { class _HashSetEntry { final E key; final int hashCode; - _HashSetEntry next; + _HashSetEntry? next; _HashSetEntry(this.key, this.hashCode, this.next); - _HashSetEntry remove() { + _HashSetEntry? remove() { final result = next; next = null; return result; @@ -813,8 +816,8 @@ class _HashSetIterator implements Iterator { final _HashSet _set; final int _modificationCount; int _index = 0; - _HashSetEntry _next; - E _current; + _HashSetEntry? _next; + E? _current; _HashSetIterator(this._set) : _modificationCount = _set._modificationCount; @@ -822,18 +825,19 @@ class _HashSetIterator implements Iterator { if (_modificationCount != _set._modificationCount) { throw new ConcurrentModificationError(_set); } - if (_next != null) { - _current = _next.key; - _next = _next.next; + var localNext = _next; + if (localNext != null) { + _current = localNext.key; + _next = localNext.next; return true; } - List<_HashSetEntry> buckets = _set._buckets; + final buckets = _set._buckets; while (_index < buckets.length) { - _next = buckets[_index]; + localNext = buckets[_index]; _index = _index + 1; - if (_next != null) { - _current = _next.key; - _next = _next.next; + if (localNext != null) { + _current = localNext.key; + _next = localNext.next; return true; } } @@ -841,7 +845,10 @@ class _HashSetIterator implements Iterator { return false; } - E get current => _current; + E get current { + final cur = _current; + return (cur != null) ? cur : cur as E; + } } /** @@ -855,9 +862,9 @@ class _HashSetIterator implements Iterator { class LinkedHashMap { @patch factory LinkedHashMap( - {bool equals(K key1, K key2), - int hashCode(K key), - bool isValidKey(potentialKey)}) { + {bool equals(K key1, K key2)?, + int hashCode(K key)?, + bool isValidKey(potentialKey)?}) { if (isValidKey == null) { if (hashCode == null) { if (equals == null) { @@ -886,9 +893,9 @@ class LinkedHashMap { class LinkedHashSet { @patch factory LinkedHashSet( - {bool equals(E e1, E e2), - int hashCode(E e), - bool isValidKey(potentialKey)}) { + {bool equals(E e1, E e2)?, + int hashCode(E e)?, + bool isValidKey(potentialKey)?}) { if (isValidKey == null) { if (hashCode == null) { if (equals == null) { @@ -912,31 +919,3 @@ class LinkedHashSet { @patch factory LinkedHashSet.identity() => new _CompactLinkedIdentityHashSet(); } - -@patch -abstract class _SplayTree> { - // We override _splayMin and _splayMax to optimize type-checks. - @patch - Node _splayMin(Node node) { - Node current = node; - while (current.left != null) { - Node left = internal.unsafeCast(current.left); - current.left = left.right; - left.right = current; - current = left; - } - return current; - } - - @patch - Node _splayMax(Node node) { - Node current = node; - while (current.right != null) { - Node right = internal.unsafeCast(current.right); - current.right = right.left; - right.left = current; - current = right; - } - return current; - } -} diff --git a/sdk/lib/_internal/vm/lib/compact_hash.dart b/sdk/lib/_internal/vm/lib/compact_hash.dart index da431134b0a..67ba9b2f202 100644 --- a/sdk/lib/_internal/vm/lib/compact_hash.dart +++ b/sdk/lib/_internal/vm/lib/compact_hash.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "collection_patch.dart"; // Hash table with open addressing that separates the index from keys/values. @@ -43,7 +41,7 @@ abstract class _HashFieldBase { // Note: All fields are initialized in a single constructor so that the VM // recognizes they cannot hold null values. This makes a big (20%) performance // difference on some operations. - _HashFieldBase(int dataSize) : this._data = new List(dataSize); + _HashFieldBase(int dataSize) : this._data = new List.filled(dataSize, null); } // Base class for VM-internal classes; keep in sync with _HashFieldBase. @@ -122,7 +120,7 @@ abstract class _HashBase implements _HashVMBase { static int _nextProbe(int i, int sizeMask) => (i + 1) & sizeMask; // A self-loop is used to mark a deleted key or value. - static bool _isDeleted(List data, Object keyOrValue) => + static bool _isDeleted(List data, Object? keyOrValue) => identical(keyOrValue, data); static void _setDeletedAt(List data, int d) { data[d] = data; @@ -159,7 +157,7 @@ class _InternalLinkedHashMap extends _HashVMBase _InternalLinkedHashMap() { _index = new Uint32List(_HashBase._INITIAL_INDEX_SIZE); _hashMask = _HashBase._indexSizeToHashMask(_HashBase._INITIAL_INDEX_SIZE); - _data = new List(_HashBase._INITIAL_INDEX_SIZE); + _data = new List.filled(_HashBase._INITIAL_INDEX_SIZE, null); _usedData = 0; _deletedKeys = 0; } @@ -193,12 +191,12 @@ abstract class _LinkedHashMapMixin implements _HashBase { } // Allocate new _index and _data, and optionally copy existing contents. - void _init(int size, int hashMask, List oldData, int oldUsed) { + void _init(int size, int hashMask, List? oldData, int oldUsed) { assert(size & (size - 1) == 0); assert(_HashBase._UNUSED_PAIR == 0); _index = new Uint32List(size); _hashMask = hashMask; - _data = new List(size); + _data = new List.filled(size, null); _usedData = 0; _deletedKeys = 0; if (oldData != null) { @@ -300,7 +298,7 @@ abstract class _LinkedHashMapMixin implements _HashBase { return value; } - V remove(Object key) { + V? remove(Object? key) { final int size = _index.length; final int sizeMask = size - 1; final int maxEntries = size >> 1; @@ -330,7 +328,7 @@ abstract class _LinkedHashMapMixin implements _HashBase { } // If key is absent, return _data (which is never a value). - Object _getValueOrData(Object key) { + Object? _getValueOrData(Object? key) { final int size = _index.length; final int sizeMask = size - 1; final int maxEntries = size >> 1; @@ -354,14 +352,14 @@ abstract class _LinkedHashMapMixin implements _HashBase { return _data; } - bool containsKey(Object key) => !identical(_data, _getValueOrData(key)); + bool containsKey(Object? key) => !identical(_data, _getValueOrData(key)); - V operator [](Object key) { + V? operator [](Object? key) { var v = _getValueOrData(key); return identical(_data, v) ? null : internal.unsafeCast(v); } - bool containsValue(Object value) { + bool containsValue(Object? value) { for (var v in values) { // Spec. says this should always use "==", also for identity maps, etc. if (v == value) { @@ -407,9 +405,9 @@ class _CompactLinkedCustomHashMap extends _HashFieldBase int _hashCode(e) => _hasher(e); bool _equals(e1, e2) => _equality(e1, e2); - bool containsKey(Object o) => _validKey(o) ? super.containsKey(o) : false; - V operator [](Object o) => _validKey(o) ? super[o] : null; - V remove(Object o) => _validKey(o) ? super.remove(o) : null; + bool containsKey(Object? o) => _validKey(o) ? super.containsKey(o) : false; + V? operator [](Object? o) => _validKey(o) ? super[o] : null; + V? remove(Object? o) => _validKey(o) ? super.remove(o) : null; _CompactLinkedCustomHashMap(this._equality, this._hasher, validKey) : _validKey = (validKey != null) ? validKey : new _TypeTest().test, @@ -443,7 +441,7 @@ class _CompactIterator implements Iterator { int _offset; final int _step; final int _checkSum; - E current; + E? _current; _CompactIterator( _HashBase table, this._data, this._len, this._offset, this._step) @@ -458,13 +456,18 @@ class _CompactIterator implements Iterator { _offset += _step; } while (_offset < _len && _HashBase._isDeleted(_data, _data[_offset])); if (_offset < _len) { - current = internal.unsafeCast(_data[_offset]); + _current = internal.unsafeCast(_data[_offset]); return true; } else { - current = null; + _current = null; return false; } } + + E get current { + final cur = _current; + return (cur != null) ? cur : cur as E; + } } // Set implementation, analogous to _CompactLinkedHashMap. @@ -483,9 +486,9 @@ class _CompactLinkedHashSet extends _HashFieldBase E get first { for (int offset = 0; offset < _usedData; offset++) { - Object current = _data[offset]; + Object? current = _data[offset]; if (!_HashBase._isDeleted(_data, current)) { - return current; + return current as E; } } throw IterableElementError.noElement(); @@ -493,9 +496,9 @@ class _CompactLinkedHashSet extends _HashFieldBase E get last { for (int offset = _usedData - 1; offset >= 0; offset--) { - Object current = _data[offset]; + Object? current = _data[offset]; if (!_HashBase._isDeleted(_data, current)) { - return current; + return current as E; } } throw IterableElementError.noElement(); @@ -515,10 +518,10 @@ class _CompactLinkedHashSet extends _HashFieldBase } } - void _init(int size, int hashMask, List oldData, int oldUsed) { + void _init(int size, int hashMask, List? oldData, int oldUsed) { _index = new Uint32List(size); _hashMask = hashMask; - _data = new List(size >> 1); + _data = new List.filled(size >> 1, null); _usedData = 0; _deletedKeys = 0; if (oldData != null) { @@ -568,7 +571,7 @@ class _CompactLinkedHashSet extends _HashFieldBase } // If key is absent, return _data (which is never a value). - Object _getKeyOrData(Object key) { + Object? _getKeyOrData(Object? key) { final int size = _index.length; final int sizeMask = size - 1; final int maxEntries = size >> 1; @@ -589,14 +592,14 @@ class _CompactLinkedHashSet extends _HashFieldBase return _data; } - E lookup(Object key) { + E? lookup(Object? key) { var k = _getKeyOrData(key); - return identical(_data, k) ? null : k; + return identical(_data, k) ? null : internal.unsafeCast(k); } - bool contains(Object key) => !identical(_data, _getKeyOrData(key)); + bool contains(Object? key) => !identical(_data, _getKeyOrData(key)); - bool remove(Object key) { + bool remove(Object? key) { final int size = _index.length; final int sizeMask = size - 1; final int maxEntries = size >> 1; @@ -651,9 +654,9 @@ class _CompactLinkedCustomHashSet extends _CompactLinkedHashSet { int _hashCode(e) => _hasher(e); bool _equals(e1, e2) => _equality(e1, e2); - bool contains(Object o) => _validKey(o) ? super.contains(o) : false; - E lookup(Object o) => _validKey(o) ? super.lookup(o) : null; - bool remove(Object o) => _validKey(o) ? super.remove(o) : false; + bool contains(Object? o) => _validKey(o) ? super.contains(o) : false; + E? lookup(Object? o) => _validKey(o) ? super.lookup(o) : null; + bool remove(Object? o) => _validKey(o) ? super.remove(o) : false; _CompactLinkedCustomHashSet(this._equality, this._hasher, validKey) : _validKey = (validKey != null) ? validKey : new _TypeTest().test; diff --git a/sdk/lib/_internal/vm/lib/convert_patch.dart b/sdk/lib/_internal/vm/lib/convert_patch.dart index da1da2ca07a..6f823376fb8 100644 --- a/sdk/lib/_internal/vm/lib/convert_patch.dart +++ b/sdk/lib/_internal/vm/lib/convert_patch.dart @@ -2,8 +2,6 @@ // 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.6 - /// Note: the VM concatenates all patch files into a single patch file. This /// file is the first patch in "dart:convert" which contains all the imports /// used by patches of that library. We plan to change this when we have a @@ -28,7 +26,8 @@ import "dart:typed_data" show Uint8List, Uint16List; // JSON conversion. @patch -dynamic _parseJson(String source, reviver(key, value)) { +dynamic _parseJson( + String source, Object? Function(Object? key, Object? value)? reviver) { _BuildJsonListener listener; if (reviver == null) { listener = new _BuildJsonListener(); @@ -58,14 +57,14 @@ class Utf8Decoder { // Allow intercepting of UTF-8 decoding when built-in lists are passed. @patch - static String _convertIntercepted( - bool allowMalformed, List codeUnits, int start, int end) { + static String? _convertIntercepted( + bool allowMalformed, List codeUnits, int start, int? end) { return null; // This call was not intercepted. } } class _JsonUtf8Decoder extends Converter, Object> { - final Function(Object key, Object value) _reviver; + final Object? Function(Object? key, Object? value)? _reviver; final bool _allowMalformed; _JsonUtf8Decoder(this._reviver, this._allowMalformed); @@ -79,7 +78,7 @@ class _JsonUtf8Decoder extends Converter, Object> { return parser.result; } - ByteConversionSink startChunkedConversion(Sink sink) { + ByteConversionSink startChunkedConversion(Sink sink) { return new _JsonUtf8DecoderSink(_reviver, sink, _allowMalformed); } } @@ -126,11 +125,11 @@ class _BuildJsonListener extends _JsonListener { * started. If the container is a [Map], there is also a current [key] * which is also stored on the stack. */ - List stack = []; + final List stack = []; /** The current [Map] or [List] being built. */ dynamic currentContainer; /** The most recently read property key. */ - String key; + String key = ''; /** The most recently read value. */ dynamic value; @@ -144,7 +143,7 @@ class _BuildJsonListener extends _JsonListener { void popContainer() { value = currentContainer; currentContainer = stack.removeLast(); - if (currentContainer is Map) key = stack.removeLast(); + if (currentContainer is Map) key = stack.removeLast() as String; } void handleString(String value) { @@ -176,7 +175,8 @@ class _BuildJsonListener extends _JsonListener { void propertyValue() { Map map = currentContainer; map[key] = value; - key = value = null; + key = ''; + value = null; } void endObject() { @@ -205,7 +205,7 @@ class _BuildJsonListener extends _JsonListener { } class _ReviverJsonListener extends _BuildJsonListener { - final Function(Object key, Object value) reviver; + final Object? Function(Object? key, Object? value) reviver; _ReviverJsonListener(this.reviver); void arrayElement() { @@ -688,12 +688,12 @@ abstract class _ChunkedJsonParser { char = getChar(position); digit = char ^ CHAR_0; } else { - return fail(position); + fail(position); } } if (state == NUM_ZERO) { // JSON does not allow insignificant leading zeros (e.g., "09"). - if (digit <= 9) return fail(position); + if (digit <= 9) fail(position); state = NUM_DIGIT; } while (state == NUM_DIGIT) { @@ -713,7 +713,7 @@ abstract class _ChunkedJsonParser { digit = char ^ CHAR_0; } if (state == NUM_DOT) { - if (digit > 9) return fail(position); + if (digit > 9) fail(position); state = NUM_DOT_DIGIT; } while (state == NUM_DOT_DIGIT) { @@ -808,7 +808,7 @@ abstract class _ChunkedJsonParser { assert(keywordType == KWD_BOM); return position; } - return fail(position); + fail(position); } position++; count++; @@ -854,41 +854,41 @@ abstract class _ChunkedJsonParser { position++; break; case QUOTE: - if ((state & ALLOW_STRING_MASK) != 0) return fail(position); + if ((state & ALLOW_STRING_MASK) != 0) fail(position); state |= VALUE_READ_BITS; position = parseString(position + 1); break; case LBRACKET: - if ((state & ALLOW_VALUE_MASK) != 0) return fail(position); + if ((state & ALLOW_VALUE_MASK) != 0) fail(position); listener.beginArray(); saveState(state); state = STATE_ARRAY_EMPTY; position++; break; case LBRACE: - if ((state & ALLOW_VALUE_MASK) != 0) return fail(position); + if ((state & ALLOW_VALUE_MASK) != 0) fail(position); listener.beginObject(); saveState(state); state = STATE_OBJECT_EMPTY; position++; break; case CHAR_n: - if ((state & ALLOW_VALUE_MASK) != 0) return fail(position); + if ((state & ALLOW_VALUE_MASK) != 0) fail(position); state |= VALUE_READ_BITS; position = parseNull(position); break; case CHAR_f: - if ((state & ALLOW_VALUE_MASK) != 0) return fail(position); + if ((state & ALLOW_VALUE_MASK) != 0) fail(position); state |= VALUE_READ_BITS; position = parseFalse(position); break; case CHAR_t: - if ((state & ALLOW_VALUE_MASK) != 0) return fail(position); + if ((state & ALLOW_VALUE_MASK) != 0) fail(position); state |= VALUE_READ_BITS; position = parseTrue(position); break; case COLON: - if (state != STATE_OBJECT_KEY) return fail(position); + if (state != STATE_OBJECT_KEY) fail(position); listener.propertyName(); state = STATE_OBJECT_COLON; position++; @@ -903,7 +903,7 @@ abstract class _ChunkedJsonParser { state = STATE_ARRAY_COMMA; position++; } else { - return fail(position); + fail(position); } break; case RBRACKET: @@ -913,7 +913,7 @@ abstract class _ChunkedJsonParser { listener.arrayElement(); listener.endArray(); } else { - return fail(position); + fail(position); } state = restoreState() | VALUE_READ_BITS; position++; @@ -925,7 +925,7 @@ abstract class _ChunkedJsonParser { listener.propertyValue(); listener.endObject(); } else { - return fail(position); + fail(position); } state = restoreState() | VALUE_READ_BITS; position++; @@ -953,7 +953,7 @@ abstract class _ChunkedJsonParser { if (getChar(position + 1) != CHAR_r || getChar(position + 2) != CHAR_u || getChar(position + 3) != CHAR_e) { - return fail(position); + fail(position); } listener.handleBool(true); return position + 4; @@ -973,7 +973,7 @@ abstract class _ChunkedJsonParser { getChar(position + 2) != CHAR_l || getChar(position + 3) != CHAR_s || getChar(position + 4) != CHAR_e) { - return fail(position); + fail(position); } listener.handleBool(false); return position + 5; @@ -992,7 +992,7 @@ abstract class _ChunkedJsonParser { if (getChar(position + 1) != CHAR_u || getChar(position + 2) != CHAR_l || getChar(position + 3) != CHAR_l) { - return fail(position); + fail(position); } listener.handleNull(); return position + 4; @@ -1005,7 +1005,7 @@ abstract class _ChunkedJsonParser { int count = 1; while (++position < length) { int char = getChar(position); - if (char != chars.codeUnitAt(count)) return fail(start); + if (char != chars.codeUnitAt(count)) fail(start); count++; } this.partialState = PARTIAL_KEYWORD | type | (count << KWD_COUNT_SHIFT); @@ -1042,7 +1042,7 @@ abstract class _ChunkedJsonParser { return position; } if (char < SPACE) { - return fail(position - 1, "Control character in string"); + fail(position - 1, "Control character in string"); } } beginString(); @@ -1102,7 +1102,7 @@ abstract class _ChunkedJsonParser { int char = getChar(position++); if (char > BACKSLASH) continue; if (char < SPACE) { - return fail(position - 1); // Control character in string. + fail(position - 1); // Control character in string. } if (char == QUOTE) { int quotePosition = position - 1; @@ -1172,7 +1172,7 @@ abstract class _ChunkedJsonParser { } else { digit = (char | 0x20) - CHAR_a; if (digit < 0 || digit > 5) { - return fail(hexStart, "Invalid unicode escape"); + fail(hexStart, "Invalid unicode escape"); } value += digit + 10; } @@ -1180,8 +1180,8 @@ abstract class _ChunkedJsonParser { char = value; break; default: - if (char < SPACE) return fail(position, "Control character in string"); - return fail(position, "Unrecognized string escape"); + if (char < SPACE) fail(position, "Control character in string"); + fail(position, "Unrecognized string escape"); } addCharToString(char); if (position == length) return chunkString(STR_PLAIN); @@ -1396,7 +1396,7 @@ abstract class _ChunkedJsonParser { return position; } - fail(int position, [String message]) { + Never fail(int position, [String? message]) { if (message == null) { message = "Unexpected character"; if (position == chunkEnd) message = "Unexpected end of input"; @@ -1409,8 +1409,8 @@ abstract class _ChunkedJsonParser { * Chunked JSON parser that parses [String] chunks. */ class _JsonStringParser extends _ChunkedJsonParser { - String chunk; - int chunkEnd; + String chunk = ''; + int chunkEnd = 0; _JsonStringParser(_JsonListener listener) : super(listener); @@ -1455,7 +1455,7 @@ class _JsonStringParser extends _ChunkedJsonParser { @patch class JsonDecoder { @patch - StringConversionSink startChunkedConversion(Sink sink) { + StringConversionSink startChunkedConversion(Sink sink) { return new _JsonStringDecoderSink(this._reviver, sink); } } @@ -1468,13 +1468,14 @@ class JsonDecoder { */ class _JsonStringDecoderSink extends StringConversionSinkBase { _JsonStringParser _parser; - final Function(Object key, Object value) _reviver; - final Sink _sink; + final Object? Function(Object? key, Object? value)? _reviver; + final Sink _sink; _JsonStringDecoderSink(this._reviver, this._sink) : _parser = _createParser(_reviver); - static _JsonStringParser _createParser(reviver) { + static _JsonStringParser _createParser( + Object? Function(Object? key, Object? value)? reviver) { _BuildJsonListener listener; if (reviver == null) { listener = new _BuildJsonListener(); @@ -1503,7 +1504,6 @@ class _JsonStringDecoderSink extends StringConversionSinkBase { } ByteConversionSink asUtf8Sink(bool allowMalformed) { - _parser = null; return new _JsonUtf8DecoderSink(_reviver, _sink, allowMalformed); } } @@ -1512,9 +1512,11 @@ class _JsonStringDecoderSink extends StringConversionSinkBase { * Chunked JSON parser that parses UTF-8 chunks. */ class _JsonUtf8Parser extends _ChunkedJsonParser> { + static final Uint8List emptyChunk = Uint8List(0); + final _Utf8Decoder decoder; - List chunk; - int chunkEnd; + List chunk = emptyChunk; + int chunkEnd = 0; _JsonUtf8Parser(_JsonListener listener, bool allowMalformed) : decoder = new _Utf8Decoder(allowMalformed), @@ -1579,12 +1581,14 @@ double _parseDouble(String source, int start, int end) native "Double_parse"; */ class _JsonUtf8DecoderSink extends ByteConversionSinkBase { final _JsonUtf8Parser _parser; - final Sink _sink; + final Sink _sink; _JsonUtf8DecoderSink(reviver, this._sink, bool allowMalformed) : _parser = _createParser(reviver, allowMalformed); - static _JsonUtf8Parser _createParser(reviver, bool allowMalformed) { + static _JsonUtf8Parser _createParser( + Object? Function(Object? key, Object? value)? reviver, + bool allowMalformed) { _BuildJsonListener listener; if (reviver == null) { listener = new _BuildJsonListener(); @@ -1711,8 +1715,8 @@ class _Utf8Decoder { } @pragma("vm:prefer-inline") - static bool _isNativeUint8List(List codeUnits) { - final int cid = ClassID.getID(codeUnits); + static bool _isNativeUint8List(List array) { + final int cid = ClassID.getID(array); return cid == ClassID.cidUint8ArrayView || cid == ClassID.cidUint8Array || cid == ClassID.cidExternalUint8Array; @@ -1723,7 +1727,7 @@ class _Utf8Decoder { _Utf8Decoder(this.allowMalformed) : _state = initial; @patch - String convertSingle(List codeUnits, int start, int maybeEnd) { + String convertSingle(List codeUnits, int start, int? maybeEnd) { int end = RangeError.checkValidRange(start, maybeEnd, codeUnits.length); // Have bytes as Uint8List. @@ -1787,7 +1791,7 @@ class _Utf8Decoder { } @patch - String convertChunked(List codeUnits, int start, int maybeEnd) { + String convertChunked(List codeUnits, int start, int? maybeEnd) { int end = RangeError.checkValidRange(start, maybeEnd, codeUnits.length); // Have bytes as Uint8List. @@ -1931,7 +1935,7 @@ class _Utf8Decoder { String decode8(Uint8List bytes, int start, int end, int size) { assert(start < end); - final String result = allocateOneByteString(size); + String result = allocateOneByteString(size); int i = start; int j = 0; if (_state == X1) { @@ -1983,7 +1987,7 @@ class _Utf8Decoder { assert(start < end); final String typeTable = _Utf8Decoder.typeTable; final String transitionTable = _Utf8Decoder.transitionTable; - final String result = allocateTwoByteString(size); + String result = allocateTwoByteString(size); int i = start; int j = 0; int state = _state; diff --git a/sdk/lib/_internal/vm/lib/core_patch.dart b/sdk/lib/_internal/vm/lib/core_patch.dart index 0994881f42e..21337633c94 100644 --- a/sdk/lib/_internal/vm/lib/core_patch.dart +++ b/sdk/lib/_internal/vm/lib/core_patch.dart @@ -2,8 +2,6 @@ // 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.6 - /// Note: the VM concatenates all patch files into a single patch file. This /// file is the first patch in "dart:core" which contains all the imports /// used by patches of that library. We plan to change this when we have a @@ -122,20 +120,27 @@ class _SyncIterable extends IterableBase { } class _SyncIterator implements Iterator { - _SyncGeneratorCallback _moveNextFn; - Iterator _yieldEachIterator; + _SyncGeneratorCallback? _moveNextFn; + Iterator? _yieldEachIterator; - // Stack of suspended _moveNextFn, if any. - List<_SyncGeneratorCallback> _stack; + // Stack of suspended _moveNextFn. + List<_SyncGeneratorCallback>? _stack; // These two fields are set by generated code for the yield and yield* // statement. - T _current; - Iterable _yieldEachIterable; + T? _current; + Iterable? _yieldEachIterable; @override - T get current => - _yieldEachIterator != null ? _yieldEachIterator.current : _current; + T get current { + final iterator = _yieldEachIterator; + if (iterator != null) { + return iterator.current; + } else { + final cur = _current; + return (cur != null) ? cur : cur as T; + } + } _SyncIterator(this._moveNextFn); @@ -157,7 +162,7 @@ class _SyncIterator implements Iterator { } final stack = _stack; - if (!_moveNextFn(this)) { + if (!_moveNextFn!.call(this)) { _moveNextFn = null; _current = null; // If we have any suspended parent generators, continue next one up: @@ -177,7 +182,7 @@ class _SyncIterator implements Iterator { if (stack == null) { _stack = []; } - _stack.add(_moveNextFn); + _stack!.add(_moveNextFn!); final typedIterable = unsafeCast<_SyncIterable>(iterable); _moveNextFn = typedIterable._moveNextFnMaker(); } else { diff --git a/sdk/lib/_internal/vm/lib/date_patch.dart b/sdk/lib/_internal/vm/lib/date_patch.dart index 25d22df2343..ee3b5a3a78e 100644 --- a/sdk/lib/_internal/vm/lib/date_patch.dart +++ b/sdk/lib/_internal/vm/lib/date_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "core_patch.dart"; // VM implementation of DateTime. @@ -32,7 +30,7 @@ class DateTime { static const _MONTH_INDEX = 7; static const _YEAR_INDEX = 8; - List __parts; + List? __parts; @patch DateTime.fromMillisecondsSinceEpoch(int millisecondsSinceEpoch, @@ -51,8 +49,9 @@ class DateTime { int second, int millisecond, int microsecond, bool isUtc) : this.isUtc = isUtc, this._value = _brokenDownDateToValue(year, month, day, hour, minute, - second, millisecond, microsecond, isUtc) { - if (_value == null) throw new ArgumentError(); + second, millisecond, microsecond, isUtc) ?? + -1 { + if (_value == -1) throw new ArgumentError(); if (isUtc == null) throw new ArgumentError(); } @@ -101,7 +100,7 @@ class DateTime { const [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335] ]; - static List _computeUpperPart(int localMicros) { + static List _computeUpperPart(int localMicros) { const int DAYS_IN_4_YEARS = 4 * 365 + 1; const int DAYS_IN_100_YEARS = 25 * DAYS_IN_4_YEARS - 1; const int DAYS_IN_400_YEARS = 4 * DAYS_IN_100_YEARS + 1; @@ -120,18 +119,18 @@ class DateTime { int days = daysSince1970; days += DAYS_OFFSET; resultYear = 400 * (days ~/ DAYS_IN_400_YEARS) - YEARS_OFFSET; - days = days.remainder(DAYS_IN_400_YEARS); + days = unsafeCast(days.remainder(DAYS_IN_400_YEARS)); days--; int yd1 = days ~/ DAYS_IN_100_YEARS; - days = days.remainder(DAYS_IN_100_YEARS); + days = unsafeCast(days.remainder(DAYS_IN_100_YEARS)); resultYear += 100 * yd1; days++; int yd2 = days ~/ DAYS_IN_4_YEARS; - days = days.remainder(DAYS_IN_4_YEARS); + days = unsafeCast(days.remainder(DAYS_IN_4_YEARS)); resultYear += 4 * yd2; days--; int yd3 = days ~/ 365; - days = days.remainder(365); + days = unsafeCast(days.remainder(365)); resultYear += yd3; bool isLeap = (yd1 == 0 || yd2 != 0) && yd3 == 0; @@ -168,7 +167,7 @@ class DateTime { DateTime.daysPerWeek) + DateTime.monday; - List list = new List(_YEAR_INDEX + 1); + List list = new List.filled(_YEAR_INDEX + 1, 0); list[_MICROSECOND_INDEX] = resultMicrosecond; list[_MILLISECOND_INDEX] = resultMillisecond; list[_SECOND_INDEX] = resultSecond; @@ -182,8 +181,7 @@ class DateTime { } get _parts { - __parts ??= _computeUpperPart(_localDateInUtcMicros); - return __parts; + return __parts ??= _computeUpperPart(_localDateInUtcMicros); } @patch @@ -280,7 +278,7 @@ class DateTime { /// Converts the given broken down date to microseconds. @patch - static int _brokenDownDateToValue(int year, int month, int day, int hour, + static int? _brokenDownDateToValue(int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond, bool isUtc) { // Simplify calculations by working with zero-based month. --month; diff --git a/sdk/lib/_internal/vm/lib/deferred_load_patch.dart b/sdk/lib/_internal/vm/lib/deferred_load_patch.dart index 0ab5e984b3a..3f3cf12cea8 100644 --- a/sdk/lib/_internal/vm/lib/deferred_load_patch.dart +++ b/sdk/lib/_internal/vm/lib/deferred_load_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "async_patch.dart"; final Set _loadedLibraries = new Set(); @@ -14,7 +12,7 @@ class DeferredLibrary { Future load() { // Dummy implementation that should eventually be replaced by real // implementation. - Future future = new Future.value(null); + Future future = new Future.value(null); _loadedLibraries.add(libraryName); return future; } diff --git a/sdk/lib/_internal/vm/lib/developer.dart b/sdk/lib/_internal/vm/lib/developer.dart index d6ab6af1541..d9c87a87f58 100644 --- a/sdk/lib/_internal/vm/lib/developer.dart +++ b/sdk/lib/_internal/vm/lib/developer.dart @@ -2,8 +2,6 @@ // 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.6 - /// Note: the VM concatenates all patch files into a single patch file. This /// file is the first patch in "dart:developer" which contains all the imports /// used by patches of that library. We plan to change this when we have a @@ -20,20 +18,20 @@ import "dart:isolate" show SendPort; // part "timeline.dart" @patch -bool debugger({bool when: true, String message}) native "Developer_debugger"; +bool debugger({bool when: true, String? message}) native "Developer_debugger"; @patch Object inspect(Object object) native "Developer_inspect"; @patch void log(String message, - {DateTime time, - int sequenceNumber, + {DateTime? time, + int? sequenceNumber, int level: 0, String name: '', - Zone zone, - Object error, - StackTrace stackTrace}) { + Zone? zone, + Object? error, + StackTrace? stackTrace}) { if (message is! String) { throw new ArgumentError.value(message, "message", "Must be a String"); } @@ -53,14 +51,14 @@ void log(String message, int _nextSequenceNumber = 0; _log(String message, int timestamp, int sequenceNumber, int level, String name, - Zone zone, Object error, StackTrace stackTrace) native "Developer_log"; + Zone? zone, Object? error, StackTrace? stackTrace) native "Developer_log"; @patch void _postEvent(String eventKind, String eventData) native "Developer_postEvent"; @patch -ServiceExtensionHandler _lookupExtension(String method) +ServiceExtensionHandler? _lookupExtension(String method) native "Developer_lookupExtension"; @patch diff --git a/sdk/lib/_internal/vm/lib/double.dart b/sdk/lib/_internal/vm/lib/double.dart index cd09dac0e30..83b32623c45 100644 --- a/sdk/lib/_internal/vm/lib/double.dart +++ b/sdk/lib/_internal/vm/lib/double.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "core_patch.dart"; @pragma("vm:entry-point") @@ -174,6 +172,7 @@ class _Double implements double { double truncateToDouble() native "Double_truncate"; num clamp(num lowerLimit, num upperLimit) { + // TODO: Remove these null checks once all code is opted into strong nonnullable mode. if (lowerLimit == null) { throw new ArgumentError.notNull("lowerLimit"); } @@ -200,7 +199,7 @@ class _Double implements double { static const int CACHE_LENGTH = 1 << (CACHE_SIZE_LOG2 + 1); static const int CACHE_MASK = CACHE_LENGTH - 1; // Each key (double) followed by its toString result. - static final List _cache = new List(CACHE_LENGTH); + static final List _cache = new List.filled(CACHE_LENGTH, null); static int _cacheEvictIndex = 0; String _toString() native "Double_toString"; @@ -228,6 +227,7 @@ class _Double implements double { String toStringAsFixed(int fractionDigits) { // See ECMAScript-262, 15.7.4.5 for details. + // TODO: Remove these null checks once all code is opted into strong nonnullable mode. if (fractionDigits == null) { throw new ArgumentError.notNull("fractionDigits"); } @@ -255,7 +255,7 @@ class _Double implements double { String _toStringAsFixed(int fractionDigits) native "Double_toStringAsFixed"; - String toStringAsExponential([int fractionDigits]) { + String toStringAsExponential([int? fractionDigits]) { // See ECMAScript-262, 15.7.4.6 for details. // The EcmaScript specification checks for NaN and Infinity before looking diff --git a/sdk/lib/_internal/vm/lib/double_patch.dart b/sdk/lib/_internal/vm/lib/double_patch.dart index c70ab77ecac..e6ccf5ca4c4 100644 --- a/sdk/lib/_internal/vm/lib/double_patch.dart +++ b/sdk/lib/_internal/vm/lib/double_patch.dart @@ -2,18 +2,16 @@ // 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.6 - // part of "core_patch.dart"; // VM implementation of double. @patch class double { - static double _nativeParse(String str, int start, int end) + static double? _nativeParse(String str, int start, int end) native "Double_parse"; - static double _tryParseDouble(var str, var start, var end) { + static double? _tryParseDouble(String str, int start, int end) { assert(start < end); const int _DOT = 0x2e; // '.' const int _ZERO = 0x30; // '0' @@ -73,7 +71,7 @@ class double { i++; if (i == end) return null; // int._tryParseSmi treats its end argument as inclusive. - int expPart = int._tryParseSmi(str, i, end - 1); + final int? expPart = int._tryParseSmi(str, i, end - 1); if (expPart == null) return null; exponent += expPart; break; @@ -93,11 +91,12 @@ class double { return sign * (doubleValue * P10[exponent]); } - static double _parse(var str) { + static double? _parse(String str) { int len = str.length; - int start = str._firstNonWhitespace(); + final strbase = str as _StringBase; + int start = strbase._firstNonWhitespace(); if (start == len) return null; // All whitespace. - int end = str._lastNonWhitespace() + 1; + int end = strbase._lastNonWhitespace() + 1; assert(start < end); var result = _tryParseDouble(str, start, end); if (result != null) return result; @@ -106,7 +105,7 @@ class double { @patch static double parse(String source, - [@deprecated double onError(String source)]) { + [@deprecated double onError(String source)?]) { var result = _parse(source); if (result == null) { if (onError == null) throw new FormatException("Invalid double", source); @@ -116,5 +115,5 @@ class double { } @patch - static double tryParse(String source) => _parse(source); + static double? tryParse(String source) => _parse(source); } diff --git a/sdk/lib/_internal/vm/lib/empty_source.dart b/sdk/lib/_internal/vm/lib/empty_source.dart index e5dbe091a94..95e028f13ca 100644 --- a/sdk/lib/_internal/vm/lib/empty_source.dart +++ b/sdk/lib/_internal/vm/lib/empty_source.dart @@ -2,6 +2,4 @@ // 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.6 - // THIS FILE INTENTIONALLY LEFT BLANK. diff --git a/sdk/lib/_internal/vm/lib/errors_patch.dart b/sdk/lib/_internal/vm/lib/errors_patch.dart index add6b295db9..c4b91f205e3 100644 --- a/sdk/lib/_internal/vm/lib/errors_patch.dart +++ b/sdk/lib/_internal/vm/lib/errors_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "core_patch.dart"; @patch @@ -19,10 +17,10 @@ class Error { } @patch - StackTrace get stackTrace => _stackTrace; + StackTrace? get stackTrace => _stackTrace; @pragma("vm:entry-point") - StackTrace _stackTrace; + StackTrace? _stackTrace; } class _AssertionError extends Error implements AssertionError { @@ -34,11 +32,11 @@ class _AssertionError extends Error implements AssertionError { // out of the script. It expects a Dart stack frame from class // _AssertionError. Thus we need a Dart stub that calls the native code. @pragma("vm:entry-point", "call") - static _throwNew(int assertionStart, int assertionEnd, Object message) { + static _throwNew(int assertionStart, int assertionEnd, Object? message) { _doThrowNew(assertionStart, assertionEnd, message); } - static _doThrowNew(int assertionStart, int assertionEnd, Object message) + static _doThrowNew(int assertionStart, int assertionEnd, Object? message) native "AssertionError_throwNew"; @pragma("vm:entry-point", "call") @@ -56,15 +54,16 @@ class _AssertionError extends Error implements AssertionError { } String get _messageString { - if (message == null) return "is not true."; - if (message is String) return message; - return Error.safeToString(message); + final msg = message; + if (msg == null) return "is not true."; + if (msg is String) return msg; + return Error.safeToString(msg); } String toString() { if (_url == null) { - if (message == null) return _failedAssertion?.trim(); - return "'${_failedAssertion?.trim()}': $_messageString"; + if (message == null) return _failedAssertion.trim(); + return "'${_failedAssertion.trim()}': $_messageString"; } var columnInfo = ""; if (_column > 0) { @@ -79,7 +78,7 @@ class _AssertionError extends Error implements AssertionError { final String _url; final int _line; final int _column; - final Object message; + final Object? message; } class _TypeError extends Error implements TypeError, CastError { @@ -87,22 +86,22 @@ class _TypeError extends Error implements TypeError, CastError { _TypeError._create(this._url, this._line, this._column, this._message); @pragma("vm:entry-point", "call") - static _throwNew(int location, Object src_value, _Type dst_type, - String dst_name) native "TypeError_throwNew"; + static _throwNew(int location, Object srcValue, _Type dstType, String dstName) + native "TypeError_throwNew"; String toString() => _message; final String _url; final int _line; final int _column; - final Object _message; + final String _message; } class _CastError extends Error implements CastError, TypeError { @pragma("vm:entry-point") _CastError._create(this._url, this._line, this._column, this._errorMsg); - // A CastError is allocated by TypeError._throwNew() when dst_name equals + // A CastError is allocated by TypeError._throwNew() when dstName equals // Symbols::InTypeCast(). String toString() => _errorMsg; @@ -118,11 +117,9 @@ class _CastError extends Error implements CastError, TypeError { class FallThroughError { @patch @pragma("vm:entry-point") - FallThroughError._create(String url, int line) - : _url = url, - _line = line; + FallThroughError._create(this._url, this._line); - static _throwNew(int case_clause_pos) native "FallThroughError_throwNew"; + static _throwNew(int caseClausePos) native "FallThroughError_throwNew"; @patch String toString() { @@ -131,8 +128,8 @@ class FallThroughError { // These new fields cannot be declared final, because a constructor exists // in the original version of this patched class. - String _url; - int _line; + String? _url; + int _line = 0; } class _InternalError { @@ -163,7 +160,7 @@ class AbstractClassInstantiationError { AbstractClassInstantiationError._create( this._className, this._url, this._line); - static _throwNew(int case_clause_pos, String className) + static _throwNew(int caseClausePos, String className) native "AbstractClassInstantiationError_throwNew"; @patch @@ -174,21 +171,21 @@ class AbstractClassInstantiationError { // These new fields cannot be declared final, because a constructor exists // in the original version of this patched class. - String _url; - int _line; + String? _url; + int _line = 0; } @patch class NoSuchMethodError { - final Object _receiver; + final Object? _receiver; final Invocation _invocation; @patch - NoSuchMethodError.withInvocation(Object receiver, Invocation invocation) + NoSuchMethodError.withInvocation(Object? receiver, Invocation invocation) : _receiver = receiver, _invocation = invocation; - static void _throwNewInvocation(Object receiver, Invocation invocation) { + static void _throwNewInvocation(Object? receiver, Invocation invocation) { throw new NoSuchMethodError.withInvocation(receiver, invocation); } @@ -201,18 +198,18 @@ class NoSuchMethodError { String memberName, int invocationType, int typeArgumentsLength, - Object typeArguments, - List arguments, - List argumentNames) { + Object? typeArguments, + List? arguments, + List? argumentNames) { throw new NoSuchMethodError._withType(receiver, memberName, invocationType, typeArgumentsLength, typeArguments, arguments, argumentNames); } // Deprecated constructor. @patch - NoSuchMethodError(this._receiver, Symbol memberName, List positionalArguments, - Map namedArguments, - [List existingArgumentNames = null]) // existingArgumentNames ignored. + NoSuchMethodError(this._receiver, Symbol memberName, + List? positionalArguments, Map? namedArguments, + [List? existingArgumentNames = null]) // existingArgumentNames ignored. : this._invocation = new _InvocationMirror._withType( memberName, _InvocationMirror._UNINITIALIZED, @@ -242,52 +239,54 @@ class NoSuchMethodError { String memberName, int invocationType, int typeArgumentsLength, // Needed with all-dynamic (null) typeArguments. - Object typeArguments, - List arguments, - List argumentNames) + Object? typeArguments, + List? arguments, + List? argumentNames) : this._invocation = new _InvocationMirror._withType( new Symbol(memberName), invocationType, _InvocationMirror._unpackTypeArguments( typeArguments, typeArgumentsLength), argumentNames != null - ? arguments.sublist(0, arguments.length - argumentNames.length) + ? arguments!.sublist(0, arguments.length - argumentNames.length) : arguments, argumentNames != null - ? _NamedArgumentsMap(arguments, argumentNames) + ? _NamedArgumentsMap(arguments!, argumentNames) : null); - static String _existingMethodSignature(Object receiver, String methodName, + static String? _existingMethodSignature(Object? receiver, String methodName, int invocationType) native "NoSuchMethodError_existingMethodSignature"; @patch String toString() { - var invocation = _invocation; - if (invocation is _InvocationMirror) { - String memberName = - internal.Symbol.computeUnmangledName(invocation.memberName); - var level = (invocation._type >> _InvocationMirror._LEVEL_SHIFT) & + final localInvocation = _invocation; + if (localInvocation is _InvocationMirror) { + var internalName = localInvocation.memberName as internal.Symbol; + String memberName = internal.Symbol.computeUnmangledName(internalName); + + var level = (localInvocation._type >> _InvocationMirror._LEVEL_SHIFT) & _InvocationMirror._LEVEL_MASK; - var kind = invocation._type & _InvocationMirror._KIND_MASK; + var kind = localInvocation._type & _InvocationMirror._KIND_MASK; if (kind == _InvocationMirror._LOCAL_VAR) { return "NoSuchMethodError: Cannot assign to final variable '$memberName'"; } - StringBuffer typeArgumentsBuf = null; - var typeArguments = invocation.typeArguments; + StringBuffer? typeArgumentsBuf = null; + final typeArguments = localInvocation.typeArguments; if ((typeArguments != null) && (typeArguments.length > 0)) { - typeArgumentsBuf = new StringBuffer(); - typeArgumentsBuf.write("<"); + final argsBuf = new StringBuffer(); + argsBuf.write("<"); for (int i = 0; i < typeArguments.length; i++) { if (i > 0) { - typeArgumentsBuf.write(", "); + argsBuf.write(", "); } - typeArgumentsBuf.write(Error.safeToString(typeArguments[i])); + argsBuf.write(Error.safeToString(typeArguments[i])); } - typeArgumentsBuf.write(">"); + argsBuf.write(">"); + typeArgumentsBuf = argsBuf; } StringBuffer argumentsBuf = new StringBuffer(); - var positionalArguments = invocation.positionalArguments; + var positionalArguments = localInvocation.positionalArguments; int argumentCount = 0; if (positionalArguments != null) { for (; argumentCount < positionalArguments.length; argumentCount++) { @@ -298,20 +297,22 @@ class NoSuchMethodError { .write(Error.safeToString(positionalArguments[argumentCount])); } } - var namedArguments = invocation.namedArguments; + var namedArguments = localInvocation.namedArguments; if (namedArguments != null) { namedArguments.forEach((Symbol key, var value) { if (argumentCount > 0) { argumentsBuf.write(", "); } - argumentsBuf.write(internal.Symbol.computeUnmangledName(key)); + var internalName = key as internal.Symbol; + argumentsBuf + .write(internal.Symbol.computeUnmangledName(internalName)); argumentsBuf.write(": "); argumentsBuf.write(Error.safeToString(value)); argumentCount++; }); } - String existingSig = - _existingMethodSignature(_receiver, memberName, invocation._type); + String? existingSig = _existingMethodSignature( + _receiver, memberName, localInvocation._type); String argsMsg = existingSig != null ? " with matching arguments" : ""; String kindBuf = "function"; @@ -326,7 +327,7 @@ class NoSuchMethodError { } StringBuffer msgBuf = new StringBuffer("NoSuchMethodError: "); - bool is_type_call = false; + bool isTypeCall = false; switch (level) { case _InvocationMirror._DYNAMIC: { @@ -343,7 +344,7 @@ class NoSuchMethodError { msgBuf.writeln("Closure call with mismatched arguments: " "function '$memberName'"); } else if (_receiver is _Type && memberName == "call") { - is_type_call = true; + isTypeCall = true; String name = _receiver.toString(); msgBuf.writeln("Attempted to use type '$name' as a function. " "Since types do not define a method 'call', this is not " @@ -393,7 +394,7 @@ class NoSuchMethodError { } if (kind == _InvocationMirror._METHOD) { - String m = is_type_call ? "$_receiver" : "$memberName"; + String m = isTypeCall ? "$_receiver" : "$memberName"; msgBuf.write("Tried calling: $m"); if (typeArgumentsBuf != null) { msgBuf.write(typeArgumentsBuf); @@ -413,7 +414,7 @@ class NoSuchMethodError { return msgBuf.toString(); } - return _toStringPlain(_receiver, invocation); + return _toStringPlain(_receiver, localInvocation); } /// Creates a string representation of an invocation. @@ -421,7 +422,7 @@ class NoSuchMethodError { /// Used for situations where there is no extra information available /// about the failed invocation than the [Invocation] object and receiver, /// which includes errors created using [NoSuchMethodError.withInvocation]. - static String _toStringPlain(Object receiver, Invocation invocation) { + static String _toStringPlain(Object? receiver, Invocation invocation) { var name = _symbolToString(invocation.memberName); var receiverType = "${receiver.runtimeType}"; if (invocation.isAccessor) { diff --git a/sdk/lib/_internal/vm/lib/expando_patch.dart b/sdk/lib/_internal/vm/lib/expando_patch.dart index 7653c26eeac..1d99cab6cad 100644 --- a/sdk/lib/_internal/vm/lib/expando_patch.dart +++ b/sdk/lib/_internal/vm/lib/expando_patch.dart @@ -2,23 +2,21 @@ // 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.6 - // part of "core_patch.dart"; @patch class Expando { @patch - Expando([String name]) + Expando([String? name]) : name = name, - _data = new List(_minSize), + _data = new List.filled(_minSize, null), _used = 0; static const _minSize = 8; static final _deletedEntry = new _WeakProperty(null, null); @patch - T operator [](Object object) { + T? operator [](Object object) { _checkType(object); var mask = _size - 1; @@ -40,7 +38,7 @@ class Expando { } @patch - void operator []=(Object object, T value) { + void operator []=(Object object, T? value) { _checkType(object); var mask = _size - 1; @@ -118,7 +116,7 @@ class Expando { // Reset the mappings to empty so that we can just add the existing // valid entries. - _data = new List(new_size); + _data = new List.filled(new_size, null); _used = 0; for (var i = 0; i < old_data.length; i++) { diff --git a/sdk/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart b/sdk/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart index 0d47898e952..303c5a4d385 100644 --- a/sdk/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart +++ b/sdk/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // All imports must be in all FFI patch files to not depend on the order // the patches are applied. import "dart:_internal" show patch; @@ -37,9 +35,10 @@ class DynamicLibrary { int getHandle() native "Ffi_dl_getHandle"; @patch - bool operator ==(other) { - if (other == null) return false; - return getHandle() == other.getHandle(); + bool operator ==(Object other) { + if (other is! DynamicLibrary) return false; + DynamicLibrary otherLib = other; + return getHandle() == otherLib.getHandle(); } @patch diff --git a/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart b/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart index 316dc7a524e..cc7831b26c6 100644 --- a/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart +++ b/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // All imports must be in all FFI patch files to not depend on the order // the patches are applied. import "dart:_internal" show patch; diff --git a/sdk/lib/_internal/vm/lib/ffi_patch.dart b/sdk/lib/_internal/vm/lib/ffi_patch.dart index 726f6198969..d42689ce0d3 100644 --- a/sdk/lib/_internal/vm/lib/ffi_patch.dart +++ b/sdk/lib/_internal/vm/lib/ffi_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // All imports must be in all FFI patch files to not depend on the order // the patches are applied. import "dart:_internal" show patch; @@ -31,7 +29,7 @@ int sizeOf() { // This is not super fast, but it is faster than a runtime entry. // Hot loops with elementAt().load() do not use this sizeOf, elementAt is // optimized per NativeType statically to prevent use of sizeOf at runtime. - final int knownSize = _knownSizes[T]; + final int? knownSize = _knownSizes[T]; if (knownSize != null) return knownSize; if (T == IntPtr) return _intPtrSize; if (T == Pointer) return _intPtrSize; @@ -66,10 +64,13 @@ dynamic _asExternalTypedData(Pointer ptr, int count) // implementation, since that would pull the callback trampoline into JIT // snapshots. The callback trampolines can only be serialized into AOT snapshots // because they embed the addresses of runtime routines in JIT mode. -Object _nativeCallbackFunction(Function target, +// +// Function objects returned by this native method are not Dart instances, +// so we need to use top type as a return type to avoid type check. +dynamic _nativeCallbackFunction(Function target, Object exceptionalReturn) native "Ffi_nativeCallbackFunction"; -Pointer _pointerFromFunction(Object function) +Pointer _pointerFromFunction(dynamic function) native "Ffi_pointerFromFunction"; @patch @@ -86,7 +87,7 @@ class Pointer { @patch static Pointer> fromFunction( @DartRepresentationOf("T") Function f, - [Object exceptionalReturn]) { + [Object? exceptionalReturn]) { throw UnsupportedError( "Pointer.fromFunction cannot be called dynamically."); } diff --git a/sdk/lib/_internal/vm/lib/ffi_struct_patch.dart b/sdk/lib/_internal/vm/lib/ffi_struct_patch.dart index d3545f06d59..8fad96754e1 100644 --- a/sdk/lib/_internal/vm/lib/ffi_struct_patch.dart +++ b/sdk/lib/_internal/vm/lib/ffi_struct_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // All imports must be in all FFI patch files to not depend on the order // the patches are applied. import "dart:_internal" show patch; diff --git a/sdk/lib/_internal/vm/lib/function.dart b/sdk/lib/_internal/vm/lib/function.dart index 128a7dd624c..1c99ca26e5f 100644 --- a/sdk/lib/_internal/vm/lib/function.dart +++ b/sdk/lib/_internal/vm/lib/function.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "core_patch.dart"; @pragma("vm:entry-point") diff --git a/sdk/lib/_internal/vm/lib/function_patch.dart b/sdk/lib/_internal/vm/lib/function_patch.dart index 9d33e30ee33..b4d3daa75e2 100644 --- a/sdk/lib/_internal/vm/lib/function_patch.dart +++ b/sdk/lib/_internal/vm/lib/function_patch.dart @@ -2,32 +2,33 @@ // 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.6 - // part of "core_patch.dart"; @patch class Function { // TODO(regis): Pass type arguments to generic functions. Wait for API spec. - static _apply(List arguments, List names) native "Function_apply"; + static _apply(List? arguments, List? names) + native "Function_apply"; @patch - static apply(Function function, List positionalArguments, - [Map namedArguments]) { + static apply(Function function, List? positionalArguments, + [Map? namedArguments]) { int numPositionalArguments = 1 + // Function is first implicit argument. (positionalArguments != null ? positionalArguments.length : 0); int numNamedArguments = namedArguments != null ? namedArguments.length : 0; int numArguments = numPositionalArguments + numNamedArguments; - List arguments = new List(numArguments); + List arguments = new List.filled(numArguments, null); arguments[0] = function; - arguments.setRange(1, numPositionalArguments, positionalArguments); - List names = new List(numNamedArguments); + if (positionalArguments != null) { + arguments.setRange(1, numPositionalArguments, positionalArguments); + } + List names = new List.filled(numNamedArguments, null); int argumentIndex = numPositionalArguments; int nameIndex = 0; if (numNamedArguments > 0) { - namedArguments.forEach((name, value) { + namedArguments?.forEach((name, value) { arguments[argumentIndex++] = value; - names[nameIndex++] = internal.Symbol.getName(name); + names[nameIndex++] = internal.Symbol.getName(name as internal.Symbol); }); } return _apply(arguments, names); diff --git a/sdk/lib/_internal/vm/lib/growable_array.dart b/sdk/lib/_internal/vm/lib/growable_array.dart index 6c0e32715c7..bca95abd0f4 100644 --- a/sdk/lib/_internal/vm/lib/growable_array.dart +++ b/sdk/lib/_internal/vm/lib/growable_array.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "core_patch.dart"; @pragma("vm:entry-point") @@ -12,12 +10,11 @@ class _GrowableList extends ListBase { if ((index < 0) || (index > length)) { throw new RangeError.range(index, 0, length); } - if (index == this.length) { - add(element); + int oldLength = this.length; + add(element); + if (index == oldLength) { return; } - int oldLength = this.length; - this.length++; Lists.copy(this, index, this, index + 1, oldLength - index); this[index] = element; } @@ -32,7 +29,7 @@ class _GrowableList extends ListBase { return result; } - bool remove(Object element) { + bool remove(Object? element) { for (int i = 0; i < this.length; i++) { if (this[i] == element) { removeAt(i); @@ -54,7 +51,15 @@ class _GrowableList extends ListBase { // There might be errors after the length change, in which case the list // will end up being modified but the operation not complete. Unless we // always go through a "toList" we can't really avoid that. - this.length += insertionLength; + int capacity = _capacity; + int newLength = length + insertionLength; + if (newLength > capacity) { + do { + capacity = _nextCapacity(capacity); + } while (newLength > capacity); + _grow(capacity); + } + _setLength(newLength); setRange(index + insertionLength, this.length, this, index); setAll(index, iterable); } @@ -75,15 +80,15 @@ class _GrowableList extends ListBase { this.length = this.length - (end - start); } - List sublist(int start, [int end]) { - end = RangeError.checkValidRange(start, end, this.length); - int length = end - start; + List sublist(int start, [int? end]) { + final int actualEnd = RangeError.checkValidRange(start, end, this.length); + int length = actualEnd - start; if (length == 0) return []; - List list = new _List(length); + final list = new _List(length); for (int i = 0; i < length; i++) { list[i] = this[start + i]; } - var result = new _GrowableList._withData(list); + final result = new _GrowableList._withData(list); result._setLength(length); return result; } @@ -103,7 +108,7 @@ class _GrowableList extends ListBase { } @pragma("vm:exact-result-type", - [_GrowableList, "result-type-uses-passed-type-arguments"]) + [_GrowableList, "result-type-uses-passed-type-arguments"]) factory _GrowableList._withData(_List data) native "GrowableList_allocate"; @pragma("vm:exact-result-type", "dart:core#_Smi") @@ -118,6 +123,8 @@ class _GrowableList extends ListBase { int old_capacity = _capacity; int new_capacity = new_length; if (new_capacity > old_capacity) { + // Verify that element type is nullable. + null as T; _grow(new_capacity); _setLength(new_length); return; @@ -133,7 +140,7 @@ class _GrowableList extends ListBase { _shrink(new_capacity, new_length); } else { for (int i = new_length; i < length; i++) { - this[i] = null; + _setIndexed(i, null); } } _setLength(new_length); @@ -149,7 +156,7 @@ class _GrowableList extends ListBase { _setIndexed(index, value); } - void _setIndexed(int index, T value) native "GrowableList_setIndexed"; + void _setIndexed(int index, T? value) native "GrowableList_setIndexed"; @pragma("vm:entry-point", "call") @pragma("vm:prefer-inline") @@ -184,7 +191,7 @@ class _GrowableList extends ListBase { throw new ConcurrentModificationError(this); } this._setLength(newLen); - final ListBase iterableAsList = iterable; + final ListBase iterableAsList = iterable as ListBase; for (int i = 0; i < iterLen; i++) { this[len++] = iterableAsList[i]; } @@ -393,11 +400,11 @@ class _GrowableList extends ListBase { } return list; } - return new List(0); + return List.empty(growable: false); } } Set toSet() { - return new Set.from(this); + return new Set.of(this); } } diff --git a/sdk/lib/_internal/vm/lib/identical_patch.dart b/sdk/lib/_internal/vm/lib/identical_patch.dart index 3e4dc1ec69e..4b5743084c7 100644 --- a/sdk/lib/_internal/vm/lib/identical_patch.dart +++ b/sdk/lib/_internal/vm/lib/identical_patch.dart @@ -2,14 +2,12 @@ // 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.6 - // part of "core_patch.dart"; @patch @pragma("vm:exact-result-type", bool) -bool identical(Object a, Object b) native "Identical_comparison"; +bool identical(Object? a, Object? b) native "Identical_comparison"; @patch @pragma("vm:entry-point", "call") -int identityHashCode(Object object) => object._identityHashCode; +int identityHashCode(Object? object) => object._identityHashCode; diff --git a/sdk/lib/_internal/vm/lib/immutable_map.dart b/sdk/lib/_internal/vm/lib/immutable_map.dart index 86e5d8da645..7be9890c2be 100644 --- a/sdk/lib/_internal/vm/lib/immutable_map.dart +++ b/sdk/lib/_internal/vm/lib/immutable_map.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "core_patch.dart"; /// Immutable map class for compiler generated map literals. @@ -18,7 +16,7 @@ class _ImmutableMap implements Map { : _kvPairs = keyValuePairs; Map cast() => Map.castFrom(this); - V operator [](Object key) { + V? operator [](Object? key) { // To preserve the key-value order of the map literal, the keys are // not sorted. Need to do linear search or implement an additional // lookup table. @@ -54,7 +52,7 @@ class _ImmutableMap implements Map { return new _ImmutableMapValueIterable(this); } - bool containsKey(Object key) { + bool containsKey(Object? key) { for (int i = 0; i < _kvPairs.length; i += 2) { if (key == _kvPairs[i]) { return true; @@ -63,7 +61,7 @@ class _ImmutableMap implements Map { return false; } - bool containsValue(Object value) { + bool containsValue(Object? value) { for (int i = 1; i < _kvPairs.length; i += 2) { if (value == _kvPairs[i]) { return true; @@ -88,7 +86,7 @@ class _ImmutableMap implements Map { throw new UnsupportedError("Cannot clear unmodifiable Map"); } - V remove(Object key) { + V? remove(Object? key) { throw new UnsupportedError("Cannot remove from unmodifiable Map"); } @@ -108,7 +106,7 @@ class _ImmutableMap implements Map { throw new UnsupportedError("Cannot modify an unmodifiable Map"); } - V update(K key, V update(V value), {V ifAbsent()}) { + V update(K key, V update(V value), {V ifAbsent()?}) { throw new UnsupportedError("Cannot modify an unmodifiable Map"); } @@ -160,7 +158,7 @@ class _ImmutableMapEntryIterable class _ImmutableMapKeyIterator implements Iterator { _ImmutableMap _map; int _nextIndex = 0; - E _current; + E? _current; _ImmutableMapKeyIterator(this._map); @@ -175,13 +173,16 @@ class _ImmutableMapKeyIterator implements Iterator { return false; } - E get current => _current; + E get current { + final cur = _current; + return (cur != null) ? cur : cur as E; + } } class _ImmutableMapValueIterator implements Iterator { _ImmutableMap _map; int _nextIndex = 0; - E _current; + E? _current; _ImmutableMapValueIterator(this._map); @@ -196,13 +197,16 @@ class _ImmutableMapValueIterator implements Iterator { return false; } - E get current => _current; + E get current { + final cur = _current; + return (cur != null) ? cur : cur as E; + } } class _ImmutableMapEntryIterator implements Iterator> { _ImmutableMap _map; int _nextIndex = 0; - MapEntry _current; + MapEntry? _current; _ImmutableMapEntryIterator(this._map); @@ -218,5 +222,8 @@ class _ImmutableMapEntryIterator implements Iterator> { return false; } - MapEntry get current => _current; + MapEntry get current { + final cur = _current; + return (cur != null) ? cur : cur as MapEntry; + } } diff --git a/sdk/lib/_internal/vm/lib/integers.dart b/sdk/lib/_internal/vm/lib/integers.dart index 73a5fffd715..9fd3a76d013 100644 --- a/sdk/lib/_internal/vm/lib/integers.dart +++ b/sdk/lib/_internal/vm/lib/integers.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "core_patch.dart"; abstract class _IntegerImplementation implements int { @@ -41,7 +39,9 @@ abstract class _IntegerImplementation implements int { @pragma("vm:non-nullable-result-type") @pragma("vm:never-inline") int operator -() { - return 0 - this; + // Issue(https://dartbug.com/39639): The analyzer incorrectly reports the + // result type as `num`. + return unsafeCast(0 - this); } @pragma("vm:non-nullable-result-type") @@ -81,7 +81,9 @@ abstract class _IntegerImplementation implements int { @pragma("vm:non-nullable-result-type") int _moduloFromInteger(int other) native "Integer_moduloFromInteger"; int _remainderFromInteger(int other) { - return other - (other ~/ this) * this; + // Issue(https://dartbug.com/39639): The analyzer incorrectly reports the + // result type as `num`. + return unsafeCast(other - (other ~/ this) * this); } @pragma("vm:non-nullable-result-type") @@ -238,6 +240,7 @@ abstract class _IntegerImplementation implements int { } num clamp(num lowerLimit, num upperLimit) { + // TODO: Remove these null checks once all code is opted into strong nonnullable mode. if (lowerLimit == null) { throw new ArgumentError.notNull("lowerLimit"); } @@ -274,7 +277,7 @@ abstract class _IntegerImplementation implements int { return this.toDouble().toStringAsFixed(fractionDigits); } - String toStringAsExponential([int fractionDigits]) { + String toStringAsExponential([int? fractionDigits]) { return this.toDouble().toStringAsExponential(fractionDigits); } @@ -300,7 +303,7 @@ abstract class _IntegerImplementation implements int { // -MIN_INT64 == MIN_INT64, so it requires special handling. return _minInt64ToRadixString(radix); } - var temp = new List(); + var temp = []; do { int digit = value % radix; value ~/= radix; @@ -348,11 +351,11 @@ abstract class _IntegerImplementation implements int { /// This method is only used to handle corner case of /// MIN_INT64 = -0x8000000000000000. String _minInt64ToRadixString(int radix) { - var temp = new List(); + var temp = []; int value = this; assert(value < 0); do { - int digit = -value.remainder(radix); + int digit = -unsafeCast(value.remainder(radix)); value ~/= radix; temp.add(_digits.codeUnitAt(digit)); } while (value != 0); @@ -367,6 +370,7 @@ abstract class _IntegerImplementation implements int { // Returns pow(this, e) % m. int modPow(int e, int m) { + // TODO: Remove these null checks once all code is opted into strong nonnullable mode. if (e == null) { throw new ArgumentError.notNull("exponent"); } @@ -473,6 +477,7 @@ abstract class _IntegerImplementation implements int { // Returns 1/this % m, with m > 0. int modInverse(int m) { + // TODO: Remove these null checks once all code is opted into strong nonnullable mode. if (m == null) { throw new ArgumentError.notNull("modulus"); } @@ -489,6 +494,7 @@ abstract class _IntegerImplementation implements int { // Returns gcd of abs(this) and abs(other). int gcd(int other) { + // TODO: Remove these null checks once all code is opted into strong nonnullable mode. if (other == null) { throw new ArgumentError.notNull("other"); } @@ -606,7 +612,11 @@ class _Smi extends _IntegerImplementation { } String toString() { - if (this < 100 && this > -100) return _smallLookupTable[this + 99]; + if (this < 100 && this > -100) { + // Issue(https://dartbug.com/39639): The analyzer incorrectly reports the + // result type as `num`. + return _smallLookupTable[unsafeCast(this + 99)]; + } if (this < 0) return _negativeToString(this); // Inspired by Andrei Alexandrescu: "Three Optimization Tips for C++" // Avoid expensive remainder operation by doing it on more than @@ -615,11 +625,11 @@ class _Smi extends _IntegerImplementation { int length = _positiveBase10Length(this); _OneByteString result = _OneByteString._allocate(length); int index = length - 1; - var smi = this; + _Smi smi = this; do { // Two digits at a time. - var twoDigits = smi.remainder(100); - smi = smi ~/ 100; + final int twoDigits = unsafeCast(smi.remainder(100)); + smi = unsafeCast<_Smi>(smi ~/ 100); int digitIndex = twoDigits * 2; result._setAt(index, _digitTable[digitIndex + 1]); result._setAt(index - 1, _digitTable[digitIndex]); @@ -627,10 +637,14 @@ class _Smi extends _IntegerImplementation { } while (smi >= 100); if (smi < 10) { // Character code for '0'. - result._setAt(index, DIGIT_ZERO + smi); + // Issue(https://dartbug.com/39639): The analyzer incorrectly reports the + // result type as `num`. + result._setAt(index, unsafeCast(DIGIT_ZERO + smi)); } else { // No remainder for this case. - int digitIndex = smi * 2; + // Issue(https://dartbug.com/39639): The analyzer incorrectly reports the + // result type as `num`. + int digitIndex = unsafeCast(smi * 2); result._setAt(index, _digitTable[digitIndex + 1]); result._setAt(index - 1, _digitTable[digitIndex]); } @@ -684,7 +698,7 @@ class _Smi extends _IntegerImplementation { result._setAt(0, MINUS_SIGN); // '-'. int index = digitCount; do { - var twoDigits = negSmi.remainder(100); + int twoDigits = unsafeCast(negSmi.remainder(100)); negSmi = negSmi ~/ 100; int digitIndex = -twoDigits * 2; result._setAt(index, _digitTable[digitIndex + 1]); diff --git a/sdk/lib/_internal/vm/lib/integers_patch.dart b/sdk/lib/_internal/vm/lib/integers_patch.dart index 5582dfc067a..48313538f64 100644 --- a/sdk/lib/_internal/vm/lib/integers_patch.dart +++ b/sdk/lib/_internal/vm/lib/integers_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "core_patch.dart"; /// VM implementation of int. @@ -20,7 +18,7 @@ class int { int _shrFromInteger(int other); int _shlFromInteger(int other); - static int _tryParseSmi(String str, int first, int last) { + static int? _tryParseSmi(String str, int first, int last) { assert(first <= last); var ix = first; var sign = 1; @@ -49,23 +47,23 @@ class int { } @patch - static int parse(String source, {int radix, int onError(String source)}) { + static int parse(String source, {int? radix, int onError(String source)?}) { if (source == null) throw new ArgumentError("The source must not be null"); if (source.isEmpty) { return _throwFormatException(onError, source, 0, radix, null); } if (radix == null || radix == 10) { // Try parsing immediately, without trimming whitespace. - int result = _tryParseSmi(source, 0, source.length - 1); + int? result = _tryParseSmi(source, 0, source.length - 1); if (result != null) return result; } else if (radix < 2 || radix > 36) { throw new RangeError("Radix $radix not in range 2..36"); } // Split here so improve odds of parse being inlined and the checks omitted. - return _parse(source, radix, onError); + return _parse(unsafeCast<_StringBase>(source), radix, onError); } - static int _parse(_StringBase source, int radix, onError) { + static int _parse(_StringBase source, int? radix, onError) { int end = source._lastNonWhitespace() + 1; if (end == 0) { return _throwFormatException(onError, source, source.length, radix, null); @@ -103,18 +101,18 @@ class int { } @patch - static int tryParse(String source, {int radix}) { + static int? tryParse(String source, {int? radix}) { if (source == null) throw new ArgumentError("The source must not be null"); if (source.isEmpty) return null; if (radix == null || radix == 10) { // Try parsing immediately, without trimming whitespace. - int result = _tryParseSmi(source, 0, source.length - 1); + int? result = _tryParseSmi(source, 0, source.length - 1); if (result != null) return result; } else if (radix < 2 || radix > 36) { throw new RangeError("Radix $radix not in range 2..36"); } try { - return _parse(source, radix, _kNull); + return _parse(unsafeCast<_StringBase>(source), radix, _kNull); } catch (e) { return null; } @@ -139,7 +137,7 @@ class int { int blockSize = _PARSE_LIMITS[tableIndex]; int length = end - start; if (length <= blockSize) { - _Smi smi = _parseBlock(source, radix, start, end); + int? smi = _parseBlock(source, radix, start, end); if (smi == null) { return _throwFormatException(onError, source, start, radix, null); } @@ -154,7 +152,7 @@ class int { int result = 0; if (smallBlockSize > 0) { int blockEnd = start + smallBlockSize; - _Smi smi = _parseBlock(source, radix, start, blockEnd); + int? smi = _parseBlock(source, radix, start, blockEnd); if (smi == null) { return _throwFormatException(onError, source, start, radix, null); } @@ -172,7 +170,7 @@ class int { negativeOverflowLimit = _int64OverflowLimits[tableIndex + 1]; int blockEnd = start + blockSize; do { - _Smi smi = _parseBlock(source, radix, start, blockEnd); + int? smi = _parseBlock(source, radix, start, blockEnd); if (smi == null) { return _throwFormatException(onError, source, start, radix, null); } @@ -208,13 +206,13 @@ class int { } // Parse block of digits into a Smi. - static _Smi _parseBlock(String source, int radix, int start, int end) { - _Smi result = 0; + static _Smi? _parseBlock(String source, int radix, int start, int end) { + _Smi result = unsafeCast<_Smi>(0); if (radix <= 10) { for (int i = start; i < end; i++) { int digit = source.codeUnitAt(i) ^ 0x30; if (digit >= radix) return null; - result = radix * result + digit; + result = (radix * result + digit) as _Smi; } } else { for (int i = start; i < end; i++) { @@ -224,7 +222,7 @@ class int { digit = (char | 0x20) - (0x61 - 10); if (digit < 10 || digit >= radix) return null; } - result = radix * result + digit; + result = (radix * result + digit) as _Smi; } } return result; @@ -301,8 +299,10 @@ class int { static int _initInt64OverflowLimits(int tableIndex, int multiplier) { _int64OverflowLimits[tableIndex] = _maxInt64 ~/ multiplier; _int64OverflowLimits[tableIndex + 1] = _minInt64 ~/ multiplier; - _int64OverflowLimits[tableIndex + 2] = _maxInt64.remainder(multiplier); - _int64OverflowLimits[tableIndex + 3] = -(_minInt64.remainder(multiplier)); + _int64OverflowLimits[tableIndex + 2] = + unsafeCast(_maxInt64.remainder(multiplier)); + _int64OverflowLimits[tableIndex + 3] = + -unsafeCast(_minInt64.remainder(multiplier)); return _int64OverflowLimits[tableIndex]; } } diff --git a/sdk/lib/_internal/vm/lib/internal_patch.dart b/sdk/lib/_internal/vm/lib/internal_patch.dart index 2a05d999bfe..b904f9eb3f1 100644 --- a/sdk/lib/_internal/vm/lib/internal_patch.dart +++ b/sdk/lib/_internal/vm/lib/internal_patch.dart @@ -2,8 +2,6 @@ // 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.6 - /// Note: the VM concatenates all patch files into a single patch file. This /// file is the first patch in "dart:_internal" which contains all the imports /// used by patches of that library. We plan to change this when we have a @@ -19,6 +17,12 @@ import "dart:typed_data" show Int32List, Uint8List; // part "print_patch.dart"; // part "symbol_patch.dart"; +// On the VM, we don't make the entire legacy weak mode check +// const to avoid having a constant in the platform libraries +// which evaluates differently in weak vs strong mode. +@patch +bool typeAcceptsNull() => (const []) is List || null is T; + @patch List makeListFixedLength(List growableList) native "Internal_makeListFixedLength"; @@ -155,7 +159,7 @@ Int32List _growRegExpStack(Int32List stack) { // type of a value. // // Important: this is unsafe and must be used with care. -T unsafeCast(Object v) native "Internal_unsafeCast"; +T unsafeCast(Object? v) native "Internal_unsafeCast"; // This function can be used to keep an object alive til that point. // @@ -173,11 +177,11 @@ void spawnFunction( var message, bool paused, bool errorsAreFatal, - SendPort onExit, - SendPort onError, - String packageConfig, + SendPort? onExit, + SendPort? onError, + String? packageConfig, bool newIsolateGroup, - String debugName) native "Isolate_spawnFunction"; + String? debugName) native "Isolate_spawnFunction"; // Collection of functions which should only be used for testing purposes. abstract class VMInternalsForTesting { diff --git a/sdk/lib/_internal/vm/lib/invocation_mirror_patch.dart b/sdk/lib/_internal/vm/lib/invocation_mirror_patch.dart index 1f43d545969..075e001b14d 100644 --- a/sdk/lib/_internal/vm/lib/invocation_mirror_patch.dart +++ b/sdk/lib/_internal/vm/lib/invocation_mirror_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "core_patch.dart"; // NOTE: When making changes to this class, please also update @@ -41,41 +39,43 @@ class _InvocationMirror implements Invocation { static const int _FIRST_NAMED_ENTRY = 4; // Internal representation of the invocation mirror. - String _functionName; - List _argumentsDescriptor; - List _arguments; - bool _isSuperInvocation; - int _delayedTypeArgumentsLen; + String? _functionName; + List? _argumentsDescriptor; + List? _arguments; + bool _isSuperInvocation = false; + int _delayedTypeArgumentsLen = 0; // External representation of the invocation mirror; populated on demand. - Symbol _memberName; + Symbol? _memberName; int _type = _UNINITIALIZED; - List _typeArguments; - List _positionalArguments; - Map _namedArguments; + List? _typeArguments; + List? _positionalArguments; + Map? _namedArguments; - _InvocationMirror._withType(this._memberName, this._type, this._typeArguments, - this._positionalArguments, this._namedArguments) { + _InvocationMirror._withType(this._memberName, int? type, this._typeArguments, + this._positionalArguments, this._namedArguments) + : _type = type ?? _UNINITIALIZED { _typeArguments ??= const []; _positionalArguments ??= const []; _namedArguments ??= const {}; } void _setMemberNameAndType() { + final funcName = _functionName!; if (_type == _UNINITIALIZED) { _type = 0; } - if (_functionName.startsWith("get:")) { + if (funcName.startsWith("get:")) { _type |= _GETTER; - _memberName = new internal.Symbol.unvalidated(_functionName.substring(4)); - } else if (_functionName.startsWith("set:")) { + _memberName = new internal.Symbol.unvalidated(funcName.substring(4)); + } else if (funcName.startsWith("set:")) { _type |= _SETTER; _memberName = - new internal.Symbol.unvalidated(_functionName.substring(4) + "="); + new internal.Symbol.unvalidated(funcName.substring(4) + "="); } else { _type |= _isSuperInvocation ? (_SUPER << _LEVEL_SHIFT) | _METHOD : _METHOD; - _memberName = new internal.Symbol.unvalidated(_functionName); + _memberName = new internal.Symbol.unvalidated(funcName); } } @@ -83,11 +83,11 @@ class _InvocationMirror implements Invocation { if (_memberName == null) { _setMemberNameAndType(); } - return _memberName; + return _memberName!; } int get _typeArgsLen { - int typeArgsLen = _argumentsDescriptor[_TYPE_ARGS_LEN]; + int typeArgsLen = _argumentsDescriptor![_TYPE_ARGS_LEN]; return typeArgsLen == 0 ? _delayedTypeArgumentsLen : typeArgsLen; } @@ -99,9 +99,9 @@ class _InvocationMirror implements Invocation { // A TypeArguments object does not have a corresponding Dart class and // cannot be accessed as an array in Dart. Therefore, we need a native // call to unpack the individual types into a list. - _typeArguments = _unpackTypeArguments(_arguments[0], _typeArgsLen); + _typeArguments = _unpackTypeArguments(_arguments![0], _typeArgsLen); } - return _typeArguments; + return _typeArguments!; } // Unpack the given TypeArguments object into a new list of individual types. @@ -112,38 +112,40 @@ class _InvocationMirror implements Invocation { if (_positionalArguments == null) { // The argument descriptor counts the receiver, but not the type arguments // as positional arguments. - int numPositionalArguments = _argumentsDescriptor[_POSITIONAL_COUNT] - 1; + int numPositionalArguments = _argumentsDescriptor![_POSITIONAL_COUNT] - 1; if (numPositionalArguments == 0) { return _positionalArguments = const []; } // Exclude receiver and type args in the returned list. int receiverIndex = _typeArgsLen > 0 ? 1 : 0; + var args = _arguments!; _positionalArguments = new _ImmutableList._from( - _arguments, receiverIndex + 1, numPositionalArguments); + args, receiverIndex + 1, numPositionalArguments); } - return _positionalArguments; + return _positionalArguments!; } Map get namedArguments { if (_namedArguments == null) { - int numArguments = _argumentsDescriptor[_COUNT] - 1; // Exclude receiver. - int numPositionalArguments = _argumentsDescriptor[_POSITIONAL_COUNT] - 1; + final argsDescriptor = _argumentsDescriptor!; + int numArguments = argsDescriptor[_COUNT] - 1; // Exclude receiver. + int numPositionalArguments = argsDescriptor[_POSITIONAL_COUNT] - 1; int numNamedArguments = numArguments - numPositionalArguments; if (numNamedArguments == 0) { return _namedArguments = const {}; } int receiverIndex = _typeArgsLen > 0 ? 1 : 0; - _namedArguments = new Map(); + final namedArguments = new Map(); for (int i = 0; i < numNamedArguments; i++) { int namedEntryIndex = _FIRST_NAMED_ENTRY + 2 * i; - String arg_name = _argumentsDescriptor[namedEntryIndex]; - var arg_value = _arguments[ - receiverIndex + _argumentsDescriptor[namedEntryIndex + 1]]; - _namedArguments[new internal.Symbol.unvalidated(arg_name)] = arg_value; + int pos = argsDescriptor[namedEntryIndex + 1]; + String arg_name = argsDescriptor[namedEntryIndex]; + var arg_value = _arguments![receiverIndex + pos]; + namedArguments[new internal.Symbol.unvalidated(arg_name)] = arg_value; } - _namedArguments = new Map.unmodifiable(_namedArguments); + _namedArguments = new Map.unmodifiable(namedArguments); } - return _namedArguments; + return _namedArguments!; } bool get isMethod { @@ -200,7 +202,7 @@ class _InvocationMirror implements Invocation { String functionName, List argumentsDescriptor, List arguments, - int type, + int? type, int delayedTypeArgumentsLen) { return new _InvocationMirror(functionName, argumentsDescriptor, arguments, false, type ?? _UNINITIALIZED, delayedTypeArgumentsLen); diff --git a/sdk/lib/_internal/vm/lib/isolate_patch.dart b/sdk/lib/_internal/vm/lib/isolate_patch.dart index c06dc3fe1ad..da2ed6829ba 100644 --- a/sdk/lib/_internal/vm/lib/isolate_patch.dart +++ b/sdk/lib/_internal/vm/lib/isolate_patch.dart @@ -2,8 +2,6 @@ // 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.6 - /// Note: the VM concatenates all patch files into a single patch file. This /// file is the first patch in "dart:isolate" which contains all the imports /// used by patches of that library. We plan to change this when we have a @@ -64,7 +62,7 @@ class RawReceivePort { * event is received. */ @patch - factory RawReceivePort([Function handler]) { + factory RawReceivePort([Function? handler]) { _RawReceivePortImpl result = new _RawReceivePortImpl(); result.handler = handler; return result; @@ -74,8 +72,9 @@ class RawReceivePort { class _ReceivePortImpl extends Stream implements ReceivePort { _ReceivePortImpl() : this.fromRawReceivePort(new RawReceivePort()); - _ReceivePortImpl.fromRawReceivePort(this._rawPort) { - _controller = new StreamController(onCancel: close, sync: true); + _ReceivePortImpl.fromRawReceivePort(this._rawPort) + : _controller = new StreamController(sync: true) { + _controller.onCancel = close; _rawPort.handler = _controller.add; } @@ -83,8 +82,8 @@ class _ReceivePortImpl extends Stream implements ReceivePort { return _rawPort.sendPort; } - StreamSubscription listen(void onData(var message), - {Function onError, void onDone(), bool cancelOnError}) { + StreamSubscription listen(void onData(var message)?, + {Function? onError, void onDone()?, bool? cancelOnError}) { return _controller.stream.listen(onData, onError: onError, onDone: onDone, cancelOnError: cancelOnError); } @@ -95,13 +94,13 @@ class _ReceivePortImpl extends Stream implements ReceivePort { } final RawReceivePort _rawPort; - StreamController _controller; + final StreamController _controller; } typedef void _ImmediateCallback(); /// The callback that has been registered through `scheduleImmediate`. -_ImmediateCallback _pendingImmediateCallback; +_ImmediateCallback? _pendingImmediateCallback; /// The closure that should be used as scheduleImmediateClosure, when the VM /// is responsible for the event loop. @@ -173,7 +172,7 @@ class _RawReceivePortImpl implements RawReceivePort { // Call into the VM to close the VM maintained mappings. _closeInternal() native "RawReceivePortImpl_closeInternal"; - void set handler(Function value) { + void set handler(Function? value) { _handlerMap[this._get_id()] = value; } @@ -221,8 +220,8 @@ class _SendPortImpl implements SendPort { } typedef _NullaryFunction(); -typedef _UnaryFunction(Null args); -typedef _BinaryFunction(Null args, Null message); +typedef _UnaryFunction(Never args); +typedef _BinaryFunction(Never args, Never message); /** * Takes the real entry point as argument and invokes it with the @@ -258,13 +257,13 @@ Function _getStartMainIsolateFunction() { */ @pragma("vm:entry-point", "call") void _startIsolate( - SendPort parentPort, + SendPort? parentPort, Function entryPoint, - List args, - var message, + List? args, + Object? message, bool isSpawnUri, - RawReceivePort controlPort, - List capabilities) { + RawReceivePort? controlPort, + List? capabilities) { // The control port (aka the main isolate port) does not handle any messages. if (controlPort != null) { controlPort.handler = (_) {}; // Nobody home on the control port. @@ -274,7 +273,7 @@ void _startIsolate( // current isolate's control port and capabilities. // // TODO(floitsch): Send an error message if we can't find the entry point. - final readyMessage = List(2); + final readyMessage = List.filled(2, null); readyMessage[0] = controlPort.sendPort; readyMessage[1] = capabilities; @@ -321,12 +320,12 @@ class Isolate { String get debugName => _getDebugName(controlPort); @patch - static Future get packageRoot { + static Future get packageRoot { return Future.value(null); } @patch - static Future get packageConfig { + static Future get packageConfig { var hook = VMLibraryHooks.packageConfigUriFuture; if (hook == null) { throw new UnsupportedError("Isolate.packageConfig"); @@ -335,7 +334,7 @@ class Isolate { } @patch - static Future resolvePackageUri(Uri packageUri) { + static Future resolvePackageUri(Uri packageUri) { var hook = VMLibraryHooks.resolvePackageUriFuture; if (hook == null) { throw new UnsupportedError("Isolate.resolvePackageUri"); @@ -349,11 +348,11 @@ class Isolate { @patch static Future spawn(void entryPoint(T message), T message, - {bool paused: false, - bool errorsAreFatal, - SendPort onExit, - SendPort onError, - String debugName}) async { + {bool paused = false, + bool errorsAreFatal = true, + SendPort? onExit, + SendPort? onError, + String? debugName}) async { // `paused` isn't handled yet. // Check for the type of `entryPoint` on the spawning isolate to make // error-handling easier. @@ -399,16 +398,16 @@ class Isolate { @patch static Future spawnUri(Uri uri, List args, var message, - {bool paused: false, - SendPort onExit, - SendPort onError, - bool errorsAreFatal, - bool checked, - Map environment, - Uri packageRoot, - Uri packageConfig, - bool automaticPackageResolution: false, - String debugName}) async { + {bool paused = false, + SendPort? onExit, + SendPort? onError, + bool errorsAreFatal = true, + bool? checked, + Map? environment, + Uri? packageRoot, + Uri? packageConfig, + bool automaticPackageResolution = false, + String? debugName}) async { if (environment != null) { throw new UnimplementedError("environment"); } @@ -432,7 +431,7 @@ class Isolate { } } // Resolve the uri against the current isolate's root Uri first. - final Uri spawnedUri = _rootUri.resolveUri(uri); + final Uri spawnedUri = _rootUri!.resolveUri(uri); // Inherit this isolate's package resolution setup if not overridden. if (!automaticPackageResolution && packageConfig == null) { @@ -521,13 +520,13 @@ class Isolate { List args, var message, bool paused, - SendPort onExit, - SendPort onError, + SendPort? onExit, + SendPort? onError, bool errorsAreFatal, - bool checked, - List environment, - String packageConfig, - String debugName) native "Isolate_spawnUri"; + bool? checked, + List? environment, + String? packageConfig, + String? debugName) native "Isolate_spawnUri"; static void _sendOOB(port, msg) native "Isolate_sendOOB"; @@ -536,7 +535,9 @@ class Isolate { @patch void _pause(Capability resumeCapability) { - var msg = new List(4) + // _sendOOB expects a fixed length array and hence we create a fixed + // length array and assign values to it instead of using [ ... ]. + var msg = new List.filled(4, null) ..[0] = 0 // Make room for OOB message type. ..[1] = _PAUSE ..[2] = pauseCapability @@ -546,7 +547,7 @@ class Isolate { @patch void resume(Capability resumeCapability) { - var msg = new List(4) + var msg = new List.filled(4, null) ..[0] = 0 // Make room for OOB message type. ..[1] = _RESUME ..[2] = pauseCapability @@ -555,8 +556,8 @@ class Isolate { } @patch - void addOnExitListener(SendPort responsePort, {Object response}) { - var msg = new List(4) + void addOnExitListener(SendPort responsePort, {Object? response}) { + var msg = new List.filled(4, null) ..[0] = 0 // Make room for OOB message type. ..[1] = _ADD_EXIT ..[2] = responsePort @@ -566,7 +567,7 @@ class Isolate { @patch void removeOnExitListener(SendPort responsePort) { - var msg = new List(3) + var msg = new List.filled(3, null) ..[0] = 0 // Make room for OOB message type. ..[1] = _DEL_EXIT ..[2] = responsePort; @@ -575,7 +576,7 @@ class Isolate { @patch void setErrorsFatal(bool errorsAreFatal) { - var msg = new List(4) + var msg = new List.filled(4, null) ..[0] = 0 // Make room for OOB message type. ..[1] = _ERROR_FATAL ..[2] = terminateCapability @@ -585,7 +586,7 @@ class Isolate { @patch void kill({int priority: beforeNextEvent}) { - var msg = new List(4) + var msg = new List.filled(4, null) ..[0] = 0 // Make room for OOB message type. ..[1] = _KILL ..[2] = terminateCapability @@ -594,8 +595,9 @@ class Isolate { } @patch - void ping(SendPort responsePort, {Object response, int priority: immediate}) { - var msg = new List(5) + void ping(SendPort responsePort, + {Object? response, int priority: immediate}) { + var msg = new List.filled(5, null) ..[0] = 0 // Make room for OOM message type. ..[1] = _PING ..[2] = responsePort @@ -606,7 +608,7 @@ class Isolate { @patch void addErrorListener(SendPort port) { - var msg = new List(3) + var msg = new List.filled(3, null) ..[0] = 0 // Make room for OOB message type. ..[1] = _ADD_ERROR ..[2] = port; @@ -615,7 +617,7 @@ class Isolate { @patch void removeErrorListener(SendPort port) { - var msg = new List(3) + var msg = new List.filled(3, null) ..[0] = 0 // Make room for OOB message type. ..[1] = _DEL_ERROR ..[2] = port; @@ -632,7 +634,7 @@ class Isolate { static List _getPortAndCapabilitiesOfCurrentIsolate() native "Isolate_getPortAndCapabilitiesOfCurrentIsolate"; - static Uri _getCurrentRootUri() { + static Uri? _getCurrentRootUri() { try { return Uri.parse(_getCurrentRootUriStr()); } catch (e) { diff --git a/sdk/lib/_internal/vm/lib/lib_prefix.dart b/sdk/lib/_internal/vm/lib/lib_prefix.dart index 5135a26926f..d8e52fdb3e0 100644 --- a/sdk/lib/_internal/vm/lib/lib_prefix.dart +++ b/sdk/lib/_internal/vm/lib/lib_prefix.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "core_patch.dart"; // This type corresponds to the VM-internal class LibraryPrefix. diff --git a/sdk/lib/_internal/vm/lib/map_patch.dart b/sdk/lib/_internal/vm/lib/map_patch.dart index cda2946fe1c..07dbc690b57 100644 --- a/sdk/lib/_internal/vm/lib/map_patch.dart +++ b/sdk/lib/_internal/vm/lib/map_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "core_patch.dart"; @patch diff --git a/sdk/lib/_internal/vm/lib/math_patch.dart b/sdk/lib/_internal/vm/lib/math_patch.dart index 03aa4e0c1a2..b41daad7009 100644 --- a/sdk/lib/_internal/vm/lib/math_patch.dart +++ b/sdk/lib/_internal/vm/lib/math_patch.dart @@ -2,8 +2,6 @@ // 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.6 - /// Note: the VM concatenates all patch files into a single patch file. This /// file is the first patch in "dart:math" which contains all the imports used /// by patches of that library. We plan to change this when we have a shared @@ -29,7 +27,7 @@ T min(T a, T b) { // The following returns -0.0 if either a or b is -0.0, and it // returns NaN if b is NaN. num n = (a + b) * a * b; - return n; + return n as T; } } // Check for NaN and b == -0.0. @@ -53,7 +51,7 @@ T max(T a, T b) { // The following returns 0.0 if either a or b is 0.0, and it // returns NaN if b is NaN. num n = a + b; - return n; + return n as T; } } // Check for NaN. @@ -172,7 +170,7 @@ double _log(double x) native "Math_log"; @patch class Random { @patch - factory Random([int seed]) { + factory Random([int? seed]) { var state = _Random._setupSeed((seed == null) ? _Random._nextSeed() : seed); // Crank a couple of times to distribute the seed bits a bit further. return new _Random._withState(state) diff --git a/sdk/lib/_internal/vm/lib/mirror_reference.dart b/sdk/lib/_internal/vm/lib/mirror_reference.dart index 4fe5ffe7577..0cb1e377661 100644 --- a/sdk/lib/_internal/vm/lib/mirror_reference.dart +++ b/sdk/lib/_internal/vm/lib/mirror_reference.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "mirrors_patch.dart"; @pragma("vm:entry-point") @@ -12,5 +10,5 @@ class _MirrorReference { throw "Unreachable"; } - bool operator ==(other) native "MirrorReference_equals"; + bool operator ==(Object other) native "MirrorReference_equals"; } diff --git a/sdk/lib/_internal/vm/lib/mirrors_impl.dart b/sdk/lib/_internal/vm/lib/mirrors_impl.dart index 8f362068a29..a7f1f136814 100644 --- a/sdk/lib/_internal/vm/lib/mirrors_impl.dart +++ b/sdk/lib/_internal/vm/lib/mirrors_impl.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "mirrors_patch.dart"; var _dirty = false; // Set to true by the VM when more libraries are loaded. @@ -20,12 +18,12 @@ Symbol _s(String name) { return new internal.Symbol.unvalidated(name); } -Symbol _sOpt(String name) { +Symbol? _sOpt(String? name) { if (name == null) return null; return new internal.Symbol.unvalidated(name); } -Symbol _computeQualifiedName(DeclarationMirror owner, Symbol simpleName) { +Symbol _computeQualifiedName(DeclarationMirror? owner, Symbol simpleName) { if (owner == null) return simpleName; return _s('${_n(owner.qualifiedName)}.${_n(simpleName)}'); } @@ -67,12 +65,12 @@ String _makeSignatureString( return buf.toString(); } -SourceLocation _location(reflectee) native "DeclarationMirror_location"; +SourceLocation? _location(reflectee) native "DeclarationMirror_location"; List _metadata(reflectee) native 'DeclarationMirror_metadata'; List _wrapMetadata(List reflectees) { - var mirrors = new List(); + var mirrors = []; for (var reflectee in reflectees) { mirrors.add(reflect(reflectee)); } @@ -101,7 +99,7 @@ class _MirrorSystem extends MirrorSystem { static List _computeLibraries() native "MirrorSystem_libraries"; - IsolateMirror _isolate; + IsolateMirror? _isolate; IsolateMirror get isolate { var i = _isolate; if (i != null) return i; @@ -147,7 +145,7 @@ class _IsolateMirror extends Mirror implements IsolateMirror { return result; } - static LibraryMirror _loadUri(String uri) native "IsolateMirror_loadUri"; + static LibraryMirror? _loadUri(String uri) native "IsolateMirror_loadUri"; } class _SyntheticAccessor implements MethodMirror { @@ -186,9 +184,9 @@ class _SyntheticAccessor implements MethodMirror { [new _SyntheticSetterParameter(this, this._target)]); } - SourceLocation get location => null; + SourceLocation? get location => null; List get metadata => const []; - String get source => null; + String? get source => null; } class _SyntheticSetterParameter implements ParameterMirror { @@ -210,8 +208,8 @@ class _SyntheticSetterParameter implements ParameterMirror { bool get isPrivate => false; bool get isExtensionMember => false; bool get hasDefaultValue => false; - InstanceMirror get defaultValue => null; - SourceLocation get location => null; + InstanceMirror? get defaultValue => null; + SourceLocation? get location => null; List get metadata => const []; } @@ -224,14 +222,14 @@ abstract class _ObjectMirror extends Mirror implements ObjectMirror { _ObjectMirror._(this._reflectee); - InstanceMirror invoke(Symbol memberName, List positionalArguments, - [Map namedArguments]) { + InstanceMirror invoke(Symbol memberName, List positionalArguments, + [Map namedArguments = const {}]) { int numPositionalArguments = positionalArguments.length; - int numNamedArguments = namedArguments != null ? namedArguments.length : 0; + int numNamedArguments = namedArguments.length; int numArguments = numPositionalArguments + numNamedArguments; - List arguments = new List(numArguments); + List arguments = new List.filled(numArguments, null); arguments.setRange(0, numPositionalArguments, positionalArguments); - List names = new List(numNamedArguments); + List names = new List.filled(numNamedArguments, null); int argumentIndex = numPositionalArguments; int nameIndex = 0; if (numNamedArguments > 0) { @@ -277,7 +275,7 @@ abstract class _ObjectMirror extends Mirror implements ObjectMirror { class _InstanceMirror extends _ObjectMirror implements InstanceMirror { _InstanceMirror._(reflectee) : super._(reflectee); - ClassMirror _type; + ClassMirror? _type; ClassMirror get type { var t = _type; if (t != null) return t; @@ -294,7 +292,7 @@ class _InstanceMirror extends _ObjectMirror implements InstanceMirror { String toString() => 'InstanceMirror on ${Error.safeToString(_reflectee)}'; - bool operator ==(other) { + bool operator ==(Object other) { return other is _InstanceMirror && identical(_reflectee, other._reflectee); } @@ -314,15 +312,15 @@ class _InstanceMirror extends _ObjectMirror implements InstanceMirror { } // Override to include the receiver in the arguments. - InstanceMirror invoke(Symbol memberName, List positionalArguments, - [Map namedArguments]) { + InstanceMirror invoke(Symbol memberName, List positionalArguments, + [Map namedArguments = const {}]) { int numPositionalArguments = positionalArguments.length + 1; // Receiver. - int numNamedArguments = namedArguments != null ? namedArguments.length : 0; + int numNamedArguments = namedArguments.length; int numArguments = numPositionalArguments + numNamedArguments; - List arguments = new List(numArguments); + List arguments = new List.filled(numArguments, null); arguments[0] = _reflectee; // Receiver. arguments.setRange(1, numPositionalArguments, positionalArguments); - List names = new List(numNamedArguments); + List names = new List.filled(numNamedArguments, null); int argumentIndex = numPositionalArguments; int nameIndex = 0; if (numNamedArguments > 0) { @@ -349,15 +347,15 @@ class _InstanceMirror extends _ObjectMirror implements InstanceMirror { class _ClosureMirror extends _InstanceMirror implements ClosureMirror { _ClosureMirror._(reflectee) : super._(reflectee); - MethodMirror _function; + MethodMirror? _function; MethodMirror get function { var f = _function; if (f != null) return f; return _function = _computeFunction(reflectee); } - InstanceMirror apply(List positionalArguments, - [Map namedArguments]) { + InstanceMirror apply(List positionalArguments, + [Map namedArguments = const {}]) { return this.invoke(#call, positionalArguments, namedArguments); } @@ -372,8 +370,8 @@ abstract class _TypeMirror { class _ClassMirror extends _ObjectMirror implements ClassMirror, _TypeMirror { final Type _reflectedType; - Symbol _simpleName; - DeclarationMirror _owner; + Symbol? _simpleName; + DeclarationMirror? _owner; final bool isAbstract; final bool _isGeneric; @@ -389,7 +387,7 @@ class _ClassMirror extends _ObjectMirror implements ClassMirror, _TypeMirror { _ClassMirror._( reflectee, reflectedType, - String simpleName, + String? simpleName, this._owner, this.isAbstract, this._isGeneric, @@ -418,7 +416,7 @@ class _ClassMirror extends _ObjectMirror implements ClassMirror, _TypeMirror { return _simpleName = this._mixinApplicationName; } - Symbol _qualifiedName; + Symbol? _qualifiedName; Symbol get qualifiedName { var n = _qualifiedName; if (n != null) return n; @@ -426,7 +424,7 @@ class _ClassMirror extends _ObjectMirror implements ClassMirror, _TypeMirror { return _qualifiedName = _computeQualifiedName(owner, simpleName); } - DeclarationMirror get owner { + DeclarationMirror? get owner { var o = _owner; if (o != null) return o; @@ -438,14 +436,14 @@ class _ClassMirror extends _ObjectMirror implements ClassMirror, _TypeMirror { bool get isTopLevel => true; - SourceLocation get location { + SourceLocation? get location { return _location(_reflectee); } - _ClassMirror _trueSuperclassField; - _ClassMirror get _trueSuperclass { + _ClassMirror? _trueSuperclassField; + _ClassMirror? get _trueSuperclass { if (_trueSuperclassField == null) { - Type supertype = isOriginalDeclaration + Type? supertype = isOriginalDeclaration ? _supertype(_reflectedType) : _supertypeInstantiated(_reflectedType); if (supertype == null) { @@ -459,7 +457,7 @@ class _ClassMirror extends _ObjectMirror implements ClassMirror, _TypeMirror { return _trueSuperclassField; } - ClassMirror get superclass { + ClassMirror? get superclass { return _trueSuperclass; } @@ -474,7 +472,7 @@ class _ClassMirror extends _ObjectMirror implements ClassMirror, _TypeMirror { if (_isTransformedMixinApplication) { interfaceTypes = interfaceTypes.sublist(0, interfaceTypes.length - 1); } - var interfaceMirrors = new List(); + var interfaceMirrors = []; for (var interfaceType in interfaceTypes) { interfaceMirrors.add(reflectType(interfaceType) as ClassMirror); } @@ -483,7 +481,7 @@ class _ClassMirror extends _ObjectMirror implements ClassMirror, _TypeMirror { } Symbol get _mixinApplicationName { - var mixins = new List(); + var mixins = []; var klass = this; while (_nativeMixin(klass._reflectedType) != null) { mixins.add(klass.mixin); @@ -494,12 +492,12 @@ class _ClassMirror extends _ObjectMirror implements ClassMirror, _TypeMirror { mixins.reversed.map((ClassMirror m) => _n(m.qualifiedName)).join(', ')); } - ClassMirror _mixin; + ClassMirror? _mixin; ClassMirror get mixin { var m = _mixin; if (m != null) return m; - Type mixinType = _nativeMixinInstantiated(_reflectedType, _instantiator); + Type? mixinType = _nativeMixinInstantiated(_reflectedType, _instantiator); if (mixinType == null) { // The reflectee is not a mixin application. return _mixin = this; @@ -567,7 +565,7 @@ class _ClassMirror extends _ObjectMirror implements ClassMirror, _TypeMirror { new UnmodifiableMapView(result); } - Map _declarations; + Map? _declarations; Map get declarations { var d = _declarations; if (d != null) return d; @@ -600,7 +598,7 @@ class _ClassMirror extends _ObjectMirror implements ClassMirror, _TypeMirror { return true; } - List _typeVariables; + List? _typeVariables; List get typeVariables { var v = _typeVariables; if (v != null) return v; @@ -608,7 +606,7 @@ class _ClassMirror extends _ObjectMirror implements ClassMirror, _TypeMirror { if (!_isTransformedMixinApplication && _isAnonymousMixinApplication) { return _typeVariables = const []; } - var result = new List(); + var result = []; List params = _ClassMirror_type_variables(_reflectee); ClassMirror owner = originalDeclaration; @@ -621,7 +619,7 @@ class _ClassMirror extends _ObjectMirror implements ClassMirror, _TypeMirror { new UnmodifiableListView(result); } - List _typeArguments; + List? _typeArguments; List get typeArguments { var a = _typeArguments; if (a != null) return a; @@ -647,17 +645,16 @@ class _ClassMirror extends _ObjectMirror implements ClassMirror, _TypeMirror { String toString() => "ClassMirror on '${MirrorSystem.getName(simpleName)}'"; - InstanceMirror newInstance( - Symbol constructorName, List positionalArguments, - [Map namedArguments]) { + InstanceMirror newInstance(Symbol constructorName, List positionalArguments, + [Map namedArguments = const {}]) { // Native code will add the 1 or 2 implicit arguments depending on whether // we end up invoking a factory or constructor respectively. int numPositionalArguments = positionalArguments.length; - int numNamedArguments = namedArguments != null ? namedArguments.length : 0; + int numNamedArguments = namedArguments.length; int numArguments = numPositionalArguments + numNamedArguments; - List arguments = new List(numArguments); + List arguments = new List.filled(numArguments, null); arguments.setRange(0, numPositionalArguments, positionalArguments); - List names = new List(numNamedArguments); + List names = new List.filled(numNamedArguments, null); int argumentIndex = numPositionalArguments; int nameIndex = 0; if (numNamedArguments > 0) { @@ -675,8 +672,8 @@ class _ClassMirror extends _ObjectMirror implements ClassMirror, _TypeMirror { return _wrapMetadata(_metadata(_reflectee)); } - bool operator ==(other) { - return this.runtimeType == other.runtimeType && + bool operator ==(Object other) { + return other is _ClassMirror && this._reflectee == other._reflectee && this._reflectedType == other._reflectedType && this._isGenericDeclaration == other._isGenericDeclaration; @@ -701,6 +698,7 @@ class _ClassMirror extends _ObjectMirror implements ClassMirror, _TypeMirror { } bool isSubclassOf(ClassMirror other) { + // TODO: Remove these null checks once all code is opted into strong nonnullable mode. if (other == null) { throw new ArgumentError.notNull('other'); } @@ -716,9 +714,9 @@ class _ClassMirror extends _ObjectMirror implements ClassMirror, _TypeMirror { static String _libraryUri(reflectee) native "ClassMirror_libraryUri"; - static Type _supertype(reflectedType) native "ClassMirror_supertype"; + static Type? _supertype(reflectedType) native "ClassMirror_supertype"; - static Type _supertypeInstantiated(reflectedType) + static Type? _supertypeInstantiated(reflectedType) native "ClassMirror_supertype_instantiated"; static List _nativeInterfaces(reflectedType) @@ -727,9 +725,9 @@ class _ClassMirror extends _ObjectMirror implements ClassMirror, _TypeMirror { static List _nativeInterfacesInstantiated(reflectedType) native "ClassMirror_interfaces_instantiated"; - static Type _nativeMixin(reflectedType) native "ClassMirror_mixin"; + static Type? _nativeMixin(reflectedType) native "ClassMirror_mixin"; - static Type _nativeMixinInstantiated(reflectedType, instantiator) + static Type? _nativeMixinInstantiated(reflectedType, instantiator) native "ClassMirror_mixin_instantiated"; static List _computeMembers(owner, reflectee, instantiator) @@ -764,21 +762,21 @@ class _FunctionTypeMirror extends _ClassMirror implements FunctionTypeMirror { bool get _isAnonymousMixinApplication => false; // FunctionTypeMirrors have a simpleName generated from their signature. - Symbol _simpleName; + Symbol? _simpleName; Symbol get simpleName { var n = _simpleName; if (n != null) return n; return _simpleName = _s(_makeSignatureString(returnType, parameters)); } - MethodMirror _callMethod; + MethodMirror? _callMethod; MethodMirror get callMethod { var m = _callMethod; if (m != null) return m; return _callMethod = _FunctionTypeMirror_call_method(_functionReflectee); } - TypeMirror _returnType; + TypeMirror? _returnType; TypeMirror get returnType { var t = _returnType; if (t != null) return t; @@ -786,7 +784,7 @@ class _FunctionTypeMirror extends _ClassMirror implements FunctionTypeMirror { reflectType(_FunctionTypeMirror_return_type(_functionReflectee)); } - List _parameters; + List? _parameters; List get parameters { var p = _parameters; if (p != null) return p; @@ -800,7 +798,7 @@ class _FunctionTypeMirror extends _ClassMirror implements FunctionTypeMirror { List get typeVariables => const []; List get typeArguments => const []; List get metadata => const []; - SourceLocation get location => null; + SourceLocation? get location => null; String toString() => "FunctionTypeMirror on '${_n(simpleName)}'"; @@ -822,7 +820,7 @@ abstract class _DeclarationMirror extends Mirror implements DeclarationMirror { Symbol get simpleName => _simpleName; - Symbol _qualifiedName; + Symbol? _qualifiedName; Symbol get qualifiedName { var n = _qualifiedName; if (n != null) return n; @@ -831,7 +829,7 @@ abstract class _DeclarationMirror extends Mirror implements DeclarationMirror { bool get isPrivate => _n(simpleName).startsWith('_'); - SourceLocation get location { + SourceLocation? get location { return _location(_reflectee); } @@ -839,9 +837,8 @@ abstract class _DeclarationMirror extends Mirror implements DeclarationMirror { return _wrapMetadata(_metadata(_reflectee)); } - bool operator ==(other) { - return this.runtimeType == other.runtimeType && - this._reflectee == other._reflectee; + bool operator ==(Object other) { + return other is _DeclarationMirror && this._reflectee == other._reflectee; } int get hashCode => simpleName.hashCode; @@ -852,7 +849,7 @@ class _TypeVariableMirror extends _DeclarationMirror _TypeVariableMirror._(reflectee, String simpleName, this._owner) : super._(reflectee, _s(simpleName)); - DeclarationMirror _owner; + DeclarationMirror? _owner; DeclarationMirror get owner { var o = _owner; if (o != null) return o; @@ -863,7 +860,7 @@ class _TypeVariableMirror extends _DeclarationMirror bool get isStatic => false; bool get isTopLevel => false; - TypeMirror _upperBound; + TypeMirror? _upperBound; TypeMirror get upperBound { var b = _upperBound; if (b != null) return b; @@ -886,7 +883,7 @@ class _TypeVariableMirror extends _DeclarationMirror String toString() => "TypeVariableMirror on '${_n(simpleName)}'"; - bool operator ==(other) { + bool operator ==(Object other) { return other is TypeVariableMirror && simpleName == other.simpleName && owner == other.owner; @@ -929,15 +926,15 @@ class _TypedefMirror extends _DeclarationMirror bool get isTopLevel => true; - DeclarationMirror _owner; - DeclarationMirror get owner { + DeclarationMirror? _owner; + DeclarationMirror? get owner { var o = _owner; if (o != null) return o; var uri = _ClassMirror._libraryUri(_reflectee); return _owner = currentMirrorSystem().libraries[Uri.parse(uri)]; } - _FunctionTypeMirror _referent; + _FunctionTypeMirror? _referent; FunctionTypeMirror get referent { var r = _referent; if (r != null) return r; @@ -965,12 +962,12 @@ class _TypedefMirror extends _DeclarationMirror } } - List _typeVariables; + List? _typeVariables; List get typeVariables { var v = _typeVariables; if (v != null) return v; - var result = new List(); + var result = []; List params = _ClassMirror._ClassMirror_type_variables(_reflectee); TypedefMirror owner = originalDeclaration; var mirror; @@ -982,7 +979,7 @@ class _TypedefMirror extends _DeclarationMirror new UnmodifiableListView(result); } - List _typeArguments; + List? _typeArguments; List get typeArguments { var a = _typeArguments; if (a != null) return a; @@ -1038,14 +1035,14 @@ class _LibraryMirror extends _ObjectMirror implements LibraryMirror { // The simple name and the qualified name are the same for a library. Symbol get qualifiedName => simpleName; - DeclarationMirror get owner => null; + DeclarationMirror? get owner => null; bool get isPrivate => false; bool get isTopLevel => false; - Type get _instantiator => null; + Type? get _instantiator => null; - Map _declarations; + Map? _declarations; Map get declarations { var d = _declarations; if (d != null) return d; @@ -1060,7 +1057,7 @@ class _LibraryMirror extends _ObjectMirror implements LibraryMirror { new UnmodifiableMapView(decls); } - SourceLocation get location { + SourceLocation? get location { return _location(_reflectee); } @@ -1068,9 +1065,8 @@ class _LibraryMirror extends _ObjectMirror implements LibraryMirror { return _wrapMetadata(_metadata(_reflectee)); } - bool operator ==(other) { - return this.runtimeType == other.runtimeType && - this._reflectee == other._reflectee; + bool operator ==(Object other) { + return other is _LibraryMirror && this._reflectee == other._reflectee; } int get hashCode => simpleName.hashCode; @@ -1105,7 +1101,7 @@ class _LibraryDependencyMirror extends Mirror final LibraryMirror sourceLibrary; var _targetMirrorOrPrefix; final List combinators; - final Symbol prefix; + final Symbol? prefix; final bool isImport; final bool isDeferred; final List metadata; @@ -1125,7 +1121,7 @@ class _LibraryDependencyMirror extends Mirror bool get isExport => !isImport; - LibraryMirror get targetLibrary { + LibraryMirror? get targetLibrary { if (_targetMirrorOrPrefix is _LibraryMirror) { return _targetMirrorOrPrefix; } @@ -1149,7 +1145,7 @@ class _LibraryDependencyMirror extends Mirror static LibraryMirror _tryUpgradePrefix(libraryPrefix) native "LibraryMirror_fromPrefix"; - SourceLocation get location => null; + SourceLocation? get location => null; } class _CombinatorMirror extends Mirror implements CombinatorMirror { @@ -1206,7 +1202,7 @@ class _MethodMirror extends _DeclarationMirror implements MethodMirror { ]; bool get isOperator => _operators.contains(_n(simpleName)); - DeclarationMirror _owner; + DeclarationMirror? _owner; DeclarationMirror get owner { // For nested closures it is possible, that the mirror for the owner has not // been created yet. @@ -1220,7 +1216,7 @@ class _MethodMirror extends _DeclarationMirror implements MethodMirror { bool get isTopLevel => owner is LibraryMirror; - TypeMirror _returnType; + TypeMirror? _returnType; TypeMirror get returnType { var t = _returnType; if (t != null) return t; @@ -1232,7 +1228,7 @@ class _MethodMirror extends _DeclarationMirror implements MethodMirror { } } - List _parameters; + List? _parameters; List get parameters { var p = _parameters; if (p != null) return p; @@ -1242,7 +1238,7 @@ class _MethodMirror extends _DeclarationMirror implements MethodMirror { bool get isRegularMethod => !isGetter && !isSetter && !isConstructor; - Symbol _constructorName; + Symbol? _constructorName; Symbol get constructorName { var n = _constructorName; if (n != null) return n; @@ -1265,7 +1261,7 @@ class _MethodMirror extends _DeclarationMirror implements MethodMirror { } } - String get source => _MethodMirror_source(_reflectee); + String? get source => _MethodMirror_source(_reflectee); void _patchConstructorName(ownerName) { var cn = _n(constructorName); @@ -1287,7 +1283,7 @@ class _MethodMirror extends _DeclarationMirror implements MethodMirror { List _MethodMirror_parameters(reflectee) native "MethodMirror_parameters"; - static String _MethodMirror_source(reflectee) native "MethodMirror_source"; + static String? _MethodMirror_source(reflectee) native "MethodMirror_source"; } class _VariableMirror extends _DeclarationMirror implements VariableMirror { @@ -1303,7 +1299,7 @@ class _VariableMirror extends _DeclarationMirror implements VariableMirror { bool get isTopLevel => owner is LibraryMirror; - Type get _instantiator { + Type? get _instantiator { final o = owner; // Note: need local variable for promotion to happen. if (o is _ClassMirror) { return o._instantiator; @@ -1316,7 +1312,7 @@ class _VariableMirror extends _DeclarationMirror implements VariableMirror { } } - TypeMirror _type; + TypeMirror? _type; TypeMirror get type { var t = _type; if (t != null) return t; @@ -1334,7 +1330,7 @@ class _ParameterMirror extends _VariableMirror implements ParameterMirror { final int _position; final bool isOptional; final bool isNamed; - final List _unmirroredMetadata; + final List? _unmirroredMetadata; _ParameterMirror._( reflectee, @@ -1358,8 +1354,8 @@ class _ParameterMirror extends _VariableMirror implements ParameterMirror { ); Object _defaultValueReflectee; - InstanceMirror _defaultValue; - InstanceMirror get defaultValue { + InstanceMirror? _defaultValue; + InstanceMirror? get defaultValue { if (!isOptional) { return null; } @@ -1371,7 +1367,7 @@ class _ParameterMirror extends _VariableMirror implements ParameterMirror { bool get hasDefaultValue => _defaultValueReflectee != null; - SourceLocation get location { + SourceLocation? get location { throw new UnsupportedError("ParameterMirror.location unimplemented"); } @@ -1381,7 +1377,7 @@ class _ParameterMirror extends _VariableMirror implements ParameterMirror { return _wrapMetadata(m); } - TypeMirror _type; + TypeMirror? _type; TypeMirror get type { var t = _type; if (t != null) return t; @@ -1404,9 +1400,9 @@ class _SpecialTypeMirror extends Mirror bool get isPrivate => false; bool get isTopLevel => true; - DeclarationMirror get owner => null; + DeclarationMirror? get owner => null; - SourceLocation get location => null; + SourceLocation? get location => null; List get metadata => const []; bool get hasReflectedType => simpleName == #dynamic; @@ -1423,7 +1419,7 @@ class _SpecialTypeMirror extends Mirror Symbol get qualifiedName => simpleName; - bool operator ==(other) { + bool operator ==(Object other) { if (other is! _SpecialTypeMirror) { return false; } @@ -1478,7 +1474,7 @@ class _Mirrors { return classMirror; } - static TypeMirror reflectType(Type key, [List typeArguments]) { + static TypeMirror reflectType(Type key, [List? typeArguments]) { if (typeArguments != null) { key = _instantiateType(key, typeArguments); } diff --git a/sdk/lib/_internal/vm/lib/mirrors_patch.dart b/sdk/lib/_internal/vm/lib/mirrors_patch.dart index 6b8edd60da2..a06d5464580 100644 --- a/sdk/lib/_internal/vm/lib/mirrors_patch.dart +++ b/sdk/lib/_internal/vm/lib/mirrors_patch.dart @@ -2,8 +2,6 @@ // 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.6 - /// Note: the VM concatenates all patch files into a single patch file. This /// file is the first patch in "dart:_internal" which contains all the imports /// used by patches of that library. We plan to change this when we have a @@ -52,7 +50,7 @@ ClassMirror reflectClass(Type key) { } @patch -TypeMirror reflectType(Type key, [List typeArguments]) { +TypeMirror reflectType(Type key, [List? typeArguments]) { return _Mirrors.reflectType(key, typeArguments); } @@ -79,7 +77,7 @@ class MirrorSystem { } @patch - static Symbol getSymbol(String name, [LibraryMirror library]) { + static Symbol getSymbol(String name, [LibraryMirror? library]) { if ((library != null && library is! _LibraryMirror) || ((name.length > 0) && (name[0] == '_') && (library == null))) { throw new ArgumentError(library); diff --git a/sdk/lib/_internal/vm/lib/null_patch.dart b/sdk/lib/_internal/vm/lib/null_patch.dart index 3e724f7817f..01bb5aa8829 100644 --- a/sdk/lib/_internal/vm/lib/null_patch.dart +++ b/sdk/lib/_internal/vm/lib/null_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "core_patch.dart"; @patch diff --git a/sdk/lib/_internal/vm/lib/object_patch.dart b/sdk/lib/_internal/vm/lib/object_patch.dart index fe75579c2d6..e862e5cd1a5 100644 --- a/sdk/lib/_internal/vm/lib/object_patch.dart +++ b/sdk/lib/_internal/vm/lib/object_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "core_patch.dart"; @pragma("vm:exact-result-type", "dart:core#_Smi") @@ -17,7 +15,7 @@ class Object { @patch @pragma("vm:exact-result-type", bool) @pragma("vm:prefer-inline") - bool operator ==(other) native "Object_equals"; + bool operator ==(Object other) native "Object_equals"; // Helpers used to implement hashCode. If a hashCode is used, we remember it // in a weak table in the VM (32 bit) or in the header of the object (64 diff --git a/sdk/lib/_internal/vm/lib/print_patch.dart b/sdk/lib/_internal/vm/lib/print_patch.dart index 96ee6b48aa7..f0e7d916dc4 100644 --- a/sdk/lib/_internal/vm/lib/print_patch.dart +++ b/sdk/lib/_internal/vm/lib/print_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "internal_patch.dart"; // A print-closure gets a String that should be printed. In general the diff --git a/sdk/lib/_internal/vm/lib/profiler.dart b/sdk/lib/_internal/vm/lib/profiler.dart index 4a7140f3d0f..745eaa5f175 100644 --- a/sdk/lib/_internal/vm/lib/profiler.dart +++ b/sdk/lib/_internal/vm/lib/profiler.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "developer.dart"; @patch diff --git a/sdk/lib/_internal/vm/lib/regexp_patch.dart b/sdk/lib/_internal/vm/lib/regexp_patch.dart index d4c875e8a64..7a575836a37 100644 --- a/sdk/lib/_internal/vm/lib/regexp_patch.dart +++ b/sdk/lib/_internal/vm/lib/regexp_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "core_patch.dart"; @patch @@ -16,7 +14,7 @@ class RegExp { bool dotAll: false}) { _RegExpHashKey key = new _RegExpHashKey(source, multiLine, caseSensitive, unicode, dotAll); - _RegExpHashValue value = _cache[key]; + _RegExpHashValue? value = _cache[key]; if (value == null) { if (_cache.length > _MAX_CACHE_SIZE) { @@ -163,7 +161,7 @@ class _RegExpMatch implements RegExpMatch { return _match[(groupIdx * _MATCH_PAIR) + 1]; } - String group(int groupIdx) { + String? group(int groupIdx) { if (groupIdx < 0 || groupIdx > _regexp._groupCount) { throw new RangeError.value(groupIdx); } @@ -176,12 +174,12 @@ class _RegExpMatch implements RegExpMatch { return input._substringUnchecked(startIndex, endIndex); } - String operator [](int groupIdx) { + String? operator [](int groupIdx) { return this.group(groupIdx); } - List groups(List groupsSpec) { - var groupsList = new List(groupsSpec.length); + List groups(List groupsSpec) { + var groupsList = new List.filled(groupsSpec.length, null); for (int i = 0; i < groupsSpec.length; i++) { groupsList[i] = group(groupsSpec[i]); } @@ -192,7 +190,7 @@ class _RegExpMatch implements RegExpMatch { Pattern get pattern => _regexp; - String namedGroup(String name) { + String? namedGroup(String name) { var idx = _regexp._groupNameIndex(name); if (idx < 0) { throw ArgumentError("Not a capture group name: ${name}"); @@ -218,9 +216,10 @@ class _RegExp implements RegExp { bool unicode: false, bool dotAll: false}) native "RegExp_factory"; - RegExpMatch firstMatch(String input) { + RegExpMatch? firstMatch(String input) { + // TODO: Remove these null checks once all code is opted into strong nonnullable mode. if (input == null) throw new ArgumentError.notNull('input'); - List match = _ExecuteMatch(input, 0); + final match = _ExecuteMatch(input, 0); if (match == null) { return null; } @@ -228,7 +227,8 @@ class _RegExp implements RegExp { } Iterable allMatches(String string, [int start = 0]) { - if (string == null) throw new ArgumentError.notNull('input'); + // TODO: Remove these null checks once all code is opted into strong nonnullable mode. + if (string == null) throw new ArgumentError.notNull('string'); if (start == null) throw new ArgumentError.notNull('start'); if (0 > start || start > string.length) { throw new RangeError.range(start, 0, string.length); @@ -236,26 +236,29 @@ class _RegExp implements RegExp { return new _AllMatchesIterable(this, string, start); } - RegExpMatch matchAsPrefix(String string, [int start = 0]) { + RegExpMatch? matchAsPrefix(String string, [int start = 0]) { + // TODO: Remove these null checks once all code is opted into strong nonnullable mode. if (string == null) throw new ArgumentError.notNull('string'); if (start == null) throw new ArgumentError.notNull('start'); if (start < 0 || start > string.length) { throw new RangeError.range(start, 0, string.length); } - List list = _ExecuteMatchSticky(string, start); + final list = _ExecuteMatchSticky(string, start); if (list == null) return null; return new _RegExpMatch._(this, string, list); } bool hasMatch(String input) { + // TODO: Remove these null checks once all code is opted into strong nonnullable mode. if (input == null) throw new ArgumentError.notNull('input'); - List match = _ExecuteMatch(input, 0); + List? match = _ExecuteMatch(input, 0); return (match == null) ? false : true; } - String stringMatch(String input) { + String? stringMatch(String input) { + // TODO: Remove these null checks once all code is opted into strong nonnullable mode. if (input == null) throw new ArgumentError.notNull('input'); - List match = _ExecuteMatch(input, 0); + List? match = _ExecuteMatch(input, 0); if (match == null) { return null; } @@ -281,7 +284,7 @@ class _RegExp implements RegExp { /// [String] is the name of a capture group and the following /// [int] is that capture group's index. /// Returns `null` if there are no group names. - List get _groupNameList native "RegExp_getGroupNameMap"; + List? get _groupNameList native "RegExp_getGroupNameMap"; Iterable get _groupNames sync* { final nameList = _groupNameList; @@ -347,9 +350,10 @@ class _RegExp implements RegExp { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ]; - List _ExecuteMatch(String str, int start_index) native "RegExp_ExecuteMatch"; + List? _ExecuteMatch(String str, int start_index) + native "RegExp_ExecuteMatch"; - List _ExecuteMatchSticky(String str, int start_index) + List? _ExecuteMatchSticky(String str, int start_index) native "RegExp_ExecuteMatchSticky"; } @@ -367,12 +371,12 @@ class _AllMatchesIterable extends IterableBase { class _AllMatchesIterator implements Iterator { final String _str; int _nextIndex; - _RegExp _re; - RegExpMatch _current; + _RegExp? _re; + RegExpMatch? _current; _AllMatchesIterator(this._re, this._str, this._nextIndex); - RegExpMatch get current => _current; + RegExpMatch get current => _current!; static bool _isLeadSurrogate(int c) { return c >= 0xd800 && c <= 0xdbff; @@ -383,17 +387,19 @@ class _AllMatchesIterator implements Iterator { } bool moveNext() { - if (_re == null) return false; // Cleared after a failed match. + final re = _re; + if (re == null) return false; // Cleared after a failed match. if (_nextIndex <= _str.length) { - var match = _re._ExecuteMatch(_str, _nextIndex); + final match = re._ExecuteMatch(_str, _nextIndex); if (match != null) { - _current = new _RegExpMatch._(_re, _str, match); - _nextIndex = _current.end; - if (_nextIndex == _current.start) { + var current = new _RegExpMatch._(re, _str, match); + _current = current; + _nextIndex = current.end; + if (_nextIndex == current.start) { // Zero-width match. Advance by one more, unless the regexp // is in unicode mode and it would put us within a surrogate // pair. In that case, advance past the code point as a whole. - if (_re.isUnicode && + if (re.isUnicode && _nextIndex + 1 < _str.length && _isLeadSurrogate(_str.codeUnitAt(_nextIndex)) && _isTrailSurrogate(_str.codeUnitAt(_nextIndex + 1))) { diff --git a/sdk/lib/_internal/vm/lib/schedule_microtask_patch.dart b/sdk/lib/_internal/vm/lib/schedule_microtask_patch.dart index b1cfc525457..3abbcb593f9 100644 --- a/sdk/lib/_internal/vm/lib/schedule_microtask_patch.dart +++ b/sdk/lib/_internal/vm/lib/schedule_microtask_patch.dart @@ -2,25 +2,24 @@ // 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.6 - // part of "async_patch.dart"; @patch class _AsyncRun { @patch static void _scheduleImmediate(void callback()) { - if (_ScheduleImmediate._closure == null) { + final closure = _ScheduleImmediate._closure; + if (closure == null) { throw new UnsupportedError("Microtasks are not supported"); } - _ScheduleImmediate._closure(callback); + closure(callback); } } typedef void _ScheduleImmediateClosure(void callback()); class _ScheduleImmediate { - static _ScheduleImmediateClosure _closure; + static _ScheduleImmediateClosure? _closure; } @pragma("vm:entry-point", "call") diff --git a/sdk/lib/_internal/vm/lib/stacktrace.dart b/sdk/lib/_internal/vm/lib/stacktrace.dart index 94464a53c7f..719d55a8162 100644 --- a/sdk/lib/_internal/vm/lib/stacktrace.dart +++ b/sdk/lib/_internal/vm/lib/stacktrace.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "core_patch.dart"; /// VM internal StackTrace implementation. diff --git a/sdk/lib/_internal/vm/lib/stopwatch_patch.dart b/sdk/lib/_internal/vm/lib/stopwatch_patch.dart index baf57aa4b3c..df29ecaf7cd 100644 --- a/sdk/lib/_internal/vm/lib/stopwatch_patch.dart +++ b/sdk/lib/_internal/vm/lib/stopwatch_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "core_patch.dart"; @patch @@ -11,11 +9,7 @@ class Stopwatch { static const _maxInt = 0x7FFFFFFFFFFFFFFF; @patch - static void _initTicker() { - if (_frequency == null) { - _frequency = _computeFrequency(); - } - } + static int _initTicker() => _computeFrequency(); // Returns the current clock tick. @patch @@ -37,7 +31,7 @@ class Stopwatch { } // Multiplication would have overflowed. int ticksPerSecond = ticks ~/ _frequency; - int remainingTicks = ticks.remainder(_frequency); + int remainingTicks = unsafeCast(ticks.remainder(_frequency)); return ticksPerSecond * 1000000 + (remainingTicks * 1000000) ~/ _frequency; } @@ -52,7 +46,7 @@ class Stopwatch { } // Multiplication would have overflowed. int ticksPerSecond = ticks ~/ _frequency; - int remainingTicks = ticks.remainder(_frequency); + int remainingTicks = unsafeCast(ticks.remainder(_frequency)); return ticksPerSecond * 1000 + (remainingTicks * 1000) ~/ _frequency; } } diff --git a/sdk/lib/_internal/vm/lib/string_buffer_patch.dart b/sdk/lib/_internal/vm/lib/string_buffer_patch.dart index d2ecf80bfad..0a1b06d8046 100644 --- a/sdk/lib/_internal/vm/lib/string_buffer_patch.dart +++ b/sdk/lib/_internal/vm/lib/string_buffer_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "core_patch.dart"; @patch @@ -16,7 +14,7 @@ class StringBuffer { * When strings are written to the string buffer, we add them to a * list of string parts. */ - List _parts; + List? _parts; /** * Total number of code units in the string parts. Does not include @@ -39,7 +37,7 @@ class StringBuffer { * used when writing short strings or individual char codes to the * buffer. The buffer is allocated on demand. */ - Uint16List _buffer; + Uint16List? _buffer; int _bufferPosition = 0; /** @@ -62,8 +60,8 @@ class StringBuffer { int get length => _partsCodeUnits + _bufferPosition; @patch - void write(Object obj) { - String str = '$obj'; + void write(Object? obj) { + String str = obj.toString(); if (str.isEmpty) return; _consumeBuffer(); _addPart(str); @@ -76,7 +74,8 @@ class StringBuffer { throw new RangeError.range(charCode, 0, 0x10FFFF); } _ensureCapacity(1); - _buffer[_bufferPosition++] = charCode; + final localBuffer = _buffer!; + localBuffer[_bufferPosition++] = charCode; _bufferCodeUnitMagnitude |= charCode; } else { if (charCode > 0x10FFFF) { @@ -84,8 +83,9 @@ class StringBuffer { } _ensureCapacity(2); int bits = charCode - 0x10000; - _buffer[_bufferPosition++] = 0xD800 | (bits >> 10); - _buffer[_bufferPosition++] = 0xDC00 | (bits & 0x3FF); + final localBuffer = _buffer!; + localBuffer[_bufferPosition++] = 0xD800 | (bits >> 10); + localBuffer[_bufferPosition++] = 0xDC00 | (bits & 0x3FF); _bufferCodeUnitMagnitude |= 0xFFFF; } } @@ -108,7 +108,7 @@ class StringBuffer { } @patch - void writeln([Object obj = ""]) { + void writeln([Object? obj = ""]) { write(obj); write("\n"); } @@ -124,16 +124,18 @@ class StringBuffer { @patch String toString() { _consumeBuffer(); - return (_partsCodeUnits == 0) + final localParts = _parts; + return (_partsCodeUnits == 0 || localParts == null) ? "" - : _StringBase._concatRange(_parts, 0, _parts.length); + : _StringBase._concatRange(localParts, 0, localParts.length); } /** Ensures that the buffer has enough capacity to add n code units. */ void _ensureCapacity(int n) { - if (_buffer == null) { + final localBuffer = _buffer; + if (localBuffer == null) { _buffer = new Uint16List(_BUFFER_SIZE); - } else if (_bufferPosition + n > _buffer.length) { + } else if (_bufferPosition + n > localBuffer.length) { _consumeBuffer(); } } @@ -146,7 +148,7 @@ class StringBuffer { void _consumeBuffer() { if (_bufferPosition == 0) return; bool isLatin1 = _bufferCodeUnitMagnitude <= 0xFF; - String str = _create(_buffer, _bufferPosition, isLatin1); + String str = _create(_buffer!, _bufferPosition, isLatin1); _bufferPosition = _bufferCodeUnitMagnitude = 0; _addPart(str); } @@ -156,16 +158,17 @@ class StringBuffer { * many code units are contained in the parts. */ void _addPart(String str) { + final localParts = _parts; int length = str.length; _partsCodeUnits += length; _partsCodeUnitsSinceCompaction += length; - if (_parts == null) { + if (localParts == null) { // Empirically this is a good capacity to minimize total bytes allocated. _parts = new _GrowableList.withCapacity(10)..add(str); } else { - _parts.add(str); - int partsSinceCompaction = _parts.length - _partsCompactionIndex; + localParts.add(str); + int partsSinceCompaction = localParts.length - _partsCompactionIndex; if (partsSinceCompaction == _PARTS_TO_COMPACT) { _compact(); } @@ -177,17 +180,18 @@ class StringBuffer { * lot of memory by turning them all into a single part. */ void _compact() { + final localParts = _parts!; if (_partsCodeUnitsSinceCompaction < _PARTS_TO_COMPACT_SIZE_LIMIT) { String compacted = _StringBase._concatRange( - _parts, + localParts, _partsCompactionIndex, // Start _partsCompactionIndex + _PARTS_TO_COMPACT // End ); - _parts.length = _parts.length - _PARTS_TO_COMPACT; - _parts.add(compacted); + localParts.length = localParts.length - _PARTS_TO_COMPACT; + localParts.add(compacted); } _partsCodeUnitsSinceCompaction = 0; - _partsCompactionIndex = _parts.length; + _partsCompactionIndex = localParts.length; } /** diff --git a/sdk/lib/_internal/vm/lib/string_patch.dart b/sdk/lib/_internal/vm/lib/string_patch.dart index 028bb6bb0f1..55fc053fbe3 100644 --- a/sdk/lib/_internal/vm/lib/string_patch.dart +++ b/sdk/lib/_internal/vm/lib/string_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "core_patch.dart"; const int _maxAscii = 0x7f; @@ -15,7 +13,8 @@ const int _maxUnicode = 0x10ffff; class String { @patch factory String.fromCharCodes(Iterable charCodes, - [int start = 0, int end]) { + [int start = 0, int? end]) { + // TODO: Remove these null checks once all code is opted into strong nonnullable mode. if (charCodes == null) throw new ArgumentError.notNull("charCodes"); if (start == null) throw new ArgumentError.notNull("start"); return _StringBase.createFromCharCodes(charCodes, start, end, null); @@ -119,39 +118,43 @@ abstract class _StringBase implements String { * It's `null` if unknown. */ static String createFromCharCodes( - Iterable charCodes, int start, int end, int limit) { - if (start == null) throw new ArgumentError.notNull("start"); - if (charCodes == null) throw new ArgumentError(charCodes); + Iterable charCodes, int start, int? end, int? limit) { // TODO(srdjan): Also skip copying of wide typed arrays. final ccid = ClassID.getID(charCodes); if ((ccid != ClassID.cidArray) && (ccid != ClassID.cidGrowableObjectArray) && (ccid != ClassID.cidImmutableArray)) { if (charCodes is Uint8List) { - end = RangeError.checkValidRange(start, end, charCodes.length); - return _createOneByteString(charCodes, start, end - start); + final actualEnd = + RangeError.checkValidRange(start, end, charCodes.length); + return _createOneByteString(charCodes, start, actualEnd - start); } else if (charCodes is! Uint16List) { return _createStringFromIterable(charCodes, start, end); } } - int codeCount = charCodes.length; - end = RangeError.checkValidRange(start, end, codeCount); - final len = end - start; + final int codeCount = charCodes.length; + final actualEnd = RangeError.checkValidRange(start, end, codeCount); + final len = actualEnd - start; if (len == 0) return ""; - limit ??= _scanCodeUnits(charCodes, start, end); - if (limit < 0) { - throw new ArgumentError(charCodes); + + final typedCharCodes = unsafeCast>(charCodes); + + final int actualLimit = + limit ?? _scanCodeUnits(typedCharCodes, start, actualEnd); + if (actualLimit < 0) { + throw new ArgumentError(typedCharCodes); } - if (limit <= _maxLatin1) { - return _createOneByteString(charCodes, start, len); + if (actualLimit <= _maxLatin1) { + return _createOneByteString(typedCharCodes, start, len); } - if (limit <= _maxUtf16) { - return _TwoByteString._allocateFromTwoByteList(charCodes, start, end); + if (actualLimit <= _maxUtf16) { + return _TwoByteString._allocateFromTwoByteList( + typedCharCodes, start, actualEnd); } // TODO(lrn): Consider passing limit to _createFromCodePoints, because // the function is currently fully generic and doesn't know that its // charCodes are not all Latin-1 or Utf-16. - return _createFromCodePoints(charCodes, start, end); + return _createFromCodePoints(typedCharCodes, start, actualEnd); } static int _scanCodeUnits(List charCodes, int start, int end) { @@ -165,13 +168,14 @@ abstract class _StringBase implements String { } static String _createStringFromIterable( - Iterable charCodes, int start, int end) { + Iterable charCodes, int start, int? end) { // Treat charCodes as Iterable. if (charCodes is EfficientLengthIterable) { int length = charCodes.length; - end = RangeError.checkValidRange(start, end, length); - final charCodeList = - new List.from(charCodes.take(end).skip(start), growable: false); + final endVal = RangeError.checkValidRange(start, end, length); + final charCodeList = new List.from( + charCodes.take(endVal).skip(start), + growable: false); return createFromCharCodes(charCodeList, 0, charCodeList.length, null); } // Don't know length of iterable, so iterate and see if all the values @@ -185,7 +189,8 @@ abstract class _StringBase implements String { } List charCodeList; int bits = 0; // Bitwise-or of all char codes in list. - if (end == null) { + final endVal = end; + if (endVal == null) { var list = []; while (it.moveNext()) { int code = it.current; @@ -194,13 +199,13 @@ abstract class _StringBase implements String { } charCodeList = makeListFixedLength(list); } else { - if (end < start) { - throw new RangeError.range(end, start, charCodes.length); + if (endVal < start) { + throw new RangeError.range(endVal, start, charCodes.length); } - int len = end - start; + int len = endVal - start; charCodeList = new List.generate(len, (int i) { if (!it.moveNext()) { - throw new RangeError.range(end, start, start + i); + throw new RangeError.range(endVal, start, start + i); } int code = it.current; bits |= code; @@ -353,7 +358,7 @@ abstract class _StringBase implements String { return -1; } - int lastIndexOf(Pattern pattern, [int start = null]) { + int lastIndexOf(Pattern pattern, [int? start]) { if (start == null) { start = this.length; } else if (start < 0 || start > this.length) { @@ -378,7 +383,7 @@ abstract class _StringBase implements String { return -1; } - String substring(int startIndex, [int endIndex]) { + String substring(int startIndex, [int? endIndex]) { endIndex ??= this.length; if ((startIndex < 0) || (startIndex > this.length)) { @@ -572,6 +577,7 @@ abstract class _StringBase implements String { String replaceFirst(Pattern pattern, String replacement, [int startIndex = 0]) { + // TODO: Remove these null checks once all code is opted into strong nonnullable mode. if (pattern == null) { throw new ArgumentError.notNull("pattern"); } @@ -590,25 +596,25 @@ abstract class _StringBase implements String { return replaceRange(match.start, match.end, replacement); } - String replaceRange(int start, int end, String replacement) { - int length = this.length; - end = RangeError.checkValidRange(start, end, length); + String replaceRange(int start, int? end, String replacement) { + final length = this.length; + final localEnd = RangeError.checkValidRange(start, end, length); bool replacementIsOneByte = replacement._isOneByte; - if (start == 0 && end == length) return replacement; + if (start == 0 && localEnd == length) return replacement; int replacementLength = replacement.length; - int totalLength = start + (length - end) + replacementLength; + int totalLength = start + (length - localEnd) + replacementLength; if (replacementIsOneByte && this._isOneByte) { var result = _OneByteString._allocate(totalLength); int index = 0; index = result._setRange(index, this, 0, start); index = result._setRange(start, replacement, 0, replacementLength); - result._setRange(index, this, end, length); + result._setRange(index, this, localEnd, length); return result; } List slices = []; _addReplaceSlice(slices, 0, start); if (replacement.length > 0) slices.add(replacement); - _addReplaceSlice(slices, end, length); + _addReplaceSlice(slices, localEnd, length); return _joinReplaceAllResult( this, slices, totalLength, replacementIsOneByte); } @@ -760,7 +766,7 @@ abstract class _StringBase implements String { return replaceRange(match.start, match.end, replacement); } - static String _matchString(Match match) => match[0]; + static String _matchString(Match match) => match[0]!; static String _stringIdentity(String string) => string; String _splitMapJoinEmptyString( @@ -793,7 +799,7 @@ abstract class _StringBase implements String { } String splitMapJoin(Pattern pattern, - {String onMatch(Match match), String onNonMatch(String nonMatch)}) { + {String onMatch(Match match)?, String onNonMatch(String nonMatch)?}) { if (pattern == null) { throw new ArgumentError.notNull("pattern"); } @@ -870,7 +876,7 @@ abstract class _StringBase implements String { return new _StringAllMatchesIterable(string, this, start); } - Match matchAsPrefix(String string, [int start = 0]) { + Match? matchAsPrefix(String string, [int start = 0]) { if (start < 0 || start > string.length) { throw new RangeError.range(start, 0, string.length); } @@ -895,7 +901,7 @@ abstract class _StringBase implements String { // A matched empty string input returns the empty list. return []; } - List result = new List(); + List result = []; int startIndex = 0; int previousIndex = 0; // 'pattern' may not be implemented correctly and therefore we cannot @@ -976,7 +982,7 @@ class _OneByteString extends _StringBase { // check without performance penalty. Front-end would then promote // pattern variable to _OneByteString. if (ClassID.getID(pattern) == ClassID.cidOneByteString) { - final String patternAsString = pattern; + final String patternAsString = unsafeCast(pattern); if (patternAsString.length == 1) { return _splitWithCharCode(patternAsString.codeUnitAt(0)); } @@ -1009,7 +1015,7 @@ class _OneByteString extends _StringBase { if ((pCid == ClassID.cidOneByteString) || (pCid == ClassID.cidTwoByteString) || (pCid == ClassID.cidExternalOneByteString)) { - final String patternAsString = pattern; + final String patternAsString = unsafeCast(pattern); final len = this.length; if ((patternAsString.length == 1) && (start >= 0) && (start < len)) { final patternCu0 = patternAsString.codeUnitAt(0); @@ -1032,7 +1038,7 @@ class _OneByteString extends _StringBase { if ((pCid == ClassID.cidOneByteString) || (pCid == ClassID.cidTwoByteString) || (pCid == ClassID.cidExternalOneByteString)) { - final String patternAsString = pattern; + final String patternAsString = unsafeCast(pattern); final len = this.length; if ((patternAsString.length == 1) && (start >= 0) && (start < len)) { final patternCu0 = patternAsString.codeUnitAt(0); @@ -1345,7 +1351,7 @@ class _StringMatch implements Match { } List groups(List groups) { - List result = new List(); + List result = []; for (int g in groups) { result.add(group(g)); } @@ -1380,7 +1386,7 @@ class _StringAllMatchesIterator implements Iterator { final String _input; final String _pattern; int _index; - Match _current; + Match? _current; _StringAllMatchesIterator(this._input, this._pattern, this._index); @@ -1403,5 +1409,8 @@ class _StringAllMatchesIterator implements Iterator { return true; } - Match get current => _current; + Match get current { + final cur = _current; + return (cur != null) ? cur : cur as Match; + } } diff --git a/sdk/lib/_internal/vm/lib/symbol_patch.dart b/sdk/lib/_internal/vm/lib/symbol_patch.dart index 338b3395170..06eb58833a8 100644 --- a/sdk/lib/_internal/vm/lib/symbol_patch.dart +++ b/sdk/lib/_internal/vm/lib/symbol_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "internal_patch.dart"; @patch diff --git a/sdk/lib/_internal/vm/lib/timeline.dart b/sdk/lib/_internal/vm/lib/timeline.dart index 1fb51b888cf..5e8066b8c04 100644 --- a/sdk/lib/_internal/vm/lib/timeline.dart +++ b/sdk/lib/_internal/vm/lib/timeline.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "developer.dart"; @patch diff --git a/sdk/lib/_internal/vm/lib/timer_impl.dart b/sdk/lib/_internal/vm/lib/timer_impl.dart index bc515f38f9b..db626c2a39d 100644 --- a/sdk/lib/_internal/vm/lib/timer_impl.dart +++ b/sdk/lib/_internal/vm/lib/timer_impl.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "isolate_patch.dart"; // Timer heap implemented as a array-based binary heap[0]. @@ -45,7 +43,7 @@ class _TimerHeap { void remove(_Timer timer) { _used--; if (isEmpty) { - _list[0] = null; + _list[0] = _Timer._sentinelTimer; timer._indexOrNext = null; return; } @@ -59,7 +57,7 @@ class _TimerHeap { _bubbleDown(last); } } - _list[_used] = null; + _list[_used] = _Timer._sentinelTimer; timer._indexOrNext = null; } @@ -119,8 +117,9 @@ class _Timer implements Timer { // Cancels the timer in the event handler. static const _NO_TIMER = -1; - // A sentinel timer. - static _Timer _sentinelTimer = _Timer._sentinel(); + // A generic null timer object that is used to populate unused slots + // in TimerHeap. + static final _sentinelTimer = _Timer._sentinel(); // We distinguish what kind of message arrived based on the value being sent. static const _ZERO_EVENT = 1; @@ -129,7 +128,7 @@ class _Timer implements Timer { // Timers are ordered by wakeup time. Timers with a timeout value of > 0 do // end up on the TimerHeap. Timers with a timeout of 0 are queued in a list. static final _heap = new _TimerHeap(); - static _Timer _firstZeroTimer; + static _Timer? _firstZeroTimer; static _Timer _lastZeroTimer = _sentinelTimer; // We use an id to be able to sort timers with the same expiration time. @@ -137,13 +136,13 @@ class _Timer implements Timer { static const _ID_MASK = 0x1fffffff; static int _idCount = 0; - static RawReceivePort _receivePort; - static SendPort _sendPort; + static RawReceivePort? _receivePort; + static SendPort? _sendPort; static int _scheduledWakeupTime = 0; static bool _handlingCallbacks = false; - Function _callback; // Closure to call when timer fires. null if canceled. + Function? _callback; // Closure to call when timer fires. null if canceled. int _wakeupTime; // Expiration time. final int _milliSeconds; // Duration specified at creation. final bool _repeating; // Indicates periodic timers. @@ -274,13 +273,13 @@ class _Timer implements Timer { // Handle the notification of a zero timer. Make sure to also execute non-zero // timers with a lower expiration time. static List _queueFromZeroEvent() { - var pendingTimers = new List(); - _Timer ftimer = _firstZeroTimer; - if (ftimer != null) { + var pendingTimers = []; + final firstTimer = _firstZeroTimer; + if (firstTimer != null) { // Collect pending timers from the timer heap that have an expiration prior // to the currently notified zero timer. var timer; - while (!_heap.isEmpty && (_heap.first._compareTo(ftimer) < 0)) { + while (!_heap.isEmpty && (_heap.first._compareTo(firstTimer) < 0)) { timer = _heap.removeFirst(); pendingTimers.add(timer); } @@ -325,9 +324,9 @@ class _Timer implements Timer { } static List _queueFromTimeoutEvent() { - var pendingTimers = new List(); - _Timer ftimer = _firstZeroTimer; - if (ftimer != null) { + var pendingTimers = []; + final firstTimer = _firstZeroTimer; + if (firstTimer != null) { // Collect pending timers from the timer heap that have an expiration // prior to the next zero timer. // By definition the first zero timer has been scheduled before the @@ -335,7 +334,7 @@ class _Timer implements Timer { // timer are expired. The first zero timer will be dispatched when its // corresponding message is delivered. var timer; - while (!_heap.isEmpty && (_heap.first._compareTo(ftimer) < 0)) { + while (!_heap.isEmpty && (_heap.first._compareTo(firstTimer) < 0)) { timer = _heap.removeFirst(); pendingTimers.add(timer); } @@ -456,21 +455,19 @@ class _Timer implements Timer { static SendPort _createTimerHandler() { assert(_receivePort == null); assert(_sendPort == null); - RawReceivePort port = new RawReceivePort(_handleMessage); + final port = new RawReceivePort(_handleMessage); + final sendPort = port.sendPort; _receivePort = port; - _sendPort = port.sendPort; + _sendPort = sendPort; _scheduledWakeupTime = 0; - return port.sendPort; + return sendPort; } static void _shutdownTimerHandler() { - var port = _receivePort; - if (port != null) { - port.close(); - _receivePort = null; - } _sendPort = null; _scheduledWakeupTime = 0; + _receivePort!.close(); + _receivePort = null; } // The Timer factory registered with the dart:async library by the embedder. diff --git a/sdk/lib/_internal/vm/lib/timer_patch.dart b/sdk/lib/_internal/vm/lib/timer_patch.dart index db181ab8ed3..5e8b987fbd4 100644 --- a/sdk/lib/_internal/vm/lib/timer_patch.dart +++ b/sdk/lib/_internal/vm/lib/timer_patch.dart @@ -2,24 +2,19 @@ // 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.6 - // part of "async_patch.dart"; @patch class Timer { @patch static Timer _createTimer(Duration duration, void callback()) { - // TODO(iposva): Remove _TimerFactory and use VMLibraryHooks exclusively. - if (_TimerFactory._factory == null) { - _TimerFactory._factory = VMLibraryHooks.timerFactory; - } - if (_TimerFactory._factory == null) { + final factory = VMLibraryHooks.timerFactory; + if (factory == null) { throw new UnsupportedError("Timer interface not supported."); } int milliseconds = duration.inMilliseconds; if (milliseconds < 0) milliseconds = 0; - return _TimerFactory._factory(milliseconds, (_) { + return factory(milliseconds, (_) { callback(); }, false); } @@ -27,20 +22,12 @@ class Timer { @patch static Timer _createPeriodicTimer( Duration duration, void callback(Timer timer)) { - // TODO(iposva): Remove _TimerFactory and use VMLibraryHooks exclusively. - _TimerFactory._factory ??= VMLibraryHooks.timerFactory; - if (_TimerFactory._factory == null) { + final factory = VMLibraryHooks.timerFactory; + if (factory == null) { throw new UnsupportedError("Timer interface not supported."); } int milliseconds = duration.inMilliseconds; if (milliseconds < 0) milliseconds = 0; - return _TimerFactory._factory(milliseconds, callback, true); + return factory(milliseconds, callback, true); } } - -typedef Timer _TimerFactoryClosure( - int milliseconds, void callback(Timer timer), bool repeating); - -class _TimerFactory { - static _TimerFactoryClosure _factory; -} diff --git a/sdk/lib/_internal/vm/lib/type_patch.dart b/sdk/lib/_internal/vm/lib/type_patch.dart index 5a7623aef9b..1b8f3c1cab9 100644 --- a/sdk/lib/_internal/vm/lib/type_patch.dart +++ b/sdk/lib/_internal/vm/lib/type_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "core_patch.dart"; // These Dart classes correspond to the VM internal implementation classes. diff --git a/sdk/lib/_internal/vm/lib/typed_data_patch.dart b/sdk/lib/_internal/vm/lib/typed_data_patch.dart index 21ca2def0f1..6d0cc5a8933 100644 --- a/sdk/lib/_internal/vm/lib/typed_data_patch.dart +++ b/sdk/lib/_internal/vm/lib/typed_data_patch.dart @@ -2,8 +2,6 @@ // 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.6 - /// Note: the VM concatenates all patch files into a single patch file. This /// file is the first patch in "dart:typed_data" which contains all the imports /// used by patches of that library. We plan to change this when we have a @@ -87,7 +85,7 @@ abstract class _TypedListBase { throw new UnsupportedError("Cannot remove from a fixed-length list"); } - bool remove(Object element) { + bool remove(Object? element) { throw new UnsupportedError("Cannot remove from a fixed-length list"); } @@ -142,9 +140,10 @@ mixin _IntListMixin implements List { return -1; } - int lastIndexWhere(bool test(int element), [int start]) { - if (start == null || start >= this.length) start = this.length - 1; - for (int i = start; i >= 0; i--) { + int lastIndexWhere(bool test(int element), [int? start]) { + int startIndex = + (start == null || start >= this.length) ? this.length - 1 : start; + for (int i = startIndex; i >= 0; i--) { if (test(this[i])) return i; } return -1; @@ -158,7 +157,7 @@ mixin _IntListMixin implements List { ..setRange(this.length, totalLength, other); } - bool contains(Object element) { + bool contains(Object? element) { var len = this.length; for (var i = 0; i < len; ++i) { if (this[i] == element) return true; @@ -166,7 +165,7 @@ mixin _IntListMixin implements List { return false; } - void shuffle([Random random]) { + void shuffle([Random? random]) { random ??= new Random(); var i = this.length; while (i > 1) { @@ -194,9 +193,9 @@ mixin _IntListMixin implements List { Map asMap() => new ListMapView(this); - Iterable getRange(int start, [int end]) { - RangeError.checkValidRange(start, end, this.length); - return new SubListIterable(this, start, end); + Iterable getRange(int start, [int? end]) { + int endIndex = RangeError.checkValidRange(start, end, this.length); + return new SubListIterable(this, start, endIndex); } Iterator get iterator => new _TypedListIterator(this); @@ -255,7 +254,7 @@ mixin _IntListMixin implements List { return false; } - int firstWhere(bool test(int element), {int orElse()}) { + int firstWhere(bool test(int element), {int orElse()?}) { var len = this.length; for (var i = 0; i < len; ++i) { var element = this[i]; @@ -265,7 +264,7 @@ mixin _IntListMixin implements List { throw IterableElementError.noElement(); } - int lastWhere(bool test(int element), {int orElse()}) { + int lastWhere(bool test(int element), {int orElse()?}) { var len = this.length; for (var i = len - 1; i >= 0; --i) { var element = this[i]; @@ -277,7 +276,7 @@ mixin _IntListMixin implements List { throw IterableElementError.noElement(); } - int singleWhere(bool test(int element), {int orElse()}) { + int singleWhere(bool test(int element), {int orElse()?}) { var result = null; bool foundMatching = false; var len = this.length; @@ -316,7 +315,7 @@ mixin _IntListMixin implements List { throw new UnsupportedError("Cannot insert into a fixed-length list"); } - void sort([int compare(int a, int b)]) { + void sort([int compare(int a, int b)?]) { Sort.sort(this, compare ?? Comparable.compare); } @@ -332,13 +331,10 @@ mixin _IntListMixin implements List { return -1; } - int lastIndexOf(int element, [int start = null]) { - if (start == null || start >= this.length) { - start = this.length - 1; - } else if (start < 0) { - return -1; - } - for (int i = start; i >= 0; i--) { + int lastIndexOf(int element, [int? start]) { + int startIndex = + (start == null || start >= this.length) ? this.length - 1 : start; + for (int i = startIndex; i >= 0; i--) { if (this[i] == element) return i; } return -1; @@ -381,8 +377,12 @@ mixin _IntListMixin implements List { setRange(index, end, iterable); } - void fillRange(int start, int end, [int fillValue]) { + void fillRange(int start, int end, [int? fillValue]) { RangeError.checkValidRange(start, end, this.length); + if (start == end) return; + if (fillValue == null) { + throw ArgumentError.notNull("fillValue"); + } for (var i = start; i < end; ++i) { this[i] = fillValue; } @@ -458,9 +458,9 @@ mixin _TypedIntListMixin> on _IntListMixin Lists.copy(otherList, otherStart, this, start, count); } - SpawnedType sublist(int start, [int end]) { - end = RangeError.checkValidRange(start, end, this.length); - var length = end - start; + SpawnedType sublist(int start, [int? end]) { + int endIndex = RangeError.checkValidRange(start, end, this.length); + var length = endIndex - start; SpawnedType result = _createList(length); result.setRange(0, length, this, start); return result; @@ -496,9 +496,10 @@ mixin _DoubleListMixin implements List { return -1; } - int lastIndexWhere(bool test(double element), [int start]) { - if (start == null || start >= this.length) start = this.length - 1; - for (int i = start; i >= 0; i--) { + int lastIndexWhere(bool test(double element), [int? start]) { + int startIndex = + (start == null || start >= this.length) ? this.length - 1 : start; + for (int i = startIndex; i >= 0; i--) { if (test(this[i])) return i; } return -1; @@ -512,7 +513,7 @@ mixin _DoubleListMixin implements List { ..setRange(this.length, totalLength, other); } - bool contains(Object element) { + bool contains(Object? element) { var len = this.length; for (var i = 0; i < len; ++i) { if (this[i] == element) return true; @@ -520,7 +521,7 @@ mixin _DoubleListMixin implements List { return false; } - void shuffle([Random random]) { + void shuffle([Random? random]) { random ??= new Random(); var i = this.length; while (i > 1) { @@ -549,9 +550,9 @@ mixin _DoubleListMixin implements List { Map asMap() => new ListMapView(this); - Iterable getRange(int start, [int end]) { - RangeError.checkValidRange(start, end, this.length); - return new SubListIterable(this, start, end); + Iterable getRange(int start, [int? end]) { + int endIndex = RangeError.checkValidRange(start, end, this.length); + return new SubListIterable(this, start, endIndex); } Iterator get iterator => new _TypedListIterator(this); @@ -611,7 +612,7 @@ mixin _DoubleListMixin implements List { return false; } - double firstWhere(bool test(double element), {double orElse()}) { + double firstWhere(bool test(double element), {double orElse()?}) { var len = this.length; for (var i = 0; i < len; ++i) { var element = this[i]; @@ -621,7 +622,7 @@ mixin _DoubleListMixin implements List { throw IterableElementError.noElement(); } - double lastWhere(bool test(double element), {double orElse()}) { + double lastWhere(bool test(double element), {double orElse()?}) { var len = this.length; for (var i = len - 1; i >= 0; --i) { var element = this[i]; @@ -633,7 +634,7 @@ mixin _DoubleListMixin implements List { throw IterableElementError.noElement(); } - double singleWhere(bool test(double element), {double orElse()}) { + double singleWhere(bool test(double element), {double orElse()?}) { var result = null; bool foundMatching = false; var len = this.length; @@ -672,7 +673,7 @@ mixin _DoubleListMixin implements List { throw new UnsupportedError("Cannot insert into a fixed-length list"); } - void sort([int compare(double a, double b)]) { + void sort([int compare(double a, double b)?]) { Sort.sort(this, compare ?? Comparable.compare); } @@ -688,13 +689,10 @@ mixin _DoubleListMixin implements List { return -1; } - int lastIndexOf(double element, [int start = null]) { - if (start == null || start >= this.length) { - start = this.length - 1; - } else if (start < 0) { - return -1; - } - for (int i = start; i >= 0; i--) { + int lastIndexOf(double element, [int? start]) { + int startIndex = + (start == null || start >= this.length) ? this.length - 1 : start; + for (int i = startIndex; i >= 0; i--) { if (this[i] == element) return i; } return -1; @@ -737,8 +735,13 @@ mixin _DoubleListMixin implements List { setRange(index, end, iterable); } - void fillRange(int start, int end, [double fillValue]) { + void fillRange(int start, int end, [double? fillValue]) { + // TODO(eernst): Could use zero as default and not throw; issue . RangeError.checkValidRange(start, end, this.length); + if (start == end) return; + if (fillValue == null) { + throw ArgumentError.notNull("fillValue"); + } for (var i = start; i < end; ++i) { this[i] = fillValue; } @@ -815,9 +818,9 @@ mixin _TypedDoubleListMixin> Lists.copy(otherList, otherStart, this, start, count); } - SpawnedType sublist(int start, [int end]) { - end = RangeError.checkValidRange(start, end, this.length); - var length = end - start; + SpawnedType sublist(int start, [int? end]) { + int endIndex = RangeError.checkValidRange(start, end, this.length); + var length = endIndex - start; SpawnedType result = _createList(length); result.setRange(0, length, this, start); return result; @@ -855,9 +858,10 @@ abstract class _Float32x4ListMixin implements List { return -1; } - int lastIndexWhere(bool test(Float32x4 element), [int start]) { - if (start == null || start >= this.length) start = this.length - 1; - for (int i = start; i >= 0; i--) { + int lastIndexWhere(bool test(Float32x4 element), [int? start]) { + int startIndex = + (start == null || start >= this.length) ? this.length - 1 : start; + for (int i = startIndex; i >= 0; i--) { if (test(this[i])) return i; } return -1; @@ -871,7 +875,7 @@ abstract class _Float32x4ListMixin implements List { ..setRange(this.length, totalLength, other); } - bool contains(Object element) { + bool contains(Object? element) { var len = this.length; for (var i = 0; i < len; ++i) { if (this[i] == element) return true; @@ -879,7 +883,7 @@ abstract class _Float32x4ListMixin implements List { return false; } - void shuffle([Random random]) { + void shuffle([Random? random]) { random ??= new Random(); var i = this.length; while (i > 1) { @@ -975,9 +979,9 @@ abstract class _Float32x4ListMixin implements List { Map asMap() => new ListMapView(this); - Iterable getRange(int start, [int end]) { - RangeError.checkValidRange(start, end, this.length); - return new SubListIterable(this, start, end); + Iterable getRange(int start, [int? end]) { + int endIndex = RangeError.checkValidRange(start, end, this.length); + return new SubListIterable(this, start, endIndex); } Iterator get iterator => new _TypedListIterator(this); @@ -1037,7 +1041,7 @@ abstract class _Float32x4ListMixin implements List { return false; } - Float32x4 firstWhere(bool test(Float32x4 element), {Float32x4 orElse()}) { + Float32x4 firstWhere(bool test(Float32x4 element), {Float32x4 orElse()?}) { var len = this.length; for (var i = 0; i < len; ++i) { var element = this[i]; @@ -1047,7 +1051,7 @@ abstract class _Float32x4ListMixin implements List { throw IterableElementError.noElement(); } - Float32x4 lastWhere(bool test(Float32x4 element), {Float32x4 orElse()}) { + Float32x4 lastWhere(bool test(Float32x4 element), {Float32x4 orElse()?}) { var len = this.length; for (var i = len - 1; i >= 0; --i) { var element = this[i]; @@ -1059,7 +1063,7 @@ abstract class _Float32x4ListMixin implements List { throw IterableElementError.noElement(); } - Float32x4 singleWhere(bool test(Float32x4 element), {Float32x4 orElse()}) { + Float32x4 singleWhere(bool test(Float32x4 element), {Float32x4 orElse()?}) { var result = null; bool foundMatching = false; var len = this.length; @@ -1098,7 +1102,7 @@ abstract class _Float32x4ListMixin implements List { throw new UnsupportedError("Cannot insert into a fixed-length list"); } - void sort([int compare(Float32x4 a, Float32x4 b)]) { + void sort([int compare(Float32x4 a, Float32x4 b)?]) { if (compare == null) { throw "SIMD don't have default compare."; } @@ -1117,13 +1121,10 @@ abstract class _Float32x4ListMixin implements List { return -1; } - int lastIndexOf(Float32x4 element, [int start = null]) { - if (start == null || start >= this.length) { - start = this.length - 1; - } else if (start < 0) { - return -1; - } - for (int i = start; i >= 0; i--) { + int lastIndexOf(Float32x4 element, [int? start]) { + int startIndex = + (start == null || start >= this.length) ? this.length - 1 : start; + for (int i = startIndex; i >= 0; i--) { if (this[i] == element) return i; } return -1; @@ -1161,9 +1162,9 @@ abstract class _Float32x4ListMixin implements List { throw IterableElementError.tooMany(); } - Float32x4List sublist(int start, [int end]) { - end = RangeError.checkValidRange(start, end, this.length); - var length = end - start; + Float32x4List sublist(int start, [int? end]) { + int endIndex = RangeError.checkValidRange(start, end, this.length); + var length = endIndex - start; Float32x4List result = _createList(length); result.setRange(0, length, this, start); return result; @@ -1174,8 +1175,12 @@ abstract class _Float32x4ListMixin implements List { setRange(index, end, iterable); } - void fillRange(int start, int end, [Float32x4 fillValue]) { + void fillRange(int start, int end, [Float32x4? fillValue]) { RangeError.checkValidRange(start, end, this.length); + if (start == end) return; + if (fillValue == null) { + throw ArgumentError.notNull("fillValue"); + } for (var i = start; i < end; ++i) { this[i] = fillValue; } @@ -1213,9 +1218,10 @@ abstract class _Int32x4ListMixin implements List { return -1; } - int lastIndexWhere(bool test(Int32x4 element), [int start]) { - if (start == null || start >= this.length) start = this.length - 1; - for (int i = start; i >= 0; i--) { + int lastIndexWhere(bool test(Int32x4 element), [int? start]) { + int startIndex = + (start == null || start >= this.length) ? this.length - 1 : start; + for (int i = startIndex; i >= 0; i--) { if (test(this[i])) return i; } return -1; @@ -1229,7 +1235,7 @@ abstract class _Int32x4ListMixin implements List { ..setRange(this.length, totalLength, other); } - bool contains(Object element) { + bool contains(Object? element) { var len = this.length; for (var i = 0; i < len; ++i) { if (this[i] == element) return true; @@ -1237,7 +1243,7 @@ abstract class _Int32x4ListMixin implements List { return false; } - void shuffle([Random random]) { + void shuffle([Random? random]) { random ??= new Random(); var i = this.length; while (i > 1) { @@ -1332,9 +1338,9 @@ abstract class _Int32x4ListMixin implements List { Map asMap() => new ListMapView(this); - Iterable getRange(int start, [int end]) { - RangeError.checkValidRange(start, end, this.length); - return new SubListIterable(this, start, end); + Iterable getRange(int start, [int? end]) { + int endIndex = RangeError.checkValidRange(start, end, this.length); + return new SubListIterable(this, start, endIndex); } Iterator get iterator => new _TypedListIterator(this); @@ -1394,7 +1400,7 @@ abstract class _Int32x4ListMixin implements List { return false; } - Int32x4 firstWhere(bool test(Int32x4 element), {Int32x4 orElse()}) { + Int32x4 firstWhere(bool test(Int32x4 element), {Int32x4 orElse()?}) { var len = this.length; for (var i = 0; i < len; ++i) { var element = this[i]; @@ -1404,7 +1410,7 @@ abstract class _Int32x4ListMixin implements List { throw IterableElementError.noElement(); } - Int32x4 lastWhere(bool test(Int32x4 element), {Int32x4 orElse()}) { + Int32x4 lastWhere(bool test(Int32x4 element), {Int32x4 orElse()?}) { var len = this.length; for (var i = len - 1; i >= 0; --i) { var element = this[i]; @@ -1416,7 +1422,7 @@ abstract class _Int32x4ListMixin implements List { throw IterableElementError.noElement(); } - Int32x4 singleWhere(bool test(Int32x4 element), {Int32x4 orElse()}) { + Int32x4 singleWhere(bool test(Int32x4 element), {Int32x4 orElse()?}) { var result = null; bool foundMatching = false; var len = this.length; @@ -1455,7 +1461,7 @@ abstract class _Int32x4ListMixin implements List { throw new UnsupportedError("Cannot insert into a fixed-length list"); } - void sort([int compare(Int32x4 a, Int32x4 b)]) { + void sort([int compare(Int32x4 a, Int32x4 b)?]) { if (compare == null) { throw "SIMD don't have default compare."; } @@ -1474,13 +1480,10 @@ abstract class _Int32x4ListMixin implements List { return -1; } - int lastIndexOf(Int32x4 element, [int start = null]) { - if (start == null || start >= this.length) { - start = this.length - 1; - } else if (start < 0) { - return -1; - } - for (int i = start; i >= 0; i--) { + int lastIndexOf(Int32x4 element, [int? start]) { + int startIndex = + (start == null || start >= this.length) ? this.length - 1 : start; + for (int i = startIndex; i >= 0; i--) { if (this[i] == element) return i; } return -1; @@ -1518,9 +1521,9 @@ abstract class _Int32x4ListMixin implements List { throw IterableElementError.tooMany(); } - Int32x4List sublist(int start, [int end]) { - end = RangeError.checkValidRange(start, end, this.length); - var length = end - start; + Int32x4List sublist(int start, [int? end]) { + int endIndex = RangeError.checkValidRange(start, end, this.length); + var length = endIndex - start; Int32x4List result = _createList(length); result.setRange(0, length, this, start); return result; @@ -1531,8 +1534,12 @@ abstract class _Int32x4ListMixin implements List { setRange(index, end, iterable); } - void fillRange(int start, int end, [Int32x4 fillValue]) { + void fillRange(int start, int end, [Int32x4? fillValue]) { RangeError.checkValidRange(start, end, this.length); + if (start == end) return; + if (fillValue == null) { + throw ArgumentError.notNull("fillValue"); + } for (var i = start; i < end; ++i) { this[i] = fillValue; } @@ -1570,9 +1577,10 @@ abstract class _Float64x2ListMixin implements List { return -1; } - int lastIndexWhere(bool test(Float64x2 element), [int start]) { - if (start == null || start >= this.length) start = this.length - 1; - for (int i = start; i >= 0; i--) { + int lastIndexWhere(bool test(Float64x2 element), [int? start]) { + int startIndex = + (start == null || start >= this.length) ? this.length - 1 : start; + for (int i = startIndex; i >= 0; i--) { if (test(this[i])) return i; } return -1; @@ -1586,7 +1594,7 @@ abstract class _Float64x2ListMixin implements List { ..setRange(this.length, totalLength, other); } - bool contains(Object element) { + bool contains(Object? element) { var len = this.length; for (var i = 0; i < len; ++i) { if (this[i] == element) return true; @@ -1594,7 +1602,7 @@ abstract class _Float64x2ListMixin implements List { return false; } - void shuffle([Random random]) { + void shuffle([Random? random]) { random ??= new Random(); var i = this.length; while (i > 1) { @@ -1690,9 +1698,9 @@ abstract class _Float64x2ListMixin implements List { Map asMap() => new ListMapView(this); - Iterable getRange(int start, [int end]) { - RangeError.checkValidRange(start, end, this.length); - return new SubListIterable(this, start, end); + Iterable getRange(int start, [int? end]) { + int endIndex = RangeError.checkValidRange(start, end, this.length); + return new SubListIterable(this, start, endIndex); } Iterator get iterator => new _TypedListIterator(this); @@ -1752,7 +1760,7 @@ abstract class _Float64x2ListMixin implements List { return false; } - Float64x2 firstWhere(bool test(Float64x2 element), {Float64x2 orElse()}) { + Float64x2 firstWhere(bool test(Float64x2 element), {Float64x2 orElse()?}) { var len = this.length; for (var i = 0; i < len; ++i) { var element = this[i]; @@ -1762,7 +1770,7 @@ abstract class _Float64x2ListMixin implements List { throw IterableElementError.noElement(); } - Float64x2 lastWhere(bool test(Float64x2 element), {Float64x2 orElse()}) { + Float64x2 lastWhere(bool test(Float64x2 element), {Float64x2 orElse()?}) { var len = this.length; for (var i = len - 1; i >= 0; --i) { var element = this[i]; @@ -1774,7 +1782,7 @@ abstract class _Float64x2ListMixin implements List { throw IterableElementError.noElement(); } - Float64x2 singleWhere(bool test(Float64x2 element), {Float64x2 orElse()}) { + Float64x2 singleWhere(bool test(Float64x2 element), {Float64x2 orElse()?}) { var result = null; bool foundMatching = false; var len = this.length; @@ -1813,7 +1821,7 @@ abstract class _Float64x2ListMixin implements List { throw new UnsupportedError("Cannot insert into a fixed-length list"); } - void sort([int compare(Float64x2 a, Float64x2 b)]) { + void sort([int compare(Float64x2 a, Float64x2 b)?]) { if (compare == null) { throw "SIMD don't have default compare."; } @@ -1832,13 +1840,10 @@ abstract class _Float64x2ListMixin implements List { return -1; } - int lastIndexOf(Float64x2 element, [int start = null]) { - if (start == null || start >= this.length) { - start = this.length - 1; - } else if (start < 0) { - return -1; - } - for (int i = start; i >= 0; i--) { + int lastIndexOf(Float64x2 element, [int? start]) { + int startIndex = + (start == null || start >= this.length) ? this.length - 1 : start; + for (int i = startIndex; i >= 0; i--) { if (this[i] == element) return i; } return -1; @@ -1876,9 +1881,9 @@ abstract class _Float64x2ListMixin implements List { throw IterableElementError.tooMany(); } - Float64x2List sublist(int start, [int end]) { - end = RangeError.checkValidRange(start, end, this.length); - var length = end - start; + Float64x2List sublist(int start, [int? end]) { + int endIndex = RangeError.checkValidRange(start, end, this.length); + var length = endIndex - start; Float64x2List result = _createList(length); result.setRange(0, length, this, start); return result; @@ -1889,8 +1894,12 @@ abstract class _Float64x2ListMixin implements List { setRange(index, end, iterable); } - void fillRange(int start, int end, [Float64x2 fillValue]) { + void fillRange(int start, int end, [Float64x2? fillValue]) { RangeError.checkValidRange(start, end, this.length); + if (start == end) return; + if (fillValue == null) { + throw ArgumentError.notNull("fillValue"); + } for (var i = start; i < end; ++i) { this[i] = fillValue; } @@ -1912,20 +1921,20 @@ class _ByteBuffer implements ByteBuffer { bool operator ==(Object other) => (other is _ByteBuffer) && identical(_data, other._data); - ByteData asByteData([int offsetInBytes = 0, int length]) { + ByteData asByteData([int offsetInBytes = 0, int? length]) { length ??= this.lengthInBytes - offsetInBytes; _rangeCheck(this._data.lengthInBytes, offsetInBytes, length); return new _ByteDataView._(this._data, offsetInBytes, length); } - Int8List asInt8List([int offsetInBytes = 0, int length]) { + Int8List asInt8List([int offsetInBytes = 0, int? length]) { length ??= (this.lengthInBytes - offsetInBytes) ~/ Int8List.bytesPerElement; _rangeCheck( this.lengthInBytes, offsetInBytes, length * Int8List.bytesPerElement); return new _Int8ArrayView._(this._data, offsetInBytes, length); } - Uint8List asUint8List([int offsetInBytes = 0, int length]) { + Uint8List asUint8List([int offsetInBytes = 0, int? length]) { length ??= (this.lengthInBytes - offsetInBytes) ~/ Uint8List.bytesPerElement; _rangeCheck( @@ -1933,7 +1942,7 @@ class _ByteBuffer implements ByteBuffer { return new _Uint8ArrayView._(this._data, offsetInBytes, length); } - Uint8ClampedList asUint8ClampedList([int offsetInBytes = 0, int length]) { + Uint8ClampedList asUint8ClampedList([int offsetInBytes = 0, int? length]) { length ??= (this.lengthInBytes - offsetInBytes) ~/ Uint8ClampedList.bytesPerElement; _rangeCheck(this.lengthInBytes, offsetInBytes, @@ -1941,7 +1950,7 @@ class _ByteBuffer implements ByteBuffer { return new _Uint8ClampedArrayView._(this._data, offsetInBytes, length); } - Int16List asInt16List([int offsetInBytes = 0, int length]) { + Int16List asInt16List([int offsetInBytes = 0, int? length]) { length ??= (this.lengthInBytes - offsetInBytes) ~/ Int16List.bytesPerElement; _rangeCheck( @@ -1950,7 +1959,7 @@ class _ByteBuffer implements ByteBuffer { return new _Int16ArrayView._(this._data, offsetInBytes, length); } - Uint16List asUint16List([int offsetInBytes = 0, int length]) { + Uint16List asUint16List([int offsetInBytes = 0, int? length]) { length ??= (this.lengthInBytes - offsetInBytes) ~/ Uint16List.bytesPerElement; _rangeCheck( @@ -1959,7 +1968,7 @@ class _ByteBuffer implements ByteBuffer { return new _Uint16ArrayView._(this._data, offsetInBytes, length); } - Int32List asInt32List([int offsetInBytes = 0, int length]) { + Int32List asInt32List([int offsetInBytes = 0, int? length]) { length ??= (this.lengthInBytes - offsetInBytes) ~/ Int32List.bytesPerElement; _rangeCheck( @@ -1968,7 +1977,7 @@ class _ByteBuffer implements ByteBuffer { return new _Int32ArrayView._(this._data, offsetInBytes, length); } - Uint32List asUint32List([int offsetInBytes = 0, int length]) { + Uint32List asUint32List([int offsetInBytes = 0, int? length]) { length ??= (this.lengthInBytes - offsetInBytes) ~/ Uint32List.bytesPerElement; _rangeCheck( @@ -1977,7 +1986,7 @@ class _ByteBuffer implements ByteBuffer { return new _Uint32ArrayView._(this._data, offsetInBytes, length); } - Int64List asInt64List([int offsetInBytes = 0, int length]) { + Int64List asInt64List([int offsetInBytes = 0, int? length]) { length ??= (this.lengthInBytes - offsetInBytes) ~/ Int64List.bytesPerElement; _rangeCheck( @@ -1986,7 +1995,7 @@ class _ByteBuffer implements ByteBuffer { return new _Int64ArrayView._(this._data, offsetInBytes, length); } - Uint64List asUint64List([int offsetInBytes = 0, int length]) { + Uint64List asUint64List([int offsetInBytes = 0, int? length]) { length ??= (this.lengthInBytes - offsetInBytes) ~/ Uint64List.bytesPerElement; _rangeCheck( @@ -1995,7 +2004,7 @@ class _ByteBuffer implements ByteBuffer { return new _Uint64ArrayView._(this._data, offsetInBytes, length); } - Float32List asFloat32List([int offsetInBytes = 0, int length]) { + Float32List asFloat32List([int offsetInBytes = 0, int? length]) { length ??= (this.lengthInBytes - offsetInBytes) ~/ Float32List.bytesPerElement; _rangeCheck(this.lengthInBytes, offsetInBytes, @@ -2004,7 +2013,7 @@ class _ByteBuffer implements ByteBuffer { return new _Float32ArrayView._(this._data, offsetInBytes, length); } - Float64List asFloat64List([int offsetInBytes = 0, int length]) { + Float64List asFloat64List([int offsetInBytes = 0, int? length]) { length ??= (this.lengthInBytes - offsetInBytes) ~/ Float64List.bytesPerElement; _rangeCheck(this.lengthInBytes, offsetInBytes, @@ -2013,7 +2022,7 @@ class _ByteBuffer implements ByteBuffer { return new _Float64ArrayView._(this._data, offsetInBytes, length); } - Float32x4List asFloat32x4List([int offsetInBytes = 0, int length]) { + Float32x4List asFloat32x4List([int offsetInBytes = 0, int? length]) { length ??= (this.lengthInBytes - offsetInBytes) ~/ Float32x4List.bytesPerElement; _rangeCheck(this.lengthInBytes, offsetInBytes, @@ -2022,7 +2031,7 @@ class _ByteBuffer implements ByteBuffer { return new _Float32x4ArrayView._(this._data, offsetInBytes, length); } - Int32x4List asInt32x4List([int offsetInBytes = 0, int length]) { + Int32x4List asInt32x4List([int offsetInBytes = 0, int? length]) { length ??= (this.lengthInBytes - offsetInBytes) ~/ Int32x4List.bytesPerElement; _rangeCheck(this.lengthInBytes, offsetInBytes, @@ -2031,7 +2040,7 @@ class _ByteBuffer implements ByteBuffer { return new _Int32x4ArrayView._(this._data, offsetInBytes, length); } - Float64x2List asFloat64x2List([int offsetInBytes = 0, int length]) { + Float64x2List asFloat64x2List([int offsetInBytes = 0, int? length]) { length ??= (this.lengthInBytes - offsetInBytes) ~/ Float64x2List.bytesPerElement; _rangeCheck(this.lengthInBytes, offsetInBytes, @@ -2314,7 +2323,8 @@ class _Int16List extends _TypedList _setIndexedInt16(index, _toInt16(value)); } - void setRange(int start, int end, Iterable iterable, [int skipCount = 0]) { + void setRange(int start, int end, Iterable iterable, + [int skipCount = 0]) { if (iterable is CodeUnits) { end = RangeError.checkValidRange(start, end, this.length); int length = end - start; @@ -2381,7 +2391,8 @@ class _Uint16List extends _TypedList _setIndexedUint16(index, _toUint16(value)); } - void setRange(int start, int end, Iterable iterable, [int skipCount = 0]) { + void setRange(int start, int end, Iterable iterable, + [int skipCount = 0]) { if (iterable is CodeUnits) { end = RangeError.checkValidRange(start, end, this.length); int length = end - start; @@ -3829,9 +3840,9 @@ class _TypedListIterator implements Iterator { final List _array; final int _length; int _position; - E _current; + E? _current; - _TypedListIterator(List array) + _TypedListIterator(List array) : _array = array, _length = array.length, _position = -1 { @@ -3850,7 +3861,10 @@ class _TypedListIterator implements Iterator { return false; } - E get current => _current; + E get current { + final cur = _current; + return (cur != null) ? cur : cur as E; + } } abstract class _TypedListView extends _TypedListBase implements TypedData { @@ -4022,7 +4036,8 @@ class _Int16ArrayView extends _TypedListView offsetInBytes + (index * Int16List.bytesPerElement), _toInt16(value)); } - void setRange(int start, int end, Iterable iterable, [int skipCount = 0]) { + void setRange(int start, int end, Iterable iterable, + [int skipCount = 0]) { if (iterable is CodeUnits) { end = RangeError.checkValidRange(start, end, this.length); int length = end - start; @@ -4073,7 +4088,8 @@ class _Uint16ArrayView extends _TypedListView offsetInBytes + (index * Uint16List.bytesPerElement), _toUint16(value)); } - void setRange(int start, int end, Iterable iterable, [int skipCount = 0]) { + void setRange(int start, int end, Iterable iterable, + [int skipCount = 0]) { if (iterable is CodeUnits) { end = RangeError.checkValidRange(start, end, this.length); int length = end - start; diff --git a/sdk/lib/_internal/vm/lib/uri_patch.dart b/sdk/lib/_internal/vm/lib/uri_patch.dart index 741f2d0fa00..de10c9e008c 100644 --- a/sdk/lib/_internal/vm/lib/uri_patch.dart +++ b/sdk/lib/_internal/vm/lib/uri_patch.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "core_patch.dart"; typedef Uri _UriBaseClosure(); diff --git a/sdk/lib/_internal/vm/lib/wasm_patch.dart b/sdk/lib/_internal/vm/lib/wasm_patch.dart index c24a396d2d3..f3a996d2b51 100644 --- a/sdk/lib/_internal/vm/lib/wasm_patch.dart +++ b/sdk/lib/_internal/vm/lib/wasm_patch.dart @@ -2,8 +2,6 @@ // 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.6 - import 'dart:_internal' show patch; import "dart:nativewrappers" show NativeFieldWrapperClass1; import 'dart:typed_data'; @@ -39,7 +37,7 @@ class WasmModule { @patch class WasmMemory { @patch - factory WasmMemory(int initialPages, [int maxPages]) { + factory WasmMemory(int initialPages, [int? maxPages]) { return _NativeWasmMemory(initialPages, maxPages); } } @@ -107,11 +105,12 @@ class _NativeWasmImports extends NativeFieldWrapperClass1 } class _NativeWasmMemory extends NativeFieldWrapperClass1 implements WasmMemory { - int _pages; - Uint8List _buffer; + late int _pages; + late Uint8List _buffer; - _NativeWasmMemory(int initialPages, int maxPages) : _pages = initialPages { + _NativeWasmMemory(int initialPages, int? maxPages) { _buffer = _init(initialPages, maxPages); + _pages = initialPages; } _NativeWasmMemory.fromInstance(_NativeWasmInstance inst) { @@ -133,7 +132,7 @@ class _NativeWasmMemory extends NativeFieldWrapperClass1 implements WasmMemory { return oldPages; } - Uint8List _init(int initialPages, int maxPages) native 'Wasm_initMemory'; + Uint8List _init(int initialPages, int? maxPages) native 'Wasm_initMemory'; Uint8List _grow(int deltaPages) native 'Wasm_growMemory'; Uint8List _initFromInstance(_NativeWasmInstance inst) native 'Wasm_initMemoryFromInstance'; diff --git a/sdk/lib/_internal/vm/lib/weak_property.dart b/sdk/lib/_internal/vm/lib/weak_property.dart index ed8e5709745..bc903e9f988 100644 --- a/sdk/lib/_internal/vm/lib/weak_property.dart +++ b/sdk/lib/_internal/vm/lib/weak_property.dart @@ -2,8 +2,6 @@ // 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.6 - // part of "core_patch.dart"; @pragma("vm:entry-point") diff --git a/sdk/lib/async/async.dart b/sdk/lib/async/async.dart index c58801f8cb6..8cce95923bf 100644 --- a/sdk/lib/async/async.dart +++ b/sdk/lib/async/async.dart @@ -2,8 +2,6 @@ // 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.6 - /** * Support for asynchronous programming, * with classes such as Future and Stream. @@ -95,7 +93,7 @@ */ library dart.async; -import "dart:collection" show HashMap, IterableBase; +import "dart:collection" show HashMap; import "dart:_internal" show CastStream, @@ -104,7 +102,8 @@ import "dart:_internal" IterableElementError, printToZone, printToConsole, - Since; + Since, + typeAcceptsNull; part 'async_error.dart'; part 'broadcast_stream_controller.dart'; diff --git a/sdk/lib/async/async_error.dart b/sdk/lib/async/async_error.dart index f0e81194557..a7172bde6a5 100644 --- a/sdk/lib/async/async_error.dart +++ b/sdk/lib/async/async_error.dart @@ -2,20 +2,17 @@ // 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.6 - part of dart.async; _invokeErrorHandler( Function errorHandler, Object error, StackTrace stackTrace) { - if (errorHandler is ZoneBinaryCallback) { + var handler = errorHandler; // Rename to avoid promotion. + if (handler is ZoneBinaryCallback) { // Dynamic invocation because we don't know the actual type of the // first argument or the error object, but we should successfully call // the handler if they match up. - // TODO(lrn): Should we? Why not the same below for the unary case? - return (errorHandler as dynamic)(error, stackTrace); + return errorHandler(error, stackTrace); } else { - ZoneUnaryCallback unaryErrorHandler = errorHandler; - return unaryErrorHandler(error); + return errorHandler(error); } } diff --git a/sdk/lib/async/broadcast_stream_controller.dart b/sdk/lib/async/broadcast_stream_controller.dart index 6a62e0b2bc7..c362eeabe06 100644 --- a/sdk/lib/async/broadcast_stream_controller.dart +++ b/sdk/lib/async/broadcast_stream_controller.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.async; class _BroadcastStream extends _ControllerStream { @@ -22,11 +20,15 @@ class _BroadcastSubscription extends _ControllerSubscription { // does not assume that it's use of the state integer is the only use. int _eventState = 0; // Initialized to help dart2js type inference. - _BroadcastSubscription _next; - _BroadcastSubscription _previous; + _BroadcastSubscription? _next; + _BroadcastSubscription? _previous; - _BroadcastSubscription(_StreamControllerLifecycle controller, - void onData(T data), Function onError, void onDone(), bool cancelOnError) + _BroadcastSubscription( + _StreamControllerLifecycle controller, + void onData(T data)?, + Function? onError, + void onDone()?, + bool cancelOnError) : super(controller, onData, onError, onDone, cancelOnError) { _next = _previous = this; } @@ -66,18 +68,18 @@ abstract class _BroadcastStreamController static const int _STATE_CLOSED = 4; static const int _STATE_ADDSTREAM = 8; - ControllerCallback onListen; - ControllerCancelCallback onCancel; + void Function()? onListen; + FutureOr Function()? onCancel; // State of the controller. int _state; // Double-linked list of active listeners. - _BroadcastSubscription _firstSubscription; - _BroadcastSubscription _lastSubscription; + _BroadcastSubscription? _firstSubscription; + _BroadcastSubscription? _lastSubscription; // Extra state used during an [addStream] call. - _AddStreamState _addStreamState; + _AddStreamState? _addStreamState; /** * Future returned by [close] and [done]. @@ -92,27 +94,27 @@ abstract class _BroadcastStreamController * Any attempt to listen after calling [close] will throw, so there won't * be any further listeners. */ - _Future _doneFuture; + _Future? _doneFuture; _BroadcastStreamController(this.onListen, this.onCancel) : _state = _STATE_INITIAL; - ControllerCallback get onPause { + void Function() get onPause { throw new UnsupportedError( "Broadcast stream controllers do not support pause callbacks"); } - void set onPause(void onPauseHandler()) { + void set onPause(void onPauseHandler()?) { throw new UnsupportedError( "Broadcast stream controllers do not support pause callbacks"); } - ControllerCallback get onResume { + void Function() get onResume { throw new UnsupportedError( "Broadcast stream controllers do not support pause callbacks"); } - void set onResume(void onResumeHandler()) { + void set onResume(void onResumeHandler()?) { throw new UnsupportedError( "Broadcast stream controllers do not support pause callbacks"); } @@ -153,10 +155,7 @@ abstract class _BroadcastStreamController bool get _mayAddEvent => (_state < _STATE_CLOSED); - _Future _ensureDoneFuture() { - if (_doneFuture != null) return _doneFuture; - return _doneFuture = new _Future(); - } + _Future _ensureDoneFuture() => _doneFuture ??= _Future(); // Linked list helpers @@ -167,7 +166,7 @@ abstract class _BroadcastStreamController assert(identical(subscription._next, subscription)); subscription._eventState = (_state & _STATE_EVENT_ID); // Insert in linked list as last subscription. - _BroadcastSubscription oldLast = _lastSubscription; + _BroadcastSubscription? oldLast = _lastSubscription; _lastSubscription = subscription; subscription._next = null; subscription._previous = oldLast; @@ -181,8 +180,8 @@ abstract class _BroadcastStreamController void _removeListener(_BroadcastSubscription subscription) { assert(identical(subscription._controller, this)); assert(!identical(subscription._next, subscription)); - _BroadcastSubscription previous = subscription._previous; - _BroadcastSubscription next = subscription._next; + _BroadcastSubscription? previous = subscription._previous; + _BroadcastSubscription? next = subscription._next; if (previous == null) { // This was the first subscription. _firstSubscription = next; @@ -201,13 +200,12 @@ abstract class _BroadcastStreamController // _StreamControllerLifecycle interface. - StreamSubscription _subscribe(void onData(T data), Function onError, - void onDone(), bool cancelOnError) { + StreamSubscription _subscribe(void onData(T data)?, Function? onError, + void onDone()?, bool cancelOnError) { if (isClosed) { - onDone ??= _nullDoneHandler; return new _DoneStreamSubscription(onDone); } - StreamSubscription subscription = new _BroadcastSubscription( + var subscription = new _BroadcastSubscription( this, onData, onError, onDone, cancelOnError); _addListener(subscription); if (identical(_firstSubscription, _lastSubscription)) { @@ -217,8 +215,8 @@ abstract class _BroadcastStreamController return subscription; } - Future _recordCancel(StreamSubscription sub) { - _BroadcastSubscription subscription = sub; + Future? _recordCancel(StreamSubscription sub) { + _BroadcastSubscription subscription = sub as _BroadcastSubscription; // If already removed by the stream, don't remove it again. if (identical(subscription._next, subscription)) return null; if (subscription._isFiring) { @@ -252,22 +250,25 @@ abstract class _BroadcastStreamController _sendData(data); } - void addError(Object error, [StackTrace stackTrace]) { + void addError(Object error, [StackTrace? stackTrace]) { + // TODO(40614): Remove once non-nullability is sound. ArgumentError.checkNotNull(error, "error"); if (!_mayAddEvent) throw _addEventError(); - AsyncError replacement = Zone.current.errorCallback(error, stackTrace); + AsyncError? replacement = Zone.current.errorCallback(error, stackTrace); if (replacement != null) { - error = _nonNullError(replacement.error); + error = replacement.error; stackTrace = replacement.stackTrace; + } else { + stackTrace ??= AsyncError.defaultStackTrace(error); } - stackTrace ??= AsyncError.defaultStackTrace(error); + if (stackTrace == null) throw "unreachable"; // TODO(40088) _sendError(error, stackTrace); } Future close() { if (isClosed) { assert(_doneFuture != null); - return _doneFuture; + return _doneFuture!; } if (!_mayAddEvent) throw _addEventError(); _state |= _STATE_CLOSED; @@ -276,13 +277,15 @@ abstract class _BroadcastStreamController return doneFuture; } - Future get done => _ensureDoneFuture(); + Future get done => _ensureDoneFuture(); - Future addStream(Stream stream, {bool cancelOnError}) { + Future addStream(Stream stream, {bool? cancelOnError}) { if (!_mayAddEvent) throw _addEventError(); _state |= _STATE_ADDSTREAM; - _addStreamState = new _AddStreamState(this, stream, cancelOnError ?? false); - return _addStreamState.addStreamFuture; + var addStreamState = + new _AddStreamState(this, stream, cancelOnError ?? false); + _addStreamState = addStreamState; + return addStreamState.addStreamFuture; } // _EventSink interface, called from AddStreamState. @@ -296,7 +299,7 @@ abstract class _BroadcastStreamController void _close() { assert(_isAddingStream); - _AddStreamState addState = _addStreamState; + _AddStreamState addState = _addStreamState!; _addStreamState = null; _state &= ~_STATE_ADDSTREAM; addState.complete(); @@ -320,13 +323,13 @@ abstract class _BroadcastStreamController // Any listeners added while firing this event will expect the next event, // not this one, and won't get notified. _state ^= _STATE_EVENT_ID | _STATE_FIRING; - _BroadcastSubscription subscription = _firstSubscription; + _BroadcastSubscription? subscription = _firstSubscription; while (subscription != null) { if (subscription._expectsEvent(id)) { subscription._eventState |= _BroadcastSubscription._STATE_FIRING; action(subscription); subscription._toggleEventId(); - _BroadcastSubscription next = subscription._next; + _BroadcastSubscription? next = subscription._next; if (subscription._removeAfterFiring) { _removeListener(subscription); } @@ -345,9 +348,12 @@ abstract class _BroadcastStreamController void _callOnCancel() { assert(_isEmpty); - if (isClosed && _doneFuture._mayComplete) { + if (isClosed) { // When closed, _doneFuture is not null. - _doneFuture._asyncComplete(null); + var doneFuture = _doneFuture!; + if (doneFuture._mayComplete) { + doneFuture._asyncComplete(null); + } } _runGuarded(onCancel); } @@ -355,7 +361,7 @@ abstract class _BroadcastStreamController class _SyncBroadcastStreamController extends _BroadcastStreamController implements SynchronousStreamController { - _SyncBroadcastStreamController(void onListen(), void onCancel()) + _SyncBroadcastStreamController(void onListen()?, void onCancel()?) : super(onListen, onCancel); // EventDispatch interface. @@ -374,8 +380,9 @@ class _SyncBroadcastStreamController extends _BroadcastStreamController if (_isEmpty) return; if (_hasOneListener) { _state |= _BroadcastStreamController._STATE_FIRING; - _BroadcastSubscription subscription = _firstSubscription; - subscription._add(data); + _BroadcastSubscription firstSubscription = + _firstSubscription as dynamic; + firstSubscription._add(data); _state &= ~_BroadcastStreamController._STATE_FIRING; if (_isEmpty) { _callOnCancel(); @@ -400,21 +407,20 @@ class _SyncBroadcastStreamController extends _BroadcastStreamController subscription._close(); }); } else { - assert(_doneFuture != null); - assert(_doneFuture._mayComplete); - _doneFuture._asyncComplete(null); + assert(_doneFuture != null && _doneFuture!._mayComplete); + _doneFuture!._asyncComplete(null); } } } class _AsyncBroadcastStreamController extends _BroadcastStreamController { - _AsyncBroadcastStreamController(void onListen(), void onCancel()) + _AsyncBroadcastStreamController(void onListen()?, void onCancel()?) : super(onListen, onCancel); // EventDispatch interface. void _sendData(T data) { - for (_BroadcastSubscription subscription = _firstSubscription; + for (var subscription = _firstSubscription; subscription != null; subscription = subscription._next) { subscription._addPending(new _DelayedData(data)); @@ -422,7 +428,7 @@ class _AsyncBroadcastStreamController extends _BroadcastStreamController { } void _sendError(Object error, StackTrace stackTrace) { - for (_BroadcastSubscription subscription = _firstSubscription; + for (var subscription = _firstSubscription; subscription != null; subscription = subscription._next) { subscription._addPending(new _DelayedError(error, stackTrace)); @@ -431,15 +437,14 @@ class _AsyncBroadcastStreamController extends _BroadcastStreamController { void _sendDone() { if (!_isEmpty) { - for (_BroadcastSubscription subscription = _firstSubscription; + for (var subscription = _firstSubscription; subscription != null; subscription = subscription._next) { subscription._addPending(const _DelayedDone()); } } else { - assert(_doneFuture != null); - assert(_doneFuture._mayComplete); - _doneFuture._asyncComplete(null); + assert(_doneFuture != null && _doneFuture!._mayComplete); + _doneFuture!._asyncComplete(null); } } } @@ -457,16 +462,18 @@ class _AsyncBroadcastStreamController extends _BroadcastStreamController { */ class _AsBroadcastStreamController extends _SyncBroadcastStreamController implements _EventDispatch { - _StreamImplEvents _pending; + _StreamImplEvents? _pending; - _AsBroadcastStreamController(void onListen(), void onCancel()) + _AsBroadcastStreamController(void onListen()?, void onCancel()?) : super(onListen, onCancel); - bool get _hasPending => _pending != null && !_pending.isEmpty; + bool get _hasPending { + var pending = _pending; + return pending != null && !pending.isEmpty; + } void _addPendingEvent(_DelayedEvent event) { - _pending ??= new _StreamImplEvents(); - _pending.add(event); + (_pending ??= new _StreamImplEvents()).add(event); } void add(T data) { @@ -475,12 +482,11 @@ class _AsBroadcastStreamController extends _SyncBroadcastStreamController return; } super.add(data); - while (_hasPending) { - _pending.handleNext(this); - } + _flushPending(); } - void addError(Object error, [StackTrace stackTrace]) { + void addError(Object error, [StackTrace? stackTrace]) { + // TODO(40614): Remove once non-nullability is sound. ArgumentError.checkNotNull(error, "error"); stackTrace ??= AsyncError.defaultStackTrace(error); if (!isClosed && _isFiring) { @@ -489,8 +495,14 @@ class _AsBroadcastStreamController extends _SyncBroadcastStreamController } if (!_mayAddEvent) throw _addEventError(); _sendError(error, stackTrace); - while (_hasPending) { - _pending.handleNext(this); + _flushPending(); + } + + void _flushPending() { + var pending = _pending; + while (pending != null && !pending.isEmpty) { + pending.handleNext(this); + pending = _pending; } } @@ -506,8 +518,9 @@ class _AsBroadcastStreamController extends _SyncBroadcastStreamController } void _callOnCancel() { - if (_hasPending) { - _pending.clear(); + var pending = _pending; + if (pending != null) { + pending.clear(); _pending = null; } super._callOnCancel(); diff --git a/sdk/lib/async/deferred_load.dart b/sdk/lib/async/deferred_load.dart index 0019f685477..419db5863cc 100644 --- a/sdk/lib/async/deferred_load.dart +++ b/sdk/lib/async/deferred_load.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.async; /** @@ -15,7 +13,7 @@ part of dart.async; @Deprecated("Dart sdk v. 1.8") class DeferredLibrary { final String libraryName; - final String uri; + final String? uri; const DeferredLibrary(this.libraryName, {this.uri}); @@ -32,7 +30,7 @@ class DeferredLibrary { * Thrown when a deferred library fails to load. */ class DeferredLoadException implements Exception { - DeferredLoadException(this._s); + DeferredLoadException(String message) : _s = message; String toString() => "DeferredLoadException: '$_s'"; final String _s; } diff --git a/sdk/lib/async/future.dart b/sdk/lib/async/future.dart index 5de97188c13..6449304df41 100644 --- a/sdk/lib/async/future.dart +++ b/sdk/lib/async/future.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.async; /// A type representing values that are either `Future` or `T`. @@ -150,11 +148,11 @@ abstract class FutureOr { abstract class Future { /// A `Future` completed with `null`. static final _Future _nullFuture = - new _Future.zoneValue(null, Zone.root); + new _Future.zoneValue(null, _rootZone); /// A `Future` completed with `false`. static final _Future _falseFuture = - new _Future.zoneValue(false, Zone.root); + new _Future.zoneValue(false, _rootZone); /** * Creates a future containing the result of calling [computation] @@ -226,14 +224,14 @@ abstract class Future { if (result is Future) { return result; } else { - return new _Future.value(result); + // TODO(40014): Remove cast when type promotion works. + return new _Future.value(result as dynamic); } } catch (error, stackTrace) { var future = new _Future(); - AsyncError replacement = Zone.current.errorCallback(error, stackTrace); + AsyncError? replacement = Zone.current.errorCallback(error, stackTrace); if (replacement != null) { - future._asyncCompleteError( - _nonNullError(replacement.error), replacement.stackTrace); + future._asyncCompleteError(replacement.error, replacement.stackTrace); } else { future._asyncCompleteError(error, stackTrace); } @@ -253,11 +251,15 @@ abstract class Future { * with the [value] value, * equivalently to `new Future.sync(() => value)`. * + * If [value] is omitted or `null`, it is converted to `FutureOr` by + * `value as FutureOr`. If `T` is not nullable, then the [value] is + * required, otherwise the construction throws. + * * Use [Completer] to create a future and complete it later. */ @pragma("vm:entry-point") - factory Future.value([FutureOr value]) { - return new _Future.immediate(value); + factory Future.value([FutureOr? value]) { + return new _Future.immediate(value == null ? value as dynamic : value); } /** @@ -268,16 +270,15 @@ abstract class Future { * If an error handler isn't added before the future completes, the error * will be considered unhandled. * - * The [error] must not be `null`. - * * Use [Completer] to create a future and complete it later. */ - factory Future.error(Object error, [StackTrace stackTrace]) { + factory Future.error(Object error, [StackTrace? stackTrace]) { + // TODO(40614): Remove once non-nullability is sound. ArgumentError.checkNotNull(error, "error"); if (!identical(Zone.current, _rootZone)) { - AsyncError replacement = Zone.current.errorCallback(error, stackTrace); + AsyncError? replacement = Zone.current.errorCallback(error, stackTrace); if (replacement != null) { - error = _nonNullError(replacement.error); + error = replacement.error; stackTrace = replacement.stackTrace; } } @@ -302,6 +303,7 @@ abstract class Future { * If [computation] is omitted, * it will be treated as if [computation] was `() => null`, * and the future will eventually complete with the `null` value. + * In that case, [T] must be nullable. * * If calling [computation] throws, the created future will complete with the * error. @@ -309,11 +311,15 @@ abstract class Future { * See also [Completer] for a way to create and complete a future at a * later time that isn't necessarily after a known fixed duration. */ - factory Future.delayed(Duration duration, [FutureOr computation()]) { + factory Future.delayed(Duration duration, [FutureOr computation()?]) { + if (computation == null && !typeAcceptsNull()) { + throw ArgumentError.value( + null, "computation", "The type parameter is not nullable"); + } _Future result = new _Future(); new Timer(duration, () { if (computation == null) { - result._complete(null); + result._complete(null as T); } else { try { result._complete(computation()); @@ -355,25 +361,25 @@ abstract class Future { * uncaught asynchronous error. */ static Future> wait(Iterable> futures, - {bool eagerError: false, void cleanUp(T successValue)}) { + {bool eagerError = false, void cleanUp(T successValue)?}) { final _Future> result = new _Future>(); - List values; // Collects the values. Set to null on error. + List? values; // Collects the values. Set to null on error. int remaining = 0; // How many futures are we waiting for. - var error; // The first error from a future. - StackTrace stackTrace; // The stackTrace that came with the error. + late Object error; // The first error from a future. + late StackTrace stackTrace; // The stackTrace that came with the error. // Handle an error from any of the futures. - // TODO(jmesserly): use `void` return type once it can be inferred for the - // `then` call below. - handleError(Object theError, StackTrace theStackTrace) { + void handleError(Object theError, StackTrace theStackTrace) { remaining--; - if (values != null) { + List? valueList = values; + if (valueList != null) { if (cleanUp != null) { - for (var value in values) { + for (var value in valueList) { if (value != null) { // Ensure errors from cleanUp are uncaught. + T cleanUpValue = value; new Future.sync(() { - cleanUp(value); + cleanUp(cleanUpValue); }); } } @@ -397,10 +403,11 @@ abstract class Future { int pos = remaining; future.then((T value) { remaining--; - if (values != null) { - values[pos] = value; + List? valueList = values; + if (valueList != null) { + valueList[pos] = value; if (remaining == 0) { - result._completeWithValue(values); + result._completeWithValue(List.from(valueList)); } } else { if (cleanUp != null && value != null) { @@ -410,6 +417,8 @@ abstract class Future { }); } if (remaining == 0 && !eagerError) { + // If eagerError is false, and valueList is null, then + // error and stackTrace have been set in handleError above. result._completeError(error, stackTrace); } } @@ -420,12 +429,14 @@ abstract class Future { remaining++; } if (remaining == 0) { - return new Future.value(const []); + return new Future>.value(const []); } - values = new List(remaining); + values = new List.filled(remaining, null); } catch (e, st) { // The error must have been thrown while iterating over the futures // list, or while installing a callback handler on the future. + // This is a breach of the `Future` protocol, but we try to handle it + // gracefully. if (remaining == 0 || eagerError) { // Throw a new Future.error. // Don't just call `result._completeError` since that would propagate @@ -458,12 +469,14 @@ abstract class Future { */ static Future any(Iterable> futures) { var completer = new Completer.sync(); - var onValue = (T value) { + void onValue(T value) { if (!completer.isCompleted) completer.complete(value); - }; - var onError = (error, StackTrace stack) { + } + + void onError(Object error, StackTrace stack) { if (!completer.isCompleted) completer.completeError(error, stack); - }; + } + for (var future in futures) { future.then(onValue, onError: onError); } @@ -499,7 +512,7 @@ abstract class Future { } // Constant `true` function, used as callback by [forEach]. - static bool _kTrue(_) => true; + static bool _kTrue(Object? _) => true; /** * Performs an operation repeatedly until it returns `false`. @@ -524,8 +537,8 @@ abstract class Future { * until that future has completed. */ static Future doWhile(FutureOr action()) { - _Future doneSignal = new _Future(); - void Function(bool) nextIteration; + _Future doneSignal = new _Future(); + late void Function(bool) nextIteration; // Bind this callback explicitly so that each iteration isn't bound in the // context of all the previous iterations' callbacks. // This avoids, e.g., deeply nested stack traces from the stack trace @@ -545,7 +558,8 @@ abstract class Future { result.then(nextIteration, onError: doneSignal._completeError); return; } - keepGoing = result; + // TODO(40014): Remove cast when type promotion works. + keepGoing = result as bool; } doneSignal._complete(null); }); @@ -601,7 +615,7 @@ abstract class Future { * has completed with an error then the error is reported as unhandled error. * See the description on [Future]. */ - Future then(FutureOr onValue(T value), {Function onError}); + Future then(FutureOr onValue(T value), {Function? onError}); /** * Handles errors emitted by this [Future]. @@ -640,7 +654,7 @@ abstract class Future { // - (dynamic, StackTrace) -> FutureOr // Given that there is a `test` function that is usually used to do an // `isCheck` we should also expect functions that take a specific argument. - Future catchError(Function onError, {bool test(Object error)}); + Future catchError(Function onError, {bool test(Object error)?}); /** * Registers a function to be called when this future completes. @@ -677,7 +691,7 @@ abstract class Future { * }); * } */ - Future whenComplete(FutureOr action()); + Future whenComplete(FutureOr action()); /** * Creates a [Stream] containing the result of this future. @@ -704,7 +718,7 @@ abstract class Future { * If `onTimeout` is omitted, a timeout will cause the returned future to * complete with a [TimeoutException]. */ - Future timeout(Duration timeLimit, {FutureOr onTimeout()}); + Future timeout(Duration timeLimit, {FutureOr onTimeout()?}); } /** @@ -712,9 +726,9 @@ abstract class Future { */ class TimeoutException implements Exception { /** Description of the cause of the timeout. */ - final String message; + final String? message; /** The duration that was exceeded. */ - final Duration duration; + final Duration? duration; TimeoutException(this.message, [this.duration]); @@ -858,6 +872,8 @@ abstract class Completer { * * The value must be either a value of type [T] * or a future of type `Future`. + * If the value is omitted or null, and `T` is not nullable, the call + * to `complete` throws. * * If the value is itself a future, the completer will wait for that future * to complete, and complete with the same result, whether it is a success @@ -867,7 +883,7 @@ abstract class Completer { * * All listeners on the future are informed about the value. */ - void complete([FutureOr value]); + void complete([FutureOr? value]); /** * Complete [future] with an error. @@ -877,8 +893,6 @@ abstract class Completer { * Completing a future with an error indicates that an exception was thrown * while trying to produce a value. * - * The [error] must not be `null`. - * * If `error` is a `Future`, the future itself is used as the error value. * If you want to complete with the result of the future, you can use: * ``` @@ -889,7 +903,7 @@ abstract class Completer { * theFuture.catchError(thisCompleter.completeError); * ``` */ - void completeError(Object error, [StackTrace stackTrace]); + void completeError(Object error, [StackTrace? stackTrace]); /** * Whether the [future] has been completed. @@ -907,28 +921,32 @@ abstract class Completer { } // Helper function completing a _Future with error, but checking the zone -// for error replacement first and missing stack trace. -void _completeWithErrorCallback(_Future result, error, StackTrace stackTrace) { - AsyncError replacement = Zone.current.errorCallback(error, stackTrace); +// for error replacement and missing stack trace first. +void _completeWithErrorCallback( + _Future result, Object error, StackTrace? stackTrace) { + AsyncError? replacement = Zone.current.errorCallback(error, stackTrace); if (replacement != null) { - error = _nonNullError(replacement.error); + error = replacement.error; stackTrace = replacement.stackTrace; + } else { + stackTrace ??= AsyncError.defaultStackTrace(error); } - stackTrace ??= AsyncError.defaultStackTrace(error); + if (stackTrace == null) throw "unreachable"; // TODO(40088). result._completeError(error, stackTrace); } // Like [_completeWithErrorCallback] but completes asynchronously. void _asyncCompleteWithErrorCallback( - _Future result, error, StackTrace stackTrace) { - AsyncError replacement = Zone.current.errorCallback(error, stackTrace); + _Future result, Object error, StackTrace? stackTrace) { + AsyncError? replacement = Zone.current.errorCallback(error, stackTrace); if (replacement != null) { - error = _nonNullError(replacement.error); + error = replacement.error; stackTrace = replacement.stackTrace; + } else { + stackTrace ??= AsyncError.defaultStackTrace(error); + } + if (stackTrace == null) { + throw "unreachable"; // TODO(lrn): Remove when type promotion works. } - stackTrace ??= AsyncError.defaultStackTrace(error); result._asyncCompleteError(error, stackTrace); } - -/** Helper function that converts `null` to a [NullThrownError]. */ -Object _nonNullError(Object error) => error ?? new NullThrownError(); diff --git a/sdk/lib/async/future_impl.dart b/sdk/lib/async/future_impl.dart index df685d52b45..3f337371d3d 100644 --- a/sdk/lib/async/future_impl.dart +++ b/sdk/lib/async/future_impl.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.async; /** The onValue and onError handlers return either a value or a future */ @@ -16,17 +14,20 @@ typedef dynamic _FutureAction(); abstract class _Completer implements Completer { final _Future future = new _Future(); - void complete([FutureOr value]); + void complete([FutureOr? value]); - void completeError(Object error, [StackTrace stackTrace]) { + void completeError(Object error, [StackTrace? stackTrace]) { + // TODO(40614): Remove once non-nullability is sound. ArgumentError.checkNotNull(error, "error"); if (!future._mayComplete) throw new StateError("Future already completed"); - AsyncError replacement = Zone.current.errorCallback(error, stackTrace); + AsyncError? replacement = Zone.current.errorCallback(error, stackTrace); if (replacement != null) { - error = _nonNullError(replacement.error); + error = replacement.error; stackTrace = replacement.stackTrace; + } else { + stackTrace ??= AsyncError.defaultStackTrace(error); } - stackTrace ??= AsyncError.defaultStackTrace(error); + if (stackTrace == null) throw "unreachable"; // TODO(40088) _completeError(error, stackTrace); } @@ -38,9 +39,9 @@ abstract class _Completer implements Completer { } class _AsyncCompleter extends _Completer { - void complete([FutureOr value]) { + void complete([FutureOr? value]) { if (!future._mayComplete) throw new StateError("Future already completed"); - future._asyncComplete(value); + future._asyncComplete(value == null ? value as dynamic : value); } void _completeError(Object error, StackTrace stackTrace) { @@ -49,9 +50,9 @@ class _AsyncCompleter extends _Completer { } class _SyncCompleter extends _Completer { - void complete([FutureOr value]) { + void complete([FutureOr? value]) { if (!future._mayComplete) throw new StateError("Future already completed"); - future._complete(value); + future._complete(value == null ? value as dynamic : value); } void _completeError(Object error, StackTrace stackTrace) { @@ -74,19 +75,19 @@ class _FutureListener { maskValue | maskError | maskTestError | maskWhencomplete; static const int stateIsAwait = 16; // Listeners on the same future are linked through this link. - _FutureListener _nextListener; + _FutureListener? _nextListener; // The future to complete when this listener is activated. final _Future result; // Which fields means what. final int state; // Used for then/whenDone callback and error test @pragma("vm:entry-point") - final Function callback; + final Function? callback; // Used for error callbacks. - final Function errorCallback; + final Function? errorCallback; _FutureListener.then( - this.result, _FutureOnValue onValue, Function errorCallback) + this.result, FutureOr Function(S) onValue, Function? errorCallback) : callback = onValue, errorCallback = errorCallback, state = (errorCallback == null) ? stateThen : stateThenOnerror; @@ -105,7 +106,7 @@ class _FutureListener { : errorCallback = null, state = stateWhencomplete; - Zone get _zone => result._zone; + _Zone get _zone => result._zone; bool get handlesValue => (state & maskValue != 0); bool get handlesError => (state & maskError != 0); @@ -113,20 +114,21 @@ class _FutureListener { bool get handlesComplete => (state & maskType == stateWhencomplete); bool get isAwait => (state & stateIsAwait != 0); - _FutureOnValue get _onValue { + FutureOr Function(S) get _onValue { assert(handlesValue); - return callback; + return callback as dynamic; } - Function get _onError => errorCallback; + Function? get _onError => errorCallback; + _FutureErrorTest get _errorTest { assert(hasErrorTest); - return callback; + return callback as dynamic; } _FutureAction get _whenCompleteAction { assert(handlesComplete); - return callback; + return callback as dynamic; } /// Whether this listener has an error callback. @@ -155,8 +157,8 @@ class _FutureListener { return _zone.runBinary( errorCallback, asyncError.error, asyncError.stackTrace); } else { - assert(errorCallback is dynamic Function(Object)); - return _zone.runUnary(errorCallback, asyncError.error); + return _zone.runUnary( + errorCallback as dynamic, asyncError.error); } } @@ -198,7 +200,7 @@ class _Future implements Future { * Until the future is completed, the field may hold the zone that * listener callbacks used to create this future should be run in. */ - final Zone _zone; + final _Zone _zone; /** * Either the result, a list of listeners or another future. @@ -219,9 +221,9 @@ class _Future implements Future { var _resultOrListeners; // This constructor is used by async/await. - _Future() : _zone = Zone.current; + _Future() : _zone = Zone._current; - _Future.immediate(FutureOr result) : _zone = Zone.current { + _Future.immediate(FutureOr result) : _zone = Zone._current { _asyncComplete(result); } @@ -231,12 +233,12 @@ class _Future implements Future { } _Future.immediateError(var error, StackTrace stackTrace) - : _zone = Zone.current { + : _zone = Zone._current { _asyncCompleteError(error, stackTrace); } /** Creates a future that is already completed with the value. */ - _Future.value(T value) : this.zoneValue(value, Zone.current); + _Future.value(T value) : this.zoneValue(value, Zone._current); bool get _mayComplete => _state == _stateIncomplete; bool get _isPendingComplete => _state == _statePendingComplete; @@ -245,14 +247,14 @@ class _Future implements Future { bool get _isComplete => _state >= _stateValue; bool get _hasError => _state == _stateError; - static List _continuationFunctions(_Future future) { - List result = null; + static List? _continuationFunctions(_Future future) { + List? result = null; while (true) { if (future._mayAddListener) return result; assert(!future._isComplete); assert(!future._isChained); // So _resultOrListeners contains listeners. - _FutureListener listener = future._resultOrListeners; + _FutureListener? listener = future._resultOrListeners; if (listener != null && listener._nextListener == null && listener.isAwait) { @@ -272,7 +274,7 @@ class _Future implements Future { _resultOrListeners = source; } - Future then(FutureOr f(T value), {Function onError}) { + Future then(FutureOr f(T value), {Function? onError}) { Zone currentZone = Zone.current; if (!identical(currentZone, _rootZone)) { f = currentZone.registerUnaryCallback, T>(f); @@ -300,7 +302,7 @@ class _Future implements Future { return result; } - Future catchError(Function onError, {bool test(error)}) { + Future catchError(Function onError, {bool test(Object error)?}) { _Future result = new _Future(); if (!identical(result._zone, _rootZone)) { onError = _registerErrorHandler(onError, result._zone); @@ -393,15 +395,17 @@ class _Future implements Future { } } - void _prependListeners(_FutureListener listeners) { + void _prependListeners(_FutureListener? listeners) { if (listeners == null) return; if (_mayAddListener) { - _FutureListener existingListeners = _resultOrListeners; + _FutureListener? existingListeners = _resultOrListeners; _resultOrListeners = listeners; if (existingListeners != null) { _FutureListener cursor = listeners; - while (cursor._nextListener != null) { - cursor = cursor._nextListener; + _FutureListener? next = cursor._nextListener; + while (next != null) { + cursor = next; + next = cursor._nextListener; } cursor._nextListener = existingListeners; } @@ -425,20 +429,20 @@ class _Future implements Future { } } - _FutureListener _removeListeners() { + _FutureListener? _removeListeners() { // Reverse listeners before returning them, so the resulting list is in // subscription order. assert(!_isComplete); - _FutureListener current = _resultOrListeners; + _FutureListener? current = _resultOrListeners; _resultOrListeners = null; return _reverseListeners(current); } - _FutureListener _reverseListeners(_FutureListener listeners) { - _FutureListener prev; - _FutureListener current = listeners; + _FutureListener? _reverseListeners(_FutureListener? listeners) { + _FutureListener? prev = null; + _FutureListener? current = listeners; while (current != null) { - _FutureListener next = current._nextListener; + _FutureListener? next = current._nextListener; current._nextListener = prev; prev = current; current = next; @@ -464,12 +468,7 @@ class _Future implements Future { // so use _complete instead of _completeWithValue. target._clearPendingComplete(); // Clear this first, it's set again. target._complete(value); - }, - // TODO(floitsch): eventually we would like to make this non-optional - // and dependent on the listeners of the target future. If none of - // the target future's listeners want to have the stack trace we don't - // need a trace. - onError: (error, [StackTrace stackTrace]) { + }, onError: (Object error, StackTrace stackTrace) { assert(target._isPendingComplete); target._completeError(error, stackTrace); }); @@ -492,11 +491,11 @@ class _Future implements Future { source = source._chainSource; } if (source._isComplete) { - _FutureListener listeners = target._removeListeners(); + _FutureListener? listeners = target._removeListeners(); target._cloneResult(source); _propagateToListeners(target, listeners); } else { - _FutureListener listeners = target._resultOrListeners; + _FutureListener? listeners = target._resultOrListeners; target._setChained(source); source._prependListeners(listeners); } @@ -511,8 +510,12 @@ class _Future implements Future { _chainForeignFuture(value, this); } } else { - _FutureListener listeners = _removeListeners(); - _setValue(value); + _FutureListener? listeners = _removeListeners(); + // TODO(40014): Remove cast when type promotion works. + // This would normally be `as T` but we use `as dynamic` to make the + // unneeded check be implict to match dart2js unsound optimizations in the + // user code. + _setValue(value as dynamic); // Value promoted to T. _propagateToListeners(this, listeners); } } @@ -521,15 +524,15 @@ class _Future implements Future { assert(!_isComplete); assert(value is! Future); - _FutureListener listeners = _removeListeners(); + _FutureListener? listeners = _removeListeners(); _setValue(value); _propagateToListeners(this, listeners); } - void _completeError(Object error, [StackTrace stackTrace]) { + void _completeError(Object error, StackTrace stackTrace) { assert(!_isComplete); - _FutureListener listeners = _removeListeners(); + _FutureListener? listeners = _removeListeners(); _setError(error, stackTrace); _propagateToListeners(this, listeners); } @@ -551,7 +554,11 @@ class _Future implements Future { _chainFuture(value); return; } - _asyncCompleteWithValue(value); + // TODO(40014): Remove cast when type promotion works. + // This would normally be `as T` but we use `as dynamic` to make the + // unneeded check be implict to match dart2js unsound optimizations in the + // user code. + _asyncCompleteWithValue(value as dynamic); // Value promoted to T. } void _asyncCompleteWithValue(T value) { @@ -578,7 +585,7 @@ class _Future implements Future { _chainForeignFuture(value, this); } - void _asyncCompleteError(error, StackTrace stackTrace) { + void _asyncCompleteError(Object error, StackTrace stackTrace) { assert(!_isComplete); _setPendingComplete(); @@ -591,7 +598,8 @@ class _Future implements Future { * Propagates the value/error of [source] to its [listeners], executing the * listeners' callbacks. */ - static void _propagateToListeners(_Future source, _FutureListener listeners) { + static void _propagateToListeners( + _Future source, _FutureListener? listeners) { while (true) { assert(source._isComplete); bool hasError = source._hasError; @@ -606,13 +614,15 @@ class _Future implements Future { // Usually futures only have one listener. If they have several, we // call handle them separately in recursive calls, continuing // here only when there is only one listener left. - while (listeners._nextListener != null) { - _FutureListener listener = listeners; - listeners = listener._nextListener; + _FutureListener listener = listeners; + _FutureListener? nextListener = listener._nextListener; + while (nextListener != null) { listener._nextListener = null; _propagateToListeners(source, listener); + listener = nextListener; + nextListener = listener._nextListener; } - _FutureListener listener = listeners; + final sourceResult = source._resultOrListeners; // Do the actual propagation. // Set initial state of listenerHasError and listenerValueOrError. These @@ -628,7 +638,7 @@ class _Future implements Future { // expensive, branch. Here we'll enter/leave the zone. Many futures // don't have callbacks, so this is a significant optimization. if (hasError || listener.handlesValue || listener.handlesComplete) { - Zone zone = listener._zone; + _Zone zone = listener._zone; if (hasError && !source._zone.inSameErrorZone(zone)) { // Don't cross zone boundaries with errors. AsyncError asyncError = source._error; @@ -637,8 +647,8 @@ class _Future implements Future { return; } - Zone oldZone; - if (!identical(Zone.current, zone)) { + _Zone? oldZone; + if (!identical(Zone._current, zone)) { // Change zone if it's not current. oldZone = Zone._enter(zone); } @@ -663,15 +673,15 @@ class _Future implements Future { listenerHasError = true; return; } - if (completeResult is Future) { - if (completeResult is _Future && completeResult._isComplete) { - if (completeResult._hasError) { - listenerValueOrError = completeResult._error; - listenerHasError = true; - } - // Otherwise use the existing result of source. - return; + if (completeResult is _Future && completeResult._isComplete) { + if (completeResult._hasError) { + listenerValueOrError = completeResult._error; + listenerHasError = true; } + // Otherwise use the existing result of source. + return; + } + if (completeResult is Future) { // We have to wait for the completeResult future to complete // before knowing if it's an error or we should use the result // of source. @@ -758,21 +768,24 @@ class _Future implements Future { } } - Future timeout(Duration timeLimit, {FutureOr onTimeout()}) { + Future timeout(Duration timeLimit, {FutureOr onTimeout()?}) { if (_isComplete) return new _Future.immediate(this); _Future result = new _Future(); Timer timer; if (onTimeout == null) { timer = new Timer(timeLimit, () { result._completeError( - new TimeoutException("Future not completed", timeLimit)); + new TimeoutException("Future not completed", timeLimit), + StackTrace.empty); }); } else { Zone zone = Zone.current; - onTimeout = zone.registerCallback(onTimeout); + FutureOr Function() onTimeoutHandler = + zone.registerCallback(onTimeout); + timer = new Timer(timeLimit, () { try { - result._complete(zone.run(onTimeout)); + result._complete(zone.run(onTimeoutHandler)); } catch (e, s) { result._completeError(e, s); } @@ -783,7 +796,7 @@ class _Future implements Future { timer.cancel(); result._completeWithValue(v); } - }, onError: (e, StackTrace s) { + }, onError: (Object e, StackTrace s) { if (timer.isActive) { timer.cancel(); result._completeError(e, s); diff --git a/sdk/lib/async/schedule_microtask.dart b/sdk/lib/async/schedule_microtask.dart index 40f65237912..940989ca495 100644 --- a/sdk/lib/async/schedule_microtask.dart +++ b/sdk/lib/async/schedule_microtask.dart @@ -2,22 +2,20 @@ // 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.6 - part of dart.async; typedef void _AsyncCallback(); class _AsyncCallbackEntry { final _AsyncCallback callback; - _AsyncCallbackEntry next; + _AsyncCallbackEntry? next; _AsyncCallbackEntry(this.callback); } /** Head of single linked list of pending callbacks. */ -_AsyncCallbackEntry _nextCallback; +_AsyncCallbackEntry? _nextCallback; /** Tail of single linked list of pending callbacks. */ -_AsyncCallbackEntry _lastCallback; +_AsyncCallbackEntry? _lastCallback; /** * Tail of priority callbacks added by the currently executing callback. * @@ -25,7 +23,7 @@ _AsyncCallbackEntry _lastCallback; * callback queue, so that if one callback schedules more than one * priority callback, they are still enqueued in scheduling order. */ -_AsyncCallbackEntry _lastPriorityCallback; +_AsyncCallbackEntry? _lastPriorityCallback; /** * Whether we are currently inside the callback loop. * @@ -35,11 +33,11 @@ _AsyncCallbackEntry _lastPriorityCallback; bool _isInCallbackLoop = false; void _microtaskLoop() { - while (_nextCallback != null) { + for (var entry = _nextCallback; entry != null; entry = _nextCallback) { _lastPriorityCallback = null; - _AsyncCallbackEntry entry = _nextCallback; - _nextCallback = entry.next; - if (_nextCallback == null) _lastCallback = null; + var next = entry.next; + _nextCallback = next; + if (next == null) _lastCallback = null; (entry.callback)(); } } @@ -67,13 +65,14 @@ void _startMicrotaskLoop() { */ void _scheduleAsyncCallback(_AsyncCallback callback) { _AsyncCallbackEntry newEntry = new _AsyncCallbackEntry(callback); - if (_nextCallback == null) { + _AsyncCallbackEntry? lastCallback = _lastCallback; + if (lastCallback == null) { _nextCallback = _lastCallback = newEntry; if (!_isInCallbackLoop) { _AsyncRun._scheduleImmediate(_startMicrotaskLoop); } } else { - _lastCallback.next = newEntry; + lastCallback.next = newEntry; _lastCallback = newEntry; } } @@ -93,14 +92,16 @@ void _schedulePriorityAsyncCallback(_AsyncCallback callback) { return; } _AsyncCallbackEntry entry = new _AsyncCallbackEntry(callback); - if (_lastPriorityCallback == null) { + _AsyncCallbackEntry? lastPriorityCallback = _lastPriorityCallback; + if (lastPriorityCallback == null) { entry.next = _nextCallback; _nextCallback = _lastPriorityCallback = entry; } else { - entry.next = _lastPriorityCallback.next; - _lastPriorityCallback.next = entry; + var next = lastPriorityCallback.next; + entry.next = next; + lastPriorityCallback.next = entry; _lastPriorityCallback = entry; - if (entry.next == null) { + if (next == null) { _lastCallback = entry; } } @@ -131,8 +132,8 @@ void _schedulePriorityAsyncCallback(_AsyncCallback callback) { * Learn how Dart handles the event queue and microtask queue, so you can write * better asynchronous code with fewer surprises. */ -void scheduleMicrotask(void callback()) { - _Zone currentZone = Zone.current; +void scheduleMicrotask(void Function() callback) { + _Zone currentZone = Zone._current; if (identical(_rootZone, currentZone)) { // No need to bind the callback. We know that the root's scheduleMicrotask // will be invoked in the root zone. @@ -151,5 +152,5 @@ void scheduleMicrotask(void callback()) { class _AsyncRun { /** Schedule the given callback before any other event in the event-loop. */ - external static void _scheduleImmediate(void callback()); + external static void _scheduleImmediate(void Function() callback); } diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart index 4aae043619d..46ec1617af3 100644 --- a/sdk/lib/async/stream.dart +++ b/sdk/lib/async/stream.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.async; // ------------------------------------------------------------------- @@ -65,7 +63,7 @@ typedef void _TimerCallback(); * call occurs. * For example, the [first] getter listens to the stream, then returns the first * event that listener receives. - * This is not necessarily the first event emitted by the stream, but the first + * This is not necessarily the first even emitted by the stream, but the first * of the *remaining* events of the broadcast stream. * * When the "done" event is fired, subscribers are unsubscribed before @@ -132,7 +130,6 @@ abstract class Stream { * * This stream emits a single error event of [error] and [stackTrace] * and then completes with a done event. - * The [error] must not be `null`. * * Example: * ```dart @@ -153,7 +150,8 @@ abstract class Stream { * stack trace as well. */ @Since("2.5") - factory Stream.error(Object error, [StackTrace stackTrace]) { + factory Stream.error(Object error, [StackTrace? stackTrace]) { + // TODO(40614): Remove once non-nullability is sound. ArgumentError.checkNotNull(error, "error"); return (_AsyncStreamController(null, null, null, null) .._addError(error, stackTrace ?? AsyncError.defaultStackTrace(error)) @@ -205,18 +203,20 @@ abstract class Stream { // Declare these as variables holding closures instead of as // function declarations. // This avoids creating a new closure from the functions for each future. - var onValue = (T value) { + void onValue(T value) { if (!controller.isClosed) { controller._add(value); if (--count == 0) controller._closeUnchecked(); } - }; - var onError = (error, StackTrace stack) { + } + + void onError(Object error, StackTrace stack) { if (!controller.isClosed) { controller._addError(error, stack); if (--count == 0) controller._closeUnchecked(); } - }; + } + // The futures are already running, so start listening to them immediately // (instead of waiting for the stream to be listened on). // If we wait, we might not catch errors in the futures in time. @@ -254,65 +254,59 @@ abstract class Stream { * this callback is an integer that starts with 0 and is incremented for * every event. * + * The [period] must a non-negative [Duration]. + * * If [computation] is omitted the event values will all be `null`. * - * [period] must a non-negative [Duration]. + * The [computation] must not be omitted if the event type [T] does not + * allow `null` as a value. */ factory Stream.periodic(Duration period, - [T computation(int computationCount)]) { - Timer timer; - int computationCount = 0; - StreamController controller; + [T computation(int computationCount)?]) { + if (computation == null && !typeAcceptsNull()) { + throw ArgumentError.value(null, "computation", + "Must not be omitted when the event type is non-nullable"); + } + var controller = _SyncStreamController(null, null, null, null); // Counts the time that the Stream was running (and not paused). Stopwatch watch = new Stopwatch(); - - void sendEvent() { - watch.reset(); - T data; - if (computation != null) { - try { - data = computation(computationCount++); - } catch (e, s) { - controller.addError(e, s); - return; + controller.onListen = () { + int computationCount = 0; + void sendEvent(_) { + watch.reset(); + if (computation != null) { + T event; + try { + event = computation(computationCount++); + } catch (e, s) { + controller.addError(e, s); + return; + } + controller.add(event); + } else { + controller.add(null as T); // We have checked that null is T. } } - controller.add(data); - } - void startPeriodicTimer() { - assert(timer == null); - timer = new Timer.periodic(period, (Timer timer) { - sendEvent(); - }); - } - - controller = new StreamController( - sync: true, - onListen: () { - watch.start(); - startPeriodicTimer(); - }, - onPause: () { + Timer timer = Timer.periodic(period, sendEvent); + controller + ..onCancel = () { timer.cancel(); - timer = null; + return Future._nullFuture; + } + ..onPause = () { watch.stop(); - }, - onResume: () { - assert(timer == null); + timer.cancel(); + } + ..onResume = () { Duration elapsed = watch.elapsed; watch.start(); timer = new Timer(period - elapsed, () { - timer = null; - startPeriodicTimer(); - sendEvent(); + timer = Timer.periodic(period, sendEvent); + sendEvent(null); }); - }, - onCancel: () { - if (timer != null) timer.cancel(); - timer = null; - return Future._nullFuture; - }); + }; + }; return controller.stream; } @@ -357,7 +351,7 @@ abstract class Stream { * The resulting stream is a broadcast stream if [source] is. */ factory Stream.eventTransformed( - Stream source, EventSink mapSink(EventSink sink)) { + Stream source, EventSink mapSink(EventSink sink)) { return new _BoundSinkStream(source, mapSink); } @@ -399,8 +393,8 @@ abstract class Stream { * subscription when there are no listeners. */ Stream asBroadcastStream( - {void onListen(StreamSubscription subscription), - void onCancel(StreamSubscription subscription)}) { + {void onListen(StreamSubscription subscription)?, + void onCancel(StreamSubscription subscription)?}) { return new _AsBroadcastStream(this, onListen, onCancel); } @@ -418,8 +412,8 @@ abstract class Stream { * On errors from this stream, the [onError] handler is called with the * error object and possibly a stack trace. * - * The [onError] callback must be of type `void onError(error)` or - * `void onError(error, StackTrace stackTrace)`. If [onError] accepts + * The [onError] callback must be of type `void onError(Object error)` or + * `void onError(Object error, StackTrace stackTrace)`. If [onError] accepts * two arguments it is called with the error object and the stack trace * (which could be `null` if this stream itself received an error without * stack trace). @@ -439,8 +433,8 @@ abstract class Stream { * the subscription doesn't receive events and none of the * event handler functions are called. */ - StreamSubscription listen(void onData(T event), - {Function onError, void onDone(), bool cancelOnError}); + StreamSubscription listen(void onData(T event)?, + {Function? onError, void onDone()?, bool? cancelOnError}); /** * Creates a new stream from this stream that discards some elements. @@ -501,14 +495,23 @@ abstract class Stream { */ Stream asyncMap(FutureOr convert(T event)) { _StreamControllerBase controller; - StreamSubscription subscription; + if (isBroadcast) { + controller = _SyncBroadcastStreamController(null, null); + } else { + controller = _SyncStreamController(null, null, null, null); + } + + controller.onListen = () { + StreamSubscription subscription = this.listen(null, + onError: controller._addError, // Avoid Zone error replacement. + onDone: controller.close); + FutureOr add(E value) { + controller.add(value); + } - void onListen() { - final add = controller.add; - assert(controller is _StreamController || - controller is _BroadcastStreamController); final addError = controller._addError; - subscription = this.listen((T event) { + final resume = subscription.resume; + subscription.onData((T event) { FutureOr newValue; try { newValue = convert(event); @@ -518,34 +521,19 @@ abstract class Stream { } if (newValue is Future) { subscription.pause(); - newValue - .then(add, onError: addError) - .whenComplete(subscription.resume); + newValue.then(add, onError: addError).whenComplete(resume); } else { - controller.add(newValue); + // TODO(40014): Remove cast when type promotion works. + controller.add(newValue as dynamic); } - }, onError: addError, onDone: controller.close); - } - - if (this.isBroadcast) { - controller = new StreamController.broadcast( - onListen: onListen, - onCancel: () { - subscription.cancel(); - }, - sync: true); - } else { - controller = new StreamController( - onListen: onListen, - onPause: () { - subscription.pause(); - }, - onResume: () { - subscription.resume(); - }, - onCancel: () => subscription.cancel(), - sync: true); - } + }); + controller.onCancel = subscription.cancel; + if (!isBroadcast) { + controller + ..onPause = subscription.pause + ..onResume = resume; + } + }; return controller.stream; } @@ -567,14 +555,20 @@ abstract class Stream { * * The returned stream is a broadcast stream if this stream is. */ - Stream asyncExpand(Stream convert(T event)) { + Stream asyncExpand(Stream? convert(T event)) { _StreamControllerBase controller; - StreamSubscription subscription; - void onListen() { - assert(controller is _StreamController || - controller is _BroadcastStreamController); - subscription = this.listen((T event) { - Stream newStream; + if (isBroadcast) { + controller = _SyncBroadcastStreamController(null, null); + } else { + controller = _SyncStreamController(null, null, null, null); + } + + controller.onListen = () { + StreamSubscription subscription = this.listen(null, + onError: controller._addError, // Avoid Zone error replacement. + onDone: controller.close); + subscription.onData((T event) { + Stream? newStream; try { newStream = convert(event); } catch (e, s) { @@ -585,30 +579,14 @@ abstract class Stream { subscription.pause(); controller.addStream(newStream).whenComplete(subscription.resume); } - }, - onError: controller._addError, // Avoid Zone error replacement. - onDone: controller.close); - } - - if (this.isBroadcast) { - controller = new StreamController.broadcast( - onListen: onListen, - onCancel: () { - subscription.cancel(); - }, - sync: true); - } else { - controller = new StreamController( - onListen: onListen, - onPause: () { - subscription.pause(); - }, - onResume: () { - subscription.resume(); - }, - onCancel: () => subscription.cancel(), - sync: true); - } + }); + controller.onCancel = subscription.cancel; + if (!isBroadcast) { + controller + ..onPause = subscription.pause + ..onResume = subscription.resume; + } + }; return controller.stream; } @@ -618,8 +596,8 @@ abstract class Stream { * If this stream sends an error that matches [test], then it is intercepted * by the [onError] function. * - * The [onError] callback must be of type `void onError(error)` or - * `void onError(error, StackTrace stackTrace)`. + * The [onError] callback must be of type `void onError(Object error)` or + * `void onError(Object error, StackTrace stackTrace)`. * The function type determines whether [onError] is invoked with a stack * trace argument. * The stack trace argument may be `null` if this stream received an error @@ -644,7 +622,7 @@ abstract class Stream { * If a broadcast stream is listened to more than once, each subscription * will individually perform the `test` and handle the error. */ - Stream handleError(Function onError, {bool test(error)}) { + Stream handleError(Function onError, {bool test(error)?}) { return new _HandleErrorStream(this, onError, test); } @@ -744,35 +722,32 @@ abstract class Stream { Future reduce(T combine(T previous, T element)) { _Future result = new _Future(); bool seenFirst = false; - T value; - StreamSubscription subscription; - subscription = this.listen( - (T element) { - if (seenFirst) { - _runUserCode(() => combine(value, element), (T newValue) { - value = newValue; - }, _cancelAndErrorClosure(subscription, result)); - } else { - value = element; - seenFirst = true; - } - }, - onError: result._completeError, - onDone: () { - if (!seenFirst) { - try { - // Throw and recatch, instead of just doing - // _completeWithErrorCallback, e, theError, StackTrace.current), - // to ensure that the stackTrace is set on the error. - throw IterableElementError.noElement(); - } catch (e, s) { - _completeWithErrorCallback(result, e, s); - } - } else { - result._complete(value); - } - }, - cancelOnError: true); + late T value; + StreamSubscription subscription = + this.listen(null, onError: result._completeError, onDone: () { + if (!seenFirst) { + try { + // Throw and recatch, instead of just doing + // _completeWithErrorCallback, e, theError, StackTrace.current), + // to ensure that the stackTrace is set on the error. + throw IterableElementError.noElement(); + } catch (e, s) { + _completeWithErrorCallback(result, e, s); + } + } else { + result._complete(value); + } + }, cancelOnError: true); + subscription.onData((T element) { + if (seenFirst) { + _runUserCode(() => combine(value, element), (T newValue) { + value = newValue; + }, _cancelAndErrorClosure(subscription, result)); + } else { + value = element; + seenFirst = true; + } + }); return result; } @@ -796,18 +771,15 @@ abstract class Stream { Future fold(S initialValue, S combine(S previous, T element)) { _Future result = new _Future(); S value = initialValue; - StreamSubscription subscription; - subscription = this.listen( - (T element) { - _runUserCode(() => combine(value, element), (S newValue) { - value = newValue; - }, _cancelAndErrorClosure(subscription, result)); - }, - onError: result._completeError, - onDone: () { - result._complete(value); - }, - cancelOnError: true); + StreamSubscription subscription = + this.listen(null, onError: result._completeError, onDone: () { + result._complete(value); + }, cancelOnError: true); + subscription.onData((T element) { + _runUserCode(() => combine(value, element), (S newValue) { + value = newValue; + }, _cancelAndErrorClosure(subscription, result)); + }); return result; } @@ -828,25 +800,30 @@ abstract class Stream { Future join([String separator = ""]) { _Future result = new _Future(); StringBuffer buffer = new StringBuffer(); - StreamSubscription subscription; bool first = true; - subscription = this.listen( - (T element) { - if (!first) { - buffer.write(separator); + StreamSubscription subscription = + this.listen(null, onError: result._completeError, onDone: () { + result._complete(buffer.toString()); + }, cancelOnError: true); + subscription.onData(separator.isEmpty + ? (T element) { + try { + buffer.write(element); + } catch (e, s) { + _cancelAndErrorWithReplacement(subscription, result, e, s); + } } - first = false; - try { - buffer.write(element); - } catch (e, s) { - _cancelAndErrorWithReplacement(subscription, result, e, s); - } - }, - onError: result._completeError, - onDone: () { - result._complete(buffer.toString()); - }, - cancelOnError: true); + : (T element) { + if (!first) { + buffer.write(separator); + } + first = false; + try { + buffer.write(element); + } catch (e, s) { + _cancelAndErrorWithReplacement(subscription, result, e, s); + } + }); return result; } @@ -862,22 +839,19 @@ abstract class Stream { * the returned future is completed with that error, * and processing stops. */ - Future contains(Object needle) { + Future contains(Object? needle) { _Future future = new _Future(); - StreamSubscription subscription; - subscription = this.listen( - (T element) { - _runUserCode(() => (element == needle), (bool isMatch) { - if (isMatch) { - _cancelAndValue(subscription, future, true); - } - }, _cancelAndErrorClosure(subscription, future)); - }, - onError: future._completeError, - onDone: () { - future._complete(false); - }, - cancelOnError: true); + StreamSubscription subscription = + this.listen(null, onError: future._completeError, onDone: () { + future._complete(false); + }, cancelOnError: true); + subscription.onData((T element) { + _runUserCode(() => (element == needle), (bool isMatch) { + if (isMatch) { + _cancelAndValue(subscription, future, true); + } + }, _cancelAndErrorClosure(subscription, future)); + }); return future; } @@ -893,18 +867,14 @@ abstract class Stream { */ Future forEach(void action(T element)) { _Future future = new _Future(); - StreamSubscription subscription; - subscription = this.listen( - (T element) { - // TODO(floitsch): the type should be 'void' and inferred. - _runUserCode(() => action(element), (_) {}, - _cancelAndErrorClosure(subscription, future)); - }, - onError: future._completeError, - onDone: () { - future._complete(null); - }, - cancelOnError: true); + StreamSubscription subscription = + this.listen(null, onError: future._completeError, onDone: () { + future._complete(null); + }, cancelOnError: true); + subscription.onData((T element) { + _runUserCode(() => action(element), (_) {}, + _cancelAndErrorClosure(subscription, future)); + }); return future; } @@ -924,20 +894,17 @@ abstract class Stream { */ Future every(bool test(T element)) { _Future future = new _Future(); - StreamSubscription subscription; - subscription = this.listen( - (T element) { - _runUserCode(() => test(element), (bool isMatch) { - if (!isMatch) { - _cancelAndValue(subscription, future, false); - } - }, _cancelAndErrorClosure(subscription, future)); - }, - onError: future._completeError, - onDone: () { - future._complete(true); - }, - cancelOnError: true); + StreamSubscription subscription = + this.listen(null, onError: future._completeError, onDone: () { + future._complete(true); + }, cancelOnError: true); + subscription.onData((T element) { + _runUserCode(() => test(element), (bool isMatch) { + if (!isMatch) { + _cancelAndValue(subscription, future, false); + } + }, _cancelAndErrorClosure(subscription, future)); + }); return future; } @@ -957,20 +924,17 @@ abstract class Stream { */ Future any(bool test(T element)) { _Future future = new _Future(); - StreamSubscription subscription; - subscription = this.listen( - (T element) { - _runUserCode(() => test(element), (bool isMatch) { - if (isMatch) { - _cancelAndValue(subscription, future, true); - } - }, _cancelAndErrorClosure(subscription, future)); - }, - onError: future._completeError, - onDone: () { - future._complete(false); - }, - cancelOnError: true); + StreamSubscription subscription = + this.listen(null, onError: future._completeError, onDone: () { + future._complete(false); + }, cancelOnError: true); + subscription.onData((T element) { + _runUserCode(() => test(element), (bool isMatch) { + if (isMatch) { + _cancelAndValue(subscription, future, true); + } + }, _cancelAndErrorClosure(subscription, future)); + }); return future; } @@ -1018,16 +982,13 @@ abstract class Stream { */ Future get isEmpty { _Future future = new _Future(); - StreamSubscription subscription; - subscription = this.listen( - (_) { - _cancelAndValue(subscription, future, false); - }, - onError: future._completeError, - onDone: () { - future._complete(true); - }, - cancelOnError: true); + StreamSubscription subscription = + this.listen(null, onError: future._completeError, onDone: () { + future._complete(true); + }, cancelOnError: true); + subscription.onData((_) { + _cancelAndValue(subscription, future, false); + }); return future; } @@ -1109,9 +1070,15 @@ abstract class Stream { * * In case of a `done` event the future completes with the given * [futureValue]. + * + * The [futureValue] must not be omitted if `null` is not assignable to [E]. */ - Future drain([E futureValue]) => - listen(null, cancelOnError: true).asFuture(futureValue); + Future drain([E? futureValue]) { + if (futureValue == null) { + futureValue = futureValue as E; + } + return listen(null, cancelOnError: true).asFuture(futureValue); + } /** * Provides at most the first [count] data events of this stream. @@ -1226,7 +1193,7 @@ abstract class Stream { * If a broadcast stream is listened to more than once, each subscription * will individually perform the `equals` test. */ - Stream distinct([bool equals(T previous, T next)]) { + Stream distinct([bool equals(T previous, T next)?]) { return new _DistinctStream(this, equals); } @@ -1250,20 +1217,17 @@ abstract class Stream { */ Future get first { _Future future = new _Future(); - StreamSubscription subscription; - subscription = this.listen( - (T value) { - _cancelAndValue(subscription, future, value); - }, - onError: future._completeError, - onDone: () { - try { - throw IterableElementError.noElement(); - } catch (e, s) { - _completeWithErrorCallback(future, e, s); - } - }, - cancelOnError: true); + StreamSubscription subscription = + this.listen(null, onError: future._completeError, onDone: () { + try { + throw IterableElementError.noElement(); + } catch (e, s) { + _completeWithErrorCallback(future, e, s); + } + }, cancelOnError: true); + subscription.onData((T value) { + _cancelAndValue(subscription, future, value); + }); return future; } @@ -1279,7 +1243,7 @@ abstract class Stream { */ Future get last { _Future future = new _Future(); - T result; + late T result; bool foundResult = false; listen( (T value) { @@ -1314,36 +1278,33 @@ abstract class Stream { */ Future get single { _Future future = new _Future(); - T result; + late T result; bool foundResult = false; - StreamSubscription subscription; - subscription = this.listen( - (T value) { - if (foundResult) { - // This is the second element we get. - try { - throw IterableElementError.tooMany(); - } catch (e, s) { - _cancelAndErrorWithReplacement(subscription, future, e, s); - } - return; - } - foundResult = true; - result = value; - }, - onError: future._completeError, - onDone: () { - if (foundResult) { - future._complete(result); - return; - } - try { - throw IterableElementError.noElement(); - } catch (e, s) { - _completeWithErrorCallback(future, e, s); - } - }, - cancelOnError: true); + StreamSubscription subscription = + this.listen(null, onError: future._completeError, onDone: () { + if (foundResult) { + future._complete(result); + return; + } + try { + throw IterableElementError.noElement(); + } catch (e, s) { + _completeWithErrorCallback(future, e, s); + } + }, cancelOnError: true); + subscription.onData((T value) { + if (foundResult) { + // This is the second element we get. + try { + throw IterableElementError.tooMany(); + } catch (e, s) { + _cancelAndErrorWithReplacement(subscription, future, e, s); + } + return; + } + foundResult = true; + result = value; + }); return future; } @@ -1372,30 +1333,29 @@ abstract class Stream { * with no [orElse] function provided, * the returned future is completed with an error. */ - Future firstWhere(bool test(T element), {T orElse()}) { + Future firstWhere(bool test(T element), {T orElse()?}) { _Future future = new _Future(); - StreamSubscription subscription; - subscription = this.listen( - (T value) { - _runUserCode(() => test(value), (bool isMatch) { - if (isMatch) { - _cancelAndValue(subscription, future, value); - } - }, _cancelAndErrorClosure(subscription, future)); - }, - onError: future._completeError, - onDone: () { - if (orElse != null) { - _runUserCode(orElse, future._complete, future._completeError); - return; - } - try { - throw IterableElementError.noElement(); - } catch (e, s) { - _completeWithErrorCallback(future, e, s); - } - }, - cancelOnError: true); + StreamSubscription subscription = + this.listen(null, onError: future._completeError, onDone: () { + if (orElse != null) { + _runUserCode(orElse, future._complete, future._completeError); + return; + } + try { + // Sets stackTrace on error. + throw IterableElementError.noElement(); + } catch (e, s) { + _completeWithErrorCallback(future, e, s); + } + }, cancelOnError: true); + + subscription.onData((T value) { + _runUserCode(() => test(value), (bool isMatch) { + if (isMatch) { + _cancelAndValue(subscription, future, value); + } + }, _cancelAndErrorClosure(subscription, future)); + }); return future; } @@ -1410,37 +1370,35 @@ abstract class Stream { * That means that a non-error result cannot be provided before this stream * is done. */ - Future lastWhere(bool test(T element), {T orElse()}) { + Future lastWhere(bool test(T element), {T orElse()?}) { _Future future = new _Future(); - T result; + late T result; bool foundResult = false; - StreamSubscription subscription; - subscription = this.listen( - (T value) { - _runUserCode(() => true == test(value), (bool isMatch) { - if (isMatch) { - foundResult = true; - result = value; - } - }, _cancelAndErrorClosure(subscription, future)); - }, - onError: future._completeError, - onDone: () { - if (foundResult) { - future._complete(result); - return; - } - if (orElse != null) { - _runUserCode(orElse, future._complete, future._completeError); - return; - } - try { - throw IterableElementError.noElement(); - } catch (e, s) { - _completeWithErrorCallback(future, e, s); - } - }, - cancelOnError: true); + StreamSubscription subscription = + this.listen(null, onError: future._completeError, onDone: () { + if (foundResult) { + future._complete(result); + return; + } + if (orElse != null) { + _runUserCode(orElse, future._complete, future._completeError); + return; + } + try { + throw IterableElementError.noElement(); + } catch (e, s) { + _completeWithErrorCallback(future, e, s); + } + }, cancelOnError: true); + + subscription.onData((T value) { + _runUserCode(() => test(value), (bool isMatch) { + if (isMatch) { + foundResult = true; + result = value; + } + }, _cancelAndErrorClosure(subscription, future)); + }); return future; } @@ -1450,45 +1408,43 @@ abstract class Stream { * Like [lastWhere], except that it is an error if more than one * matching element occurs in this stream. */ - Future singleWhere(bool test(T element), {T orElse()}) { + Future singleWhere(bool test(T element), {T orElse()?}) { _Future future = new _Future(); - T result; + late T result; bool foundResult = false; - StreamSubscription subscription; - subscription = this.listen( - (T value) { - _runUserCode(() => true == test(value), (bool isMatch) { - if (isMatch) { - if (foundResult) { - try { - throw IterableElementError.tooMany(); - } catch (e, s) { - _cancelAndErrorWithReplacement(subscription, future, e, s); - } - return; - } - foundResult = true; - result = value; - } - }, _cancelAndErrorClosure(subscription, future)); - }, - onError: future._completeError, - onDone: () { + StreamSubscription subscription = + this.listen(null, onError: future._completeError, onDone: () { + if (foundResult) { + future._complete(result); + return; + } + if (orElse != null) { + _runUserCode(orElse, future._complete, future._completeError); + return; + } + try { + throw IterableElementError.noElement(); + } catch (e, s) { + _completeWithErrorCallback(future, e, s); + } + }, cancelOnError: true); + + subscription.onData((T value) { + _runUserCode(() => test(value), (bool isMatch) { + if (isMatch) { if (foundResult) { - future._complete(result); + try { + throw IterableElementError.tooMany(); + } catch (e, s) { + _cancelAndErrorWithReplacement(subscription, future, e, s); + } return; } - try { - if (orElse != null) { - _runUserCode(orElse, future._complete, future._completeError); - return; - } - throw IterableElementError.noElement(); - } catch (e, s) { - _completeWithErrorCallback(future, e, s); - } - }, - cancelOnError: true); + foundResult = true; + result = value; + } + }, _cancelAndErrorClosure(subscription, future)); + }); return future; } @@ -1509,26 +1465,25 @@ abstract class Stream { * with a [RangeError]. */ Future elementAt(int index) { - ArgumentError.checkNotNull(index, "index"); RangeError.checkNotNegative(index, "index"); - _Future future = new _Future(); - StreamSubscription subscription; + _Future result = new _Future(); int elementIndex = 0; - subscription = this.listen( - (T value) { - if (index == elementIndex) { - _cancelAndValue(subscription, future, value); - return; - } - elementIndex += 1; - }, - onError: future._completeError, - onDone: () { - future._completeError( - new RangeError.index(index, this, "index", null, elementIndex)); - }, - cancelOnError: true); - return future; + StreamSubscription subscription; + subscription = + this.listen(null, onError: result._completeError, onDone: () { + result._completeError( + new RangeError.index(index, this, "index", null, elementIndex), + StackTrace.empty); + }, cancelOnError: true); + subscription.onData((T value) { + if (index == elementIndex) { + _cancelAndValue(subscription, result, value); + return; + } + elementIndex += 1; + }); + + return result; } /** @@ -1558,81 +1513,78 @@ abstract class Stream { * will have its individually timer that starts counting on listen, * and the subscriptions' timers can be paused individually. */ - Stream timeout(Duration timeLimit, {void onTimeout(EventSink sink)}) { + Stream timeout(Duration timeLimit, {void onTimeout(EventSink sink)?}) { _StreamControllerBase controller; - // The following variables are set on listen. - StreamSubscription subscription; - Timer timer; - Zone zone; - _TimerCallback timeout; - - void onData(T event) { - timer.cancel(); - timer = zone.createTimer(timeLimit, timeout); - // It might close the stream and cancel timer, so create recuring Timer - // before calling into add(); - // issue: https://github.com/dart-lang/sdk/issues/37565 - controller.add(event); + if (isBroadcast) { + controller = new _SyncBroadcastStreamController(null, null); + } else { + controller = new _SyncStreamController(null, null, null, null); } - void onError(error, StackTrace stackTrace) { - timer.cancel(); - assert(controller is _StreamController || - controller is _BroadcastStreamController); - controller._addError(error, stackTrace); // Avoid Zone error replacement. - timer = zone.createTimer(timeLimit, timeout); + Zone zone = Zone.current; + // Register callback immediately. + _TimerCallback timeoutCallback; + if (onTimeout == null) { + timeoutCallback = () { + controller.addError( + new TimeoutException("No stream event", timeLimit), null); + }; + } else { + // TODO(floitsch): the return type should be 'void', and the type + // should be inferred. + var registeredOnTimeout = + zone.registerUnaryCallback>(onTimeout); + var wrapper = new _ControllerEventSinkWrapper(null); + timeoutCallback = () { + wrapper._sink = controller; // Only valid during call. + zone.runUnaryGuarded(registeredOnTimeout, wrapper); + wrapper._sink = null; + }; } - void onDone() { - timer.cancel(); - controller.close(); - } - - void onListen() { - // This is the onListen callback for of controller. - // It runs in the same zone that the subscription was created in. - // Use that zone for creating timers and running the onTimeout - // callback. - zone = Zone.current; - if (onTimeout == null) { - timeout = () { - controller.addError( - new TimeoutException("No stream event", timeLimit), null); - }; - } else { - // TODO(floitsch): the return type should be 'void', and the type - // should be inferred. - var registeredOnTimeout = - zone.registerUnaryCallback>(onTimeout); - var wrapper = new _ControllerEventSinkWrapper(null); - timeout = () { - wrapper._sink = controller; // Only valid during call. - zone.runUnaryGuarded(registeredOnTimeout, wrapper); - wrapper._sink = null; - }; - } - - subscription = this.listen(onData, onError: onError, onDone: onDone); - timer = zone.createTimer(timeLimit, timeout); - } - - Future onCancel() { - timer.cancel(); - Future result = subscription.cancel(); - subscription = null; - return result; - } - - controller = isBroadcast - ? new _SyncBroadcastStreamController(onListen, onCancel) - : new _SyncStreamController(onListen, () { - // Don't null the timer, onCancel may call cancel again. + // All further setup happens inside `onListen`. + controller.onListen = () { + Timer timer = zone.createTimer(timeLimit, timeoutCallback); + var subscription = this.listen(null); + // Set up event forwarding. Each data or error event resets the timer + subscription + ..onData((T event) { + timer.cancel(); + timer = zone.createTimer(timeLimit, timeoutCallback); + // Controller is synchronous, and the call might close the stream + // and cancel the timer, + // so create the Timer before calling into add(); + // issue: https://github.com/dart-lang/sdk/issues/37565 + controller.add(event); + }) + ..onError((Object error, StackTrace stackTrace) { + timer.cancel(); + timer = zone.createTimer(timeLimit, timeoutCallback); + controller._addError( + error, stackTrace); // Avoid Zone error replacement. + }) + ..onDone(() { + timer.cancel(); + controller.close(); + }); + // Set up further controller callbacks. + controller.onCancel = () { + timer.cancel(); + return subscription.cancel(); + }; + if (!isBroadcast) { + controller + ..onPause = () { timer.cancel(); subscription.pause(); - }, () { + } + ..onResume = () { subscription.resume(); - timer = zone.createTimer(timeLimit, timeout); - }, onCancel); + timer = zone.createTimer(timeLimit, timeoutCallback); + }; + } + }; + return controller.stream; } } @@ -1660,10 +1612,7 @@ abstract class StreamSubscription { * Returns a future that is completed once the stream has finished * its cleanup. * - * Historically returned `null` if no cleanup was necessary. - * Returning `null` is deprecated and should be avoided. - * - * Typically, futures are returned when the stream needs to release resources. + * Typically, cleanup happens when the stream needs to release resources. * For example, a stream might need to close an open file (as an asynchronous * operation). If the listener wants to delete the file after having * canceled the subscription, it must wait for the cleanup future to complete. @@ -1683,7 +1632,7 @@ abstract class StreamSubscription { * This method replaces the current handler set by the invocation of * [Stream.listen] or by a previous call to [onData]. */ - void onData(void handleData(T data)); + void onData(void handleData(T data)?); /** * Replaces the error event handler of this subscription. @@ -1702,7 +1651,7 @@ abstract class StreamSubscription { * This method replaces the current handler set by the invocation of * [Stream.listen], by calling [asFuture], or by a previous call to [onError]. */ - void onError(Function handleError); + void onError(Function? handleError); /** * Replaces the done event handler of this subscription. @@ -1713,7 +1662,7 @@ abstract class StreamSubscription { * This method replaces the current handler set by the invocation of * [Stream.listen], by calling [asFuture], or by a previous call to [onDone]. */ - void onDone(void handleDone()); + void onDone(void handleDone()?); /** * Request that the stream pauses events until further notice. @@ -1750,7 +1699,7 @@ abstract class StreamSubscription { * Currently DOM streams silently drop events when the stream is paused. This * is a bug and will be fixed. */ - void pause([Future resumeSignal]); + void pause([Future? resumeSignal]); /** * Resume after a pause. @@ -1788,8 +1737,12 @@ abstract class StreamSubscription { * * In case of a `done` event the future completes with the given * [futureValue]. + * + * If [futureValue] is omitted, the value `null as E` is used as a default. + * If `E` is not nullable, this will throw immediately when [asFuture] + * is called. */ - Future asFuture([E futureValue]); + Future asFuture([E? futureValue]); } /** @@ -1813,11 +1766,9 @@ abstract class EventSink implements Sink { /** * Adds an [error] to the sink. * - * The [error] must not be `null`. - * * Must not be called on a closed sink. */ - void addError(Object error, [StackTrace stackTrace]); + void addError(Object error, [StackTrace? stackTrace]); /** * Closes the sink. @@ -1840,12 +1791,12 @@ class StreamView extends Stream { bool get isBroadcast => _stream.isBroadcast; Stream asBroadcastStream( - {void onListen(StreamSubscription subscription), - void onCancel(StreamSubscription subscription)}) => + {void onListen(StreamSubscription subscription)?, + void onCancel(StreamSubscription subscription)?}) => _stream.asBroadcastStream(onListen: onListen, onCancel: onCancel); - StreamSubscription listen(void onData(T value), - {Function onError, void onDone(), bool cancelOnError}) { + StreamSubscription listen(void onData(T value)?, + {Function? onError, void onDone()?, bool? cancelOnError}) { return _stream.listen(onData, onError: onError, onDone: onDone, cancelOnError: cancelOnError); } @@ -2098,9 +2049,9 @@ abstract class StreamTransformer { * ``` */ factory StreamTransformer.fromHandlers( - {void handleData(S data, EventSink sink), - void handleError(Object error, StackTrace stackTrace, EventSink sink), - void handleDone(EventSink sink)}) = _StreamHandlerTransformer; + {void handleData(S data, EventSink sink)?, + void handleError(Object error, StackTrace stackTrace, EventSink sink)?, + void handleDone(EventSink sink)?}) = _StreamHandlerTransformer; /** * Creates a [StreamTransformer] based on a [bind] callback. @@ -2258,18 +2209,24 @@ abstract class StreamIterator { * Wraps an [_EventSink] so it exposes only the [EventSink] interface. */ class _ControllerEventSinkWrapper implements EventSink { - EventSink _sink; + EventSink? _sink; _ControllerEventSinkWrapper(this._sink); - void add(T data) { - _sink.add(data); + EventSink _ensureSink() { + var sink = _sink; + if (sink == null) throw StateError("Sink not available"); + return sink; } - void addError(error, [StackTrace stackTrace]) { - _sink.addError(error, stackTrace); + void add(T data) { + _ensureSink().add(data); + } + + void addError(error, [StackTrace? stackTrace]) { + _ensureSink().addError(error, stackTrace); } void close() { - _sink.close(); + _ensureSink().close(); } } diff --git a/sdk/lib/async/stream_controller.dart b/sdk/lib/async/stream_controller.dart index 396c53d8474..9688dd17ab8 100644 --- a/sdk/lib/async/stream_controller.dart +++ b/sdk/lib/async/stream_controller.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.async; // ------------------------------------------------------------------- @@ -17,10 +15,8 @@ typedef void ControllerCallback(); /** * Type of stream controller `onCancel` callbacks. - * - * The callback may return either `void` or a future. */ -typedef ControllerCancelCallback(); +typedef FutureOr ControllerCancelCallback(); /** * A controller with the stream it controls. @@ -74,18 +70,18 @@ abstract class StreamController implements StreamSink { * [onCancel] should return a future that completes when the cancel operation * is done. * - * If the stream is canceled before the controller needs new data the + * If the stream is canceled before the controller needs data the * [onResume] call might not be executed. */ factory StreamController( - {void onListen(), - void onPause(), - void onResume(), - onCancel(), - bool sync: false}) { + {void onListen()?, + void onPause()?, + void onResume()?, + FutureOr onCancel()?, + bool sync = false}) { return sync - ? new _SyncStreamController(onListen, onPause, onResume, onCancel) - : new _AsyncStreamController(onListen, onPause, onResume, onCancel); + ? _SyncStreamController(onListen, onPause, onResume, onCancel) + : _AsyncStreamController(onListen, onPause, onResume, onCancel); } /** @@ -140,10 +136,10 @@ abstract class StreamController implements StreamSink { * the [onListen] will be called again. */ factory StreamController.broadcast( - {void onListen(), void onCancel(), bool sync: false}) { + {void onListen()?, void onCancel()?, bool sync = false}) { return sync - ? new _SyncBroadcastStreamController(onListen, onCancel) - : new _AsyncBroadcastStreamController(onListen, onCancel); + ? _SyncBroadcastStreamController(onListen, onCancel) + : _AsyncBroadcastStreamController(onListen, onCancel); } /** @@ -151,9 +147,9 @@ abstract class StreamController implements StreamSink { * * May be set to `null`, in which case no callback will happen. */ - ControllerCallback get onListen; + void Function()? get onListen; - void set onListen(void onListenHandler()); + void set onListen(void onListenHandler()?); /** * The callback which is called when the stream is paused. @@ -162,9 +158,9 @@ abstract class StreamController implements StreamSink { * * Pause related callbacks are not supported on broadcast stream controllers. */ - ControllerCallback get onPause; + void Function()? get onPause; - void set onPause(void onPauseHandler()); + void set onPause(void onPauseHandler()?); /** * The callback which is called when the stream is resumed. @@ -173,18 +169,18 @@ abstract class StreamController implements StreamSink { * * Pause related callbacks are not supported on broadcast stream controllers. */ - ControllerCallback get onResume; + void Function()? get onResume; - void set onResume(void onResumeHandler()); + void set onResume(void onResumeHandler()?); /** * The callback which is called when the stream is canceled. * * May be set to `null`, in which case no callback will happen. */ - ControllerCancelCallback get onCancel; + FutureOr Function()? get onCancel; - void set onCancel(onCancelHandler()); + void set onCancel(FutureOr onCancelHandler()?); /** * Returns a view of this object that only exposes the [StreamSink] interface. @@ -237,14 +233,14 @@ abstract class StreamController implements StreamSink { /** * Sends or enqueues an error event. * - * The [error] must not be `null`. + * If [error] is `null`, it is replaced by a [NullThrownError]. * * Listeners receive this event at a later microtask. This behavior can be * overridden by using `sync` controllers. Note, however, that sync * controllers have to satisfy the preconditions mentioned in the * documentation of the constructors. */ - void addError(Object error, [StackTrace stackTrace]); + void addError(Object error, [StackTrace? stackTrace]); /** * Closes the stream. @@ -300,9 +296,9 @@ abstract class StreamController implements StreamSink { * forwarded to the controller's stream, and the `addStream` ends * after this. If [cancelOnError] is false, all errors are forwarded * and only a done event will end the `addStream`. - * If [cancelOnError] is omitted, it defaults to false. + * If [cancelOnError] is omitted or `null`, it defaults to false. */ - Future addStream(Stream source, {bool cancelOnError}); + Future addStream(Stream source, {bool? cancelOnError}); } /** @@ -388,12 +384,10 @@ abstract class SynchronousStreamController implements StreamController { /** * Adds error to the controller's stream. * - * The [error] must not be `null`. - * * As [StreamController.addError], but must not be called while an event is * being added by [add], [addError] or [close]. */ - void addError(Object error, [StackTrace stackTrace]); + void addError(Object error, [StackTrace? stackTrace]); /** * Closes the controller's stream. @@ -405,11 +399,11 @@ abstract class SynchronousStreamController implements StreamController { } abstract class _StreamControllerLifecycle { - StreamSubscription _subscribe( - void onData(T data), Function onError, void onDone(), bool cancelOnError); + StreamSubscription _subscribe(void onData(T data)?, Function? onError, + void onDone()?, bool cancelOnError); void _recordPause(StreamSubscription subscription) {} void _recordResume(StreamSubscription subscription) {} - Future _recordCancel(StreamSubscription subscription) => null; + Future? _recordCancel(StreamSubscription subscription) => null; } // Base type for implementations of stream controllers. @@ -479,10 +473,11 @@ abstract class _StreamController implements _StreamControllerBase { * * While [_state] is [_STATE_SUBSCRIBED], the field contains the subscription. * - * When [_state] is [_STATE_CANCELED] the field is currently not used. + * When [_state] is [_STATE_CANCELED] the field is currently not used, + * and will contain `null`. */ @pragma("vm:entry-point") - var _varData; + Object? _varData; /** Current state of the controller. */ @pragma("vm:entry-point") @@ -496,22 +491,22 @@ abstract class _StreamController implements _StreamControllerBase { // TODO(lrn): Could this be stored in the varData field too, if it's not // accessed until the call to "close"? Then we need to special case if it's // accessed earlier, or if close is called before subscribing. - _Future _doneFuture; + _Future? _doneFuture; - ControllerCallback onListen; - ControllerCallback onPause; - ControllerCallback onResume; - ControllerCancelCallback onCancel; + void Function()? onListen; + void Function()? onPause; + void Function()? onResume; + FutureOr Function()? onCancel; _StreamController(this.onListen, this.onPause, this.onResume, this.onCancel); // Return a new stream every time. The streams are equal, but not identical. - Stream get stream => new _ControllerStream(this); + Stream get stream => _ControllerStream(this); /** * Returns a view of this object that only exposes the [StreamSink] interface. */ - StreamSink get sink => new _StreamSinkWrapper(this); + StreamSink get sink => _StreamSinkWrapper(this); /** * Whether a listener has existed and been canceled. @@ -544,12 +539,12 @@ abstract class _StreamController implements _StreamControllerBase { // stream is listened to. // While adding a stream, pending events are moved into the // state object to allow the state object to use the _varData field. - _PendingEvents get _pendingEvents { + _PendingEvents? get _pendingEvents { assert(_isInitialState); if (!_isAddingStream) { - return _varData; + return _varData as dynamic; } - _StreamControllerAddStreamState state = _varData; + _StreamControllerAddStreamState state = _varData as dynamic; return state.varData; } @@ -557,12 +552,18 @@ abstract class _StreamController implements _StreamControllerBase { _StreamImplEvents _ensurePendingEvents() { assert(_isInitialState); if (!_isAddingStream) { - _varData ??= new _StreamImplEvents(); - return _varData; + Object? events = _varData; + if (events == null) { + _varData = events = _StreamImplEvents(); + } + return events as dynamic; } - _StreamControllerAddStreamState state = _varData; - if (state.varData == null) state.varData = new _StreamImplEvents(); - return state.varData; + _StreamControllerAddStreamState state = _varData as dynamic; + Object? events = state.varData; + if (events == null) { + state.varData = events = _StreamImplEvents(); + } + return events as dynamic; } // Get the current subscription. @@ -570,11 +571,12 @@ abstract class _StreamController implements _StreamControllerBase { // object to allow the state object to use the _varData field. _ControllerSubscription get _subscription { assert(hasListener); + Object? varData = _varData; if (_isAddingStream) { - _StreamControllerAddStreamState addState = _varData; - return addState.varData; + _StreamControllerAddStreamState streamState = varData as dynamic; + varData = streamState.varData; } - return _varData; + return varData as dynamic; } /** @@ -584,30 +586,35 @@ abstract class _StreamController implements _StreamControllerBase { */ Error _badEventState() { if (isClosed) { - return new StateError("Cannot add event after closing"); + return StateError("Cannot add event after closing"); } assert(_isAddingStream); - return new StateError("Cannot add event while adding a stream"); + return StateError("Cannot add event while adding a stream"); } // StreamSink interface. - Future addStream(Stream source, {bool cancelOnError}) { + Future addStream(Stream source, {bool? cancelOnError}) { if (!_mayAddEvent) throw _badEventState(); - if (_isCanceled) return new _Future.immediate(null); + if (_isCanceled) return _Future.immediate(null); _StreamControllerAddStreamState addState = - new _StreamControllerAddStreamState( + _StreamControllerAddStreamState( this, _varData, source, cancelOnError ?? false); _varData = addState; _state |= _STATE_ADDSTREAM; return addState.addStreamFuture; } - Future get done => _ensureDoneFuture(); + /** + * Returns a future that is completed when the stream is done + * processing events. + * + * This happens either when the done event has been sent, or if the + * subscriber of a single-subscription stream is cancelled. + */ + Future get done => _ensureDoneFuture(); - Future _ensureDoneFuture() { - _doneFuture ??= _isCanceled ? Future._nullFuture : new _Future(); - return _doneFuture; - } + Future _ensureDoneFuture() => + _doneFuture ??= _isCanceled ? Future._nullFuture : _Future(); /** * Send or enqueue a data event. @@ -619,19 +626,19 @@ abstract class _StreamController implements _StreamControllerBase { /** * Send or enqueue an error event. - * - * The [error] must not be `null`. */ - void addError(Object error, [StackTrace stackTrace]) { + void addError(Object error, [StackTrace? stackTrace]) { + // TODO(40614): Remove once non-nullability is sound. ArgumentError.checkNotNull(error, "error"); if (!_mayAddEvent) throw _badEventState(); - error = _nonNullError(error); - AsyncError replacement = Zone.current.errorCallback(error, stackTrace); + AsyncError? replacement = Zone.current.errorCallback(error, stackTrace); if (replacement != null) { - error = _nonNullError(replacement.error); + error = replacement.error; stackTrace = replacement.stackTrace; + } else { + stackTrace ??= AsyncError.defaultStackTrace(error); } - stackTrace ??= AsyncError.defaultStackTrace(error); + if (stackTrace == null) throw "unreachable"; // TODO(40088) _addError(error, stackTrace); } @@ -674,7 +681,7 @@ abstract class _StreamController implements _StreamControllerBase { if (hasListener) { _sendData(value); } else if (_isInitialState) { - _ensurePendingEvents().add(new _DelayedData(value)); + _ensurePendingEvents().add(_DelayedData(value)); } } @@ -682,14 +689,14 @@ abstract class _StreamController implements _StreamControllerBase { if (hasListener) { _sendError(error, stackTrace); } else if (_isInitialState) { - _ensurePendingEvents().add(new _DelayedError(error, stackTrace)); + _ensurePendingEvents().add(_DelayedError(error, stackTrace)); } } void _close() { // End of addStream stream. assert(_isAddingStream); - _StreamControllerAddStreamState addState = _varData; + _StreamControllerAddStreamState addState = _varData as dynamic; _varData = addState.varData; _state &= ~_STATE_ADDSTREAM; addState.complete(); @@ -697,18 +704,18 @@ abstract class _StreamController implements _StreamControllerBase { // _StreamControllerLifeCycle interface - StreamSubscription _subscribe(void onData(T data), Function onError, - void onDone(), bool cancelOnError) { + StreamSubscription _subscribe(void onData(T data)?, Function? onError, + void onDone()?, bool cancelOnError) { if (!_isInitialState) { - throw new StateError("Stream has already been listened to."); + throw StateError("Stream has already been listened to."); } - _ControllerSubscription subscription = new _ControllerSubscription( + _ControllerSubscription subscription = _ControllerSubscription( this, onData, onError, onDone, cancelOnError); - _PendingEvents pendingEvents = _pendingEvents; + _PendingEvents? pendingEvents = _pendingEvents; _state |= _STATE_SUBSCRIBED; if (_isAddingStream) { - _StreamControllerAddStreamState addState = _varData; + _StreamControllerAddStreamState addState = _varData as dynamic; addState.varData = subscription; addState.resume(); } else { @@ -722,7 +729,7 @@ abstract class _StreamController implements _StreamControllerBase { return subscription; } - Future _recordCancel(StreamSubscription subscription) { + Future? _recordCancel(StreamSubscription subscription) { // When we cancel, we first cancel any stream being added, // Then we call `onCancel`, and finally the _doneFuture is completed. // If either of addStream's cancel or `onCancel` returns a future, @@ -731,26 +738,30 @@ abstract class _StreamController implements _StreamControllerBase { // If more errors happen, we act as if it happens inside nested try/finallys // or whenComplete calls, and only the last error ends up in the // returned future. - Future result; + Future? result; if (_isAddingStream) { - _StreamControllerAddStreamState addState = _varData; + _StreamControllerAddStreamState addState = _varData as dynamic; result = addState.cancel(); } _varData = null; _state = (_state & ~(_STATE_SUBSCRIBED | _STATE_ADDSTREAM)) | _STATE_CANCELED; + var onCancel = this.onCancel; if (onCancel != null) { if (result == null) { // Only introduce a future if one is needed. // If _onCancel returns null, no future is needed. try { - result = onCancel(); + var cancelResult = onCancel(); + if (cancelResult is Future) { + result = cancelResult; + } } catch (e, s) { // Return the error in the returned future. // Complete it asynchronously, so there is time for a listener // to handle the error. - result = new _Future().._asyncCompleteError(e, s); + result = _Future().._asyncCompleteError(e, s); } } else { // Simpler case when we already know that we will return a future. @@ -759,8 +770,9 @@ abstract class _StreamController implements _StreamControllerBase { } void complete() { - if (_doneFuture != null && _doneFuture._mayComplete) { - _doneFuture._asyncComplete(null); + var doneFuture = _doneFuture; + if (doneFuture != null && doneFuture._mayComplete) { + doneFuture._asyncComplete(null); } } @@ -775,7 +787,7 @@ abstract class _StreamController implements _StreamControllerBase { void _recordPause(StreamSubscription subscription) { if (_isAddingStream) { - _StreamControllerAddStreamState addState = _varData; + _StreamControllerAddStreamState addState = _varData as dynamic; addState.pause(); } _runGuarded(onPause); @@ -783,7 +795,7 @@ abstract class _StreamController implements _StreamControllerBase { void _recordResume(StreamSubscription subscription) { if (_isAddingStream) { - _StreamControllerAddStreamState addState = _varData; + _StreamControllerAddStreamState addState = _varData as dynamic; addState.resume(); } _runGuarded(onResume); @@ -811,11 +823,11 @@ abstract class _SyncStreamControllerDispatch abstract class _AsyncStreamControllerDispatch implements _StreamController { void _sendData(T data) { - _subscription._addPending(new _DelayedData(data)); + _subscription._addPending(_DelayedData(data)); } void _sendError(Object error, StackTrace stackTrace) { - _subscription._addPending(new _DelayedError(error, stackTrace)); + _subscription._addPending(_DelayedError(error, stackTrace)); } void _sendDone() { @@ -832,9 +844,7 @@ class _AsyncStreamController = _StreamController class _SyncStreamController = _StreamController with _SyncStreamControllerDispatch; -typedef _NotificationHandler(); - -void _runGuarded(_NotificationHandler notificationHandler) { +void _runGuarded(void Function()? notificationHandler) { if (notificationHandler == null) return; try { notificationHandler(); @@ -848,8 +858,8 @@ class _ControllerStream extends _StreamImpl { _ControllerStream(this._controller); - StreamSubscription _createSubscription(void onData(T data), - Function onError, void onDone(), bool cancelOnError) => + StreamSubscription _createSubscription(void onData(T data)?, + Function? onError, void onDone()?, bool cancelOnError) => _controller._subscribe(onData, onError, onDone, cancelOnError); // Override == and hashCode so that new streams returned by the same @@ -868,11 +878,11 @@ class _ControllerStream extends _StreamImpl { class _ControllerSubscription extends _BufferingStreamSubscription { final _StreamControllerLifecycle _controller; - _ControllerSubscription(this._controller, void onData(T data), - Function onError, void onDone(), bool cancelOnError) + _ControllerSubscription(this._controller, void onData(T data)?, + Function? onError, void onDone()?, bool cancelOnError) : super(onData, onError, onDone, cancelOnError); - Future _onCancel() { + Future? _onCancel() { return _controller._recordCancel(this); } @@ -893,7 +903,7 @@ class _StreamSinkWrapper implements StreamSink { _target.add(data); } - void addError(Object error, [StackTrace stackTrace]) { + void addError(Object error, [StackTrace? stackTrace]) { _target.addError(error, stackTrace); } @@ -916,7 +926,7 @@ class _AddStreamState { _AddStreamState( _EventSink controller, Stream source, bool cancelOnError) - : addStreamFuture = new _Future(), + : addStreamFuture = _Future(), addSubscription = source.listen(controller._add, onError: cancelOnError ? makeErrorHandler(controller) @@ -924,7 +934,7 @@ class _AddStreamState { onDone: controller._close, cancelOnError: cancelOnError); - static makeErrorHandler(_EventSink controller) => (e, StackTrace s) { + static makeErrorHandler(_EventSink controller) => (Object e, StackTrace s) { controller._addError(e, s); controller._close(); }; @@ -945,11 +955,11 @@ class _AddStreamState { * * Return a future if the cancel takes time, otherwise return `null`. */ - Future cancel() { + Future cancel() { var cancel = addSubscription.cancel(); if (cancel == null) { addStreamFuture._asyncComplete(null); - return null; + return Future._nullFuture; } return cancel.whenComplete(() { addStreamFuture._asyncComplete(null); diff --git a/sdk/lib/async/stream_impl.dart b/sdk/lib/async/stream_impl.dart index b62ad88d016..1c6fa50c7f7 100644 --- a/sdk/lib/async/stream_impl.dart +++ b/sdk/lib/async/stream_impl.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.async; /** Abstract and private interface for a place to put events. */ @@ -93,29 +91,33 @@ class _BufferingStreamSubscription _DataHandler _onData; Function _onError; _DoneHandler _onDone; - final Zone _zone = Zone.current; + + final Zone _zone; /** Bit vector based on state-constants above. */ int _state; // TODO(floitsch): reuse another field /** The future [_onCancel] may return. */ - Future _cancelFuture; + Future? _cancelFuture; /** * Queue of pending events. * * Is created when necessary, or set in constructor for preconfigured events. */ - _PendingEvents _pending; + _PendingEvents? _pending; - _BufferingStreamSubscription( - void onData(T data), Function onError, void onDone(), bool cancelOnError) - : _state = (cancelOnError ? _STATE_CANCEL_ON_ERROR : 0) { - this.onData(onData); - this.onError(onError); - this.onDone(onDone); - } + _BufferingStreamSubscription(void onData(T data)?, Function? onError, + void onDone()?, bool cancelOnError) + : this.zoned(Zone.current, onData, onError, onDone, cancelOnError); + + _BufferingStreamSubscription.zoned(this._zone, void onData(T data)?, + Function? onError, void onDone()?, bool cancelOnError) + : _state = (cancelOnError ? _STATE_CANCEL_ON_ERROR : 0), + _onData = _registerDataHandler(_zone, onData), + _onError = _registerErrorHandler(_zone, onError), + _onDone = _registerDoneHandler(_zone, onDone); /** * Sets the subscription's pending events object. @@ -123,51 +125,62 @@ class _BufferingStreamSubscription * This can only be done once. The pending events object is used for the * rest of the subscription's life cycle. */ - void _setPendingEvents(_PendingEvents pendingEvents) { + void _setPendingEvents(_PendingEvents? pendingEvents) { assert(_pending == null); if (pendingEvents == null) return; _pending = pendingEvents; if (!pendingEvents.isEmpty) { _state |= _STATE_HAS_PENDING; - _pending.schedule(this); + pendingEvents.schedule(this); } } // StreamSubscription interface. - void onData(void handleData(T event)) { - handleData ??= _nullDataHandler; - // TODO(floitsch): the return type should be 'void', and the type - // should be inferred. - _onData = _zone.registerUnaryCallback(handleData); + void onData(void handleData(T event)?) { + _onData = _registerDataHandler(_zone, handleData); } - void onError(Function handleError) { + static void Function(T) _registerDataHandler( + Zone zone, void Function(T)? handleData) { + return zone.registerUnaryCallback(handleData ?? _nullDataHandler); + } + + void onError(Function? handleError) { + _onError = _registerErrorHandler(_zone, handleError); + } + + static Function _registerErrorHandler(Zone zone, Function? handleError) { + // TODO(lrn): Consider whether we need to register the null handler. handleError ??= _nullErrorHandler; if (handleError is void Function(Object, StackTrace)) { - _onError = _zone + return zone .registerBinaryCallback(handleError); - } else if (handleError is void Function(Object)) { - _onError = _zone.registerUnaryCallback(handleError); - } else { - throw new ArgumentError("handleError callback must take either an Object " - "(the error), or both an Object (the error) and a StackTrace."); } + if (handleError is void Function(Object)) { + return zone.registerUnaryCallback(handleError); + } + throw new ArgumentError("handleError callback must take either an Object " + "(the error), or both an Object (the error) and a StackTrace."); } - void onDone(void handleDone()) { - handleDone ??= _nullDoneHandler; - _onDone = _zone.registerCallback(handleDone); + void onDone(void handleDone()?) { + _onDone = _registerDoneHandler(_zone, handleDone); } - void pause([Future resumeSignal]) { + static void Function() _registerDoneHandler( + Zone zone, void Function()? handleDone) { + return zone.registerCallback(handleDone ?? _nullDoneHandler); + } + + void pause([Future? resumeSignal]) { if (_isCanceled) return; bool wasPaused = _isPaused; bool wasInputPaused = _isInputPaused; // Increment pause count and mark input paused (if it isn't already). _state = (_state + _STATE_PAUSE_COUNT) | _STATE_INPUT_PAUSED; - if (resumeSignal != null) resumeSignal.whenComplete(resume); - if (!wasPaused && _pending != null) _pending.cancelSchedule(); + resumeSignal?.whenComplete(resume); + if (!wasPaused) _pending?.cancelSchedule(); if (!wasInputPaused && !_inCallback) _guardCallback(_onPause); } @@ -176,9 +189,9 @@ class _BufferingStreamSubscription if (_isPaused) { _decrementPauseCount(); if (!_isPaused) { - if (_hasPending && !_pending.isEmpty) { + if (_hasPending && !_pending!.isEmpty) { // Input is still paused. - _pending.schedule(this); + _pending!.schedule(this); } else { assert(_mayResumeInput); _state &= ~_STATE_INPUT_PAUSED; @@ -199,14 +212,22 @@ class _BufferingStreamSubscription return _cancelFuture ?? Future._nullFuture; } - Future asFuture([E futureValue]) { - _Future result = new _Future(); - + Future asFuture([E? futureValue]) { + E resultValue; + if (futureValue == null) { + if (!typeAcceptsNull()) { + throw ArgumentError.notNull("futureValue"); + } + resultValue = futureValue as dynamic; + } else { + resultValue = futureValue; + } // Overwrite the onDone and onError handlers. + _Future result = new _Future(); _onDone = () { - result._complete(futureValue); + result._complete(resultValue); }; - _onError = (error, StackTrace stackTrace) { + _onError = (Object error, StackTrace stackTrace) { Future cancelFuture = cancel(); if (!identical(cancelFuture, Future._nullFuture)) { cancelFuture.whenComplete(() { @@ -216,7 +237,6 @@ class _BufferingStreamSubscription result._completeError(error, stackTrace); } }; - return result; } @@ -230,8 +250,7 @@ class _BufferingStreamSubscription bool get _hasPending => (_state & _STATE_HAS_PENDING) != 0; bool get _isPaused => _state >= _STATE_PAUSE_COUNT; bool get _canFire => _state < _STATE_IN_CALLBACK; - bool get _mayResumeInput => - !_isPaused && (_pending == null || _pending.isEmpty); + bool get _mayResumeInput => !_isPaused && (_pending?.isEmpty ?? true); bool get _cancelOnError => (_state & _STATE_CANCEL_ON_ERROR) != 0; bool get isPaused => _isPaused; @@ -239,7 +258,7 @@ class _BufferingStreamSubscription void _cancel() { _state |= _STATE_CANCELED; if (_hasPending) { - _pending.cancelSchedule(); + _pending!.cancelSchedule(); } if (!_inCallback) _pending = null; _cancelFuture = _onCancel(); @@ -301,7 +320,7 @@ class _BufferingStreamSubscription assert(!_isInputPaused); } - Future _onCancel() { + Future? _onCancel() { assert(_isCanceled); return null; } @@ -315,15 +334,14 @@ class _BufferingStreamSubscription * of pending events later (if necessary). */ void _addPending(_DelayedEvent event) { - _StreamImplEvents pending = _pending; - if (_pending == null) { - pending = _pending = new _StreamImplEvents(); - } + _StreamImplEvents? pending = _pending as dynamic; + pending ??= _StreamImplEvents(); + _pending = pending; pending.add(event); if (!_hasPending) { _state |= _STATE_HAS_PENDING; if (!_isPaused) { - _pending.schedule(this); + pending.schedule(this); } } } @@ -357,8 +375,7 @@ class _BufferingStreamSubscription if (onError is void Function(Object, StackTrace)) { _zone.runBinaryGuarded(onError, error, stackTrace); } else { - assert(_onError is void Function(Object)); - _zone.runUnaryGuarded(_onError, error); + _zone.runUnaryGuarded(_onError as dynamic, error); } _state &= ~_STATE_IN_CALLBACK; } @@ -366,9 +383,10 @@ class _BufferingStreamSubscription if (_cancelOnError) { _state |= _STATE_WAIT_FOR_CANCEL; _cancel(); - if (_cancelFuture != null && - !identical(_cancelFuture, Future._nullFuture)) { - _cancelFuture.whenComplete(sendError); + var cancelFuture = _cancelFuture; + if (cancelFuture != null && + !identical(cancelFuture, Future._nullFuture)) { + cancelFuture.whenComplete(sendError); } else { sendError(); } @@ -395,9 +413,9 @@ class _BufferingStreamSubscription _cancel(); _state |= _STATE_WAIT_FOR_CANCEL; - if (_cancelFuture != null && - !identical(_cancelFuture, Future._nullFuture)) { - _cancelFuture.whenComplete(sendDone); + var cancelFuture = _cancelFuture; + if (cancelFuture != null && !identical(cancelFuture, Future._nullFuture)) { + cancelFuture.whenComplete(sendDone); } else { sendDone(); } @@ -410,7 +428,7 @@ class _BufferingStreamSubscription * during the call, and it checks for state changes after the call * that should cause further callbacks. */ - void _guardCallback(void callback()) { + void _guardCallback(void Function() callback) { assert(!_inCallback); bool wasInputPaused = _isInputPaused; _state |= _STATE_IN_CALLBACK; @@ -431,7 +449,7 @@ class _BufferingStreamSubscription */ void _checkState(bool wasInputPaused) { assert(!_inCallback); - if (_hasPending && _pending.isEmpty) { + if (_hasPending && _pending!.isEmpty) { _state &= ~_STATE_HAS_PENDING; if (_isInputPaused && _mayResumeInput) { _state &= ~_STATE_INPUT_PAUSED; @@ -456,7 +474,7 @@ class _BufferingStreamSubscription wasInputPaused = isInputPaused; } if (_hasPending && !_isPaused) { - _pending.schedule(this); + _pending!.schedule(this); } } } @@ -468,9 +486,9 @@ abstract class _StreamImpl extends Stream { // ------------------------------------------------------------------ // Stream interface. - StreamSubscription listen(void onData(T data), - {Function onError, void onDone(), bool cancelOnError}) { - cancelOnError = identical(true, cancelOnError); + StreamSubscription listen(void onData(T data)?, + {Function? onError, void onDone()?, bool? cancelOnError}) { + cancelOnError ??= false; StreamSubscription subscription = _createSubscription(onData, onError, onDone, cancelOnError); _onListen(subscription); @@ -479,8 +497,8 @@ abstract class _StreamImpl extends Stream { // ------------------------------------------------------------------- /** Create a subscription object. Called by [subcribe]. */ - StreamSubscription _createSubscription(void onData(T data), - Function onError, void onDone(), bool cancelOnError) { + StreamSubscription _createSubscription(void onData(T data)?, + Function? onError, void onDone()?, bool cancelOnError) { return new _BufferingStreamSubscription( onData, onError, onDone, cancelOnError); } @@ -503,8 +521,8 @@ class _GeneratedStreamImpl extends _StreamImpl { */ _GeneratedStreamImpl(this._pending); - StreamSubscription _createSubscription(void onData(T data), - Function onError, void onDone(), bool cancelOnError) { + StreamSubscription _createSubscription(void onData(T data)?, + Function? onError, void onDone()?, bool cancelOnError) { if (_isUsed) throw new StateError("Stream has already been listened to."); _isUsed = true; return new _BufferingStreamSubscription( @@ -517,14 +535,15 @@ class _GeneratedStreamImpl extends _StreamImpl { class _IterablePendingEvents extends _PendingEvents { // The iterator providing data for data events. // Set to null when iteration has completed. - Iterator _iterator; + Iterator? _iterator; _IterablePendingEvents(Iterable data) : _iterator = data.iterator; bool get isEmpty => _iterator == null; void handleNext(_EventDispatch dispatch) { - if (_iterator == null) { + var iterator = _iterator; + if (iterator == null) { throw new StateError("No events pending."); } // Send one event per call to moveNext. @@ -533,25 +552,23 @@ class _IterablePendingEvents extends _PendingEvents { // If moveNext returns false, send a done event and clear the _iterator. // If moveNext throws an error, send an error and prepare to send a done // event afterwards. - bool hasMore; + bool movedNext = false; try { - hasMore = _iterator.moveNext(); - if (hasMore) { - dispatch._sendData(_iterator.current); + if (iterator.moveNext()) { + movedNext = true; + dispatch._sendData(iterator.current); } else { _iterator = null; dispatch._sendDone(); } } catch (e, s) { - if (hasMore == null) { + if (!movedNext) { // Threw in .moveNext(). // Ensure that we send a done afterwards. - _iterator = const EmptyIterator(); - dispatch._sendError(e, s); - } else { - // Threw in .current. - dispatch._sendError(e, s); + _iterator = const EmptyIterator(); } + // Else threw in .current. + dispatch._sendError(e, s); } } @@ -568,10 +585,10 @@ typedef void _DataHandler(T value); typedef void _DoneHandler(); /** Default data handler, does nothing. */ -void _nullDataHandler(Object value) {} +void _nullDataHandler(dynamic value) {} /** Default error handler, reports the error to the current zone's handler. */ -void _nullErrorHandler(Object error, [StackTrace stackTrace]) { +void _nullErrorHandler(Object error, StackTrace stackTrace) { Zone.current.handleUncaughtError(error, stackTrace); } @@ -581,7 +598,7 @@ void _nullDoneHandler() {} /** A delayed event on a buffering stream subscription. */ abstract class _DelayedEvent { /** Added as a linked list on the [StreamController]. */ - _DelayedEvent next; + _DelayedEvent? next; /** Execute the delayed event on the [StreamController]. */ void perform(_EventDispatch dispatch); } @@ -597,7 +614,7 @@ class _DelayedData extends _DelayedEvent { /** A delayed error event. */ class _DelayedError extends _DelayedEvent { - final error; + final Object error; final StackTrace stackTrace; _DelayedError(this.error, this.stackTrace); @@ -613,9 +630,9 @@ class _DelayedDone implements _DelayedEvent { dispatch._sendDone(); } - _DelayedEvent get next => null; + _DelayedEvent? get next => null; - void set next(_DelayedEvent _) { + void set next(_DelayedEvent? _) { throw new StateError("No events after a done."); } } @@ -685,26 +702,29 @@ abstract class _PendingEvents { /** Class holding pending events for a [_StreamImpl]. */ class _StreamImplEvents extends _PendingEvents { /// Single linked list of [_DelayedEvent] objects. - _DelayedEvent firstPendingEvent; + _DelayedEvent? firstPendingEvent; /// Last element in the list of pending events. New events are added after it. - _DelayedEvent lastPendingEvent; + _DelayedEvent? lastPendingEvent; bool get isEmpty => lastPendingEvent == null; void add(_DelayedEvent event) { - if (lastPendingEvent == null) { + var lastEvent = lastPendingEvent; + if (lastEvent == null) { firstPendingEvent = lastPendingEvent = event; } else { - lastPendingEvent = lastPendingEvent.next = event; + lastPendingEvent = lastEvent.next = event; } } void handleNext(_EventDispatch dispatch) { assert(!isScheduled); - _DelayedEvent event = firstPendingEvent; - firstPendingEvent = event.next; - if (firstPendingEvent == null) { + assert(!isEmpty); + _DelayedEvent event = firstPendingEvent!; + _DelayedEvent? nextEvent = event.next; + firstPendingEvent = nextEvent; + if (nextEvent == null) { lastPendingEvent = null; } event.perform(dispatch); @@ -728,7 +748,7 @@ class _DoneStreamSubscription implements StreamSubscription { final Zone _zone; int _state = 0; - _DoneHandler _onDone; + _DoneHandler? _onDone; _DoneStreamSubscription(this._onDone) : _zone = Zone.current { _schedule(); @@ -744,13 +764,13 @@ class _DoneStreamSubscription implements StreamSubscription { _state |= _SCHEDULED; } - void onData(void handleData(T data)) {} - void onError(Function handleError) {} - void onDone(void handleDone()) { + void onData(void handleData(T data)?) {} + void onError(Function? handleError) {} + void onDone(void handleDone()?) { _onDone = handleDone; } - void pause([Future resumeSignal]) { + void pause([Future? resumeSignal]) { _state += _PAUSED; if (resumeSignal != null) resumeSignal.whenComplete(resume); } @@ -766,10 +786,19 @@ class _DoneStreamSubscription implements StreamSubscription { Future cancel() => Future._nullFuture; - Future asFuture([E futureValue]) { + Future asFuture([E? futureValue]) { + E resultValue; + if (futureValue == null) { + if (!typeAcceptsNull()) { + throw ArgumentError.notNull("futureValue"); + } + resultValue = futureValue as dynamic; + } else { + resultValue = futureValue; + } _Future result = new _Future(); _onDone = () { - result._completeWithValue(futureValue); + result._completeWithValue(resultValue); }; return result; } @@ -778,30 +807,31 @@ class _DoneStreamSubscription implements StreamSubscription { _state &= ~_SCHEDULED; if (isPaused) return; _state |= _DONE_SENT; - if (_onDone != null) _zone.runGuarded(_onDone); + var doneHandler = _onDone; + if (doneHandler != null) _zone.runGuarded(doneHandler); } } class _AsBroadcastStream extends Stream { final Stream _source; - final _BroadcastCallback _onListenHandler; - final _BroadcastCallback _onCancelHandler; + final _BroadcastCallback? _onListenHandler; + final _BroadcastCallback? _onCancelHandler; final Zone _zone; - _AsBroadcastStreamController _controller; - StreamSubscription _subscription; + _AsBroadcastStreamController? _controller; + StreamSubscription? _subscription; _AsBroadcastStream( this._source, - void onListenHandler(StreamSubscription subscription), - void onCancelHandler(StreamSubscription subscription)) - // TODO(floitsch): the return type should be void and should be - // inferred. - : _onListenHandler = Zone.current - .registerUnaryCallback>( + void onListenHandler(StreamSubscription subscription)?, + void onCancelHandler(StreamSubscription subscription)?) + : _onListenHandler = onListenHandler == null + ? null + : Zone.current.registerUnaryCallback>( onListenHandler), - _onCancelHandler = Zone.current - .registerUnaryCallback>( + _onCancelHandler = onCancelHandler == null + ? null + : Zone.current.registerUnaryCallback>( onCancelHandler), _zone = Zone.current { _controller = new _AsBroadcastStreamController(_onListen, _onCancel); @@ -809,63 +839,64 @@ class _AsBroadcastStream extends Stream { bool get isBroadcast => true; - StreamSubscription listen(void onData(T data), - {Function onError, void onDone(), bool cancelOnError}) { - if (_controller == null || _controller.isClosed) { + StreamSubscription listen(void onData(T data)?, + {Function? onError, void onDone()?, bool? cancelOnError}) { + var controller = _controller; + if (controller == null || controller.isClosed) { // Return a dummy subscription backed by nothing, since // it will only ever send one done event. return new _DoneStreamSubscription(onDone); } - _subscription ??= _source.listen(_controller.add, - onError: _controller.addError, onDone: _controller.close); - cancelOnError = identical(true, cancelOnError); - return _controller._subscribe(onData, onError, onDone, cancelOnError); + _subscription ??= _source.listen(controller.add, + onError: controller.addError, onDone: controller.close); + return controller._subscribe( + onData, onError, onDone, cancelOnError ?? false); } void _onCancel() { - bool shutdown = (_controller == null) || _controller.isClosed; - if (_onCancelHandler != null) { - _zone.runUnary( - _onCancelHandler, new _BroadcastSubscriptionWrapper(this)); + var controller = _controller; + bool shutdown = (controller == null) || controller.isClosed; + var cancelHandler = _onCancelHandler; + if (cancelHandler != null) { + _zone.runUnary(cancelHandler, new _BroadcastSubscriptionWrapper(this)); } if (shutdown) { - if (_subscription != null) { - _subscription.cancel(); + var subscription = _subscription; + if (subscription != null) { + subscription.cancel(); _subscription = null; } } } void _onListen() { - if (_onListenHandler != null) { - _zone.runUnary( - _onListenHandler, new _BroadcastSubscriptionWrapper(this)); + var listenHandler = _onListenHandler; + if (listenHandler != null) { + _zone.runUnary(listenHandler, new _BroadcastSubscriptionWrapper(this)); } } // Methods called from _BroadcastSubscriptionWrapper. void _cancelSubscription() { - if (_subscription == null) return; // Called by [_controller] when it has no subscribers left. - StreamSubscription subscription = _subscription; - _subscription = null; - _controller = null; // Marks the stream as no longer listenable. - subscription.cancel(); + var subscription = _subscription; + if (subscription != null) { + _subscription = null; + _controller = null; // Marks the stream as no longer listenable. + subscription.cancel(); + } } - void _pauseSubscription(Future resumeSignal) { - if (_subscription == null) return; - _subscription.pause(resumeSignal); + void _pauseSubscription(Future? resumeSignal) { + _subscription?.pause(resumeSignal); } void _resumeSubscription() { - if (_subscription == null) return; - _subscription.resume(); + _subscription?.resume(); } bool get _isSubscriptionPaused { - if (_subscription == null) return false; - return _subscription.isPaused; + return _subscription?.isPaused ?? false; } } @@ -877,22 +908,22 @@ class _BroadcastSubscriptionWrapper implements StreamSubscription { _BroadcastSubscriptionWrapper(this._stream); - void onData(void handleData(T data)) { + void onData(void handleData(T data)?) { throw new UnsupportedError( "Cannot change handlers of asBroadcastStream source subscription."); } - void onError(Function handleError) { + void onError(Function? handleError) { throw new UnsupportedError( "Cannot change handlers of asBroadcastStream source subscription."); } - void onDone(void handleDone()) { + void onDone(void handleDone()?) { throw new UnsupportedError( "Cannot change handlers of asBroadcastStream source subscription."); } - void pause([Future resumeSignal]) { + void pause([Future? resumeSignal]) { _stream._pauseSubscription(resumeSignal); } @@ -909,7 +940,7 @@ class _BroadcastSubscriptionWrapper implements StreamSubscription { return _stream._isSubscriptionPaused; } - Future asFuture([E futureValue]) { + Future asFuture([E? futureValue]) { throw new UnsupportedError( "Cannot change handlers of asBroadcastStream source subscription."); } @@ -948,7 +979,7 @@ class _StreamIterator implements StreamIterator { /// Subscription being listened to. /// /// Set to `null` when the stream subscription is done or canceled. - StreamSubscription _subscription; + StreamSubscription? _subscription; /// Data value depending on the current state. /// @@ -963,7 +994,7 @@ class _StreamIterator implements StreamIterator { /// After calling [moveNext] and the returned future has completed /// with `false`, or after calling [cancel]: `null`. @pragma("vm:entry-point") - Object _stateData; + Object? _stateData; /// Whether the iterator is between calls to `moveNext`. /// This will usually cause the [_subscription] to be paused, but as an @@ -971,23 +1002,25 @@ class _StreamIterator implements StreamIterator { /// completed. bool _isPaused = false; - _StreamIterator(final Stream stream) - : _stateData = stream ?? (throw ArgumentError.notNull("stream")); + _StreamIterator(final Stream stream) : _stateData = stream { + ArgumentError.checkNotNull(stream, "stream"); + } T get current { if (_subscription != null && _isPaused) { - return _stateData; + return _stateData as dynamic; } - return null; + return null as dynamic; } Future moveNext() { - if (_subscription != null) { + var subscription = _subscription; + if (subscription != null) { if (_isPaused) { var future = new _Future(); _stateData = future; _isPaused = false; - _subscription.resume(); + subscription.resume(); return future; } throw new StateError("Already waiting for next."); @@ -1004,7 +1037,7 @@ class _StreamIterator implements StreamIterator { assert(_subscription == null); var stateData = _stateData; if (stateData != null) { - Stream stream = stateData; + Stream stream = stateData as dynamic; _subscription = stream.listen(_onData, onError: _onError, onDone: _onDone, cancelOnError: true); var future = new _Future(); @@ -1015,13 +1048,13 @@ class _StreamIterator implements StreamIterator { } Future cancel() { - StreamSubscription subscription = _subscription; - Object stateData = _stateData; + StreamSubscription? subscription = _subscription; + Object? stateData = _stateData; _stateData = null; if (subscription != null) { _subscription = null; if (!_isPaused) { - _Future future = stateData; + _Future future = stateData as dynamic; future._asyncComplete(false); } return subscription.cancel(); @@ -1031,16 +1064,16 @@ class _StreamIterator implements StreamIterator { void _onData(T data) { assert(_subscription != null && !_isPaused); - _Future moveNextFuture = _stateData; + _Future moveNextFuture = _stateData as dynamic; _stateData = data; _isPaused = true; moveNextFuture._complete(true); - if (_subscription != null && _isPaused) _subscription.pause(); + if (_isPaused) _subscription?.pause(); } - void _onError(Object error, [StackTrace stackTrace]) { + void _onError(Object error, StackTrace stackTrace) { assert(_subscription != null && !_isPaused); - _Future moveNextFuture = _stateData; + _Future moveNextFuture = _stateData as dynamic; _subscription = null; _stateData = null; moveNextFuture._completeError(error, stackTrace); @@ -1048,7 +1081,7 @@ class _StreamIterator implements StreamIterator { void _onDone() { assert(_subscription != null && !_isPaused); - _Future moveNextFuture = _stateData; + _Future moveNextFuture = _stateData as dynamic; _subscription = null; _stateData = null; moveNextFuture._complete(false); @@ -1059,8 +1092,8 @@ class _StreamIterator implements StreamIterator { class _EmptyStream extends Stream { const _EmptyStream() : super._internal(); bool get isBroadcast => true; - StreamSubscription listen(void onData(T data), - {Function onError, void onDone(), bool cancelOnError}) { + StreamSubscription listen(void onData(T data)?, + {Function? onError, void onDone()?, bool? cancelOnError}) { return new _DoneStreamSubscription(onDone); } } diff --git a/sdk/lib/async/stream_pipe.dart b/sdk/lib/async/stream_pipe.dart index 5771db4a6b3..fd202283b5a 100644 --- a/sdk/lib/async/stream_pipe.dart +++ b/sdk/lib/async/stream_pipe.dart @@ -2,21 +2,19 @@ // 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.6 - part of dart.async; /** Runs user code and takes actions depending on success or failure. */ -_runUserCode( - T userCode(), onSuccess(T value), onError(error, StackTrace stackTrace)) { +_runUserCode(T userCode(), onSuccess(T value), + onError(Object error, StackTrace stackTrace)) { try { onSuccess(userCode()); } catch (e, s) { - AsyncError replacement = Zone.current.errorCallback(e, s); + AsyncError? replacement = Zone.current.errorCallback(e, s); if (replacement == null) { onError(e, s); } else { - var error = _nonNullError(replacement.error); + var error = replacement.error; var stackTrace = replacement.stackTrace; onError(error, stackTrace); } @@ -25,8 +23,8 @@ _runUserCode( /** Helper function to cancel a subscription and wait for the potential future, before completing with an error. */ -void _cancelAndError(StreamSubscription subscription, _Future future, error, - StackTrace stackTrace) { +void _cancelAndError(StreamSubscription subscription, _Future future, + Object error, StackTrace stackTrace) { var cancelFuture = subscription.cancel(); if (cancelFuture != null && !identical(cancelFuture, Future._nullFuture)) { cancelFuture.whenComplete(() => future._completeError(error, stackTrace)); @@ -36,21 +34,19 @@ void _cancelAndError(StreamSubscription subscription, _Future future, error, } void _cancelAndErrorWithReplacement(StreamSubscription subscription, - _Future future, error, StackTrace stackTrace) { - AsyncError replacement = Zone.current.errorCallback(error, stackTrace); + _Future future, Object error, StackTrace stackTrace) { + AsyncError? replacement = Zone.current.errorCallback(error, stackTrace); if (replacement != null) { - error = _nonNullError(replacement.error); + error = replacement.error; stackTrace = replacement.stackTrace; } _cancelAndError(subscription, future, error, stackTrace); } -typedef void _ErrorCallback(error, StackTrace stackTrace); - /** Helper function to make an onError argument to [_runUserCode]. */ -_ErrorCallback _cancelAndErrorClosure( +void Function(Object error, StackTrace stackTrace) _cancelAndErrorClosure( StreamSubscription subscription, _Future future) { - return (error, StackTrace stackTrace) { + return (Object error, StackTrace stackTrace) { _cancelAndError(subscription, future, error, stackTrace); }; } @@ -82,25 +78,22 @@ abstract class _ForwardingStream extends Stream { bool get isBroadcast => _source.isBroadcast; - StreamSubscription listen(void onData(T value), - {Function onError, void onDone(), bool cancelOnError}) { - cancelOnError = identical(true, cancelOnError); - return _createSubscription(onData, onError, onDone, cancelOnError); + StreamSubscription listen(void onData(T value)?, + {Function? onError, void onDone()?, bool? cancelOnError}) { + return _createSubscription(onData, onError, onDone, cancelOnError ?? false); } - StreamSubscription _createSubscription(void onData(T data), - Function onError, void onDone(), bool cancelOnError) { + StreamSubscription _createSubscription(void onData(T data)?, + Function? onError, void onDone()?, bool cancelOnError) { return new _ForwardingStreamSubscription( this, onData, onError, onDone, cancelOnError); } // Override the following methods in subclasses to change the behavior. - void _handleData(S data, _EventSink sink) { - sink._add(data as Object); - } + void _handleData(S data, _EventSink sink); - void _handleError(error, StackTrace stackTrace, _EventSink sink) { + void _handleError(Object error, StackTrace stackTrace, _EventSink sink) { sink._addError(error, stackTrace); } @@ -116,10 +109,10 @@ class _ForwardingStreamSubscription extends _BufferingStreamSubscription { final _ForwardingStream _stream; - StreamSubscription _subscription; + StreamSubscription? _subscription; - _ForwardingStreamSubscription(this._stream, void onData(T data), - Function onError, void onDone(), bool cancelOnError) + _ForwardingStreamSubscription(this._stream, void onData(T data)?, + Function? onError, void onDone()?, bool cancelOnError) : super(onData, onError, onDone, cancelOnError) { _subscription = _stream._source .listen(_handleData, onError: _handleError, onDone: _handleDone); @@ -142,18 +135,16 @@ class _ForwardingStreamSubscription // StreamSubscription callbacks. void _onPause() { - if (_subscription == null) return; - _subscription.pause(); + _subscription?.pause(); } void _onResume() { - if (_subscription == null) return; - _subscription.resume(); + _subscription?.resume(); } - Future _onCancel() { - if (_subscription != null) { - StreamSubscription subscription = _subscription; + Future? _onCancel() { + var subscription = _subscription; + if (subscription != null) { _subscription = null; return subscription.cancel(); } @@ -179,19 +170,18 @@ class _ForwardingStreamSubscription // Stream transformers used by the default Stream implementation. // ------------------------------------------------------------------- -typedef bool _Predicate(T value); - -void _addErrorWithReplacement(_EventSink sink, error, StackTrace stackTrace) { - AsyncError replacement = Zone.current.errorCallback(error, stackTrace); +void _addErrorWithReplacement( + _EventSink sink, Object error, StackTrace stackTrace) { + AsyncError? replacement = Zone.current.errorCallback(error, stackTrace); if (replacement != null) { - error = _nonNullError(replacement.error); + error = replacement.error; stackTrace = replacement.stackTrace; } sink._addError(error, stackTrace); } class _WhereStream extends _ForwardingStream { - final _Predicate _test; + final bool Function(T) _test; _WhereStream(Stream source, bool test(T value)) : _test = test, @@ -258,26 +248,30 @@ class _ExpandStream extends _ForwardingStream { } } -typedef bool _ErrorTest(error); - /** * A stream pipe that converts or disposes error events * before passing them on. */ class _HandleErrorStream extends _ForwardingStream { final Function _transform; - final _ErrorTest _test; + final bool Function(Object)? _test; - _HandleErrorStream(Stream source, Function onError, bool test(error)) + _HandleErrorStream( + Stream source, Function onError, bool test(Object error)?) : this._transform = onError, this._test = test, super(source); + void _handleData(T data, _EventSink sink) { + sink._add(data); + } + void _handleError(Object error, StackTrace stackTrace, _EventSink sink) { bool matches = true; - if (_test != null) { + var test = _test; + if (test != null) { try { - matches = _test(error); + matches = test(error); } catch (e, s) { _addErrorWithReplacement(sink, e, s); return; @@ -305,29 +299,25 @@ class _TakeStream extends _ForwardingStream { _TakeStream(Stream source, int count) : this._count = count, - super(source) { - // This test is done early to avoid handling an async error - // in the _handleData method. - ArgumentError.checkNotNull(count, "count"); - } + super(source); - StreamSubscription _createSubscription(void onData(T data), - Function onError, void onDone(), bool cancelOnError) { + StreamSubscription _createSubscription(void onData(T data)?, + Function? onError, void onDone()?, bool cancelOnError) { if (_count == 0) { _source.listen(null).cancel(); return new _DoneStreamSubscription(onDone); } - return new _StateStreamSubscription( + return new _StateStreamSubscription( this, onData, onError, onDone, cancelOnError, _count); } void _handleData(T inputEvent, _EventSink sink) { - _StateStreamSubscription subscription = sink; - int count = subscription._count; + var subscription = sink as _StateStreamSubscription; + int count = subscription._subState; if (count > 0) { sink._add(inputEvent); count -= 1; - subscription._count = count; + subscription._subState = count; if (count == 0) { // Closing also unsubscribes all subscribers, which unsubscribes // this from source. @@ -342,32 +332,17 @@ class _TakeStream extends _ForwardingStream { * * Use by several different classes, storing an integer, bool or general. */ -class _StateStreamSubscription extends _ForwardingStreamSubscription { - // Raw state field. Typed access provided by getters and setters below. - var _sharedState; +class _StateStreamSubscription + extends _ForwardingStreamSubscription { + S _subState; - _StateStreamSubscription(_ForwardingStream stream, void onData(T data), - Function onError, void onDone(), bool cancelOnError, this._sharedState) + _StateStreamSubscription(_ForwardingStream stream, void onData(T data)?, + Function? onError, void onDone()?, bool cancelOnError, this._subState) : super(stream, onData, onError, onDone, cancelOnError); - - bool get _flag => _sharedState; - void set _flag(bool flag) { - _sharedState = flag; - } - - int get _count => _sharedState; - void set _count(int count) { - _sharedState = count; - } - - Object get _value => _sharedState; - void set _value(Object value) { - _sharedState = value; - } } class _TakeWhileStream extends _ForwardingStream { - final _Predicate _test; + final bool Function(T) _test; _TakeWhileStream(Stream source, bool test(T value)) : this._test = test, @@ -399,21 +374,20 @@ class _SkipStream extends _ForwardingStream { super(source) { // This test is done early to avoid handling an async error // in the _handleData method. - ArgumentError.checkNotNull(count, "count"); RangeError.checkNotNegative(count, "count"); } - StreamSubscription _createSubscription(void onData(T data), - Function onError, void onDone(), bool cancelOnError) { - return new _StateStreamSubscription( + StreamSubscription _createSubscription(void onData(T data)?, + Function? onError, void onDone()?, bool cancelOnError) { + return new _StateStreamSubscription( this, onData, onError, onDone, cancelOnError, _count); } void _handleData(T inputEvent, _EventSink sink) { - _StateStreamSubscription subscription = sink; - int count = subscription._count; + var subscription = sink as _StateStreamSubscription; + int count = subscription._subState; if (count > 0) { - subscription._count = count - 1; + subscription._subState = count - 1; return; } sink._add(inputEvent); @@ -421,21 +395,21 @@ class _SkipStream extends _ForwardingStream { } class _SkipWhileStream extends _ForwardingStream { - final _Predicate _test; + final bool Function(T) _test; _SkipWhileStream(Stream source, bool test(T value)) : this._test = test, super(source); - StreamSubscription _createSubscription(void onData(T data), - Function onError, void onDone(), bool cancelOnError) { - return new _StateStreamSubscription( + StreamSubscription _createSubscription(void onData(T data)?, + Function? onError, void onDone()?, bool cancelOnError) { + return new _StateStreamSubscription( this, onData, onError, onDone, cancelOnError, false); } void _handleData(T inputEvent, _EventSink sink) { - _StateStreamSubscription subscription = sink; - bool hasFailed = subscription._flag; + var subscription = sink as _StateStreamSubscription; + bool hasFailed = subscription._subState; if (hasFailed) { sink._add(inputEvent); return; @@ -446,48 +420,47 @@ class _SkipWhileStream extends _ForwardingStream { } catch (e, s) { _addErrorWithReplacement(sink, e, s); // A failure to return a boolean is considered "not matching". - subscription._flag = true; + subscription._subState = true; return; } if (!satisfies) { - subscription._flag = true; + subscription._subState = true; sink._add(inputEvent); } } } -typedef bool _Equality(T a, T b); - class _DistinctStream extends _ForwardingStream { static final _SENTINEL = new Object(); - final _Equality _equals; + final bool Function(T, T)? _equals; - _DistinctStream(Stream source, bool equals(T a, T b)) + _DistinctStream(Stream source, bool equals(T a, T b)?) : _equals = equals, super(source); - StreamSubscription _createSubscription(void onData(T data), - Function onError, void onDone(), bool cancelOnError) { - return new _StateStreamSubscription( + StreamSubscription _createSubscription(void onData(T data)?, + Function? onError, void onDone()?, bool cancelOnError) { + return new _StateStreamSubscription( this, onData, onError, onDone, cancelOnError, _SENTINEL); } void _handleData(T inputEvent, _EventSink sink) { - _StateStreamSubscription subscription = sink; - var previous = subscription._value; + var subscription = sink as _StateStreamSubscription; + var previous = subscription._subState; if (identical(previous, _SENTINEL)) { - // First event. - subscription._value = inputEvent; + // First event. Cannot use [_equals]. + subscription._subState = inputEvent; sink._add(inputEvent); } else { - T previousEvent = previous; + T previousEvent = previous as T; + var equals = _equals; bool isEqual; try { - if (_equals == null) { + if (equals == null) { isEqual = (previousEvent == inputEvent); } else { - isEqual = _equals(previousEvent, inputEvent); + isEqual = equals(previousEvent, inputEvent); } } catch (e, s) { _addErrorWithReplacement(sink, e, s); @@ -495,7 +468,7 @@ class _DistinctStream extends _ForwardingStream { } if (!isEqual) { sink._add(inputEvent); - subscription._value = inputEvent; + subscription._subState = inputEvent; } } } diff --git a/sdk/lib/async/stream_transformers.dart b/sdk/lib/async/stream_transformers.dart index 243e934fc29..ca7934c5c40 100644 --- a/sdk/lib/async/stream_transformers.dart +++ b/sdk/lib/async/stream_transformers.dart @@ -2,22 +2,20 @@ // 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.6 - part of dart.async; /** * Wraps an [_EventSink] so it exposes only the [EventSink] interface. */ class _EventSinkWrapper implements EventSink { - _EventSink _sink; + _EventSink _sink; _EventSinkWrapper(this._sink); void add(T data) { _sink._add(data); } - void addError(error, [StackTrace stackTrace]) { + void addError(Object error, [StackTrace? stackTrace]) { _sink._addError(error, stackTrace ?? AsyncError.defaultStackTrace(error)); } @@ -36,24 +34,25 @@ class _EventSinkWrapper implements EventSink { class _SinkTransformerStreamSubscription extends _BufferingStreamSubscription { /// The transformer's input sink. - EventSink _transformerSink; + late EventSink _transformerSink; /// The subscription to the input stream. - StreamSubscription _subscription; + StreamSubscription? _subscription; - _SinkTransformerStreamSubscription(Stream source, _SinkMapper mapper, - void onData(T data), Function onError, void onDone(), bool cancelOnError) + _SinkTransformerStreamSubscription( + Stream source, + _SinkMapper mapper, + void onData(T data)?, + Function? onError, + void onDone()?, + bool cancelOnError) // We set the adapter's target only when the user is allowed to send data. : super(onData, onError, onDone, cancelOnError) { - _EventSinkWrapper eventSink = new _EventSinkWrapper(this); - _transformerSink = mapper(eventSink); + _transformerSink = mapper(_EventSinkWrapper(this)); _subscription = source.listen(_handleData, onError: _handleError, onDone: _handleDone); } - /** Whether this subscription is still subscribed to its source. */ - bool get _isSubscribed => _subscription != null; - // _EventSink interface. /** @@ -65,7 +64,7 @@ class _SinkTransformerStreamSubscription */ void _add(T data) { if (_isClosed) { - throw new StateError("Stream is already closed"); + throw StateError("Stream is already closed"); } super._add(data); } @@ -101,16 +100,16 @@ class _SinkTransformerStreamSubscription // _BufferingStreamSubscription hooks. void _onPause() { - if (_isSubscribed) _subscription.pause(); + _subscription?.pause(); } void _onResume() { - if (_isSubscribed) _subscription.resume(); + _subscription?.resume(); } - Future _onCancel() { - if (_isSubscribed) { - StreamSubscription subscription = _subscription; + Future? _onCancel() { + var subscription = _subscription; + if (subscription != null) { _subscription = null; return subscription.cancel(); } @@ -125,7 +124,7 @@ class _SinkTransformerStreamSubscription } } - void _handleError(error, [StackTrace stackTrace]) { + void _handleError(Object error, StackTrace stackTrace) { try { _transformerSink.addError(error, stackTrace); } catch (e, s) { @@ -180,12 +179,11 @@ class _BoundSinkStream extends Stream { _BoundSinkStream(this._stream, this._sinkMapper); - StreamSubscription listen(void onData(T event), - {Function onError, void onDone(), bool cancelOnError}) { - cancelOnError = identical(true, cancelOnError); + StreamSubscription listen(void onData(T event)?, + {Function? onError, void onDone()?, bool? cancelOnError}) { StreamSubscription subscription = - new _SinkTransformerStreamSubscription( - _stream, _sinkMapper, onData, onError, onDone, cancelOnError); + _SinkTransformerStreamSubscription(_stream, _sinkMapper, onData, + onError, onDone, cancelOnError ?? false); return subscription; } } @@ -206,52 +204,53 @@ typedef void _TransformDoneHandler(EventSink sink); * This way we can reuse the code from [_StreamSinkTransformer]. */ class _HandlerEventSink implements EventSink { - final _TransformDataHandler _handleData; - final _TransformErrorHandler _handleError; - final _TransformDoneHandler _handleDone; + final _TransformDataHandler? _handleData; + final _TransformErrorHandler? _handleError; + final _TransformDoneHandler? _handleDone; /// The output sink where the handlers should send their data into. - EventSink _sink; + /// Set to `null` when closed. + EventSink? _sink; - _HandlerEventSink( - this._handleData, this._handleError, this._handleDone, this._sink) { - if (_sink == null) { - throw new ArgumentError("The provided sink must not be null."); - } - } - - bool get _isClosed => _sink == null; + _HandlerEventSink(this._handleData, this._handleError, this._handleDone, + EventSink this._sink); void add(S data) { - if (_isClosed) { + var sink = _sink; + if (sink == null) { throw StateError("Sink is closed"); } - if (_handleData != null) { - _handleData(data, _sink); + var handleData = _handleData; + if (handleData != null) { + handleData(data, sink); } else { - _sink.add(data as T); + sink.add(data as T); } } - void addError(Object error, [StackTrace stackTrace]) { + void addError(Object error, [StackTrace? stackTrace]) { + // TODO(40614): Remove once non-nullability is sound. ArgumentError.checkNotNull(error, "error"); - if (_isClosed) { + var sink = _sink; + if (sink == null) { throw StateError("Sink is closed"); } - if (_handleError != null) { - stackTrace ??= AsyncError.defaultStackTrace(error); - _handleError(error, stackTrace, _sink); + var handleError = _handleError; + stackTrace ??= AsyncError.defaultStackTrace(error); + if (handleError != null) { + handleError(error, stackTrace, sink); } else { - _sink.addError(error, stackTrace); + sink.addError(error, stackTrace); } } void close() { - if (_isClosed) return; var sink = _sink; + if (sink == null) return; _sink = null; - if (_handleDone != null) { - _handleDone(sink); + var handleDone = _handleDone; + if (handleDone != null) { + handleDone(sink); } else { sink.close(); } @@ -265,9 +264,9 @@ class _HandlerEventSink implements EventSink { */ class _StreamHandlerTransformer extends _StreamSinkTransformer { _StreamHandlerTransformer( - {void handleData(S data, EventSink sink), - void handleError(Object error, StackTrace stackTrace, EventSink sink), - void handleDone(EventSink sink)}) + {void handleData(S data, EventSink sink)?, + void handleError(Object error, StackTrace stackTrace, EventSink sink)?, + void handleDone(EventSink sink)?}) : super((EventSink outputSink) { return new _HandlerEventSink( handleData, handleError, handleDone, outputSink); @@ -328,10 +327,9 @@ class _BoundSubscriptionStream extends Stream { _BoundSubscriptionStream(this._stream, this._onListen); - StreamSubscription listen(void onData(T event), - {Function onError, void onDone(), bool cancelOnError}) { - cancelOnError = identical(true, cancelOnError); - StreamSubscription result = _onListen(_stream, cancelOnError); + StreamSubscription listen(void onData(T event)?, + {Function? onError, void onDone()?, bool? cancelOnError}) { + StreamSubscription result = _onListen(_stream, cancelOnError ?? false); result.onData(onData); result.onError(onError); result.onDone(onDone); diff --git a/sdk/lib/async/timer.dart b/sdk/lib/async/timer.dart index 6c42767426a..e0ef4471fb6 100644 --- a/sdk/lib/async/timer.dart +++ b/sdk/lib/async/timer.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.async; /** @@ -44,7 +42,7 @@ abstract class Timer { * The [callback] function is invoked after the given [duration]. * */ - factory Timer(Duration duration, void callback()) { + factory Timer(Duration duration, void Function() callback) { if (Zone.current == Zone.root) { // No need to bind the callback. We know that the root's timer will // be invoked in the root zone. @@ -87,7 +85,7 @@ abstract class Timer { * * This function is equivalent to `new Timer(Duration.zero, callback)`. */ - static void run(void callback()) { + static void run(void Function() callback) { new Timer(Duration.zero, callback); } @@ -125,7 +123,8 @@ abstract class Timer { */ bool get isActive; - external static Timer _createTimer(Duration duration, void callback()); + external static Timer _createTimer( + Duration duration, void Function() callback); external static Timer _createPeriodicTimer( Duration duration, void callback(Timer timer)); } diff --git a/sdk/lib/async/zone.dart b/sdk/lib/async/zone.dart index e200ad00faf..b4e3994cbcc 100644 --- a/sdk/lib/async/zone.dart +++ b/sdk/lib/async/zone.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.async; typedef R ZoneCallback(); @@ -25,8 +23,8 @@ typedef RegisterUnaryCallbackHandler = ZoneUnaryCallback Function( typedef RegisterBinaryCallbackHandler = ZoneBinaryCallback Function(Zone self, ZoneDelegate parent, Zone zone, R Function(T1 arg1, T2 arg2) f); -typedef AsyncError ErrorCallbackHandler(Zone self, ZoneDelegate parent, - Zone zone, Object error, StackTrace stackTrace); +typedef AsyncError? ErrorCallbackHandler(Zone self, ZoneDelegate parent, + Zone zone, Object error, StackTrace? stackTrace); typedef void ScheduleMicrotaskHandler( Zone self, ZoneDelegate parent, Zone zone, void f()); typedef Timer CreateTimerHandler( @@ -36,15 +34,16 @@ typedef Timer CreatePeriodicTimerHandler(Zone self, ZoneDelegate parent, typedef void PrintHandler( Zone self, ZoneDelegate parent, Zone zone, String line); typedef Zone ForkHandler(Zone self, ZoneDelegate parent, Zone zone, - ZoneSpecification specification, Map zoneValues); + ZoneSpecification? specification, Map? zoneValues); /** Pair of error and stack trace. Returned by [Zone.errorCallback]. */ class AsyncError implements Error { final Object error; final StackTrace stackTrace; - AsyncError(this.error, StackTrace stackTrace) + AsyncError(this.error, StackTrace? stackTrace) : stackTrace = stackTrace ?? defaultStackTrace(error) { + // TODO(40614): Remove once non-nullability is sound. ArgumentError.checkNotNull(error, "error"); } @@ -130,38 +129,38 @@ abstract class ZoneSpecification { * Creates a specification with the provided handlers. */ const factory ZoneSpecification( - {HandleUncaughtErrorHandler handleUncaughtError, - RunHandler run, - RunUnaryHandler runUnary, - RunBinaryHandler runBinary, - RegisterCallbackHandler registerCallback, - RegisterUnaryCallbackHandler registerUnaryCallback, - RegisterBinaryCallbackHandler registerBinaryCallback, - ErrorCallbackHandler errorCallback, - ScheduleMicrotaskHandler scheduleMicrotask, - CreateTimerHandler createTimer, - CreatePeriodicTimerHandler createPeriodicTimer, - PrintHandler print, - ForkHandler fork}) = _ZoneSpecification; + {HandleUncaughtErrorHandler? handleUncaughtError, + RunHandler? run, + RunUnaryHandler? runUnary, + RunBinaryHandler? runBinary, + RegisterCallbackHandler? registerCallback, + RegisterUnaryCallbackHandler? registerUnaryCallback, + RegisterBinaryCallbackHandler? registerBinaryCallback, + ErrorCallbackHandler? errorCallback, + ScheduleMicrotaskHandler? scheduleMicrotask, + CreateTimerHandler? createTimer, + CreatePeriodicTimerHandler? createPeriodicTimer, + PrintHandler? print, + ForkHandler? fork}) = _ZoneSpecification; /** * Creates a specification from [other] with the provided handlers overriding * the ones in [other]. */ factory ZoneSpecification.from(ZoneSpecification other, - {HandleUncaughtErrorHandler handleUncaughtError, - RunHandler run, - RunUnaryHandler runUnary, - RunBinaryHandler runBinary, - RegisterCallbackHandler registerCallback, - RegisterUnaryCallbackHandler registerUnaryCallback, - RegisterBinaryCallbackHandler registerBinaryCallback, - ErrorCallbackHandler errorCallback, - ScheduleMicrotaskHandler scheduleMicrotask, - CreateTimerHandler createTimer, - CreatePeriodicTimerHandler createPeriodicTimer, - PrintHandler print, - ForkHandler fork}) { + {HandleUncaughtErrorHandler? handleUncaughtError, + RunHandler? run, + RunUnaryHandler? runUnary, + RunBinaryHandler? runBinary, + RegisterCallbackHandler? registerCallback, + RegisterUnaryCallbackHandler? registerUnaryCallback, + RegisterBinaryCallbackHandler? registerBinaryCallback, + ErrorCallbackHandler? errorCallback, + ScheduleMicrotaskHandler? scheduleMicrotask, + CreateTimerHandler? createTimer, + CreatePeriodicTimerHandler? createPeriodicTimer, + PrintHandler? print, + ForkHandler? fork}) { return new ZoneSpecification( handleUncaughtError: handleUncaughtError ?? other.handleUncaughtError, run: run ?? other.run, @@ -180,19 +179,19 @@ abstract class ZoneSpecification { fork: fork ?? other.fork); } - HandleUncaughtErrorHandler get handleUncaughtError; - RunHandler get run; - RunUnaryHandler get runUnary; - RunBinaryHandler get runBinary; - RegisterCallbackHandler get registerCallback; - RegisterUnaryCallbackHandler get registerUnaryCallback; - RegisterBinaryCallbackHandler get registerBinaryCallback; - ErrorCallbackHandler get errorCallback; - ScheduleMicrotaskHandler get scheduleMicrotask; - CreateTimerHandler get createTimer; - CreatePeriodicTimerHandler get createPeriodicTimer; - PrintHandler get print; - ForkHandler get fork; + HandleUncaughtErrorHandler? get handleUncaughtError; + RunHandler? get run; + RunUnaryHandler? get runUnary; + RunBinaryHandler? get runBinary; + RegisterCallbackHandler? get registerCallback; + RegisterUnaryCallbackHandler? get registerUnaryCallback; + RegisterBinaryCallbackHandler? get registerBinaryCallback; + ErrorCallbackHandler? get errorCallback; + ScheduleMicrotaskHandler? get scheduleMicrotask; + CreateTimerHandler? get createTimer; + CreatePeriodicTimerHandler? get createPeriodicTimer; + PrintHandler? get print; + ForkHandler? get fork; } /** @@ -218,19 +217,19 @@ class _ZoneSpecification implements ZoneSpecification { this.print, this.fork}); - final HandleUncaughtErrorHandler handleUncaughtError; - final RunHandler run; - final RunUnaryHandler runUnary; - final RunBinaryHandler runBinary; - final RegisterCallbackHandler registerCallback; - final RegisterUnaryCallbackHandler registerUnaryCallback; - final RegisterBinaryCallbackHandler registerBinaryCallback; - final ErrorCallbackHandler errorCallback; - final ScheduleMicrotaskHandler scheduleMicrotask; - final CreateTimerHandler createTimer; - final CreatePeriodicTimerHandler createPeriodicTimer; - final PrintHandler print; - final ForkHandler fork; + final HandleUncaughtErrorHandler? handleUncaughtError; + final RunHandler? run; + final RunUnaryHandler? runUnary; + final RunBinaryHandler? runBinary; + final RegisterCallbackHandler? registerCallback; + final RegisterUnaryCallbackHandler? registerUnaryCallback; + final RegisterBinaryCallbackHandler? registerBinaryCallback; + final ErrorCallbackHandler? errorCallback; + final ScheduleMicrotaskHandler? scheduleMicrotask; + final CreateTimerHandler? createTimer; + final CreatePeriodicTimerHandler? createPeriodicTimer; + final PrintHandler? print; + final ForkHandler? fork; } /** @@ -256,7 +255,7 @@ class _ZoneSpecification implements ZoneSpecification { * to skip zones that would just delegate to their parents. */ abstract class ZoneDelegate { - void handleUncaughtError(Zone zone, error, StackTrace stackTrace); + void handleUncaughtError(Zone zone, Object error, StackTrace stackTrace); R run(Zone zone, R f()); R runUnary(Zone zone, R f(T arg), T arg); R runBinary(Zone zone, R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2); @@ -264,12 +263,12 @@ abstract class ZoneDelegate { ZoneUnaryCallback registerUnaryCallback(Zone zone, R f(T arg)); ZoneBinaryCallback registerBinaryCallback( Zone zone, R f(T1 arg1, T2 arg2)); - AsyncError errorCallback(Zone zone, Object error, StackTrace stackTrace); + AsyncError? errorCallback(Zone zone, Object error, StackTrace? stackTrace); void scheduleMicrotask(Zone zone, void f()); Timer createTimer(Zone zone, Duration duration, void f()); Timer createPeriodicTimer(Zone zone, Duration period, void f(Timer timer)); void print(Zone zone, String line); - Zone fork(Zone zone, ZoneSpecification specification, Map zoneValues); + Zone fork(Zone zone, ZoneSpecification? specification, Map? zoneValues); } /** @@ -283,7 +282,7 @@ abstract class ZoneDelegate { * an existing zone likely created using [Zone.fork]. * * Developers can create a new zone that overrides some of the functionality of - * an existing zone. For example, custom zones can replace or modify the + * an existing zone. For example, custom zones can replace of modify the * behavior of `print`, timers, microtasks or how uncaught errors are handled. * * The [Zone] class is not subclassable, but users can provide custom zones by @@ -340,7 +339,7 @@ abstract class Zone { static const Zone root = _rootZone; /** The currently running zone. */ - static Zone _current = _rootZone; + static _Zone _current = _rootZone; /** The zone that is currently active. */ static Zone get current => _current; @@ -363,7 +362,7 @@ abstract class Zone { * By default, when handled by the root zone, uncaught asynchronous errors are * treated like uncaught synchronous exceptions. */ - void handleUncaughtError(error, StackTrace stackTrace); + void handleUncaughtError(Object error, StackTrace stackTrace); /** * The parent zone of the this zone. @@ -374,7 +373,7 @@ abstract class Zone { * forks the [current] zone. The new zone's parent zone is the zone it was * forked from. */ - Zone get parent; + Zone? get parent; /** * The error zone is the one that is responsible for dealing with uncaught @@ -395,7 +394,7 @@ abstract class Zone { * runZoned(() { * // The asynchronous error is caught by the custom zone which prints * // 'asynchronous error'. - * future = new Future.error("asynchronous error"); + * future = Future.error("asynchronous error"); * }, onError: (e) { print(e); }); // Creates a zone with an error handler. * // The following `catchError` handler is never invoked, because the * // custom zone created by the call to `runZoned` provides an @@ -416,7 +415,7 @@ abstract class Zone { * // with different error handlers. * // Instead the error is handled by the current error handler, * // printing "Caught by outer zone: asynchronous error". - * var future = new Future.error("asynchronous error"); + * var future = Future.error("asynchronous error"); * runZoned(() { * future.catchError((e) { throw "is never reached"; }); * }, onError: (e) { throw "is never reached"; }); @@ -448,7 +447,8 @@ abstract class Zone { * the zone specification (or zone values), giving the forking zone full * control over the child zone. */ - Zone fork({ZoneSpecification specification, Map zoneValues}); + Zone fork( + {ZoneSpecification? specification, Map? zoneValues}); /** * Executes [action] in this zone. @@ -599,7 +599,7 @@ abstract class Zone { * return () => this.runGuarded(registered); * */ - void Function() bindCallbackGuarded(void callback()); + void Function() bindCallbackGuarded(void Function() callback); /** * Registers the provided [callback] and returns a function that will @@ -656,7 +656,7 @@ abstract class Zone { * errors are usually reported through future completers or stream * controllers. */ - AsyncError errorCallback(Object error, StackTrace stackTrace); + AsyncError? errorCallback(Object error, StackTrace? stackTrace); /** * Runs [callback] asynchronously in this zone. @@ -668,12 +668,12 @@ abstract class Zone { * Custom zones may intercept this operation (for example to wrap the given * [callback]). */ - void scheduleMicrotask(void callback()); + void scheduleMicrotask(void Function() callback); /** * Creates a Timer where the callback is executed in this zone. */ - Timer createTimer(Duration duration, void callback()); + Timer createTimer(Duration duration, void Function() callback); /** * Creates a periodic Timer where the callback is executed in this zone. @@ -708,10 +708,9 @@ abstract class Zone { * * The previous current zone is returned. */ - static Zone _enter(Zone zone) { - assert(zone != null); + static _Zone _enter(_Zone zone) { assert(!identical(zone, _current)); - Zone previous = _current; + _Zone previous = _current; _current = zone; return previous; } @@ -721,7 +720,7 @@ abstract class Zone { * * The previous Zone must be provided as `previous`. */ - static void _leave(Zone previous) { + static void _leave(_Zone previous) { assert(previous != null); Zone._current = previous; } @@ -737,12 +736,7 @@ abstract class Zone { * By controlling access to the key, a zone can grant or deny access to the * zone value. */ - operator [](Object key); -} - -ZoneDelegate _parentDelegate(_Zone zone) { - if (zone.parent == null) return null; - return zone.parent._delegate; + dynamic operator [](Object? key); } class _ZoneDelegate implements ZoneDelegate { @@ -750,101 +744,101 @@ class _ZoneDelegate implements ZoneDelegate { _ZoneDelegate(this._delegationTarget); - void handleUncaughtError(Zone zone, error, StackTrace stackTrace) { + void handleUncaughtError(Zone zone, Object error, StackTrace stackTrace) { var implementation = _delegationTarget._handleUncaughtError; _Zone implZone = implementation.zone; HandleUncaughtErrorHandler handler = implementation.function; - return handler( - implZone, _parentDelegate(implZone), zone, error, stackTrace); + return handler(implZone, implZone._parentDelegate, zone, error, stackTrace); } R run(Zone zone, R f()) { var implementation = _delegationTarget._run; _Zone implZone = implementation.zone; - RunHandler handler = implementation.function; - return handler(implZone, _parentDelegate(implZone), zone, f); + var handler = implementation.function as RunHandler; + return handler(implZone, implZone._parentDelegate, zone, f); } R runUnary(Zone zone, R f(T arg), T arg) { var implementation = _delegationTarget._runUnary; _Zone implZone = implementation.zone; - RunUnaryHandler handler = implementation.function; - return handler(implZone, _parentDelegate(implZone), zone, f, arg); + var handler = implementation.function as RunUnaryHandler; + return handler(implZone, implZone._parentDelegate, zone, f, arg); } R runBinary(Zone zone, R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) { var implementation = _delegationTarget._runBinary; _Zone implZone = implementation.zone; - RunBinaryHandler handler = implementation.function; - return handler(implZone, _parentDelegate(implZone), zone, f, arg1, arg2); + var handler = implementation.function as RunBinaryHandler; + return handler(implZone, implZone._parentDelegate, zone, f, arg1, arg2); } ZoneCallback registerCallback(Zone zone, R f()) { var implementation = _delegationTarget._registerCallback; _Zone implZone = implementation.zone; - RegisterCallbackHandler handler = implementation.function; - return handler(implZone, _parentDelegate(implZone), zone, f); + var handler = implementation.function as RegisterCallbackHandler; + return handler(implZone, implZone._parentDelegate, zone, f); } ZoneUnaryCallback registerUnaryCallback(Zone zone, R f(T arg)) { var implementation = _delegationTarget._registerUnaryCallback; _Zone implZone = implementation.zone; - RegisterUnaryCallbackHandler handler = implementation.function; - return handler(implZone, _parentDelegate(implZone), zone, f); + var handler = implementation.function as RegisterUnaryCallbackHandler; + return handler(implZone, implZone._parentDelegate, zone, f); } ZoneBinaryCallback registerBinaryCallback( Zone zone, R f(T1 arg1, T2 arg2)) { var implementation = _delegationTarget._registerBinaryCallback; _Zone implZone = implementation.zone; - RegisterBinaryCallbackHandler handler = implementation.function; - return handler(implZone, _parentDelegate(implZone), zone, f); + var handler = implementation.function as RegisterBinaryCallbackHandler; + return handler(implZone, implZone._parentDelegate, zone, f); } - AsyncError errorCallback(Zone zone, Object error, StackTrace stackTrace) { + AsyncError? errorCallback(Zone zone, Object error, StackTrace? stackTrace) { + // TODO(40614): Remove once non-nullability is sound. ArgumentError.checkNotNull(error, "error"); var implementation = _delegationTarget._errorCallback; _Zone implZone = implementation.zone; if (identical(implZone, _rootZone)) return null; ErrorCallbackHandler handler = implementation.function; - return handler( - implZone, _parentDelegate(implZone), zone, error, stackTrace); + return handler(implZone, implZone._parentDelegate, zone, error, stackTrace); } void scheduleMicrotask(Zone zone, f()) { var implementation = _delegationTarget._scheduleMicrotask; _Zone implZone = implementation.zone; ScheduleMicrotaskHandler handler = implementation.function; - handler(implZone, _parentDelegate(implZone), zone, f); + handler(implZone, implZone._parentDelegate, zone, f); } Timer createTimer(Zone zone, Duration duration, void f()) { var implementation = _delegationTarget._createTimer; _Zone implZone = implementation.zone; CreateTimerHandler handler = implementation.function; - return handler(implZone, _parentDelegate(implZone), zone, duration, f); + return handler(implZone, implZone._parentDelegate, zone, duration, f); } Timer createPeriodicTimer(Zone zone, Duration period, void f(Timer timer)) { var implementation = _delegationTarget._createPeriodicTimer; _Zone implZone = implementation.zone; CreatePeriodicTimerHandler handler = implementation.function; - return handler(implZone, _parentDelegate(implZone), zone, period, f); + return handler(implZone, implZone._parentDelegate, zone, period, f); } void print(Zone zone, String line) { var implementation = _delegationTarget._print; _Zone implZone = implementation.zone; PrintHandler handler = implementation.function; - handler(implZone, _parentDelegate(implZone), zone, line); + handler(implZone, implZone._parentDelegate, zone, line); } - Zone fork(Zone zone, ZoneSpecification specification, Map zoneValues) { + Zone fork(Zone zone, ZoneSpecification? specification, + Map? zoneValues) { var implementation = _delegationTarget._fork; _Zone implZone = implementation.zone; ForkHandler handler = implementation.function; return handler( - implZone, _parentDelegate(implZone), zone, specification, zoneValues); + implZone, implZone._parentDelegate, zone, specification, zoneValues); } } @@ -869,9 +863,11 @@ abstract class _Zone implements Zone { _ZoneFunction get _print; _ZoneFunction get _fork; _ZoneFunction get _handleUncaughtError; - _Zone get parent; + // Parent zone. Only `null` for the root zone. + _Zone? get parent; ZoneDelegate get _delegate; - Map get _map; + ZoneDelegate get _parentDelegate; + Map get _map; bool inSameErrorZone(Zone otherZone) { return identical(this, otherZone) || @@ -883,7 +879,7 @@ class _CustomZone extends _Zone { // The actual zone and implementation of each of these // inheritable zone functions. // TODO(floitsch): the types of the `_ZoneFunction`s should have a type for - // all fields. + // all fields, but we can't use generic function types as type arguments. _RunNullaryZoneFunction _run; _RunUnaryZoneFunction _runUnary; _RunBinaryZoneFunction _runBinary; @@ -899,7 +895,7 @@ class _CustomZone extends _Zone { _ZoneFunction _handleUncaughtError; // A cached delegate to this zone. - ZoneDelegate _delegateCache; + ZoneDelegate? _delegateCache; /// The parent zone. final _Zone parent; @@ -907,63 +903,85 @@ class _CustomZone extends _Zone { /// The zone's scoped value declaration map. /// /// This is always a [HashMap]. - final Map _map; + final Map _map; - ZoneDelegate get _delegate { - if (_delegateCache != null) return _delegateCache; - _delegateCache = new _ZoneDelegate(this); - return _delegateCache; - } + ZoneDelegate get _delegate => _delegateCache ??= _ZoneDelegate(this); + ZoneDelegate get _parentDelegate => parent._delegate; - _CustomZone(this.parent, ZoneSpecification specification, this._map) { + _CustomZone(this.parent, ZoneSpecification specification, this._map) + : _run = parent._run, + _runUnary = parent._runUnary, + _runBinary = parent._runBinary, + _registerCallback = parent._registerCallback, + _registerUnaryCallback = parent._registerUnaryCallback, + _registerBinaryCallback = parent._registerBinaryCallback, + _errorCallback = parent._errorCallback, + _scheduleMicrotask = parent._scheduleMicrotask, + _createTimer = parent._createTimer, + _createPeriodicTimer = parent._createPeriodicTimer, + _print = parent._print, + _fork = parent._fork, + _handleUncaughtError = parent._handleUncaughtError { // The root zone will have implementations of all parts of the // specification, so it will never try to access the (null) parent. // All other zones have a non-null parent. - _run = (specification.run != null) - ? new _RunNullaryZoneFunction(this, specification.run) - : parent._run; - _runUnary = (specification.runUnary != null) - ? new _RunUnaryZoneFunction(this, specification.runUnary) - : parent._runUnary; - _runBinary = (specification.runBinary != null) - ? new _RunBinaryZoneFunction(this, specification.runBinary) - : parent._runBinary; - _registerCallback = (specification.registerCallback != null) - ? new _RegisterNullaryZoneFunction(this, specification.registerCallback) - : parent._registerCallback; - _registerUnaryCallback = (specification.registerUnaryCallback != null) - ? new _RegisterUnaryZoneFunction( - this, specification.registerUnaryCallback) - : parent._registerUnaryCallback; - _registerBinaryCallback = (specification.registerBinaryCallback != null) - ? new _RegisterBinaryZoneFunction( - this, specification.registerBinaryCallback) - : parent._registerBinaryCallback; - _errorCallback = (specification.errorCallback != null) - ? new _ZoneFunction( - this, specification.errorCallback) - : parent._errorCallback; - _scheduleMicrotask = (specification.scheduleMicrotask != null) - ? new _ZoneFunction( - this, specification.scheduleMicrotask) - : parent._scheduleMicrotask; - _createTimer = (specification.createTimer != null) - ? new _ZoneFunction(this, specification.createTimer) - : parent._createTimer; - _createPeriodicTimer = (specification.createPeriodicTimer != null) - ? new _ZoneFunction( - this, specification.createPeriodicTimer) - : parent._createPeriodicTimer; - _print = (specification.print != null) - ? new _ZoneFunction(this, specification.print) - : parent._print; - _fork = (specification.fork != null) - ? new _ZoneFunction(this, specification.fork) - : parent._fork; - _handleUncaughtError = (specification.handleUncaughtError != null) - ? new _ZoneFunction( - this, specification.handleUncaughtError) - : parent._handleUncaughtError; + var run = specification.run; + if (run != null) { + _run = _RunNullaryZoneFunction(this, run); + } + var runUnary = specification.runUnary; + if (runUnary != null) { + _runUnary = _RunUnaryZoneFunction(this, runUnary); + } + var runBinary = specification.runBinary; + if (runBinary != null) { + _runBinary = _RunBinaryZoneFunction(this, runBinary); + } + var registerCallback = specification.registerCallback; + if (registerCallback != null) { + _registerCallback = _RegisterNullaryZoneFunction(this, registerCallback); + } + var registerUnaryCallback = specification.registerUnaryCallback; + if (registerUnaryCallback != null) { + _registerUnaryCallback = + _RegisterUnaryZoneFunction(this, registerUnaryCallback); + } + var registerBinaryCallback = specification.registerBinaryCallback; + if (registerBinaryCallback != null) { + _registerBinaryCallback = + _RegisterBinaryZoneFunction(this, registerBinaryCallback); + } + var errorCallback = specification.errorCallback; + if (errorCallback != null) { + _errorCallback = _ZoneFunction(this, errorCallback); + } + var scheduleMicrotask = specification.scheduleMicrotask; + if (scheduleMicrotask != null) { + _scheduleMicrotask = + _ZoneFunction(this, scheduleMicrotask); + } + var createTimer = specification.createTimer; + if (createTimer != null) { + _createTimer = _ZoneFunction(this, createTimer); + } + var createPeriodicTimer = specification.createPeriodicTimer; + if (createPeriodicTimer != null) { + _createPeriodicTimer = + _ZoneFunction(this, createPeriodicTimer); + } + var print = specification.print; + if (print != null) { + _print = _ZoneFunction(this, print); + } + var fork = specification.fork; + if (fork != null) { + _fork = _ZoneFunction(this, fork); + } + var handleUncaughtError = specification.handleUncaughtError; + if (handleUncaughtError != null) { + _handleUncaughtError = + _ZoneFunction(this, handleUncaughtError); + } } /** @@ -1030,7 +1048,7 @@ class _CustomZone extends _Zone { return (arg1, arg2) => this.runBinaryGuarded(registered, arg1, arg2); } - operator [](Object key) { + dynamic operator [](Object? key) { var result = _map[key]; if (result != null || _map.containsKey(key)) return result; // If we are not the root zone, look up in the parent zone. @@ -1051,19 +1069,18 @@ class _CustomZone extends _Zone { // Methods that can be customized by the zone specification. - void handleUncaughtError(error, StackTrace stackTrace) { + void handleUncaughtError(Object error, StackTrace stackTrace) { var implementation = this._handleUncaughtError; - assert(implementation != null); - ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); + ZoneDelegate parentDelegate = implementation.zone._parentDelegate; HandleUncaughtErrorHandler handler = implementation.function; return handler( implementation.zone, parentDelegate, this, error, stackTrace); } - Zone fork({ZoneSpecification specification, Map zoneValues}) { + Zone fork( + {ZoneSpecification? specification, Map? zoneValues}) { var implementation = this._fork; - assert(implementation != null); - ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); + ZoneDelegate parentDelegate = implementation.zone._parentDelegate; ForkHandler handler = implementation.function; return handler( implementation.zone, parentDelegate, this, specification, zoneValues); @@ -1071,115 +1088,104 @@ class _CustomZone extends _Zone { R run(R f()) { var implementation = this._run; - assert(implementation != null); - ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); - RunHandler handler = implementation.function; + ZoneDelegate parentDelegate = implementation.zone._parentDelegate; + var handler = implementation.function as RunHandler; return handler(implementation.zone, parentDelegate, this, f); } R runUnary(R f(T arg), T arg) { var implementation = this._runUnary; - assert(implementation != null); - ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); - RunUnaryHandler handler = implementation.function; + ZoneDelegate parentDelegate = implementation.zone._parentDelegate; + var handler = implementation.function as RunUnaryHandler; return handler(implementation.zone, parentDelegate, this, f, arg); } R runBinary(R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) { var implementation = this._runBinary; - assert(implementation != null); - ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); - RunBinaryHandler handler = implementation.function; + ZoneDelegate parentDelegate = implementation.zone._parentDelegate; + var handler = implementation.function as RunBinaryHandler; return handler(implementation.zone, parentDelegate, this, f, arg1, arg2); } ZoneCallback registerCallback(R callback()) { var implementation = this._registerCallback; - assert(implementation != null); - ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); - RegisterCallbackHandler handler = implementation.function; + ZoneDelegate parentDelegate = implementation.zone._parentDelegate; + var handler = implementation.function as RegisterCallbackHandler; return handler(implementation.zone, parentDelegate, this, callback); } ZoneUnaryCallback registerUnaryCallback(R callback(T arg)) { var implementation = this._registerUnaryCallback; - assert(implementation != null); - ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); - RegisterUnaryCallbackHandler handler = implementation.function; + ZoneDelegate parentDelegate = implementation.zone._parentDelegate; + var handler = implementation.function as RegisterUnaryCallbackHandler; return handler(implementation.zone, parentDelegate, this, callback); } ZoneBinaryCallback registerBinaryCallback( R callback(T1 arg1, T2 arg2)) { var implementation = this._registerBinaryCallback; - assert(implementation != null); - ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); - RegisterBinaryCallbackHandler handler = implementation.function; + ZoneDelegate parentDelegate = implementation.zone._parentDelegate; + var handler = implementation.function as RegisterBinaryCallbackHandler; return handler(implementation.zone, parentDelegate, this, callback); } - AsyncError errorCallback(Object error, StackTrace stackTrace) { + AsyncError? errorCallback(Object error, StackTrace? stackTrace) { + // TODO(40614): Remove once non-nullability is sound. ArgumentError.checkNotNull(error, "error"); var implementation = this._errorCallback; - assert(implementation != null); - final Zone implementationZone = implementation.zone; + final _Zone implementationZone = implementation.zone; if (identical(implementationZone, _rootZone)) return null; - final ZoneDelegate parentDelegate = _parentDelegate(implementationZone); + final ZoneDelegate parentDelegate = implementationZone._parentDelegate; ErrorCallbackHandler handler = implementation.function; return handler(implementationZone, parentDelegate, this, error, stackTrace); } void scheduleMicrotask(void f()) { var implementation = this._scheduleMicrotask; - assert(implementation != null); - ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); + ZoneDelegate parentDelegate = implementation.zone._parentDelegate; ScheduleMicrotaskHandler handler = implementation.function; return handler(implementation.zone, parentDelegate, this, f); } Timer createTimer(Duration duration, void f()) { var implementation = this._createTimer; - assert(implementation != null); - ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); + ZoneDelegate parentDelegate = implementation.zone._parentDelegate; CreateTimerHandler handler = implementation.function; return handler(implementation.zone, parentDelegate, this, duration, f); } Timer createPeriodicTimer(Duration duration, void f(Timer timer)) { var implementation = this._createPeriodicTimer; - assert(implementation != null); - ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); + ZoneDelegate parentDelegate = implementation.zone._parentDelegate; CreatePeriodicTimerHandler handler = implementation.function; return handler(implementation.zone, parentDelegate, this, duration, f); } void print(String line) { var implementation = this._print; - assert(implementation != null); - ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); + ZoneDelegate parentDelegate = implementation.zone._parentDelegate; PrintHandler handler = implementation.function; return handler(implementation.zone, parentDelegate, this, line); } } -void _rootHandleUncaughtError( - Zone self, ZoneDelegate parent, Zone zone, error, StackTrace stackTrace) { - if (error == null) { - error = ArgumentError.notNull("error"); - stackTrace = StackTrace.current; - } +void _rootHandleUncaughtError(Zone? self, ZoneDelegate? parent, Zone zone, + Object error, StackTrace stackTrace) { _schedulePriorityAsyncCallback(() { - if (stackTrace == null) throw error; _rethrow(error, stackTrace); }); } external void _rethrow(Object error, StackTrace stackTrace); -R _rootRun(Zone self, ZoneDelegate parent, Zone zone, R f()) { - if (Zone._current == zone) return f(); +R _rootRun(Zone? self, ZoneDelegate? parent, Zone zone, R f()) { + if (identical(Zone._current, zone)) return f(); - Zone old = Zone._enter(zone); + if (zone is! _Zone) { + throw ArgumentError.value(zone, "zone", "Can only run in platform zones"); + } + + _Zone old = Zone._enter(zone); try { return f(); } finally { @@ -1188,10 +1194,14 @@ R _rootRun(Zone self, ZoneDelegate parent, Zone zone, R f()) { } R _rootRunUnary( - Zone self, ZoneDelegate parent, Zone zone, R f(T arg), T arg) { - if (Zone._current == zone) return f(arg); + Zone? self, ZoneDelegate? parent, Zone zone, R f(T arg), T arg) { + if (identical(Zone._current, zone)) return f(arg); - Zone old = Zone._enter(zone); + if (zone is! _Zone) { + throw ArgumentError.value(zone, "zone", "Can only run in platform zones"); + } + + _Zone old = Zone._enter(zone); try { return f(arg); } finally { @@ -1199,11 +1209,15 @@ R _rootRunUnary( } } -R _rootRunBinary(Zone self, ZoneDelegate parent, Zone zone, +R _rootRunBinary(Zone? self, ZoneDelegate? parent, Zone zone, R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) { - if (Zone._current == zone) return f(arg1, arg2); + if (identical(Zone._current, zone)) return f(arg1, arg2); - Zone old = Zone._enter(zone); + if (zone is! _Zone) { + throw ArgumentError.value(zone, "zone", "Can only run in platform zones"); + } + + _Zone old = Zone._enter(zone); try { return f(arg1, arg2); } finally { @@ -1226,12 +1240,12 @@ ZoneBinaryCallback _rootRegisterBinaryCallback( return f; } -AsyncError _rootErrorCallback(Zone self, ZoneDelegate parent, Zone zone, - Object error, StackTrace stackTrace) => +AsyncError? _rootErrorCallback(Zone self, ZoneDelegate parent, Zone zone, + Object error, StackTrace? stackTrace) => null; void _rootScheduleMicrotask( - Zone self, ZoneDelegate parent, Zone zone, void f()) { + Zone? self, ZoneDelegate? parent, Zone zone, void f()) { if (!identical(_rootZone, zone)) { bool hasErrorHandler = !_rootZone.inSameErrorZone(zone); if (hasErrorHandler) { @@ -1239,14 +1253,12 @@ void _rootScheduleMicrotask( } else { f = zone.bindCallback(f); } - // Use root zone as event zone if the function is already bound. - zone = _rootZone; } _scheduleAsyncCallback(f); } Timer _rootCreateTimer(Zone self, ZoneDelegate parent, Zone zone, - Duration duration, void callback()) { + Duration duration, void Function() callback) { if (!identical(_rootZone, zone)) { callback = zone.bindCallback(callback); } @@ -1256,8 +1268,7 @@ Timer _rootCreateTimer(Zone self, ZoneDelegate parent, Zone zone, Timer _rootCreatePeriodicTimer(Zone self, ZoneDelegate parent, Zone zone, Duration duration, void callback(Timer timer)) { if (!identical(_rootZone, zone)) { - // TODO(floitsch): the return type should be 'void'. - callback = zone.bindUnaryCallback(callback); + callback = zone.bindUnaryCallback(callback); } return Timer._createPeriodicTimer(duration, callback); } @@ -1270,8 +1281,11 @@ void _printToZone(String line) { Zone.current.print(line); } -Zone _rootFork(Zone self, ZoneDelegate parent, Zone zone, - ZoneSpecification specification, Map zoneValues) { +Zone _rootFork(Zone? self, ZoneDelegate? parent, Zone zone, + ZoneSpecification? specification, Map? zoneValues) { + if (zone is! _Zone) { + throw ArgumentError.value(zone, "zone", "Can only fork a platform zone"); + } // TODO(floitsch): it would be nice if we could get rid of this hack. // Change the static zoneOrDirectPrint function to go through zones // from now on. @@ -1280,20 +1294,17 @@ Zone _rootFork(Zone self, ZoneDelegate parent, Zone zone, if (specification == null) { specification = const ZoneSpecification(); } else if (specification is! _ZoneSpecification) { - throw new ArgumentError("ZoneSpecifications must be instantiated" - " with the provided constructor."); + specification = ZoneSpecification.from(specification); } - Map valueMap; + Map valueMap; if (zoneValues == null) { - if (zone is _Zone) { - valueMap = zone._map; - } else { - valueMap = new HashMap(); - } + valueMap = zone._map; } else { - valueMap = new HashMap.from(zoneValues); + valueMap = HashMap.from(zoneValues); } - return new _CustomZone(zone, specification, valueMap); + if (specification == null) + throw "unreachable"; // TODO(lrn): Remove when type promotion works. + return _CustomZone(zone, specification, valueMap); } class _RootZone extends _Zone { @@ -1330,21 +1341,20 @@ class _RootZone extends _Zone { _rootZone, _rootHandleUncaughtError); // The parent zone. - _Zone get parent => null; + _Zone? get parent => null; /// The zone's scoped value declaration map. /// /// This is always a [HashMap]. - Map get _map => _rootMap; + Map get _map => _rootMap; - static final _rootMap = new HashMap(); + static final _rootMap = HashMap(); - static ZoneDelegate _rootDelegate; + static ZoneDelegate? _rootDelegate; - ZoneDelegate get _delegate { - if (_rootDelegate != null) return _rootDelegate; - return _rootDelegate = new _ZoneDelegate(this); - } + ZoneDelegate get _delegate => _rootDelegate ??= new _ZoneDelegate(this); + // It's a lie, but the root zone never uses the parent delegate. + ZoneDelegate get _parentDelegate => _delegate; /** * The closest error-handling zone. @@ -1418,15 +1428,16 @@ class _RootZone extends _Zone { return (arg1, arg2) => this.runBinaryGuarded(f, arg1, arg2); } - operator [](Object key) => null; + dynamic operator [](Object? key) => null; // Methods that can be customized by the zone specification. - void handleUncaughtError(error, StackTrace stackTrace) { + void handleUncaughtError(Object error, StackTrace stackTrace) { _rootHandleUncaughtError(null, null, this, error, stackTrace); } - Zone fork({ZoneSpecification specification, Map zoneValues}) { + Zone fork( + {ZoneSpecification? specification, Map? zoneValues}) { return _rootFork(null, null, this, specification, zoneValues); } @@ -1453,7 +1464,7 @@ class _RootZone extends _Zone { R f(T1 arg1, T2 arg2)) => f; - AsyncError errorCallback(Object error, StackTrace stackTrace) => null; + AsyncError? errorCallback(Object error, StackTrace? stackTrace) => null; void scheduleMicrotask(void f()) { _rootScheduleMicrotask(null, null, this, f); @@ -1472,7 +1483,7 @@ class _RootZone extends _Zone { } } -const _rootZone = const _RootZone(); +const _Zone _rootZone = const _RootZone(); /** * Runs [body] in its own zone. @@ -1490,7 +1501,7 @@ const _rootZone = const _RootZone(); * If an error occurs synchronously in [body], * then throwing in the [onError] handler * makes the call to `runZone` throw that error, - * and otherwise the call to `runZoned` returns `null`. + * and otherwise the call to `runZoned` attempt to return `null`. * * If the zone specification has a `handleUncaughtError` value or the [onError] * parameter is provided, the zone becomes an error-zone. @@ -1518,23 +1529,23 @@ const _rootZone = const _RootZone(); * occur in the original zone where [runZoned] was called. */ R runZoned(R body(), - {Map zoneValues, - ZoneSpecification zoneSpecification, - @Deprecated("Use runZonedGuarded instead") Function onError}) { + {Map? zoneValues, + ZoneSpecification? zoneSpecification, + @Deprecated("Use runZonedGuarded instead") Function? onError}) { ArgumentError.checkNotNull(body, "body"); - if (onError != null) { - void Function(Object, StackTrace) typedOnError; - if (onError is void Function(Object, StackTrace)) { - typedOnError = onError; - } else if (onError is void Function(Object)) { - typedOnError = (Object e, StackTrace _) => onError(e); - } else { - throw ArgumentError.value(onError, "onError", - "Should accept one error, or one error and a stack trace"); + // TODO: Remove this when code have been migrated off using [onError]. + if (onError is! void Function(Object, StackTrace)) { + if (onError is void Function(Object)) { + var originalOnError = onError; + onError = (Object error, StackTrace stack) => originalOnError(error); + } else { + throw ArgumentError.value(onError, "onError", + "Must be Function(Object) or Function(Object, StackTrace)"); + } } - return runZonedGuarded(body, typedOnError, - zoneValues: zoneValues, zoneSpecification: zoneSpecification); + return runZonedGuarded(body, onError, + zoneSpecification: zoneSpecification, zoneValues: zoneValues) as R; } return _runZoned(body, zoneValues, zoneSpecification); } @@ -1554,41 +1565,40 @@ R runZoned(R body(), * makes the call to `runZonedGuarded` throw that error, * and otherwise the call to `runZonedGuarded` returns `null`. * - * If the zone specification has a `handleUncaughtError` value or the [onError] - * parameter is provided, the zone becomes an error-zone. + * The zone will always be an error-zone. * * Errors will never cross error-zone boundaries by themselves. * Errors that try to cross error-zone boundaries are considered uncaught in * their originating error zone. - * - * var future = new Future.value(499); - * runZoned(() { - * var future2 = future.then((_) { throw "error in first error-zone"; }); - * runZoned(() { - * var future3 = future2.catchError((e) { print("Never reached!"); }); - * }, onError: (e, s) { print("unused error handler"); }); - * }, onError: (e, s) { print("catches error of first error-zone."); }); - * + * ```dart + * var future = Future.value(499); + * runZonedGuarded(() { + * var future2 = future.then((_) { throw "error in first error-zone"; }); + * runZonedGuarded(() { + * var future3 = future2.catchError((e) { print("Never reached!"); }); + * }, (e, s) { print("unused error handler"); }); + * }, (e, s) { print("catches error of first error-zone."); }); + * ``` * Example: - * - * runZoned(() { - * new Future(() { throw "asynchronous error"; }); - * }, onError: (e, s) => print(e)); // Will print "asynchronous error". - * + * ```dart + * runZonedGuarded(() { + * new Future(() { throw "asynchronous error"; }); + * }, (e, s) => print(e)); // Will print "asynchronous error". + * ``` * It is possible to manually pass an error from one error zone to another * by re-throwing it in the new zone. If [onError] throws, that error will * occur in the original zone where [runZoned] was called. */ @Since("2.8") -R runZonedGuarded(R body(), void onError(Object error, StackTrace stack), - {Map zoneValues, ZoneSpecification zoneSpecification}) { +R? runZonedGuarded(R body(), void onError(Object error, StackTrace stack), + {Map? zoneValues, ZoneSpecification? zoneSpecification}) { ArgumentError.checkNotNull(body, "body"); ArgumentError.checkNotNull(onError, "onError"); - + _Zone parentZone = Zone._current; HandleUncaughtErrorHandler errorHandler = (Zone self, ZoneDelegate parent, - Zone zone, error, StackTrace stackTrace) { + Zone zone, Object error, StackTrace stackTrace) { try { - self.parent.runBinary(onError, error, stackTrace); + parentZone.runBinary(onError, error, stackTrace); } catch (e, s) { if (identical(e, error)) { parent.handleUncaughtError(zone, error, stackTrace); @@ -1601,7 +1611,7 @@ R runZonedGuarded(R body(), void onError(Object error, StackTrace stack), zoneSpecification = new ZoneSpecification(handleUncaughtError: errorHandler); } else { - zoneSpecification = new ZoneSpecification.from(zoneSpecification, + zoneSpecification = ZoneSpecification.from(zoneSpecification, handleUncaughtError: errorHandler); } try { @@ -1613,7 +1623,8 @@ R runZonedGuarded(R body(), void onError(Object error, StackTrace stack), } /// Runs [body] in a new zone based on [zoneValues] and [specification]. -R _runZoned(R body(), Map zoneValues, ZoneSpecification specification) => +R _runZoned(R body(), Map? zoneValues, + ZoneSpecification? specification) => Zone.current .fork(specification: specification, zoneValues: zoneValues) .run(body); diff --git a/sdk/lib/cli/cli.dart b/sdk/lib/cli/cli.dart index cabc17e5cd9..9c19c3a3252 100644 --- a/sdk/lib/cli/cli.dart +++ b/sdk/lib/cli/cli.dart @@ -2,10 +2,7 @@ // 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.6 - /// {@category VM} -/// {@nodoc} library dart.cli; import 'dart:async'; diff --git a/sdk/lib/cli/wait_for.dart b/sdk/lib/cli/wait_for.dart index 57202bc8795..35cb307ea93 100644 --- a/sdk/lib/cli/wait_for.dart +++ b/sdk/lib/cli/wait_for.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.cli; /** @@ -55,14 +53,15 @@ void Function(int) _getWaitForEvent() => _waitForEvent; // native implementation. In the standalone VM this is set to _waitForEvent() // above. If it is null, calling waitFor() will throw an UnsupportedError. @pragma("vm:entry-point") -void Function(int) _waitForEventClosure; +void Function(int)? _waitForEventClosure; class _WaitForUtils { - static void waitForEvent({Duration timeout}) { - if (_waitForEventClosure == null) { + static void waitForEvent({Duration? timeout}) { + final closure = _waitForEventClosure; + if (closure == null) { throw new UnsupportedError("waitFor is not supported by this embedder"); } - _waitForEventClosure(timeout == null ? 0 : max(1, timeout.inMilliseconds)); + closure(timeout == null ? 0 : max(1, timeout.inMilliseconds)); } } @@ -113,12 +112,12 @@ class _WaitForUtils { * subsequent calls block waiting for a condition that is only satisfied when * an earlier call returns. */ -T waitFor(Future future, {Duration timeout}) { - T result; +T waitFor(Future future, {Duration? timeout}) { + late T result; bool futureCompleted = false; - Object error; - StackTrace stacktrace; - future.then((r) { + Object? error; + StackTrace? stacktrace; + future.then((T r) { futureCompleted = true; result = r; }, onError: (e, st) { @@ -126,13 +125,13 @@ T waitFor(Future future, {Duration timeout}) { stacktrace = st; }); - Stopwatch s; + late Stopwatch s; if (timeout != null) { s = new Stopwatch()..start(); } Timer.run(() {}); // Enusre there is at least one message. while (!futureCompleted && (error == null)) { - Duration remaining; + Duration? remaining; if (timeout != null) { if (s.elapsed >= timeout) { throw new TimeoutException("waitFor() timed out", timeout); @@ -147,7 +146,7 @@ T waitFor(Future future, {Duration timeout}) { Timer.run(() {}); // Ensure that previous calls to waitFor are woken up. if (error != null) { - throw new AsyncError(error, stacktrace); + throw new AsyncError(error!, stacktrace); } return result; diff --git a/sdk/lib/collection/collection.dart b/sdk/lib/collection/collection.dart index 80f6d93f8b6..b050a485e4c 100644 --- a/sdk/lib/collection/collection.dart +++ b/sdk/lib/collection/collection.dart @@ -2,8 +2,6 @@ // 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.6 - /// Classes and utilities that supplement the collection support in dart:core. /// /// To use this library in your code: diff --git a/sdk/lib/collection/collections.dart b/sdk/lib/collection/collections.dart index 600dead1dbf..9b43996f638 100644 --- a/sdk/lib/collection/collections.dart +++ b/sdk/lib/collection/collections.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.collection; /// An unmodifiable [List] view of another List. diff --git a/sdk/lib/collection/hash_map.dart b/sdk/lib/collection/hash_map.dart index e3da5a27c34..3990cd2eb02 100644 --- a/sdk/lib/collection/hash_map.dart +++ b/sdk/lib/collection/hash_map.dart @@ -2,17 +2,15 @@ // 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.6 - part of dart.collection; -/// Default function for equality comparison in customized HashMaps -bool _defaultEquals(a, b) => a == b; +/// Default function for equality comparison in customized HashMaps. +bool _defaultEquals(Object? a, Object? b) => a == b; -/// Default function for hash-code computation in customized HashMaps -int _defaultHashCode(a) => a.hashCode; +/// Default function for hash-code computation in customized HashMaps. +int _defaultHashCode(Object? a) => a.hashCode; -/// Type of custom equality function +/// Type of custom equality function. typedef _Equality = bool Function(K a, K b); /// Type of custom hash code function. @@ -85,9 +83,9 @@ abstract class HashMap implements Map { /// If you supply one of [equals] and [hashCode], /// you should generally also to supply the other. external factory HashMap( - {bool equals(K key1, K key2), - int hashCode(K key), - bool isValidKey(potentialKey)}); + {bool Function(K, K)? equals, + int Function(K)? hashCode, + bool Function(dynamic)? isValidKey}); /// Creates an unordered identity-based map. /// @@ -101,10 +99,10 @@ abstract class HashMap implements Map { /// /// The keys must all be instances of [K] and the values of [V]. /// The [other] map itself can have any type. - factory HashMap.from(Map other) { - Map result = HashMap(); - other.forEach((k, v) { - result[k] = v; + factory HashMap.from(Map other) { + HashMap result = HashMap(); + other.forEach((dynamic k, dynamic v) { + result[k as K] = v as V; }); return result; } @@ -124,8 +122,8 @@ abstract class HashMap implements Map { /// If no values are specified for [key] and [value] the default is the /// identity function. factory HashMap.fromIterable(Iterable iterable, - {K key(element), V value(element)}) { - Map map = HashMap(); + {K Function(dynamic element)? key, V Function(dynamic element)? value}) { + HashMap map = HashMap(); MapBase._fillMapWithMappedIterable(map, iterable, key, value); return map; } @@ -140,7 +138,7 @@ abstract class HashMap implements Map { /// /// It is an error if the two [Iterable]s don't have the same length. factory HashMap.fromIterables(Iterable keys, Iterable values) { - Map map = HashMap(); + HashMap map = HashMap(); MapBase._fillMapWithIterables(map, keys, values); return map; } diff --git a/sdk/lib/collection/hash_set.dart b/sdk/lib/collection/hash_set.dart index 97492e94fe6..6ebb04e6330 100644 --- a/sdk/lib/collection/hash_set.dart +++ b/sdk/lib/collection/hash_set.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.collection; /// An unordered hash-table based [Set] implementation. @@ -66,9 +64,9 @@ abstract class HashSet implements Set { /// and the `isValidKey` defaults to accepting all keys. /// Such a map can be created directly using [HashSet.identity]. external factory HashSet( - {bool equals(E e1, E e2), - int hashCode(E e), - bool isValidKey(potentialKey)}); + {bool Function(E, E)? equals, + int Function(E)? hashCode, + bool Function(dynamic)? isValidKey}); /// Creates an unordered identity-based set. /// @@ -80,7 +78,7 @@ abstract class HashSet implements Set { /// Create a hash set containing all [elements]. /// - /// Creates a hash set as by `new HashSet()` and adds all given [elements] + /// Creates a hash set as by `HashSet()` and adds all given [elements] /// to the set. The elements are added in order. If [elements] contains /// two entries that are equal, but not identical, then the first one is /// the one in the resulting set. @@ -91,12 +89,12 @@ abstract class HashSet implements Set { /// ```dart /// Set superSet = ...; /// Set subSet = - /// new HashSet.from(superSet.whereType()); + /// HashSet.from(superSet.whereType()); /// ``` - factory HashSet.from(Iterable elements) { + factory HashSet.from(Iterable elements) { HashSet result = HashSet(); for (final e in elements) { - result.add(e); + result.add(e as E); } return result; } diff --git a/sdk/lib/collection/iterable.dart b/sdk/lib/collection/iterable.dart index 944466d654e..17f84a2a25f 100644 --- a/sdk/lib/collection/iterable.dart +++ b/sdk/lib/collection/iterable.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.collection; /// This [Iterable] mixin implements all [Iterable] members except `iterator`. @@ -35,7 +33,7 @@ abstract class IterableMixin implements Iterable { return FollowedByIterable(this, other); } - bool contains(Object element) { + bool contains(Object? element) { for (E e in this) { if (e == element) return true; } @@ -159,7 +157,7 @@ abstract class IterableMixin implements Iterable { return result; } - E firstWhere(bool test(E value), {E orElse()}) { + E firstWhere(bool test(E value), {E Function()? orElse}) { for (E element in this) { if (test(element)) return element; } @@ -167,8 +165,8 @@ abstract class IterableMixin implements Iterable { throw IterableElementError.noElement(); } - E lastWhere(bool test(E value), {E orElse()}) { - E result; + E lastWhere(bool test(E value), {E Function()? orElse}) { + late E result; bool foundMatching = false; for (E element in this) { if (test(element)) { @@ -181,8 +179,8 @@ abstract class IterableMixin implements Iterable { throw IterableElementError.noElement(); } - E singleWhere(bool test(E element), {E orElse()}) { - E result; + E singleWhere(bool test(E element), {E Function()? orElse}) { + late E result; bool foundMatching = false; for (E element in this) { if (test(element)) { @@ -277,7 +275,7 @@ abstract class IterableBase extends Iterable { } /// A collection used to identify cyclic lists during toString() calls. -final List _toStringVisiting = []; +final List _toStringVisiting = []; /// Check if we are currently visiting `o` in a toString call. bool _isToStringVisiting(Object o) { @@ -288,7 +286,7 @@ bool _isToStringVisiting(Object o) { } /// Convert elements of [iterable] to strings and store them in [parts]. -void _iterablePartsToStrings(Iterable iterable, List parts) { +void _iterablePartsToStrings(Iterable iterable, List parts) { /* * This is the complicated part of [iterableToShortString]. * It is extracted as a separate function to avoid having too much code @@ -313,7 +311,7 @@ void _iterablePartsToStrings(Iterable iterable, List parts) { int length = 0; int count = 0; - Iterator it = iterable.iterator; + Iterator it = iterable.iterator; // Initial run of elements, at least headCount, and then continue until // passing at most lengthLimit characters. while (length < lengthLimit || count < headCount) { @@ -329,14 +327,12 @@ void _iterablePartsToStrings(Iterable iterable, List parts) { // Find last two elements. One or more of them may already be in the // parts array. Include their length in `length`. - Object penultimate; - Object ultimate; if (!it.moveNext()) { if (count <= headCount + tailCount) return; ultimateString = parts.removeLast(); penultimateString = parts.removeLast(); } else { - penultimate = it.current; + Object? penultimate = it.current; count++; if (!it.moveNext()) { if (count <= headCount + 1) { @@ -347,7 +343,7 @@ void _iterablePartsToStrings(Iterable iterable, List parts) { penultimateString = parts.removeLast(); length += ultimateString.length + overhead; } else { - ultimate = it.current; + Object? ultimate = it.current; count++; // Then keep looping, keeping the last two elements in variables. assert(count < maxCount); @@ -380,7 +376,7 @@ void _iterablePartsToStrings(Iterable iterable, List parts) { // If there is a gap between the initial run and the last two, // prepare to add an ellipsis. - String elision; + String? elision; if (count > parts.length + tailCount) { elision = "..."; length += ellipsisSize + overhead; diff --git a/sdk/lib/collection/iterator.dart b/sdk/lib/collection/iterator.dart index 05bcfaed12d..671f0eea005 100644 --- a/sdk/lib/collection/iterator.dart +++ b/sdk/lib/collection/iterator.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.collection; /// The [HasNextIterator] class wraps an [Iterator] and provides methods to diff --git a/sdk/lib/collection/linked_hash_map.dart b/sdk/lib/collection/linked_hash_map.dart index 548bc49d9aa..9dfdb997dc4 100644 --- a/sdk/lib/collection/linked_hash_map.dart +++ b/sdk/lib/collection/linked_hash_map.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.collection; /// A hash-table based implementation of [Map]. @@ -69,9 +67,9 @@ abstract class LinkedHashMap implements Map { /// If you supply one of [equals] and [hashCode], /// you should generally also to supply the other. external factory LinkedHashMap( - {bool equals(K key1, K key2), - int hashCode(K key), - bool isValidKey(potentialKey)}); + {bool Function(K, K)? equals, + int Function(K)? hashCode, + bool Function(dynamic)? isValidKey}); /// Creates an insertion-ordered identity-based map. /// @@ -85,10 +83,10 @@ abstract class LinkedHashMap implements Map { /// /// The keys must all be instances of [K] and the values to [V]. /// The [other] map itself can have any type. - factory LinkedHashMap.from(Map other) { + factory LinkedHashMap.from(Map other) { LinkedHashMap result = LinkedHashMap(); - other.forEach((k, v) { - result[k] = v; + other.forEach((dynamic k, dynamic v) { + result[k as K] = v as V; }); return result; } @@ -109,7 +107,7 @@ abstract class LinkedHashMap implements Map { /// If no values are specified for [key] and [value] the default is the /// identity function. factory LinkedHashMap.fromIterable(Iterable iterable, - {K key(element), V value(element)}) { + {K Function(dynamic element)? key, V Function(dynamic element)? value}) { LinkedHashMap map = LinkedHashMap(); MapBase._fillMapWithMappedIterable(map, iterable, key, value); return map; @@ -139,5 +137,5 @@ abstract class LinkedHashMap implements Map { /// later occurrences overwrite the earlier ones. @Since("2.1") factory LinkedHashMap.fromEntries(Iterable> entries) => - {}..addEntries(entries); + LinkedHashMap()..addEntries(entries); } diff --git a/sdk/lib/collection/linked_hash_set.dart b/sdk/lib/collection/linked_hash_set.dart index 4fb199b8a50..c4f68188d2d 100644 --- a/sdk/lib/collection/linked_hash_set.dart +++ b/sdk/lib/collection/linked_hash_set.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.collection; /// A [LinkedHashSet] is a hash-table based [Set] implementation. @@ -73,9 +71,9 @@ abstract class LinkedHashSet implements Set { /// and the `isValidKey` defaults to accepting all keys. /// Such a map can be created directly using [LinkedHashSet.identity]. external factory LinkedHashSet( - {bool equals(E e1, E e2), - int hashCode(E e), - bool isValidKey(potentialKey)}); + {bool Function(E, E)? equals, + int Function(E)? hashCode, + bool Function(dynamic)? isValidKey}); /// Creates an insertion-ordered identity-based set. /// @@ -97,10 +95,10 @@ abstract class LinkedHashSet implements Set { /// Set superSet = ...; /// Iterable tmp = superSet.where((e) => e is SubType); /// Set subSet = new LinkedHashSet.from(tmp); - factory LinkedHashSet.from(Iterable elements) { + factory LinkedHashSet.from(Iterable elements) { LinkedHashSet result = LinkedHashSet(); for (final element in elements) { - result.add(element); + result.add(element as E); } return result; } diff --git a/sdk/lib/collection/linked_list.dart b/sdk/lib/collection/linked_list.dart index 94f30cfe52a..843eedde6a8 100644 --- a/sdk/lib/collection/linked_list.dart +++ b/sdk/lib/collection/linked_list.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.collection; /// A specialized double-linked list of elements that extends [LinkedListEntry]. @@ -30,7 +28,7 @@ part of dart.collection; class LinkedList> extends Iterable { int _modificationCount = 0; int _length = 0; - E _first; + E? _first; /// Construct a new empty linked list. LinkedList(); @@ -72,10 +70,10 @@ class LinkedList> extends Iterable { _modificationCount++; if (isEmpty) return; - E next = _first; + E next = _first!; do { E entry = next; - next = entry._next; + next = entry._next!; entry._next = entry._previous = entry._list = null; } while (!identical(next, _first)); @@ -87,14 +85,14 @@ class LinkedList> extends Iterable { if (isEmpty) { throw StateError('No such element'); } - return _first; + return _first!; } E get last { if (isEmpty) { throw StateError('No such element'); } - return _first._previous; + return _first!._previous!; } E get single { @@ -104,23 +102,23 @@ class LinkedList> extends Iterable { if (_length > 1) { throw StateError('Too many elements'); } - return _first; + return _first!; } /// Call [action] with each entry in this linked list. /// - /// It's an error if [action] modify the linked list. + /// It's an error if [action] modifies the linked list. void forEach(void action(E entry)) { int modificationCount = _modificationCount; if (isEmpty) return; - E current = _first; + E current = _first!; do { action(current); if (modificationCount != _modificationCount) { throw ConcurrentModificationError(this); } - current = current._next; + current = current._next!; } while (!identical(current, _first)); } @@ -130,7 +128,7 @@ class LinkedList> extends Iterable { /// /// If [updateFirst] is true and [entry] is the first entry in the list, /// updates the [_first] field to point to the [newEntry] as first entry. - void _insertBefore(E entry, E newEntry, {bool updateFirst}) { + void _insertBefore(E? entry, E newEntry, {required bool updateFirst}) { if (newEntry.list != null) { throw StateError('LinkedListEntry is already in a LinkedList'); } @@ -144,7 +142,7 @@ class LinkedList> extends Iterable { _length++; return; } - E predecessor = entry._previous; + E predecessor = entry!._previous!; E successor = entry; newEntry._previous = predecessor; newEntry._next = successor; @@ -158,8 +156,8 @@ class LinkedList> extends Iterable { void _unlink(E entry) { _modificationCount++; - entry._next._previous = entry._previous; - E next = entry._previous._next = entry._next; + entry._next!._previous = entry._previous; + E? next = entry._previous!._next = entry._next; _length--; entry._list = entry._next = entry._previous = null; if (isEmpty) { @@ -173,8 +171,8 @@ class LinkedList> extends Iterable { class _LinkedListIterator> implements Iterator { final LinkedList _list; final int _modificationCount; - E _current; - LinkedListEntry _next; + E? _current; + E? _next; bool _visitedFirst; _LinkedListIterator(LinkedList list) @@ -183,7 +181,10 @@ class _LinkedListIterator> implements Iterator { _next = list._first, _visitedFirst = false; - E get current => _current; + E get current { + final cur = _current; + return (cur != null) ? cur : cur as E; + } bool moveNext() { if (_modificationCount != _list._modificationCount) { @@ -195,7 +196,7 @@ class _LinkedListIterator> implements Iterator { } _visitedFirst = true; _current = _next; - _next = _next._next; + _next = _next!._next; return true; } } @@ -213,28 +214,28 @@ class _LinkedListIterator> implements Iterator { /// /// When created, an entry is not in any linked list. abstract class LinkedListEntry> { - LinkedList _list; - E _next; - E _previous; + LinkedList? _list; + E? _next; + E? _previous; /// Get the linked list containing this element. /// /// Returns `null` if this entry is not currently in any list. - LinkedList get list => _list; + LinkedList? get list => _list; /// Unlink the element from its linked list. /// /// The entry must currently be in a linked list when this method is called. void unlink() { - _list._unlink(this); + _list!._unlink(this as E); } /// Return the successor of this element in its linked list. /// /// Returns `null` if there is no successor in the linked list, or if this /// entry is not currently in any list. - E get next { - if (_list == null || identical(_list.first, _next)) return null; + E? get next { + if (_list == null || identical(_list!.first, _next)) return null; return _next; } @@ -242,8 +243,8 @@ abstract class LinkedListEntry> { /// /// Returns `null` if there is no predecessor in the linked list, or if this /// entry is not currently in any list. - E get previous { - if (_list == null || identical(this, _list.first)) return null; + E? get previous { + if (_list == null || identical(this, _list!.first)) return null; return _previous; } @@ -252,7 +253,7 @@ abstract class LinkedListEntry> { /// This entry must be in a linked list when this method is called. /// The [entry] must not be in a linked list. void insertAfter(E entry) { - _list._insertBefore(_next, entry, updateFirst: false); + _list!._insertBefore(_next, entry, updateFirst: false); } /// Insert an element before this element in this element's linked list. @@ -260,6 +261,6 @@ abstract class LinkedListEntry> { /// This entry must be in a linked list when this method is called. /// The [entry] must not be in a linked list. void insertBefore(E entry) { - _list._insertBefore(this, entry, updateFirst: true); + _list!._insertBefore(this as E, entry, updateFirst: true); } } diff --git a/sdk/lib/collection/list.dart b/sdk/lib/collection/list.dart index 3009b3760ed..fdf2f8ad991 100644 --- a/sdk/lib/collection/list.dart +++ b/sdk/lib/collection/list.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.collection; /// Abstract implementation of a list. @@ -15,13 +13,13 @@ part of dart.collection; /// `operator[]=` and `length=`, which need to be implemented. /// /// *NOTICE*: Forwarding just these four operations to a normal growable [List] -/// (as created by `new List()`) will give very bad performance for `add` and +/// (as created by `[]`) will give very bad performance for `add` and /// `addAll` operations of `ListBase`. These operations are implemented by /// increasing the length of the list by one for each `add` operation, and /// repeatedly increasing the length of a growable list is not efficient. /// To avoid this, either override 'add' and 'addAll' to also forward directly /// to the growable list, or, preferably, use `DelegatingList` from -/// "package:collection/wrappers.dart" instead. +/// "package:collection/collection.dart" instead. abstract class ListBase extends Object with ListMixin { /// Converts a [List] to a [String]. /// @@ -45,13 +43,13 @@ abstract class ListBase extends Object with ListMixin { /// `length=` and `operator[]=` /// /// *NOTICE*: Forwarding just these four operations to a normal growable [List] -/// (as created by `new List()`) will give very bad performance for `add` and +/// (as created by `[]`) will give very bad performance for `add` and /// `addAll` operations of `ListBase`. These operations are implemented by /// increasing the length of the list by one for each `add` operation, and /// repeatedly increasing the length of a growable list is not efficient. /// To avoid this, either override 'add' and 'addAll' to also forward directly /// to the growable list, or, if possible, use `DelegatingList` from -/// "package:collection/wrappers.dart" instead. +/// "package:collection/collection.dart" instead. abstract class ListMixin implements List { // Iterable interface. // TODO(lrn): When we get composable mixins, reuse IterableMixin instead @@ -104,7 +102,7 @@ abstract class ListMixin implements List { return this[0]; } - bool contains(Object element) { + bool contains(Object? element) { int length = this.length; for (int i = 0; i < length; i++) { if (this[i] == element) return true; @@ -137,7 +135,7 @@ abstract class ListMixin implements List { return false; } - E firstWhere(bool test(E element), {E orElse()}) { + E firstWhere(bool test(E element), {E Function()? orElse}) { int length = this.length; for (int i = 0; i < length; i++) { E element = this[i]; @@ -150,7 +148,7 @@ abstract class ListMixin implements List { throw IterableElementError.noElement(); } - E lastWhere(bool test(E element), {E orElse()}) { + E lastWhere(bool test(E element), {E Function()? orElse}) { int length = this.length; for (int i = length - 1; i >= 0; i--) { E element = this[i]; @@ -163,9 +161,9 @@ abstract class ListMixin implements List { throw IterableElementError.noElement(); } - E singleWhere(bool test(E element), {E orElse()}) { + E singleWhere(bool test(E element), {E Function()? orElse}) { int length = this.length; - E match; + late E match; bool matchFound = false; for (int i = 0; i < length; i++) { E element = this[i]; @@ -238,13 +236,10 @@ abstract class ListMixin implements List { } List toList({bool growable = true}) { - List result; - if (growable) { - result = []..length = length; - } else { - result = List(length); - } - for (int i = 0; i < length; i++) { + if (this.isEmpty) return List.empty(growable: growable); + var first = this[0]; + var result = List.filled(this.length, first, growable: growable); + for (int i = 1; i < this.length; i++) { result[i] = this[i]; } return result; @@ -267,13 +262,12 @@ abstract class ListMixin implements List { int i = this.length; for (E element in iterable) { assert(this.length == i || (throw ConcurrentModificationError(this))); - this.length = i + 1; - this[i] = element; + add(element); i++; } } - bool remove(Object element) { + bool remove(Object? element) { for (int i = 0; i < this.length; i++) { if (this[i] == element) { this._closeGap(i, i + 1); @@ -337,18 +331,18 @@ abstract class ListMixin implements List { return result; } - void sort([int compare(E a, E b)]) { + void sort([int Function(E a, E b)? compare]) { Sort.sort(this, compare ?? _compareAny); } - static int _compareAny(a, b) { - // In strong mode Comparable.compare requires an implicit cast to ensure - // `a` and `b` are Comparable. - return Comparable.compare(a, b); + static int _compareAny(dynamic a, dynamic b) { + return Comparable.compare(a as Comparable, b as Comparable); } - void shuffle([Random random]) { + void shuffle([Random? random]) { random ??= Random(); + if (random == null) throw "!"; // TODO(38493): The `??=` should promote. + int length = this.length; while (length > 1) { int pos = random.nextInt(length); @@ -363,23 +357,15 @@ abstract class ListMixin implements List { return ListMapView(this); } - List operator +(List other) { - var result = []..length = (this.length + other.length); - result.setRange(0, this.length, this); - result.setRange(this.length, result.length, other); - return result; - } + List operator +(List other) => [...this, ...other]; - List sublist(int start, [int end]) { + List sublist(int start, [int? end]) { int listLength = this.length; end ??= listLength; + if (end == null) throw "!"; // TODO(38493): The `??=` should promote. + RangeError.checkValidRange(start, end, listLength); - int length = end - start; - List result = []..length = length; - for (int i = 0; i < length; i++) { - result[i] = this[start + i]; - } - return result; + return List.from(getRange(start, end)); } Iterable getRange(int start, int end) { @@ -394,10 +380,13 @@ abstract class ListMixin implements List { } } - void fillRange(int start, int end, [E fill]) { + void fillRange(int start, int end, [E? fill]) { + // Hoist the case to fail eagerly if the user provides an invalid `null` + // value (or omits it) when E is a non-nullable type. + E value = fill as E; RangeError.checkValidRange(start, end, this.length); for (int i = start; i < end; i++) { - this[i] = fill; + this[i] = value; } } @@ -434,6 +423,10 @@ abstract class ListMixin implements List { void replaceRange(int start, int end, Iterable newContents) { RangeError.checkValidRange(start, end, this.length); + if (start == this.length) { + addAll(newContents); + return; + } if (newContents is! EfficientLengthIterable) { newContents = newContents.toList(); } @@ -445,17 +438,31 @@ abstract class ListMixin implements List { if (removeLength > insertLength) { _closeGap(insertEnd, end); } + } else if (end == this.length) { + int i = start; + for (E element in newContents) { + if (i < end) { + this[i] = element; + } else { + add(element); + } + i++; + } } else { int delta = insertLength - removeLength; - int newLength = this.length + delta; + int oldLength = this.length; int insertEnd = start + insertLength; // aka. end + delta. - this.length = newLength; - this.setRange(insertEnd, newLength, this, end); + for (int i = oldLength - delta; i < oldLength; ++i) { + add(this[i > 0 ? i : 0]); + } + if (insertEnd < oldLength) { + this.setRange(insertEnd, oldLength, this, end); + } this.setRange(start, insertEnd, newContents); } } - int indexOf(Object element, [int start = 0]) { + int indexOf(Object? element, [int start = 0]) { if (start < 0) start = 0; for (int i = start; i < this.length; i++) { if (this[i] == element) return i; @@ -471,16 +478,24 @@ abstract class ListMixin implements List { return -1; } - int lastIndexOf(Object element, [int start]) { + int lastIndexOf(Object? element, [int? start]) { if (start == null || start >= this.length) start = this.length - 1; + + // TODO(38493): The previous line should promote. + if (start == null) throw "!"; + for (int i = start; i >= 0; i--) { if (this[i] == element) return i; } return -1; } - int lastIndexWhere(bool test(E element), [int start]) { + int lastIndexWhere(bool test(E element), [int? start]) { if (start == null || start >= this.length) start = this.length - 1; + + // TODO(38493): The previous line should promote. + if (start == null) throw "!"; + for (int i = start; i >= 0; i--) { if (test(this[i])) return i; } @@ -507,21 +522,34 @@ abstract class ListMixin implements List { void insertAll(int index, Iterable iterable) { RangeError.checkValueInInterval(index, 0, length, "index"); + if (index == length) { + addAll(iterable); + return; + } if (iterable is! EfficientLengthIterable || identical(iterable, this)) { iterable = iterable.toList(); } int insertionLength = iterable.length; + if (insertionLength == 0) { + return; + } // There might be errors after the length change, in which case the list // will end up being modified but the operation not complete. Unless we // always go through a "toList" we can't really avoid that. - this.length += insertionLength; + int oldLength = length; + for (int i = oldLength - insertionLength; i < oldLength; ++i) { + add(this[i > 0 ? i : 0]); + } if (iterable.length != insertionLength) { // If the iterable's length is linked to this list's length somehow, // we can't insert one in the other. this.length -= insertionLength; throw ConcurrentModificationError(iterable); } - setRange(index + insertionLength, this.length, this, index); + int oldCopyStart = index + insertionLength; + if (oldCopyStart < oldLength) { + setRange(oldCopyStart, oldLength, this, index); + } setAll(index, iterable); } diff --git a/sdk/lib/collection/maps.dart b/sdk/lib/collection/maps.dart index 3204db0e787..85a3155a889 100644 --- a/sdk/lib/collection/maps.dart +++ b/sdk/lib/collection/maps.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.collection; /// Base class for implementing a [Map]. @@ -21,7 +19,7 @@ part of dart.collection; /// A more efficient implementation is usually possible by overriding /// some of the other members as well. abstract class MapBase extends MapMixin { - static String mapToString(Map m) { + static String mapToString(Map m) { // Reuses the list in IterableBase for detecting toString cycles. if (_isToStringVisiting(m)) { return '{...}'; @@ -32,7 +30,7 @@ abstract class MapBase extends MapMixin { _toStringVisiting.add(m); result.write('{'); bool first = true; - m.forEach((k, v) { + m.forEach((Object? k, Object? v) { if (!first) { result.write(', '); } @@ -50,17 +48,23 @@ abstract class MapBase extends MapMixin { return result.toString(); } - static _id(x) => x; + static Object? _id(Object? x) => x; /// Fills a [Map] with key/value pairs computed from [iterable]. /// /// This method is used by [Map] classes in the named constructor /// `fromIterable`. static void _fillMapWithMappedIterable( - Map map, Iterable iterable, key(element), value(element)) { + Map map, + Iterable iterable, + Object? Function(Object? element)? key, + Object? Function(Object? element)? value) { key ??= _id; value ??= _id; + if (key == null) throw "!"; // TODO(38493): The `??=` should promote. + if (value == null) throw "!"; // TODO(38493): The `??=` should promote. + for (var element in iterable) { map[key(element)] = value(element); } @@ -70,9 +74,10 @@ abstract class MapBase extends MapMixin { /// /// This method is used by [Map] classes in the named constructor /// `fromIterables`. - static void _fillMapWithIterables(Map map, Iterable keys, Iterable values) { - Iterator keyIterator = keys.iterator; - Iterator valueIterator = values.iterator; + static void _fillMapWithIterables(Map map, + Iterable keys, Iterable values) { + Iterator keyIterator = keys.iterator; + Iterator valueIterator = values.iterator; bool hasNextKey = keyIterator.moveNext(); bool hasNextValue = valueIterator.moveNext(); @@ -105,9 +110,9 @@ abstract class MapBase extends MapMixin { /// some of the other members as well. abstract class MapMixin implements Map { Iterable get keys; - V operator [](Object key); + V? operator [](Object? key); operator []=(K key, V value); - V remove(Object key); + V? remove(Object? key); // The `clear` operation should not be based on `remove`. // It should clear the map even if some keys are not equal to themselves. void clear(); @@ -115,17 +120,17 @@ abstract class MapMixin implements Map { Map cast() => Map.castFrom(this); void forEach(void action(K key, V value)) { for (K key in keys) { - action(key, this[key]); + action(key, this[key] as V); } } void addAll(Map other) { for (K key in other.keys) { - this[key] = other[key]; + this[key] = other[key] as V; } } - bool containsValue(Object value) { + bool containsValue(Object? value) { for (K key in keys) { if (this[key] == value) return true; } @@ -134,14 +139,14 @@ abstract class MapMixin implements Map { V putIfAbsent(K key, V ifAbsent()) { if (containsKey(key)) { - return this[key]; + return this[key] as V; } return this[key] = ifAbsent(); } - V update(K key, V update(V value), {V ifAbsent()}) { + V update(K key, V update(V value), {V Function()? ifAbsent}) { if (this.containsKey(key)) { - return this[key] = update(this[key]); + return this[key] = update(this[key] as V); } if (ifAbsent != null) { return this[key] = ifAbsent(); @@ -151,18 +156,18 @@ abstract class MapMixin implements Map { void updateAll(V update(K key, V value)) { for (var key in this.keys) { - this[key] = update(key, this[key]); + this[key] = update(key, this[key] as V); } } Iterable> get entries { - return keys.map((K key) => MapEntry(key, this[key])); + return keys.map((K key) => MapEntry(key, this[key] as V)); } Map map(MapEntry transform(K key, V value)) { var result = {}; for (var key in this.keys) { - var entry = transform(key, this[key]); + var entry = transform(key, this[key] as V); result[entry.key] = entry.value; } return result; @@ -177,14 +182,14 @@ abstract class MapMixin implements Map { void removeWhere(bool test(K key, V value)) { var keysToRemove = []; for (var key in keys) { - if (test(key, this[key])) keysToRemove.add(key); + if (test(key, this[key] as V)) keysToRemove.add(key); } for (var key in keysToRemove) { this.remove(key); } } - bool containsKey(Object key) => keys.contains(key); + bool containsKey(Object? key) => keys.contains(key); int get length => keys.length; bool get isEmpty => keys.isEmpty; bool get isNotEmpty => keys.isNotEmpty; @@ -224,9 +229,9 @@ class _MapBaseValueIterable extends EfficientLengthIterable { int get length => _map.length; bool get isEmpty => _map.isEmpty; bool get isNotEmpty => _map.isNotEmpty; - V get first => _map[_map.keys.first]; - V get single => _map[_map.keys.single]; - V get last => _map[_map.keys.last]; + V get first => _map[_map.keys.first] as V; + V get single => _map[_map.keys.single] as V; + V get last => _map[_map.keys.last] as V; Iterator get iterator => _MapBaseValueIterator(_map); } @@ -238,7 +243,7 @@ class _MapBaseValueIterable extends EfficientLengthIterable { class _MapBaseValueIterator implements Iterator { final Iterator _keys; final Map _map; - V _current; + V? _current; _MapBaseValueIterator(Map map) : _map = map, @@ -253,7 +258,10 @@ class _MapBaseValueIterator implements Iterator { return false; } - V get current => _current; + V get current { + final cur = _current; + return (cur != null) ? cur : cur as V; + } } /// Mixin that overrides mutating map operations with implementations that @@ -280,7 +288,7 @@ abstract class _UnmodifiableMapMixin implements Map { } /// This operation is not supported by an unmodifiable map. - V remove(Object key) { + V remove(Object? key) { throw UnsupportedError("Cannot modify unmodifiable map"); } @@ -295,7 +303,7 @@ abstract class _UnmodifiableMapMixin implements Map { } /// This operation is not supported by an unmodifiable map. - V update(K key, V update(V value), {V ifAbsent()}) { + V update(K key, V update(V value), {V Function()? ifAbsent}) { throw UnsupportedError("Cannot modify unmodifiable map"); } @@ -317,7 +325,7 @@ class MapView implements Map { const MapView(Map map) : _map = map; Map cast() => _map.cast(); - V operator [](Object key) => _map[key]; + V? operator [](Object? key) => _map[key]; void operator []=(K key, V value) { _map[key] = value; } @@ -331,8 +339,8 @@ class MapView implements Map { } V putIfAbsent(K key, V ifAbsent()) => _map.putIfAbsent(key, ifAbsent); - bool containsKey(Object key) => _map.containsKey(key); - bool containsValue(Object value) => _map.containsValue(value); + bool containsKey(Object? key) => _map.containsKey(key); + bool containsValue(Object? value) => _map.containsValue(value); void forEach(void action(K key, V value)) { _map.forEach(action); } @@ -341,7 +349,7 @@ class MapView implements Map { bool get isNotEmpty => _map.isNotEmpty; int get length => _map.length; Iterable get keys => _map.keys; - V remove(Object key) => _map.remove(key); + V? remove(Object? key) => _map.remove(key); String toString() => _map.toString(); Iterable get values => _map.values; @@ -354,7 +362,7 @@ class MapView implements Map { Map map(MapEntry transform(K key, V value)) => _map.map(transform); - V update(K key, V update(V value), {V ifAbsent()}) => + V update(K key, V update(V value), {V Function()? ifAbsent}) => _map.update(key, update, ifAbsent: ifAbsent); void updateAll(V update(K key, V value)) { diff --git a/sdk/lib/collection/queue.dart b/sdk/lib/collection/queue.dart index f51cdb56233..26abbfe0f01 100644 --- a/sdk/lib/collection/queue.dart +++ b/sdk/lib/collection/queue.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.collection; /// A [Queue] is a collection that can be manipulated at both ends. One @@ -91,7 +89,7 @@ abstract class Queue implements EfficientLengthIterable { /// /// Returns `true` if a value was removed, or `false` if the queue /// contained no element equal to [value]. - bool remove(Object value); + bool remove(Object? value); /// Adds all elements of [iterable] at the end of the queue. The /// length of the queue is extended by the length of [iterable]. @@ -112,19 +110,19 @@ abstract class Queue implements EfficientLengthIterable { } class _DoubleLink> { - Link _previousLink; - Link _nextLink; + Link? _previousLink; + Link? _nextLink; - void _link(Link previous, Link next) { + void _link(Link? previous, Link? next) { _nextLink = next; _previousLink = previous; - if (previous != null) previous._nextLink = this; - if (next != null) next._previousLink = this; + if (previous != null) previous._nextLink = this as Link; + if (next != null) next._previousLink = this as Link; } void _unlink() { - if (_previousLink != null) _previousLink._nextLink = _nextLink; - if (_nextLink != null) _nextLink._previousLink = _previousLink; + if (_previousLink != null) _previousLink!._nextLink = _nextLink; + if (_nextLink != null) _nextLink!._previousLink = _previousLink; _nextLink = null; _previousLink = null; } @@ -133,10 +131,19 @@ class _DoubleLink> { /// An entry in a doubly linked list. It contains a pointer to the next /// entry, the previous entry, and the boxed element. class DoubleLinkedQueueEntry extends _DoubleLink> { - /// The element in the queue. - E element; + // TODO(rnystrom): This needs to be nullable because the subclass + // _DoubleLinkedQueueSentinel does not have an element. A cleaner solution is + // probably to refactor the class hierarchy so that _DoubleLinkedQueueSentinel + // does not inherit an element field. + E? _element; - DoubleLinkedQueueEntry(this.element); + /// The element in the queue. + E get element => _element as E; + set element(E element) { + _element = element; + } + + DoubleLinkedQueueEntry(this._element); /// Appends the given [e] as entry just after this entry. void append(E e) { @@ -154,10 +161,10 @@ class DoubleLinkedQueueEntry extends _DoubleLink> { } /// Returns the previous entry or `null` if there is none. - DoubleLinkedQueueEntry previousEntry() => _previousLink; + DoubleLinkedQueueEntry? previousEntry() => _previousLink; /// Returns the next entry or `null` if there is none. - DoubleLinkedQueueEntry nextEntry() => _nextLink; + DoubleLinkedQueueEntry? nextEntry() => _nextLink; } /// Interface for the link classes used by [DoubleLinkedQueue]. @@ -167,10 +174,10 @@ class DoubleLinkedQueueEntry extends _DoubleLink> { /// The entry contains a link back to the queue, so calling `append` /// or `prepend` can correctly update the element count. abstract class _DoubleLinkedQueueEntry extends DoubleLinkedQueueEntry { - DoubleLinkedQueue _queue; - _DoubleLinkedQueueEntry(E element, this._queue) : super(element); + DoubleLinkedQueue? _queue; + _DoubleLinkedQueueEntry(E? element, this._queue) : super(element); - DoubleLinkedQueueEntry _asNonSentinelEntry(); + DoubleLinkedQueueEntry? _asNonSentinelEntry(); void _append(E e) { _DoubleLinkedQueueElement(e, _queue)._link(this, _nextLink); @@ -182,15 +189,16 @@ abstract class _DoubleLinkedQueueEntry extends DoubleLinkedQueueEntry { E _remove(); - E get _element => element; + E get _element => super._element as E; - DoubleLinkedQueueEntry nextEntry() { - _DoubleLinkedQueueEntry entry = _nextLink; + DoubleLinkedQueueEntry? nextEntry() { + _DoubleLinkedQueueEntry entry = _nextLink as _DoubleLinkedQueueEntry; return entry._asNonSentinelEntry(); } - DoubleLinkedQueueEntry previousEntry() { - _DoubleLinkedQueueEntry entry = _previousLink; + DoubleLinkedQueueEntry? previousEntry() { + _DoubleLinkedQueueEntry entry = + _previousLink as _DoubleLinkedQueueEntry; return entry._asNonSentinelEntry(); } } @@ -200,17 +208,17 @@ abstract class _DoubleLinkedQueueEntry extends DoubleLinkedQueueEntry { /// The entry contains a reference to the queue, allowing /// [append]/[prepend] to update the list length. class _DoubleLinkedQueueElement extends _DoubleLinkedQueueEntry { - _DoubleLinkedQueueElement(E element, DoubleLinkedQueue queue) + _DoubleLinkedQueueElement(E element, DoubleLinkedQueue? queue) : super(element, queue); void append(E e) { _append(e); - if (_queue != null) _queue._elementCount++; + if (_queue != null) _queue!._elementCount++; } void prepend(E e) { _prepend(e); - if (_queue != null) _queue._elementCount++; + if (_queue != null) _queue!._elementCount++; } E _remove() { @@ -220,11 +228,11 @@ class _DoubleLinkedQueueElement extends _DoubleLinkedQueueEntry { } E remove() { - if (_queue != null) _queue._elementCount--; + if (_queue != null) _queue!._elementCount--; return _remove(); } - _DoubleLinkedQueueElement _asNonSentinelEntry() { + _DoubleLinkedQueueElement? _asNonSentinelEntry() { return this; } } @@ -241,7 +249,7 @@ class _DoubleLinkedQueueSentinel extends _DoubleLinkedQueueEntry { _nextLink = this; } - DoubleLinkedQueueEntry _asNonSentinelEntry() { + DoubleLinkedQueueEntry? _asNonSentinelEntry() { return null; } @@ -260,12 +268,12 @@ class _DoubleLinkedQueueSentinel extends _DoubleLinkedQueueEntry { /// /// Allows constant time add, remove-at-ends and peek operations. class DoubleLinkedQueue extends Iterable implements Queue { - _DoubleLinkedQueueSentinel _sentinel; + late _DoubleLinkedQueueSentinel _sentinel = + _DoubleLinkedQueueSentinel(this); + int _elementCount = 0; - DoubleLinkedQueue() { - _sentinel = _DoubleLinkedQueueSentinel(this); - } + DoubleLinkedQueue(); /// Creates a double-linked queue containing all [elements]. /// @@ -280,10 +288,10 @@ class DoubleLinkedQueue extends Iterable implements Queue { /// Queue subQueue = /// new DoubleLinkedQueue.from(superQueue.whereType()); /// ``` - factory DoubleLinkedQueue.from(Iterable elements) { - Queue list = DoubleLinkedQueue(); + factory DoubleLinkedQueue.from(Iterable elements) { + DoubleLinkedQueue list = DoubleLinkedQueue(); for (final e in elements) { - list.addLast(e); + list.addLast(e as E); } return list; } @@ -321,21 +329,24 @@ class DoubleLinkedQueue extends Iterable implements Queue { } E removeLast() { - _DoubleLinkedQueueEntry lastEntry = _sentinel._previousLink; + _DoubleLinkedQueueEntry lastEntry = + _sentinel._previousLink as _DoubleLinkedQueueEntry; E result = lastEntry._remove(); _elementCount--; return result; } E removeFirst() { - _DoubleLinkedQueueEntry firstEntry = _sentinel._nextLink; + _DoubleLinkedQueueEntry firstEntry = + _sentinel._nextLink as _DoubleLinkedQueueEntry; E result = firstEntry._remove(); _elementCount--; return result; } - bool remove(Object o) { - _DoubleLinkedQueueEntry entry = _sentinel._nextLink; + bool remove(Object? o) { + _DoubleLinkedQueueEntry entry = + _sentinel._nextLink as _DoubleLinkedQueueEntry; while (!identical(entry, _sentinel)) { bool equals = (entry._element == o); if (!identical(this, entry._queue)) { @@ -347,25 +358,26 @@ class DoubleLinkedQueue extends Iterable implements Queue { _elementCount--; return true; } - entry = entry._nextLink; + entry = entry._nextLink as _DoubleLinkedQueueEntry; } return false; } void _filter(bool test(E element), bool removeMatching) { - _DoubleLinkedQueueEntry entry = _sentinel._nextLink; + _DoubleLinkedQueueEntry entry = + _sentinel._nextLink as _DoubleLinkedQueueEntry; while (!identical(entry, _sentinel)) { bool matches = test(entry._element); if (!identical(this, entry._queue)) { // Entry must still be in the queue. throw ConcurrentModificationError(this); } - _DoubleLinkedQueueEntry next = entry._nextLink; // Cannot be null. + DoubleLinkedQueueEntry next = entry._nextLink!; // Cannot be null. if (identical(removeMatching, matches)) { entry._remove(); _elementCount--; } - entry = next; + entry = next as _DoubleLinkedQueueEntry; } } @@ -378,21 +390,21 @@ class DoubleLinkedQueue extends Iterable implements Queue { } E get first { - _DoubleLinkedQueueEntry firstEntry = _sentinel._nextLink; - return firstEntry._element; + DoubleLinkedQueueEntry firstEntry = _sentinel._nextLink!; + return firstEntry._element as E; } E get last { - _DoubleLinkedQueueEntry lastEntry = _sentinel._previousLink; - return lastEntry._element; + DoubleLinkedQueueEntry lastEntry = _sentinel._previousLink!; + return lastEntry._element as E; } E get single { // Note that this throws correctly if the queue is empty // because reading the element of the sentinel throws. if (identical(_sentinel._nextLink, _sentinel._previousLink)) { - _DoubleLinkedQueueEntry entry = _sentinel._nextLink; - return entry._element; + DoubleLinkedQueueEntry entry = _sentinel._nextLink!; + return entry._element as E; } throw IterableElementError.tooMany(); } @@ -407,7 +419,7 @@ class DoubleLinkedQueue extends Iterable implements Queue { /// The entry objects can also be accessed using [lastEntry], /// and they can be iterated using [DoubleLinkedQueueEntry.nextEntry] and /// [DoubleLinkedQueueEntry.previousEntry]. - DoubleLinkedQueueEntry firstEntry() { + DoubleLinkedQueueEntry? firstEntry() { return _sentinel.nextEntry(); } @@ -421,7 +433,7 @@ class DoubleLinkedQueue extends Iterable implements Queue { /// The entry objects can also be accessed using [firstEntry], /// and they can be iterated using [DoubleLinkedQueueEntry.nextEntry] and /// [DoubleLinkedQueueEntry.previousEntry]. - DoubleLinkedQueueEntry lastEntry() { + DoubleLinkedQueueEntry? lastEntry() { return _sentinel.previousEntry(); } @@ -452,17 +464,20 @@ class DoubleLinkedQueue extends Iterable implements Queue { /// inserted after the current element before it is removed will not be /// visited by the iteration. void forEachEntry(void action(DoubleLinkedQueueEntry element)) { - _DoubleLinkedQueueEntry entry = _sentinel._nextLink; + _DoubleLinkedQueueEntry entry = + _sentinel._nextLink as _DoubleLinkedQueueEntry; while (!identical(entry, _sentinel)) { - _DoubleLinkedQueueElement element = entry; - _DoubleLinkedQueueEntry next = element._nextLink; + _DoubleLinkedQueueElement element = + entry as _DoubleLinkedQueueElement; + _DoubleLinkedQueueEntry next = + element._nextLink as _DoubleLinkedQueueEntry; // Remember both entry and entry._nextLink. // If someone calls `element.remove()` we continue from `next`. // Otherwise we use the value of entry._nextLink which may have been // updated. action(element); if (identical(this, entry._queue)) { - next = entry._nextLink; + next = entry._nextLink as _DoubleLinkedQueueEntry; } else if (!identical(this, next._queue)) { throw ConcurrentModificationError(this); } @@ -478,9 +493,9 @@ class DoubleLinkedQueue extends Iterable implements Queue { } class _DoubleLinkedQueueIterator implements Iterator { - _DoubleLinkedQueueSentinel _sentinel; - _DoubleLinkedQueueEntry _nextEntry; - E _current; + _DoubleLinkedQueueSentinel? _sentinel; + DoubleLinkedQueueEntry? _nextEntry; + E? _current; _DoubleLinkedQueueIterator(_DoubleLinkedQueueSentinel sentinel) : _sentinel = sentinel, @@ -493,16 +508,20 @@ class _DoubleLinkedQueueIterator implements Iterator { _sentinel = null; return false; } - _DoubleLinkedQueueElement elementEntry = _nextEntry; - if (!identical(_sentinel._queue, elementEntry._queue)) { - throw ConcurrentModificationError(_sentinel._queue); + _DoubleLinkedQueueEntry elementEntry = + _nextEntry as _DoubleLinkedQueueEntry; + if (!identical(_sentinel!._queue, elementEntry._queue)) { + throw ConcurrentModificationError(_sentinel!._queue); } _current = elementEntry._element; _nextEntry = elementEntry._nextLink; return true; } - E get current => _current; + E get current { + final cur = _current; + return (cur != null) ? cur : cur as E; + } } /// List based [Queue]. @@ -514,7 +533,7 @@ class _DoubleLinkedQueueIterator implements Iterator { /// The structure is efficient for any queue or stack usage. class ListQueue extends ListIterable implements Queue { static const int _INITIAL_CAPACITY = 8; - List _table; + List _table; int _head; int _tail; int _modificationCount = 0; @@ -523,16 +542,19 @@ class ListQueue extends ListIterable implements Queue { /// /// If [initialCapacity] is given, prepare the queue for at least that many /// elements. - ListQueue([int initialCapacity]) + ListQueue([int? initialCapacity]) : _head = 0, - _tail = 0 { + _tail = 0, + _table = List.filled(_calculateCapacity(initialCapacity), null); + + static int _calculateCapacity(int? initialCapacity) { if (initialCapacity == null || initialCapacity < _INITIAL_CAPACITY) { - initialCapacity = _INITIAL_CAPACITY; + return _INITIAL_CAPACITY; } else if (!_isPowerOf2(initialCapacity)) { - initialCapacity = _nextPowerOf2(initialCapacity); + return _nextPowerOf2(initialCapacity); } assert(_isPowerOf2(initialCapacity)); - _table = List(initialCapacity); + return initialCapacity; } /// Create a `ListQueue` containing all [elements]. @@ -548,13 +570,13 @@ class ListQueue extends ListIterable implements Queue { /// Queue subQueue = /// new ListQueue.from(superQueue.whereType()); /// ``` - factory ListQueue.from(Iterable elements) { - if (elements is List) { + factory ListQueue.from(Iterable elements) { + if (elements is List) { int length = elements.length; ListQueue queue = ListQueue(length + 1); assert(queue._table.length > length); for (int i = 0; i < length; i++) { - queue._table[i] = elements[i]; + queue._table[i] = elements[i] as E; } queue._tail = length; return queue; @@ -565,7 +587,7 @@ class ListQueue extends ListIterable implements Queue { } ListQueue result = ListQueue(capacity); for (final element in elements) { - result.addLast(element); + result.addLast(element as E); } return result; } @@ -586,7 +608,7 @@ class ListQueue extends ListIterable implements Queue { void forEach(void f(E element)) { int modificationCount = _modificationCount; for (int i = _head; i != _tail; i = (i + 1) & (_table.length - 1)) { - f(_table[i]); + f(_table[i] as E); _checkModification(modificationCount); } } @@ -597,33 +619,34 @@ class ListQueue extends ListIterable implements Queue { E get first { if (_head == _tail) throw IterableElementError.noElement(); - return _table[_head]; + return _table[_head] as E; } E get last { if (_head == _tail) throw IterableElementError.noElement(); - return _table[(_tail - 1) & (_table.length - 1)]; + return _table[(_tail - 1) & (_table.length - 1)] as E; } E get single { if (_head == _tail) throw IterableElementError.noElement(); if (length > 1) throw IterableElementError.tooMany(); - return _table[_head]; + return _table[_head] as E; } E elementAt(int index) { RangeError.checkValidIndex(index, this); - return _table[(_head + index) & (_table.length - 1)]; + return _table[(_head + index) & (_table.length - 1)] as E; } List toList({bool growable = true}) { - List list; - if (growable) { - list = []..length = length; - } else { - list = List(length); + int mask = _table.length - 1; + int length = (_tail - _head) & mask; + if (length == 0) return List.empty(growable: growable); + + var list = List.filled(length, first, growable: growable); + for (int i = 0; i < length; i++) { + list[i] = _table[(_head + i) & mask] as E; } - _writeToList(list); return list; } @@ -662,9 +685,9 @@ class ListQueue extends ListIterable implements Queue { } } - bool remove(Object value) { + bool remove(Object? value) { for (int i = _head; i != _tail; i = (i + 1) & (_table.length - 1)) { - E element = _table[i]; + E? element = _table[i]; if (element == value) { _remove(i); _modificationCount++; @@ -678,7 +701,7 @@ class ListQueue extends ListIterable implements Queue { int modificationCount = _modificationCount; int i = _head; while (i != _tail) { - E element = _table[i]; + E element = _table[i] as E; bool remove = identical(removeMatching, test(element)); _checkModification(modificationCount); if (remove) { @@ -734,7 +757,7 @@ class ListQueue extends ListIterable implements Queue { E removeFirst() { if (_head == _tail) throw IterableElementError.noElement(); _modificationCount++; - E result = _table[_head]; + E result = _table[_head] as E; _table[_head] = null; _head = (_head + 1) & (_table.length - 1); return result; @@ -744,7 +767,7 @@ class ListQueue extends ListIterable implements Queue { if (_head == _tail) throw IterableElementError.noElement(); _modificationCount++; _tail = (_tail - 1) & (_table.length - 1); - E result = _table[_tail]; + E result = _table[_tail] as E; _table[_tail] = null; return result; } @@ -824,7 +847,7 @@ class ListQueue extends ListIterable implements Queue { /// Grow the table when full. void _grow() { - List newTable = List(_table.length * 2); + List newTable = List.filled(_table.length * 2, null); int split = _table.length - _head; newTable.setRange(0, split, _table, _head); newTable.setRange(split, split + _head, _table, 0); @@ -833,7 +856,7 @@ class ListQueue extends ListIterable implements Queue { _table = newTable; } - int _writeToList(List target) { + int _writeToList(List target) { assert(target.length >= length); if (_head <= _tail) { int length = _tail - _head; @@ -855,7 +878,7 @@ class ListQueue extends ListIterable implements Queue { // expansion. newElementCount += newElementCount >> 1; int newCapacity = _nextPowerOf2(newElementCount); - List newTable = List(newCapacity); + List newTable = List.filled(newCapacity, null); _tail = _writeToList(newTable); _table = newTable; _head = 0; @@ -870,7 +893,7 @@ class _ListQueueIterator implements Iterator { final int _end; final int _modificationCount; int _position; - E _current; + E? _current; _ListQueueIterator(ListQueue queue) : _queue = queue, @@ -878,7 +901,10 @@ class _ListQueueIterator implements Iterator { _modificationCount = queue._modificationCount, _position = queue._head; - E get current => _current; + E get current { + final cur = _current; + return (cur != null) ? cur : cur as E; + } bool moveNext() { _queue._checkModification(_modificationCount); diff --git a/sdk/lib/collection/set.dart b/sdk/lib/collection/set.dart index 8efe4eb9da2..1eb74919824 100644 --- a/sdk/lib/collection/set.dart +++ b/sdk/lib/collection/set.dart @@ -2,8 +2,6 @@ // 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.6 - /// Base implementations of [Set]. part of dart.collection; @@ -29,11 +27,11 @@ abstract class SetMixin implements Set { bool add(E value); - bool contains(Object element); + bool contains(Object? element); - E lookup(Object element); + E? lookup(Object? element); - bool remove(Object value); + bool remove(Object? value); Iterator get iterator; @@ -59,22 +57,22 @@ abstract class SetMixin implements Set { for (E element in elements) add(element); } - void removeAll(Iterable elements) { - for (Object element in elements) remove(element); + void removeAll(Iterable elements) { + for (Object? element in elements) remove(element); } - void retainAll(Iterable elements) { + void retainAll(Iterable elements) { // Create a copy of the set, remove all of elements from the copy, // then remove all remaining elements in copy from this. Set toRemove = toSet(); - for (Object o in elements) { + for (Object? o in elements) { toRemove.remove(o); } removeAll(toRemove); } void removeWhere(bool test(E element)) { - List toRemove = []; + List toRemove = []; for (E element in this) { if (test(element)) toRemove.add(element); } @@ -82,15 +80,15 @@ abstract class SetMixin implements Set { } void retainWhere(bool test(E element)) { - List toRemove = []; + List toRemove = []; for (E element in this) { if (!test(element)) toRemove.add(element); } removeAll(toRemove); } - bool containsAll(Iterable other) { - for (Object o in other) { + bool containsAll(Iterable other) { + for (var o in other) { if (!contains(o)) return false; } return true; @@ -100,7 +98,7 @@ abstract class SetMixin implements Set { return toSet()..addAll(other); } - Set intersection(Set other) { + Set intersection(Set other) { Set result = toSet(); for (E element in this) { if (!other.contains(element)) result.remove(element); @@ -108,7 +106,7 @@ abstract class SetMixin implements Set { return result; } - Set difference(Set other) { + Set difference(Set other) { Set result = toSet(); for (E element in this) { if (other.contains(element)) result.remove(element); @@ -116,12 +114,8 @@ abstract class SetMixin implements Set { return result; } - List toList({bool growable = true}) { - List result = growable ? ([]..length = length) : List(length); - int i = 0; - for (E element in this) result[i++] = element; - return result; - } + List toList({bool growable = true}) => + List.of(this, growable: growable); Iterable map(T f(E element)) => EfficientLengthMappedIterable(this, f); @@ -234,7 +228,7 @@ abstract class SetMixin implements Set { return result; } - E firstWhere(bool test(E value), {E orElse()}) { + E firstWhere(bool test(E value), {E Function()? orElse}) { for (E element in this) { if (test(element)) return element; } @@ -242,8 +236,8 @@ abstract class SetMixin implements Set { throw IterableElementError.noElement(); } - E lastWhere(bool test(E value), {E orElse()}) { - E result; + E lastWhere(bool test(E value), {E Function()? orElse}) { + late E result; bool foundMatching = false; for (E element in this) { if (test(element)) { @@ -256,8 +250,8 @@ abstract class SetMixin implements Set { throw IterableElementError.noElement(); } - E singleWhere(bool test(E value), {E orElse()}) { - E result; + E singleWhere(bool test(E value), {E Function()? orElse}) { + late E result; bool foundMatching = false; for (E element in this) { if (test(element)) { @@ -329,7 +323,7 @@ abstract class _SetBase implements Set { Set cast() => Set.castFrom(this, newSet: _newSimilarSet); - Set difference(Set other) { + Set difference(Set other) { Set result = _newSet(); for (var element in this) { if (!other.contains(element)) result.add(element); @@ -337,7 +331,7 @@ abstract class _SetBase implements Set { return result; } - Set intersection(Set other) { + Set intersection(Set other) { Set result = _newSet(); for (var element in this) { if (other.contains(element)) result.add(element); @@ -368,22 +362,22 @@ abstract class _SetBase implements Set { for (E element in elements) add(element); } - void removeAll(Iterable elements) { - for (Object element in elements) remove(element); + void removeAll(Iterable elements) { + for (Object? element in elements) remove(element); } - void retainAll(Iterable elements) { + void retainAll(Iterable elements) { // Create a copy of the set, remove all of elements from the copy, // then remove all remaining elements in copy from this. Set toRemove = toSet(); - for (Object o in elements) { + for (Object? o in elements) { toRemove.remove(o); } removeAll(toRemove); } void removeWhere(bool test(E element)) { - List toRemove = []; + List toRemove = []; for (E element in this) { if (test(element)) toRemove.add(element); } @@ -391,15 +385,15 @@ abstract class _SetBase implements Set { } void retainWhere(bool test(E element)) { - List toRemove = []; + List toRemove = []; for (E element in this) { if (!test(element)) toRemove.add(element); } removeAll(toRemove); } - bool containsAll(Iterable other) { - for (Object o in other) { + bool containsAll(Iterable other) { + for (Object? o in other) { if (!contains(o)) return false; } return true; @@ -409,12 +403,8 @@ abstract class _SetBase implements Set { return toSet()..addAll(other); } - List toList({bool growable = true}) { - List result = growable ? ([]..length = length) : List(length); - int i = 0; - for (E element in this) result[i++] = element; - return result; - } + List toList({bool growable = true}) => + List.of(this, growable: growable); Iterable map(T f(E element)) => EfficientLengthMappedIterable(this, f); @@ -524,7 +514,7 @@ abstract class _SetBase implements Set { return result; } - E firstWhere(bool test(E value), {E orElse()}) { + E firstWhere(bool test(E value), {E Function()? orElse}) { for (E element in this) { if (test(element)) return element; } @@ -532,8 +522,8 @@ abstract class _SetBase implements Set { throw IterableElementError.noElement(); } - E lastWhere(bool test(E value), {E orElse()}) { - E result; + E lastWhere(bool test(E value), {E Function()? orElse}) { + late E result; bool foundMatching = false; for (E element in this) { if (test(element)) { @@ -546,8 +536,8 @@ abstract class _SetBase implements Set { throw IterableElementError.noElement(); } - E singleWhere(bool test(E value), {E orElse()}) { - E result; + E singleWhere(bool test(E value), {E Function()? orElse}) { + late E result; bool foundMatching = false; for (E element in this) { if (test(element)) { @@ -587,13 +577,13 @@ class _UnmodifiableSet extends _SetBase { // Lookups use map methods. - bool contains(Object element) => _map.containsKey(element); + bool contains(Object? element) => _map.containsKey(element); Iterator get iterator => _map.keys.iterator; int get length => _map.length; - E lookup(Object element) { + E? lookup(Object? element) { for (var key in _map.keys) { if (key == element) return key; } @@ -614,11 +604,11 @@ class _UnmodifiableSet extends _SetBase { throw UnsupportedError("Cannot change unmodifiable set"); } - void removeAll(Iterable elements) { + void removeAll(Iterable elements) { throw UnsupportedError("Cannot change unmodifiable set"); } - void retainAll(Iterable elements) { + void retainAll(Iterable elements) { throw UnsupportedError("Cannot change unmodifiable set"); } @@ -630,7 +620,7 @@ class _UnmodifiableSet extends _SetBase { throw UnsupportedError("Cannot change unmodifiable set"); } - bool remove(Object value) { + bool remove(Object? value) { throw UnsupportedError("Cannot change unmodifiable set"); } } diff --git a/sdk/lib/collection/splay_tree.dart b/sdk/lib/collection/splay_tree.dart index a877e186f4d..a019b645e87 100644 --- a/sdk/lib/collection/splay_tree.dart +++ b/sdk/lib/collection/splay_tree.dart @@ -2,26 +2,31 @@ // 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.6 - part of dart.collection; typedef _Predicate = bool Function(T value); /// A node in a splay tree. It holds the sorting key and the left /// and right children in the tree. -class _SplayTreeNode { +class _SplayTreeNode> { final K key; - _SplayTreeNode left; - _SplayTreeNode right; + + Node? left; + Node? right; _SplayTreeNode(this.key); } +/// A node in a splay tree based set. +class _SplayTreeSetNode extends _SplayTreeNode> { + _SplayTreeSetNode(K key) : super(key); +} + /// A node in a splay tree based map. /// /// A [_SplayTreeNode] that also contains a value -class _SplayTreeMapNode extends _SplayTreeNode { +class _SplayTreeMapNode + extends _SplayTreeNode> { V value; _SplayTreeMapNode(K key, this.value) : super(key); } @@ -32,15 +37,11 @@ class _SplayTreeMapNode extends _SplayTreeNode { /// are quick to access again. /// It performs basic operations such as insertion, look-up and /// removal, in O(log(n)) amortized time. -abstract class _SplayTree> { +abstract class _SplayTree> { // The root node of the splay tree. It will contain either the last // element inserted or the last element looked up. - Node get _root; - set _root(Node newValue); - - // The dummy node used when performing a splay on the tree. Reusing it - // avoids allocating a node each time a splay is performed. - Node get _dummy; + Node? get _root; + set _root(Node? newValue); // Number of elements in the splay tree. int _count = 0; @@ -57,14 +58,11 @@ abstract class _SplayTree> { int _splayCount = 0; /// The comparator that is used for this splay tree. - Comparator get _comparator; + Comparator get _compare; /// The predicate to determine that a given object is a valid key. _Predicate get _validKey; - /// Comparison used to compare keys. - int _compare(K key1, K key2); - /// Perform the splay operation for the given key. Moves the node with /// the given key to the top of the tree. If no node has the given /// key, the last node on the search path is moved to the top of the @@ -76,59 +74,80 @@ abstract class _SplayTree> { int _splay(K key) { if (_root == null) return -1; - // The right child of the dummy node will hold - // the L tree of the algorithm. The left child of the dummy node - // will hold the R tree of the algorithm. Using a dummy node, left - // and right will always be nodes and we avoid special cases. - Node left = _dummy; - Node right = _dummy; - Node current = _root; + // The right and newTreeRight variables start out null, and are set + // after the first move left. The right node is the destination + // for subsequent left rebalances, and newTreeRight holds the left + // child of the final tree. The newTreeRight variable is set at most + // once, after the first move left, and is null iff right is null. + // The left and newTreeLeft variables play the corresponding role for + // right rebalances. + Node? right; + Node? newTreeRight; + Node? left; + Node? newTreeLeft; + var current = _root!; + // Hoist the field read out of the loop. + var compare = _compare; int comp; while (true) { - comp = _compare(current.key, key); + comp = compare(current.key, key); if (comp > 0) { - if (current.left == null) break; - comp = _compare(current.left.key, key); + var currentLeft = current.left; + if (currentLeft == null) break; + comp = compare(currentLeft.key, key); if (comp > 0) { // Rotate right. - _SplayTreeNode tmp = current.left; - current.left = tmp.right; - tmp.right = current; - current = tmp; - if (current.left == null) break; + current.left = currentLeft.right; + currentLeft.right = current; + current = currentLeft; + currentLeft = current.left; + if (currentLeft == null) break; } // Link right. - right.left = current; + if (right == null) { + // First left rebalance, store the eventual right child + newTreeRight = current; + } else { + right.left = current; + } right = current; - current = current.left; + current = currentLeft; } else if (comp < 0) { - if (current.right == null) break; - comp = _compare(current.right.key, key); + var currentRight = current.right; + if (currentRight == null) break; + comp = compare(currentRight.key, key); if (comp < 0) { // Rotate left. - Node tmp = current.right; - current.right = tmp.left; - tmp.left = current; - current = tmp; - if (current.right == null) break; + current.right = currentRight.left; + currentRight.left = current; + current = currentRight; + currentRight = current.right; + if (currentRight == null) break; } // Link left. - left.right = current; + if (left == null) { + // First right rebalance, store the eventual left child + newTreeLeft = current; + } else { + left.right = current; + } left = current; - current = current.right; + current = currentRight; } else { break; } } // Assemble. - left.right = current.left; - right.left = current.right; - current.left = _dummy.right; - current.right = _dummy.left; + if (left != null) { + left.right = current.left; + current.left = newTreeLeft; + } + if (right != null) { + right.left = current.right; + current.right = newTreeRight; + } _root = current; - _dummy.right = null; - _dummy.left = null; _splayCount++; return comp; } @@ -137,31 +156,57 @@ abstract class _SplayTree> { // anchored at [node]. // and that node is returned. It should replace the reference to [node] // in any parent tree or root pointer. - external Node _splayMin(Node node); + Node _splayMin(Node node) { + var current = node; + var nextLeft = current.left; + while (nextLeft != null) { + var left = nextLeft; + current.left = left.right; + left.right = current; + current = left; + nextLeft = current.left; + } + return current; + } // Emulates splaying with a key that is greater than any in the subtree // anchored at [node]. // After this, the largest element in the tree is the root of the subtree, // and that node is returned. It should replace the reference to [node] // in any parent tree or root pointer. - external Node _splayMax(Node node); + Node _splayMax(Node node) { + var current = node; + var nextRight = current.right; + while (nextRight != null) { + var right = nextRight; + current.right = right.left; + right.left = current; + current = right; + nextRight = current.right; + } + return current; + } - Node _remove(K key) { + Node? _remove(K key) { if (_root == null) return null; int comp = _splay(key); if (comp != 0) return null; - Node result = _root; + var root = _root!; + var result = root; + var left = root.left; _count--; // assert(_count >= 0); - if (_root.left == null) { - _root = _root.right; + if (left == null) { + _root = root.right; } else { - Node right = _root.right; + var right = root.right; // Splay to make sure that the new root has an empty right child. - _root = _splayMax(_root.left); + root = _splayMax(left); + // Insert the original right child as the right child of the new // root. - _root.right = right; + root.right = right; + _root = root; } _modificationCount++; return result; @@ -174,32 +219,35 @@ abstract class _SplayTree> { void _addNewRoot(Node node, int comp) { _count++; _modificationCount++; - if (_root == null) { + var root = _root; + if (root == null) { _root = node; return; } // assert(_count >= 0); if (comp < 0) { - node.left = _root; - node.right = _root.right; - _root.right = null; + node.left = root; + node.right = root.right; + root.right = null; } else { - node.right = _root; - node.left = _root.left; - _root.left = null; + node.right = root; + node.left = root.left; + root.left = null; } _root = node; } - Node get _first { - if (_root == null) return null; - _root = _splayMin(_root); + Node? get _first { + var root = _root; + if (root == null) return null; + _root = _splayMin(root); return _root; } - Node get _last { - if (_root == null) return null; - _root = _splayMax(_root); + Node? get _last { + var root = _root; + if (root == null) return null; + _root = _splayMax(root); return _root; } @@ -210,10 +258,6 @@ abstract class _SplayTree> { } } -class _TypeTest { - bool test(v) => v is T; -} - int _dynamicCompare(dynamic a, dynamic b) => Comparable.compare(a, b); Comparator _defaultCompare() { @@ -250,24 +294,29 @@ Comparator _defaultCompare() { /// value is a [K]. class SplayTreeMap extends _SplayTree> with MapMixin { - _SplayTreeMapNode _root; - final _SplayTreeMapNode _dummy = _SplayTreeMapNode(null, null); + _SplayTreeMapNode? _root; - Comparator _comparator; + Comparator _compare; _Predicate _validKey; - SplayTreeMap([int compare(K key1, K key2), bool isValidKey(potentialKey)]) - : _comparator = compare ?? _defaultCompare(), - _validKey = isValidKey ?? ((v) => v is K); + SplayTreeMap( + [int Function(K key1, K key2)? compare, + bool Function(dynamic potentialKey)? isValidKey]) + : _compare = compare ?? _defaultCompare(), + _validKey = isValidKey ?? ((dynamic v) => v is K); /// Creates a [SplayTreeMap] that contains all key/value pairs of [other]. /// /// The keys must all be instances of [K] and the values of [V]. /// The [other] map itself can have any type. - factory SplayTreeMap.from(Map other, - [int compare(K key1, K key2), bool isValidKey(potentialKey)]) { + factory SplayTreeMap.from(Map other, + [int Function(K key1, K key2)? compare, + bool Function(dynamic potentialKey)? isValidKey]) { + if (other is Map) { + return SplayTreeMap.of(other, compare, isValidKey); + } SplayTreeMap result = SplayTreeMap(compare, isValidKey); - other.forEach((k, v) { + other.forEach((dynamic k, dynamic v) { result[k] = v; }); return result; @@ -275,7 +324,8 @@ class SplayTreeMap extends _SplayTree> /// Creates a [SplayTreeMap] that contains all key/value pairs of [other]. factory SplayTreeMap.of(Map other, - [int compare(K key1, K key2), bool isValidKey(potentialKey)]) => + [int Function(K key1, K key2)? compare, + bool Function(dynamic potentialKey)? isValidKey]) => SplayTreeMap(compare, isValidKey)..addAll(other); /// Creates a [SplayTreeMap] where the keys and values are computed from the @@ -290,10 +340,10 @@ class SplayTreeMap extends _SplayTree> /// If no functions are specified for [key] and [value] the default is to /// use the iterable value itself. factory SplayTreeMap.fromIterable(Iterable iterable, - {K key(element), - V value(element), - int compare(K key1, K key2), - bool isValidKey(potentialKey)}) { + {K Function(dynamic element)? key, + V Function(dynamic element)? value, + int Function(K key1, K key2)? compare, + bool Function(dynamic potentialKey)? isValidKey}) { SplayTreeMap map = SplayTreeMap(compare, isValidKey); MapBase._fillMapWithMappedIterable(map, iterable, key, value); return map; @@ -309,30 +359,27 @@ class SplayTreeMap extends _SplayTree> /// /// It is an error if the two [Iterable]s don't have the same length. factory SplayTreeMap.fromIterables(Iterable keys, Iterable values, - [int compare(K key1, K key2), bool isValidKey(potentialKey)]) { + [int Function(K key1, K key2)? compare, + bool Function(dynamic potentialKey)? isValidKey]) { SplayTreeMap map = SplayTreeMap(compare, isValidKey); MapBase._fillMapWithIterables(map, keys, values); return map; } - int _compare(K key1, K key2) => _comparator(key1, key2); - - SplayTreeMap._internal(); - - V operator [](Object key) { + V? operator [](Object? key) { if (!_validKey(key)) return null; if (_root != null) { - int comp = _splay(key); + int comp = _splay(key as dynamic); if (comp == 0) { - return _root.value; + return _root!.value; } } return null; } - V remove(Object key) { + V? remove(Object? key) { if (!_validKey(key)) return null; - _SplayTreeMapNode mapRoot = _remove(key); + _SplayTreeMapNode? mapRoot = _remove(key as dynamic); if (mapRoot != null) return mapRoot.value; return null; } @@ -343,7 +390,7 @@ class SplayTreeMap extends _SplayTree> // the key to the root of the tree. int comp = _splay(key); if (comp == 0) { - _root.value = value; + _root!.value = value; return; } _addNewRoot(_SplayTreeMapNode(key, value), comp); @@ -353,7 +400,7 @@ class SplayTreeMap extends _SplayTree> if (key == null) throw ArgumentError(key); int comp = _splay(key); if (comp == 0) { - return _root.value; + return _root!.value; } int modificationCount = _modificationCount; int splayCount = _splayCount; @@ -383,7 +430,8 @@ class SplayTreeMap extends _SplayTree> bool get isNotEmpty => !isEmpty; void forEach(void f(K key, V value)) { - Iterator<_SplayTreeNode> nodes = _SplayTreeNodeIterator(this); + Iterator<_SplayTreeMapNode> nodes = + _SplayTreeNodeIterator>(this); while (nodes.moveNext()) { _SplayTreeMapNode node = nodes.current; f(node.key, node.value); @@ -398,19 +446,21 @@ class SplayTreeMap extends _SplayTree> _clear(); } - bool containsKey(Object key) { - return _validKey(key) && _splay(key) == 0; + bool containsKey(Object? key) { + return _validKey(key) && _splay(key as dynamic) == 0; } - bool containsValue(Object value) { + bool containsValue(Object? value) { int initialSplayCount = _splayCount; - bool visit(_SplayTreeMapNode node) { + bool visit(_SplayTreeMapNode? node) { while (node != null) { if (node.value == value) return true; if (initialSplayCount != _splayCount) { throw ConcurrentModificationError(this); } - if (node.right != null && visit(node.right)) return true; + if (node.right != null && visit(node.right)) { + return true; + } node = node.left; } return false; @@ -419,55 +469,61 @@ class SplayTreeMap extends _SplayTree> return visit(_root); } - Iterable get keys => _SplayTreeKeyIterable(this); + Iterable get keys => + _SplayTreeKeyIterable>(this); Iterable get values => _SplayTreeValueIterable(this); - /// Get the first key in the map. Returns [:null:] if the map is empty. - K firstKey() { + /// Get the first key in the map. Returns `null` if the map is empty. + K? firstKey() { if (_root == null) return null; - return _first.key; + return _first!.key; } - /// Get the last key in the map. Returns [:null:] if the map is empty. - K lastKey() { + /// Get the last key in the map. Returns `null` if the map is empty. + K? lastKey() { if (_root == null) return null; - return _last.key; + return _last!.key; } /// Get the last key in the map that is strictly smaller than [key]. Returns - /// [:null:] if no key was not found. - K lastKeyBefore(K key) { + /// `null` if no key was not found. + K? lastKeyBefore(K key) { if (key == null) throw ArgumentError(key); if (_root == null) return null; int comp = _splay(key); - if (comp < 0) return _root.key; - _SplayTreeNode node = _root.left; + if (comp < 0) return _root!.key; + _SplayTreeMapNode? node = _root!.left; if (node == null) return null; - while (node.right != null) { - node = node.right; + var nodeRight = node.right; + while (nodeRight != null) { + node = nodeRight; + nodeRight = node.right; } - return node.key; + return node!.key; } /// Get the first key in the map that is strictly larger than [key]. Returns - /// [:null:] if no key was not found. - K firstKeyAfter(K key) { + /// `null` if no key was not found. + K? firstKeyAfter(K key) { if (key == null) throw ArgumentError(key); if (_root == null) return null; int comp = _splay(key); - if (comp > 0) return _root.key; - _SplayTreeNode node = _root.right; + if (comp > 0) return _root!.key; + _SplayTreeMapNode? node = _root!.right; if (node == null) return null; - while (node.left != null) { - node = node.left; + var nodeLeft = node.left; + while (nodeLeft != null) { + node = nodeLeft; + nodeLeft = node.left; } - return node.key; + return node!.key; } } -abstract class _SplayTreeIterator implements Iterator { - final _SplayTree> _tree; +abstract class _SplayTreeIterator, T> + implements Iterator { + final _SplayTree _tree; /// Worklist of nodes to visit. /// @@ -477,7 +533,7 @@ abstract class _SplayTreeIterator implements Iterator { /// the nodes of a full traversal. /// /// Only valid as long as the original tree isn't reordered. - final List<_SplayTreeNode> _workList = <_SplayTreeNode>[]; + final List _workList = []; /// Original modification counter of [_tree]. /// @@ -494,35 +550,37 @@ abstract class _SplayTreeIterator implements Iterator { int _splayCount; /// Current node. - _SplayTreeNode _currentNode; + Node? _currentNode; - _SplayTreeIterator(_SplayTree> tree) + _SplayTreeIterator(_SplayTree tree) : _tree = tree, _modificationCount = tree._modificationCount, _splayCount = tree._splayCount { _findLeftMostDescendent(tree._root); } - _SplayTreeIterator.startAt(_SplayTree> tree, K startKey) + _SplayTreeIterator.startAt(_SplayTree tree, K startKey) : _tree = tree, - _modificationCount = tree._modificationCount { + _modificationCount = tree._modificationCount, + _splayCount = -1 { if (tree._root == null) return; int compare = tree._splay(startKey); _splayCount = tree._splayCount; if (compare < 0) { // Don't include the root, start at the next element after the root. - _findLeftMostDescendent(tree._root.right); + _findLeftMostDescendent(tree._root!.right); } else { - _workList.add(tree._root); + _workList.add(tree._root!); } } T get current { - if (_currentNode == null) return null; - return _getValue(_currentNode); + var node = _currentNode; + if (node == null) return null as T; + return _getValue(node); } - void _findLeftMostDescendent(_SplayTreeNode node) { + void _findLeftMostDescendent(Node? node) { while (node != null) { _workList.add(node); node = node.left; @@ -535,16 +593,12 @@ abstract class _SplayTreeIterator implements Iterator { /// If the key-set changes, iteration is aborted before getting /// here, so we know that the keys are the same as before, it's /// only the tree that has been reordered. - void _rebuildWorkList(_SplayTreeNode currentNode) { + void _rebuildWorkList(Node currentNode) { assert(_workList.isNotEmpty); _workList.clear(); - if (currentNode == null) { - _findLeftMostDescendent(_tree._root); - } else { - _tree._splay(currentNode.key); - _findLeftMostDescendent(_tree._root.right); - assert(_workList.isNotEmpty); - } + _tree._splay(currentNode.key); + _findLeftMostDescendent(_tree._root!.right); + assert(_workList.isNotEmpty); } bool moveNext() { @@ -561,27 +615,28 @@ abstract class _SplayTreeIterator implements Iterator { return false; } if (_tree._splayCount != _splayCount && _currentNode != null) { - _rebuildWorkList(_currentNode); + _rebuildWorkList(_currentNode!); } _currentNode = _workList.removeLast(); - _findLeftMostDescendent(_currentNode.right); + _findLeftMostDescendent(_currentNode!.right); return true; } - T _getValue(_SplayTreeNode node); + T _getValue(Node node); } -class _SplayTreeKeyIterable extends EfficientLengthIterable { - _SplayTree> _tree; +class _SplayTreeKeyIterable> + extends EfficientLengthIterable { + _SplayTree _tree; _SplayTreeKeyIterable(this._tree); int get length => _tree._count; bool get isEmpty => _tree._count == 0; - Iterator get iterator => _SplayTreeKeyIterator(_tree); + Iterator get iterator => _SplayTreeKeyIterator(_tree); Set toSet() { - SplayTreeSet set = SplayTreeSet(_tree._comparator, _tree._validKey); + SplayTreeSet set = SplayTreeSet(_tree._compare, _tree._validKey); set._count = _tree._count; - set._root = set._copyNode(_tree._root); + set._root = set._copyNode(_tree._root); return set; } } @@ -594,26 +649,24 @@ class _SplayTreeValueIterable extends EfficientLengthIterable { Iterator get iterator => _SplayTreeValueIterator(_map); } -class _SplayTreeKeyIterator extends _SplayTreeIterator { - _SplayTreeKeyIterator(_SplayTree> map) : super(map); - K _getValue(_SplayTreeNode node) => node.key; +class _SplayTreeKeyIterator> + extends _SplayTreeIterator { + _SplayTreeKeyIterator(_SplayTree map) : super(map); + K _getValue(Node node) => node.key; } -class _SplayTreeValueIterator extends _SplayTreeIterator { +class _SplayTreeValueIterator + extends _SplayTreeIterator, V> { _SplayTreeValueIterator(SplayTreeMap map) : super(map); - V _getValue(_SplayTreeNode node) { - _SplayTreeMapNode mapNode = node; - return mapNode.value; - } + V _getValue(_SplayTreeMapNode node) => node.value; } -class _SplayTreeNodeIterator - extends _SplayTreeIterator> { - _SplayTreeNodeIterator(_SplayTree> tree) : super(tree); - _SplayTreeNodeIterator.startAt( - _SplayTree> tree, K startKey) +class _SplayTreeNodeIterator> + extends _SplayTreeIterator { + _SplayTreeNodeIterator(_SplayTree tree) : super(tree); + _SplayTreeNodeIterator.startAt(_SplayTree tree, K startKey) : super.startAt(tree, startKey); - _SplayTreeNode _getValue(_SplayTreeNode node) => node; + Node _getValue(Node node) => node; } /// A [Set] of objects that can be ordered relative to each other. @@ -630,12 +683,11 @@ class _SplayTreeNodeIterator /// [Comparable], and are compared using their [Comparable.compareTo] method. /// Non-comparable objects (including `null`) will not work as an element /// in that case. -class SplayTreeSet extends _SplayTree> +class SplayTreeSet extends _SplayTree> with IterableMixin, SetMixin { - _SplayTreeNode _root; - final _SplayTreeNode _dummy = _SplayTreeNode(null); + _SplayTreeSetNode? _root; - Comparator _comparator; + Comparator _compare; _Predicate _validKey; /// Create a new [SplayTreeSet] with the given compare function. @@ -660,9 +712,11 @@ class SplayTreeSet extends _SplayTree> /// /// If omitted, the `isValidKey` function defaults to checking against the /// type parameter: `other is E`. - SplayTreeSet([int compare(E key1, E key2), bool isValidKey(potentialKey)]) - : _comparator = compare ?? _defaultCompare(), - _validKey = isValidKey ?? ((v) => v is E); + SplayTreeSet( + [int Function(E key1, E key2)? compare, + bool Function(dynamic potentialKey)? isValidKey]) + : _compare = compare ?? _defaultCompare(), + _validKey = isValidKey ?? ((dynamic v) => v is E); /// Creates a [SplayTreeSet] that contains all [elements]. /// @@ -678,11 +732,14 @@ class SplayTreeSet extends _SplayTree> /// new SplayTreeSet.from(superSet.whereType()); /// ``` factory SplayTreeSet.from(Iterable elements, - [int compare(E key1, E key2), bool isValidKey(potentialKey)]) { + [int Function(E key1, E key2)? compare, + bool Function(dynamic potentialKey)? isValidKey]) { + if (elements is Iterable) { + return SplayTreeSet.of(elements, compare, isValidKey); + } SplayTreeSet result = SplayTreeSet(compare, isValidKey); - for (final element in elements) { - E e = element; - result.add(e); + for (var element in elements) { + result.add(element as dynamic); } return result; } @@ -693,18 +750,19 @@ class SplayTreeSet extends _SplayTree> /// /// All the [elements] should be valid as arguments to the [compare] function. factory SplayTreeSet.of(Iterable elements, - [int compare(E key1, E key2), bool isValidKey(potentialKey)]) => + [int Function(E key1, E key2)? compare, + bool Function(dynamic potentialKey)? isValidKey]) => SplayTreeSet(compare, isValidKey)..addAll(elements); Set _newSet() => - SplayTreeSet((T a, T b) => _comparator(a as E, b as E), _validKey); + SplayTreeSet((T a, T b) => _compare(a as E, b as E), _validKey); Set cast() => Set.castFrom(this, newSet: _newSet); - int _compare(E e1, E e2) => _comparator(e1, e2); // From Iterable. - Iterator get iterator => _SplayTreeKeyIterator(this); + Iterator get iterator => + _SplayTreeKeyIterator>(this); int get length => _count; bool get isEmpty => _root == null; @@ -712,64 +770,64 @@ class SplayTreeSet extends _SplayTree> E get first { if (_count == 0) throw IterableElementError.noElement(); - return _first.key; + return _first!.key; } E get last { if (_count == 0) throw IterableElementError.noElement(); - return _last.key; + return _last!.key; } E get single { if (_count == 0) throw IterableElementError.noElement(); if (_count > 1) throw IterableElementError.tooMany(); - return _root.key; + return _root!.key; } // From Set. - bool contains(Object element) { - return _validKey(element) && _splay(element) == 0; + bool contains(Object? element) { + return _validKey(element) && _splay(element as E) == 0; } bool add(E element) { int compare = _splay(element); if (compare == 0) return false; - _addNewRoot(_SplayTreeNode(element), compare); + _addNewRoot(_SplayTreeSetNode(element), compare); return true; } - bool remove(Object object) { + bool remove(Object? object) { if (!_validKey(object)) return false; - return _remove(object) != null; + return _remove(object as E) != null; } void addAll(Iterable elements) { for (E element in elements) { int compare = _splay(element); if (compare != 0) { - _addNewRoot(_SplayTreeNode(element), compare); + _addNewRoot(_SplayTreeSetNode(element), compare); } } } - void removeAll(Iterable elements) { - for (Object element in elements) { - if (_validKey(element)) _remove(element); + void removeAll(Iterable elements) { + for (Object? element in elements) { + if (_validKey(element)) _remove(element as E); } } - void retainAll(Iterable elements) { + void retainAll(Iterable elements) { // Build a set with the same sense of equality as this set. - SplayTreeSet retainSet = SplayTreeSet(_comparator, _validKey); + SplayTreeSet retainSet = SplayTreeSet(_compare, _validKey); int modificationCount = _modificationCount; - for (Object object in elements) { + for (Object? object in elements) { if (modificationCount != _modificationCount) { // The iterator should not have side effects. throw ConcurrentModificationError(this); } // Equivalent to this.contains(object). - if (_validKey(object) && _splay(object) == 0) { - retainSet.add(_root.key); + if (_validKey(object) && _splay(object as E) == 0) { + retainSet.add(_root!.key); } } // Take over the elements from the retained set, if it differs. @@ -780,23 +838,23 @@ class SplayTreeSet extends _SplayTree> } } - E lookup(Object object) { + E? lookup(Object? object) { if (!_validKey(object)) return null; - int comp = _splay(object); + int comp = _splay(object as E); if (comp != 0) return null; - return _root.key; + return _root!.key; } - Set intersection(Set other) { - Set result = SplayTreeSet(_comparator, _validKey); + Set intersection(Set other) { + Set result = SplayTreeSet(_compare, _validKey); for (E element in this) { if (other.contains(element)) result.add(element); } return result; } - Set difference(Set other) { - Set result = SplayTreeSet(_comparator, _validKey); + Set difference(Set other) { + Set result = SplayTreeSet(_compare, _validKey); for (E element in this) { if (!other.contains(element)) result.add(element); } @@ -808,19 +866,46 @@ class SplayTreeSet extends _SplayTree> } SplayTreeSet _clone() { - var set = SplayTreeSet(_comparator, _validKey); + var set = SplayTreeSet(_compare, _validKey); set._count = _count; - set._root = _copyNode(_root); + set._root = _copyNode<_SplayTreeSetNode>(_root); return set; } // Copies the structure of a SplayTree into a new similar structure. // Works on _SplayTreeMapNode as well, but only copies the keys, - _SplayTreeNode _copyNode(_SplayTreeNode node) { + _SplayTreeSetNode? _copyNode>( + Node? node) { if (node == null) return null; - return _SplayTreeNode(node.key) - ..left = _copyNode(node.left) - ..right = _copyNode(node.right); + // Given a source node and a destination node, copy the left + // and right subtrees of the source node into the destination node. + // The left subtree is copied recursively, but the right spine + // of every subtree is copied iteratively. + void copyChildren(Node node, _SplayTreeSetNode dest) { + Node? left; + Node? right; + do { + left = node.left; + right = node.right; + if (left != null) { + var newLeft = _SplayTreeSetNode(left.key); + dest.left = newLeft; + // Recursively copy the left tree. + copyChildren(left, newLeft); + } + if (right != null) { + var newRight = _SplayTreeSetNode(right.key); + dest.right = newRight; + // Set node and dest to copy the right tree iteratively. + node = right; + dest = newRight; + } + } while (right != null); + } + + var result = _SplayTreeSetNode(node.key); + copyChildren(node, result); + return result; } void clear() { diff --git a/sdk/lib/convert/ascii.dart b/sdk/lib/convert/ascii.dart index 82f22768dcb..9d980162e8a 100644 --- a/sdk/lib/convert/ascii.dart +++ b/sdk/lib/convert/ascii.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.convert; /// An instance of the default implementation of the [AsciiCodec]. @@ -50,9 +48,8 @@ class AsciiCodec extends Encoding { /// /// If [allowInvalid] is not provided, it defaults to the value used to create /// this [AsciiCodec]. - String decode(List bytes, {bool allowInvalid}) { - allowInvalid ??= _allowInvalid; - if (allowInvalid) { + String decode(List bytes, {bool? allowInvalid}) { + if (allowInvalid ?? _allowInvalid) { return const AsciiDecoder(allowInvalid: true).convert(bytes); } else { return const AsciiDecoder(allowInvalid: false).convert(bytes); @@ -77,9 +74,13 @@ class _UnicodeSubsetEncoder extends Converter> { /// /// If [start] and [end] are provided, only the substring /// `string.substring(start, end)` is used as input to the conversion. - Uint8List convert(String string, [int start = 0, int end]) { + Uint8List convert(String string, [int start = 0, int? end]) { var stringLength = string.length; end = RangeError.checkValidRange(start, end, stringLength); + // TODO(38725): Remove workaround when assignment promotion is implemented + if (end == null) { + throw RangeError("Invalid range"); + } var length = end - start; var result = Uint8List(length); for (var i = 0; i < length; i++) { @@ -164,11 +165,12 @@ abstract class _UnicodeSubsetDecoder extends Converter, String> { /// /// If [start] and [end] are provided, only the sub-list of bytes from /// `start` to `end` (`end` not inclusive) is used as input to the conversion. - String convert(List bytes, [int start = 0, int end]) { - var byteCount = bytes.length; - RangeError.checkValidRange(start, end, byteCount); - end ??= byteCount; - + String convert(List bytes, [int start = 0, int? end]) { + end = RangeError.checkValidRange(start, end, bytes.length); + // TODO(38725): Remove workaround when assignment promotion is implemented + if (end == null) { + throw RangeError("Invalid range"); + } for (var i = start; i < end; i++) { var byte = bytes[i]; if ((byte & ~_subsetMask) != 0) { diff --git a/sdk/lib/convert/base64.dart b/sdk/lib/convert/base64.dart index 2a8d462f231..0955ca1e60d 100644 --- a/sdk/lib/convert/base64.dart +++ b/sdk/lib/convert/base64.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.convert; /// A [base64](https://tools.ietf.org/html/rfc4648) encoder and decoder. @@ -37,18 +35,18 @@ const Base64Codec base64Url = Base64Codec.urlSafe(); /// Encodes [bytes] using [base64](https://tools.ietf.org/html/rfc4648) encoding. /// -/// Shorthand for `base64.encode`. Useful if a local variable shadows the global +/// Shorthand for `base64.encode(bytes)`. Useful if a local variable shadows the global /// [base64] constant. String base64Encode(List bytes) => base64.encode(bytes); /// Encodes [bytes] using [base64url](https://tools.ietf.org/html/rfc4648) encoding. /// -/// Shorthand for `base64url.encode`. +/// Shorthand for `base64url.encode(bytes)`. String base64UrlEncode(List bytes) => base64Url.encode(bytes); /// Decodes [base64](https://tools.ietf.org/html/rfc4648) or [base64url](https://tools.ietf.org/html/rfc4648) encoded bytes. /// -/// Shorthand for `base64.decode`. Useful if a local variable shadows the +/// Shorthand for `base64.decode(bytes)`. Useful if a local variable shadows the /// global [base64] constant. Uint8List base64Decode(String source) => base64.decode(source); @@ -95,11 +93,15 @@ class Base64Codec extends Codec, String> { /// * Validate that existing padding (trailing `=` characters) is correct. /// * If no padding exists, add correct padding if necessary and possible. /// * Validate that the length is correct (a multiple of four). - String normalize(String source, [int start = 0, int end]) { + String normalize(String source, [int start = 0, int? end]) { end = RangeError.checkValidRange(start, end, source.length); + // TODO(38725): Remove workaround when assignment promotion is implemented + if (end == null) { + throw RangeError("Invalid range"); + } const percent = 0x25; const equals = 0x3d; - StringBuffer buffer; + StringBuffer? buffer; var sliceStart = start; var alphabet = _Base64Encoder._base64Alphabet; var inverseAlphabet = _Base64Decoder._inverseAlphabet; @@ -142,9 +144,9 @@ class Base64Codec extends Codec, String> { if (originalChar == equals) continue; } if (value != _Base64Decoder._invalid) { - buffer ??= StringBuffer(); - buffer.write(source.substring(sliceStart, sliceEnd)); - buffer.writeCharCode(char); + (buffer ??= StringBuffer()) + ..write(source.substring(sliceStart, sliceEnd)) + ..writeCharCode(char); sliceStart = i; continue; } @@ -233,7 +235,7 @@ class Base64Encoder extends Converter, String> { String convert(List input) { if (input.isEmpty) return ""; var encoder = _Base64Encoder(_urlSafe); - var buffer = encoder.encode(input, 0, input.length, true); + var buffer = encoder.encode(input, 0, input.length, true)!; return String.fromCharCodes(buffer); } @@ -302,10 +304,10 @@ class _Base64Encoder { /// with the necessary padding. /// /// Returns `null` if there is no output. - Uint8List encode(List bytes, int start, int end, bool isLast) { + Uint8List? encode(List bytes, int start, int end, bool isLast) { assert(0 <= start); assert(start <= end); - assert(bytes == null || end <= bytes.length); + assert(end <= bytes.length); var length = end - start; var count = _stateCount(_state); @@ -395,17 +397,21 @@ class _BufferCachingBase64Encoder extends _Base64Encoder { /// /// When the buffer isn't released to the sink, only used to create another /// value (a string), the buffer can be reused between chunks. - Uint8List bufferCache; + Uint8List? bufferCache; _BufferCachingBase64Encoder(bool urlSafe) : super(urlSafe); Uint8List createBuffer(int bufferLength) { - if (bufferCache == null || bufferCache.length < bufferLength) { - bufferCache = Uint8List(bufferLength); + Uint8List? buffer = bufferCache; + if (buffer == null || buffer.length < bufferLength) { + bufferCache = buffer = Uint8List(bufferLength); + } + // TODO(38725): Remove workaround when assignment promotion is implemented + if (buffer == null) { + throw "unreachable"; } // Return a view of the buffer, so it has the requested length. - return Uint8List.view( - bufferCache.buffer, bufferCache.offsetInBytes, bufferLength); + return Uint8List.view(buffer.buffer, buffer.offsetInBytes, bufferLength); } } @@ -415,7 +421,7 @@ abstract class _Base64EncoderSink extends ByteConversionSinkBase { } void close() { - _add(null, 0, 0, true); + _add(const [], 0, 0, true); } void addSlice(List source, int start, int end, bool isLast) { @@ -481,11 +487,15 @@ class Base64Decoder extends Converter> { /// The returned [Uint8List] contains exactly the decoded bytes, /// so the [Uint8List.length] is precisely the number of decoded bytes. /// The [Uint8List.buffer] may be larger than the decoded bytes. - Uint8List convert(String input, [int start = 0, int end]) { + Uint8List convert(String input, [int start = 0, int? end]) { end = RangeError.checkValidRange(start, end, input.length); + // TODO(38725): Remove workaround when assignment promotion is implemented + if (end == null) { + throw RangeError("Invalid range"); + } if (start == end) return Uint8List(0); var decoder = _Base64Decoder(); - var buffer = decoder.decode(input, start, end); + var buffer = decoder.decode(input, start, end)!; decoder.close(input, end); return buffer; } @@ -595,7 +605,7 @@ class _Base64Decoder { /// Returns a [Uint8List] with the decoded bytes. /// If a previous call had an incomplete four-character block, the bits from /// those are included in decoding - Uint8List decode(String input, int start, int end) { + Uint8List? decode(String input, int start, int end) { assert(0 <= start); assert(start <= end); assert(end <= input.length); @@ -610,7 +620,7 @@ class _Base64Decoder { } /// Checks that [_state] represents a valid decoding. - void close(String input, int end) { + void close(String? input, int? end) { if (_state < _encodePaddingState(0)) { throw FormatException("Missing padding character", input, end); } @@ -695,6 +705,8 @@ class _Base64Decoder { throw FormatException("Invalid character", input, i); } + static Uint8List _emptyBuffer = Uint8List(0); + /// Allocates a buffer with room for the decoding of a substring of [input]. /// /// Includes room for the characters in [state], and handles padding correctly. @@ -714,7 +726,7 @@ class _Base64Decoder { if (bufferLength > 0) return Uint8List(bufferLength); // If the input plus state is less than four characters, and it's not // at the end of input, no buffer is needed. - return null; + return _emptyBuffer; } /// Returns the position of the start of padding at the end of the input. @@ -846,7 +858,7 @@ class _Base64DecoderSink extends StringConversionSinkBase { } void addSlice(String string, int start, int end, bool isLast) { - end = RangeError.checkValidRange(start, end, string.length); + RangeError.checkValidRange(start, end, string.length); if (start == end) return; var buffer = _decoder.decode(string, start, end); if (buffer != null) _sink.add(buffer); diff --git a/sdk/lib/convert/byte_conversion.dart b/sdk/lib/convert/byte_conversion.dart index ffde7d96bba..3d52d78ee1c 100644 --- a/sdk/lib/convert/byte_conversion.dart +++ b/sdk/lib/convert/byte_conversion.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.convert; /// The [ByteConversionSink] provides an interface for converters to diff --git a/sdk/lib/convert/chunked_conversion.dart b/sdk/lib/convert/chunked_conversion.dart index 3b67c3a03d1..d2c24f00f5a 100644 --- a/sdk/lib/convert/chunked_conversion.dart +++ b/sdk/lib/convert/chunked_conversion.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.convert; /// A [ChunkedConversionSink] is used to transmit data more efficiently between @@ -74,7 +72,8 @@ class _ConverterStreamEventSink implements EventSink { _chunkedSink.add(o); } - void addError(Object error, [StackTrace stackTrace]) { + void addError(Object error, [StackTrace? stackTrace]) { + // TODO(40614): Remove once non-nullability is sound. ArgumentError.checkNotNull(error, "error"); _eventSink.addError(error, stackTrace); } diff --git a/sdk/lib/convert/codec.dart b/sdk/lib/convert/codec.dart index 1d8daf3ee9a..38e4a3c32aa 100644 --- a/sdk/lib/convert/codec.dart +++ b/sdk/lib/convert/codec.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.convert; /// A [Codec] encodes and (if supported) decodes data. diff --git a/sdk/lib/convert/convert.dart b/sdk/lib/convert/convert.dart index ec6ba50772a..61737822b68 100644 --- a/sdk/lib/convert/convert.dart +++ b/sdk/lib/convert/convert.dart @@ -2,8 +2,6 @@ // 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.6 - /// /// Encoders and decoders for converting between different data representations, /// including JSON and UTF-8. diff --git a/sdk/lib/convert/converter.dart b/sdk/lib/convert/converter.dart index 047859fd2c3..21679333660 100644 --- a/sdk/lib/convert/converter.dart +++ b/sdk/lib/convert/converter.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.convert; /// A [Converter] converts data from one representation into another. diff --git a/sdk/lib/convert/encoding.dart b/sdk/lib/convert/encoding.dart index 663ae6485e4..b9238a8d67b 100644 --- a/sdk/lib/convert/encoding.dart +++ b/sdk/lib/convert/encoding.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.convert; /// Open-ended Encoding enum. @@ -74,10 +72,9 @@ abstract class Encoding extends Codec> { /// /// The [name] passed is case insensitive. /// - /// If character set is not supported [:null:] is returned. - static Encoding getByName(String name) { + /// If character set is not supported `null` is returned. + static Encoding? getByName(String? name) { if (name == null) return null; - name = name.toLowerCase(); - return _nameToEncoding[name]; + return _nameToEncoding[name.toLowerCase()]; } } diff --git a/sdk/lib/convert/html_escape.dart b/sdk/lib/convert/html_escape.dart index 5f1054426cd..317e6c194bc 100644 --- a/sdk/lib/convert/html_escape.dart +++ b/sdk/lib/convert/html_escape.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.convert; /// A `String` converter that converts characters to HTML entities. @@ -160,11 +158,11 @@ class HtmlEscape extends Converter { /// /// Returns `null` if no changes were necessary, otherwise returns /// the converted string. - String _convert(String text, int start, int end) { - StringBuffer result; + String? _convert(String text, int start, int end) { + StringBuffer? result; for (var i = start; i < end; i++) { var ch = text[i]; - String replacement; + String? replacement; switch (ch) { case '&': replacement = '&'; @@ -187,6 +185,11 @@ class HtmlEscape extends Converter { } if (replacement != null) { result ??= StringBuffer(); + // TODO(38725): Remove workaround when assignment promotion is + // implemented + if (result == null) { + throw "unreachable"; + } if (i > start) result.write(text.substring(start, i)); result.write(replacement); start = i + 1; diff --git a/sdk/lib/convert/json.dart b/sdk/lib/convert/json.dart index fc55abcf170..6d897a09416 100644 --- a/sdk/lib/convert/json.dart +++ b/sdk/lib/convert/json.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.convert; /// Error thrown by JSON serialization if an object cannot be serialized. @@ -16,15 +14,15 @@ part of dart.convert; /// serializable, the [cause] is null. class JsonUnsupportedObjectError extends Error { /// The object that could not be serialized. - final Object unsupportedObject; + final Object? unsupportedObject; /// The exception thrown when trying to convert the object. - final Object cause; + final Object? cause; /// The partial result of the conversion, up until the error happened. /// /// May be null. - final String partialResult; + final String? partialResult; JsonUnsupportedObjectError(this.unsupportedObject, {this.cause, this.partialResult}); @@ -48,7 +46,7 @@ class JsonUnsupportedObjectError extends Error { /// When the cycle is detected, a [JsonCyclicError] is thrown. class JsonCyclicError extends JsonUnsupportedObjectError { /// The first object that was detected as part of a cycle. - JsonCyclicError(Object object) : super(object); + JsonCyclicError(Object? object) : super(object); String toString() => "Cyclic error in JSON stringify"; } @@ -78,8 +76,9 @@ const JsonCodec json = JsonCodec(); /// /// Shorthand for `json.encode`. Useful if a local variable shadows the global /// [json] constant. -String jsonEncode(Object value, {Object toEncodable(Object nonEncodable)}) => - json.encode(value, toEncodable: toEncodable); +String jsonEncode(Object? object, + {Object? toEncodable(Object? nonEncodable)?}) => + json.encode(object, toEncodable: toEncodable); /// Parses the string and returns the resulting Json object. /// @@ -92,7 +91,8 @@ String jsonEncode(Object value, {Object toEncodable(Object nonEncodable)}) => /// /// Shorthand for `json.decode`. Useful if a local variable shadows the global /// [json] constant. -dynamic jsonDecode(String source, {Object reviver(Object key, Object value)}) => +dynamic jsonDecode(String source, + {Object? reviver(Object? key, Object? value)?}) => json.decode(source, reviver: reviver); /// A [JsonCodec] encodes JSON objects to strings and decodes strings to @@ -102,9 +102,9 @@ dynamic jsonDecode(String source, {Object reviver(Object key, Object value)}) => /// /// var encoded = json.encode([1, 2, { "a": null }]); /// var decoded = json.decode('["foo", { "bar": 499 }]'); -class JsonCodec extends Codec { - final Function(Object key, Object value) _reviver; - final Function(dynamic) _toEncodable; +class JsonCodec extends Codec { + final Object? Function(Object? key, Object? value)? _reviver; + final Object? Function(dynamic)? _toEncodable; /// Creates a `JsonCodec` with the given reviver and encoding function. /// @@ -127,7 +127,9 @@ class JsonCodec extends Codec { /// /// If [toEncodable] is omitted, it defaults to a function that returns the /// result of calling `.toJson()` on the unencodable object. - const JsonCodec({reviver(Object key, Object value), toEncodable(var object)}) + const JsonCodec( + {Object? reviver(Object? key, Object? value)?, + Object? toEncodable(dynamic object)?}) : _reviver = reviver, _toEncodable = toEncodable; @@ -137,7 +139,7 @@ class JsonCodec extends Codec { /// that has been parsed during decoding. The `key` argument is either the /// integer list index for a list property, the string map key for object /// properties, or `null` for the final result. - JsonCodec.withReviver(reviver(Object key, Object value)) + JsonCodec.withReviver(dynamic reviver(Object? key, Object? value)) : this(reviver: reviver); /// Parses the string and returns the resulting Json object. @@ -148,7 +150,8 @@ class JsonCodec extends Codec { /// properties, or `null` for the final result. /// /// The default [reviver] (when not provided) is the identity function. - dynamic decode(String source, {reviver(Object key, Object value)}) { + dynamic decode(String source, + {Object? reviver(Object? key, Object? value)?}) { reviver ??= _reviver; if (reviver == null) return decoder.convert(source); return JsonDecoder(reviver).convert(source); @@ -163,7 +166,7 @@ class JsonCodec extends Codec { /// /// If [toEncodable] is omitted, it defaults to a function that returns the /// result of calling `.toJson()` on the unencodable object. - String encode(Object value, {toEncodable(object)}) { + String encode(Object? value, {Object? toEncodable(dynamic object)?}) { toEncodable ??= _toEncodable; if (toEncodable == null) return encoder.convert(value); return JsonEncoder(toEncodable).convert(value); @@ -181,21 +184,18 @@ class JsonCodec extends Codec { } /// This class converts JSON objects to strings. -/// -/// When used as a [StreamTransformer], this converter does not promise -/// that the input object is emitted as a single string event. -class JsonEncoder extends Converter { +class JsonEncoder extends Converter { /// The string used for indention. /// /// When generating multi-line output, this string is inserted once at the /// beginning of each indented line for each level of indentation. /// /// If `null`, the output is encoded as a single line. - final String indent; + final String? indent; /// Function called on non-encodable objects to return a replacement /// encodable object that will be encoded in the orignal's place. - final Function(dynamic) _toEncodable; + final Object? Function(dynamic)? _toEncodable; /// Creates a JSON encoder. /// @@ -207,7 +207,7 @@ class JsonEncoder extends Converter { /// /// If [toEncodable] is omitted, it defaults to calling `.toJson()` on /// the object. - const JsonEncoder([toEncodable(object)]) + const JsonEncoder([Object? toEncodable(dynamic object)?]) : indent = null, _toEncodable = toEncodable; @@ -227,7 +227,8 @@ class JsonEncoder extends Converter { /// /// If [toEncodable] is omitted, it defaults to calling `.toJson()` on /// the object. - const JsonEncoder.withIndent(this.indent, [toEncodable(object)]) + const JsonEncoder.withIndent(this.indent, + [Object? toEncodable(dynamic object)?]) : _toEncodable = toEncodable; /// Converts [object] to a JSON [String]. @@ -256,7 +257,7 @@ class JsonEncoder extends Converter { /// If an object is serialized more than once, [convert] may cache the text /// for it. In other words, if the content of an object changes after it is /// first serialized, the new values may not be reflected in the result. - String convert(Object object) => + String convert(Object? object) => _JsonStringStringifier.stringify(object, _toEncodable, indent); /// Starts a chunked conversion. @@ -266,7 +267,7 @@ class JsonEncoder extends Converter { /// /// Returns a chunked-conversion sink that accepts at most one object. It is /// an error to invoke `add` more than once on the returned sink. - ChunkedConversionSink startChunkedConversion(Sink sink) { + ChunkedConversionSink startChunkedConversion(Sink sink) { if (sink is _Utf8EncoderSink) { return _JsonUtf8EncoderSink( sink._sink, @@ -281,15 +282,13 @@ class JsonEncoder extends Converter { } // Override the base class's bind, to provide a better type. - Stream bind(Stream stream) => super.bind(stream); + Stream bind(Stream stream) => super.bind(stream); - Converter fuse(Converter other) { + Converter fuse(Converter other) { if (other is Utf8Encoder) { // The instance check guarantees that `T` is (a subtype of) List, // but the static type system doesn't know that, and so we cast. - // Cast through dynamic to keep the cast implicit for builds using - // unchecked implicit casts. - return JsonUtf8Encoder(indent, _toEncodable) as dynamic; + return JsonUtf8Encoder(indent, _toEncodable) as Converter; } return super.fuse(other); } @@ -300,17 +299,17 @@ class JsonEncoder extends Converter { /// This encoder works equivalently to first converting the object to /// a JSON string, and then UTF-8 encoding the string, but without /// creating an intermediate string. -class JsonUtf8Encoder extends Converter> { +class JsonUtf8Encoder extends Converter> { /// Default buffer size used by the JSON-to-UTF-8 encoder. static const int _defaultBufferSize = 256; @deprecated static const int DEFAULT_BUFFER_SIZE = _defaultBufferSize; /// Indentation used in pretty-print mode, `null` if not pretty. - final List _indent; + final List? _indent; /// Function called with each un-encodable object encountered. - final Function(dynamic) _toEncodable; + final Object? Function(dynamic)? _toEncodable; /// UTF-8 buffer size. final int _bufferSize; @@ -339,12 +338,12 @@ class JsonUtf8Encoder extends Converter> { /// If [toEncodable] is omitted, it defaults to calling `.toJson()` on the /// object. JsonUtf8Encoder( - [String indent, toEncodable(object), int bufferSize = _defaultBufferSize]) + [String? indent, dynamic toEncodable(dynamic object)?, int? bufferSize]) : _indent = _utf8Encode(indent), _toEncodable = toEncodable, - _bufferSize = bufferSize; + _bufferSize = bufferSize ?? _defaultBufferSize; - static List _utf8Encode(String string) { + static List? _utf8Encode(String? string) { if (string == null) return null; if (string.isEmpty) return Uint8List(0); checkAscii: @@ -358,7 +357,7 @@ class JsonUtf8Encoder extends Converter> { } /// Convert [object] into UTF-8 encoded JSON. - List convert(Object object) { + List convert(Object? object) { var bytes = >[]; // The `stringify` function always converts into chunks. // Collect the chunks into the `bytes` list, then combine them afterwards. @@ -394,7 +393,7 @@ class JsonUtf8Encoder extends Converter> { /// /// The argument [sink] will receive byte lists in sizes depending on the /// `bufferSize` passed to the constructor when creating this encoder. - ChunkedConversionSink startChunkedConversion(Sink> sink) { + ChunkedConversionSink startChunkedConversion(Sink> sink) { ByteConversionSink byteSink; if (sink is ByteConversionSink) { byteSink = sink; @@ -405,7 +404,7 @@ class JsonUtf8Encoder extends Converter> { } // Override the base class's bind, to provide a better type. - Stream> bind(Stream stream) { + Stream> bind(Stream stream) { return super.bind(stream); } } @@ -413,9 +412,9 @@ class JsonUtf8Encoder extends Converter> { /// Implements the chunked conversion from object to its JSON representation. /// /// The sink only accepts one value, but will produce output in a chunked way. -class _JsonEncoderSink extends ChunkedConversionSink { - final String _indent; - final Function(dynamic) _toEncodable; +class _JsonEncoderSink extends ChunkedConversionSink { + final String? _indent; + final Object? Function(dynamic)? _toEncodable; final StringConversionSink _sink; bool _isDone = false; @@ -426,7 +425,7 @@ class _JsonEncoderSink extends ChunkedConversionSink { /// It is an error to invoke this method more than once on any instance. While /// this makes the input effectively non-chunked the output will be generated /// in a chunked way. - void add(Object o) { + void add(Object? o) { if (_isDone) { throw StateError("Only one call to add allowed"); } @@ -440,11 +439,11 @@ class _JsonEncoderSink extends ChunkedConversionSink { } /// Sink returned when starting a chunked conversion from object to bytes. -class _JsonUtf8EncoderSink extends ChunkedConversionSink { +class _JsonUtf8EncoderSink extends ChunkedConversionSink { /// The byte sink receiveing the encoded chunks. final ByteConversionSink _sink; - final List _indent; - final Function(dynamic) _toEncodable; + final List? _indent; + final Object? Function(dynamic)? _toEncodable; final int _bufferSize; bool _isDone = false; _JsonUtf8EncoderSink( @@ -455,7 +454,7 @@ class _JsonUtf8EncoderSink extends ChunkedConversionSink { _sink.addSlice(chunk, start, end, false); } - void add(Object object) { + void add(Object? object) { if (_isDone) { throw StateError("Only one call to add allowed"); } @@ -473,7 +472,7 @@ class _JsonUtf8EncoderSink extends ChunkedConversionSink { } } -/// This class parses JSON strings and builds the corresponding value. +/// This class parses JSON strings and builds the corresponding objects. /// /// A JSON input must be the JSON encoding of a single JSON value, /// which can be a list or map containing other values. @@ -481,13 +480,14 @@ class _JsonUtf8EncoderSink extends ChunkedConversionSink { /// When used as a [StreamTransformer], the input stream may emit /// multiple strings. The concatenation of all of these strings must /// be a valid JSON encoding of a single JSON value. -class JsonDecoder extends Converter { - final Function(Object key, Object value) _reviver; +class JsonDecoder extends Converter { + final Object? Function(Object? key, Object? value)? _reviver; /// Constructs a new JsonDecoder. /// /// The [reviver] may be `null`. - const JsonDecoder([reviver(Object key, Object value)]) : _reviver = reviver; + const JsonDecoder([Object? reviver(Object? key, Object? value)?]) + : _reviver = reviver; /// Converts the given JSON-string [input] to its corresponding object. /// @@ -507,14 +507,14 @@ class JsonDecoder extends Converter { /// Starts a conversion from a chunked JSON string to its corresponding object. /// /// The output [sink] receives exactly one decoded element through `add`. - external StringConversionSink startChunkedConversion(Sink sink); + external StringConversionSink startChunkedConversion(Sink sink); // Override the base class's bind, to provide a better type. - Stream bind(Stream stream) => super.bind(stream); + Stream bind(Stream stream) => super.bind(stream); } // Internal optimized JSON parsing implementation. -external dynamic _parseJson(String source, reviver(key, value)); +external dynamic _parseJson(String source, reviver(key, value)?); // Implementation of encoder/stringifier. @@ -552,10 +552,10 @@ abstract class _JsonStringifier { /// Function called for each un-encodable object encountered. final Function(dynamic) _toEncodable; - _JsonStringifier(toEncodable(o)) + _JsonStringifier(dynamic toEncodable(dynamic o)?) : _toEncodable = toEncodable ?? _defaultToEncodable; - String get _partialResult; + String? get _partialResult; /// Append a string to the JSON output. void writeString(String characters); @@ -648,7 +648,7 @@ abstract class _JsonStringifier { /// /// Records the object if it isn't already seen. Should have a matching call to /// [_removeSeen] when the object is no longer being traversed. - void _checkCycle(object) { + void _checkCycle(Object? object) { for (var i = 0; i < _seen.length; i++) { if (identical(object, _seen[i])) { throw JsonCyclicError(object); @@ -661,7 +661,7 @@ abstract class _JsonStringifier { /// /// Should be called in the opposite order of the matching [_checkCycle] /// calls. - void _removeSeen(object) { + void _removeSeen(Object? object) { assert(_seen.isNotEmpty); assert(identical(_seen.last, object)); _seen.removeLast(); @@ -671,7 +671,7 @@ abstract class _JsonStringifier { /// /// If [object] isn't directly encodable, the [_toEncodable] function gets one /// chance to return a replacement which is encodable. - void writeObject(object) { + void writeObject(Object? object) { // Tries stringifying object directly. If it's not a simple value, List or // Map, call toJson() to get a custom representation and try serializing // that. @@ -693,7 +693,7 @@ abstract class _JsonStringifier { /// /// Returns true if the value is one of these types, and false if not. /// If a value is both a [List] and a [Map], it's serialized as a [List]. - bool writeJsonValue(object) { + bool writeJsonValue(Object? object) { if (object is num) { if (!object.isFinite) return false; writeNumber(object); @@ -729,7 +729,7 @@ abstract class _JsonStringifier { } /// Serialize a [List]. - void writeList(List list) { + void writeList(List list) { writeString('['); if (list.isNotEmpty) { writeObject(list[0]); @@ -742,12 +742,12 @@ abstract class _JsonStringifier { } /// Serialize a [Map]. - bool writeMap(Map map) { + bool writeMap(Map map) { if (map.isEmpty) { writeString("{}"); return true; } - var keyValueList = List(map.length * 2); + var keyValueList = List.filled(map.length * 2, null); var i = 0; var allStringKeys = true; map.forEach((key, value) { @@ -763,7 +763,7 @@ abstract class _JsonStringifier { for (var i = 0; i < keyValueList.length; i += 2) { writeString(separator); separator = ',"'; - writeStringContent(keyValueList[i]); + writeStringContent(keyValueList[i] as String); writeString('":'); writeObject(keyValueList[i + 1]); } @@ -782,7 +782,7 @@ abstract class _JsonPrettyPrintMixin implements _JsonStringifier { /// Add [indentLevel] indentations to the JSON output. void writeIndentation(int indentLevel); - void writeList(List list) { + void writeList(List list) { if (list.isEmpty) { writeString('[]'); } else { @@ -802,12 +802,12 @@ abstract class _JsonPrettyPrintMixin implements _JsonStringifier { } } - bool writeMap(Map map) { + bool writeMap(Map map) { if (map.isEmpty) { writeString("{}"); return true; } - var keyValueList = List(map.length * 2); + var keyValueList = List.filled(map.length * 2, null); var i = 0; var allStringKeys = true; map.forEach((key, value) { @@ -826,7 +826,7 @@ abstract class _JsonPrettyPrintMixin implements _JsonStringifier { separator = ",\n"; writeIndentation(_indentLevel); writeString('"'); - writeStringContent(keyValueList[i]); + writeStringContent(keyValueList[i] as String); writeString('": '); writeObject(keyValueList[i + 1]); } @@ -842,7 +842,8 @@ abstract class _JsonPrettyPrintMixin implements _JsonStringifier { class _JsonStringStringifier extends _JsonStringifier { final StringSink _sink; - _JsonStringStringifier(this._sink, dynamic Function(dynamic) _toEncodable) + _JsonStringStringifier( + this._sink, dynamic Function(dynamic object)? _toEncodable) : super(_toEncodable); /// Convert object to a string. @@ -854,7 +855,8 @@ class _JsonStringStringifier extends _JsonStringifier { /// with newlines and indentation. The `indent` string is added as indentation /// for each indentation level. It should only contain valid JSON whitespace /// characters (space, tab, carriage return or line feed). - static String stringify(object, toEncodable(o), String indent) { + static String stringify( + Object? object, dynamic toEncodable(dynamic object)?, String? indent) { var output = StringBuffer(); printOn(object, output, toEncodable, indent); return output.toString(); @@ -863,8 +865,8 @@ class _JsonStringStringifier extends _JsonStringifier { /// Convert object to a string, and write the result to the [output] sink. /// /// The result is written piecemally to the sink. - static void printOn( - object, StringSink output, toEncodable(o), String indent) { + static void printOn(Object? object, StringSink output, + dynamic toEncodable(dynamic o)?, String? indent) { _JsonStringifier stringifier; if (indent == null) { stringifier = _JsonStringStringifier(output, toEncodable); @@ -874,7 +876,7 @@ class _JsonStringStringifier extends _JsonStringifier { stringifier.writeObject(object); } - String get _partialResult => _sink is StringBuffer ? _sink.toString() : null; + String? get _partialResult => _sink is StringBuffer ? _sink.toString() : null; void writeNumber(num number) { _sink.write(number.toString()); @@ -897,7 +899,8 @@ class _JsonStringStringifierPretty extends _JsonStringStringifier with _JsonPrettyPrintMixin { final String _indent; - _JsonStringStringifierPretty(StringSink sink, toEncodable(o), this._indent) + _JsonStringStringifierPretty( + StringSink sink, dynamic toEncodable(dynamic o)?, this._indent) : super(sink, toEncodable); void writeIndentation(int count) { @@ -915,7 +918,8 @@ class _JsonUtf8Stringifier extends _JsonStringifier { Uint8List buffer; int index = 0; - _JsonUtf8Stringifier(toEncodable(o), this.bufferSize, this.addChunk) + _JsonUtf8Stringifier( + dynamic toEncodable(dynamic o)?, this.bufferSize, this.addChunk) : buffer = Uint8List(bufferSize), super(toEncodable); @@ -928,8 +932,12 @@ class _JsonUtf8Stringifier extends _JsonStringifier { /// /// If [indent] is non-`null`, the result will be "pretty-printed" with extra /// newlines and indentation, using [indent] as the indentation. - static void stringify(Object object, List indent, toEncodable(o), - int bufferSize, void addChunk(Uint8List chunk, int start, int end)) { + static void stringify( + Object? object, + List? indent, + dynamic toEncodable(dynamic o)?, + int bufferSize, + void addChunk(Uint8List chunk, int start, int end)) { _JsonUtf8Stringifier stringifier; if (indent != null) { stringifier = @@ -947,11 +955,11 @@ class _JsonUtf8Stringifier extends _JsonStringifier { if (index > 0) { addChunk(buffer, 0, index); } - buffer = null; + buffer = Uint8List(0); index = 0; } - String get _partialResult => null; + String? get _partialResult => null; void writeNumber(num number) { writeAsciiString(number.toString()); @@ -975,7 +983,7 @@ class _JsonUtf8Stringifier extends _JsonStringifier { void writeStringSlice(String string, int start, int end) { // TODO(lrn): Optimize by copying directly into buffer instead of going // through writeCharCode/writeByte. Assumption is the most characters - // in starings are plain ASCII. + // in strings are plain ASCII. for (var i = start; i < end; i++) { var char = string.codeUnitAt(i); if (char <= 0x7f) { @@ -1049,8 +1057,8 @@ class _JsonUtf8Stringifier extends _JsonStringifier { class _JsonUtf8StringifierPretty extends _JsonUtf8Stringifier with _JsonPrettyPrintMixin { final List indent; - _JsonUtf8StringifierPretty(toEncodable(o), this.indent, int bufferSize, - void addChunk(Uint8List buffer, int start, int end)) + _JsonUtf8StringifierPretty(dynamic toEncodable(dynamic o)?, this.indent, + int bufferSize, void addChunk(Uint8List buffer, int start, int end)) : super(toEncodable, bufferSize, addChunk); void writeIndentation(int count) { diff --git a/sdk/lib/convert/latin1.dart b/sdk/lib/convert/latin1.dart index 06fa6811a94..f396682615b 100644 --- a/sdk/lib/convert/latin1.dart +++ b/sdk/lib/convert/latin1.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.convert; /// An instance of the default implementation of the [Latin1Codec]. @@ -49,9 +47,8 @@ class Latin1Codec extends Encoding { /// /// If [allowInvalid] is not provided, it defaults to the value used to create /// this [Latin1Codec]. - String decode(List bytes, {bool allowInvalid}) { - allowInvalid ??= _allowInvalid; - if (allowInvalid) { + String decode(List bytes, {bool? allowInvalid}) { + if (allowInvalid ?? _allowInvalid) { return const Latin1Decoder(allowInvalid: true).convert(bytes); } else { return const Latin1Decoder(allowInvalid: false).convert(bytes); @@ -102,11 +99,11 @@ class Latin1Decoder extends _UnicodeSubsetDecoder { } class _Latin1DecoderSink extends ByteConversionSinkBase { - StringConversionSink _sink; + StringConversionSink? _sink; _Latin1DecoderSink(this._sink); void close() { - _sink.close(); + _sink!.close(); _sink = null; } @@ -119,12 +116,12 @@ class _Latin1DecoderSink extends ByteConversionSinkBase { // _sink.addSlice(source, start, end, isLast). // The code below is an moderately stupid workaround until a real // solution can be made. - _sink.add(String.fromCharCodes(source, start, end)); + _sink!.add(String.fromCharCodes(source, start, end)); if (isLast) close(); } void addSlice(List source, int start, int end, bool isLast) { - end = RangeError.checkValidRange(start, end, source.length); + RangeError.checkValidRange(start, end, source.length); if (start == end) return; if (source is! Uint8List) { // List may contain value outside of the 0..255 range. If so, throw. diff --git a/sdk/lib/convert/line_splitter.dart b/sdk/lib/convert/line_splitter.dart index f51e53c3804..fa0be3f7fa4 100644 --- a/sdk/lib/convert/line_splitter.dart +++ b/sdk/lib/convert/line_splitter.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.convert; // Character constants. @@ -27,8 +25,12 @@ class LineSplitter extends StreamTransformerBase { /// `lines.substring(start, end)`. The [start] and [end] values must /// specify a valid sub-range of [lines] /// (`0 <= start <= end <= lines.length`). - static Iterable split(String lines, [int start = 0, int end]) sync* { + static Iterable split(String lines, [int start = 0, int? end]) sync* { end = RangeError.checkValidRange(start, end, lines.length); + // TODO(38725): Remove workaround when assignment promotion is implemented + if (end == null) { + throw RangeError("Invalid range"); + } var sliceStart = start; var char = 0; for (var i = start; i < end; i++) { @@ -92,7 +94,7 @@ class _LineSplitterSink extends StringConversionSinkBase { /// /// If the previous slice ended in a line without a line terminator, /// then the next slice may continue the line. - String _carry; + String? _carry; /// Whether to skip a leading LF character from the next slice. /// @@ -112,9 +114,10 @@ class _LineSplitterSink extends StringConversionSinkBase { if (isLast) close(); return; } - if (_carry != null) { + String? carry = _carry; + if (carry != null) { assert(!_skipLeadingLF); - chunk = _carry + chunk.substring(start, end); + chunk = carry + chunk.substring(start, end); start = 0; end = chunk.length; _carry = null; @@ -130,7 +133,7 @@ class _LineSplitterSink extends StringConversionSinkBase { void close() { if (_carry != null) { - _sink.add(_carry); + _sink.add(_carry!); _carry = null; } _sink.close(); @@ -168,7 +171,7 @@ class _LineSplitterEventSink extends _LineSplitterSink : _eventSink = eventSink, super(StringConversionSink.from(eventSink)); - void addError(Object o, [StackTrace stackTrace]) { + void addError(Object o, [StackTrace? stackTrace]) { _eventSink.addError(o, stackTrace); } } diff --git a/sdk/lib/convert/string_conversion.dart b/sdk/lib/convert/string_conversion.dart index 6c7d96562a3..2315330aaa9 100644 --- a/sdk/lib/convert/string_conversion.dart +++ b/sdk/lib/convert/string_conversion.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.convert; /// This class provides an interface for converters to @@ -81,11 +79,11 @@ class _ClosableStringSink implements ClosableStringSink { _sink.writeCharCode(charCode); } - void write(Object o) { + void write(Object? o) { _sink.write(o); } - void writeln([Object o = ""]) { + void writeln([Object? o = ""]) { _sink.writeln(o); } @@ -101,8 +99,8 @@ class _ClosableStringSink implements ClosableStringSink { class _StringConversionSinkAsStringSinkAdapter implements ClosableStringSink { static const _MIN_STRING_SIZE = 16; - StringBuffer _buffer; - StringConversionSink _chunkedSink; + final StringBuffer _buffer; + final StringConversionSink _chunkedSink; _StringConversionSinkAsStringSinkAdapter(this._chunkedSink) : _buffer = StringBuffer(); @@ -117,12 +115,12 @@ class _StringConversionSinkAsStringSinkAdapter implements ClosableStringSink { if (_buffer.length > _MIN_STRING_SIZE) _flush(); } - void write(Object o) { + void write(Object? o) { if (_buffer.isNotEmpty) _flush(); _chunkedSink.add(o.toString()); } - void writeln([Object o = ""]) { + void writeln([Object? o = ""]) { _buffer.writeln(o); if (_buffer.length > _MIN_STRING_SIZE) _flush(); } @@ -177,10 +175,11 @@ abstract class StringConversionSinkMixin implements StringConversionSink { /// This class is a [StringConversionSink] that wraps a [StringSink]. class _StringSinkConversionSink extends StringConversionSinkBase { - TStringSink _stringSink; + final TStringSink _stringSink; _StringSinkConversionSink(this._stringSink); void close() {} + void addSlice(String str, int start, int end, bool isLast) { if (start != 0 || end != str.length) { for (var i = start; i < end; i++) { @@ -211,6 +210,7 @@ class _StringSinkConversionSink /// This class can be used to terminate a chunked conversion. class _StringCallbackSink extends _StringSinkConversionSink { final void Function(String) _callback; + _StringCallbackSink(this._callback) : super(StringBuffer()); void close() { @@ -253,9 +253,11 @@ class _StringAdapterSink extends StringConversionSinkBase { } /// Decodes UTF-8 code units and stores them in a [StringSink]. +/// +/// The `Sink` provided is closed when this sink is closed. class _Utf8StringSinkAdapter extends ByteConversionSink { final _Utf8Decoder _decoder; - final Sink _sink; + final Sink _sink; final StringSink _stringSink; _Utf8StringSinkAdapter(this._sink, this._stringSink, bool allowMalformed) @@ -263,7 +265,7 @@ class _Utf8StringSinkAdapter extends ByteConversionSink { void close() { _decoder.flush(_stringSink); - if (_sink != null) _sink.close(); + _sink.close(); } void add(List chunk) { diff --git a/sdk/lib/convert/utf.dart b/sdk/lib/convert/utf.dart index c19bb37e90b..c74f918cfb7 100644 --- a/sdk/lib/convert/utf.dart +++ b/sdk/lib/convert/utf.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.convert; /// The Unicode Replacement character `U+FFFD` (�). @@ -56,10 +54,9 @@ class Utf8Codec extends Encoding { /// /// If [allowMalformed] is not given, it defaults to the `allowMalformed` that /// was used to instantiate `this`. - String decode(List codeUnits, {bool allowMalformed}) { - allowMalformed ??= _allowMalformed; + String decode(List codeUnits, {bool? allowMalformed}) { // Switch between const objects to avoid allocation. - Utf8Decoder decoder = allowMalformed + Utf8Decoder decoder = allowMalformed ?? _allowMalformed ? const Utf8Decoder(allowMalformed: true) : const Utf8Decoder(allowMalformed: false); return decoder.convert(codeUnits); @@ -87,9 +84,13 @@ class Utf8Encoder extends Converter> { /// /// Any unpaired surrogate character (`U+D800`-`U+DFFF`) in the input string /// is encoded as a Unicode Replacement character `U+FFFD` (�). - Uint8List convert(String string, [int start = 0, int end]) { + Uint8List convert(String string, [int start = 0, int? end]) { var stringLength = string.length; end = RangeError.checkValidRange(start, end, stringLength); + // TODO(38725): Remove workaround when assignment promotion is implemented + if (end == null) { + throw RangeError("Invalid range"); + } var length = end - start; if (length == 0) return Uint8List(0); // Create a new encoder with a length that is guaranteed to be big enough. @@ -309,7 +310,7 @@ class Utf8Decoder extends Converter, String> { /// /// If the [codeUnits] start with the encoding of a /// [unicodeBomCharacterRune], that character is discarded. - String convert(List codeUnits, [int start = 0, int end]) { + String convert(List codeUnits, [int start = 0, int? end]) { // Allow the implementation to intercept and specialize based on the type // of codeUnits. var result = _convertIntercepted(_allowMalformed, codeUnits, start, end); @@ -339,8 +340,8 @@ class Utf8Decoder extends Converter, String> { external Converter, T> fuse(Converter next); - external static String _convertIntercepted( - bool allowMalformed, List codeUnits, int start, int end); + external static String? _convertIntercepted( + bool allowMalformed, List codeUnits, int start, int? end); } // UTF-8 constants. @@ -519,12 +520,12 @@ class _Utf8Decoder { external _Utf8Decoder(bool allowMalformed); - external String convertSingle(List codeUnits, int start, int maybeEnd); + external String convertSingle(List codeUnits, int start, int? maybeEnd); - external String convertChunked(List codeUnits, int start, int maybeEnd); + external String convertChunked(List codeUnits, int start, int? maybeEnd); String convertGeneral( - List codeUnits, int start, int maybeEnd, bool single) { + List codeUnits, int start, int? maybeEnd, bool single) { int end = RangeError.checkValidRange(start, maybeEnd, codeUnits.length); if (start == end) return ""; diff --git a/sdk/lib/core/annotations.dart b/sdk/lib/core/annotations.dart index 6c39fcf62f1..f4076833d99 100644 --- a/sdk/lib/core/annotations.dart +++ b/sdk/lib/core/annotations.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.core; /** @@ -122,8 +120,8 @@ const Object override = _Override(); */ @deprecated class Provisional { - String get message => null; - const Provisional({String message}); + String? get message => null; + const Provisional({String? message}); } /** @@ -233,10 +231,10 @@ class pragma { final String name; /** Optional extra data parameterizing the hint. */ - final Object options; + final Object? options; /** Creates a hint named [name] with optional [options]. */ - const factory pragma(String name, [Object options]) = pragma._; + const factory pragma(String name, [Object? options]) = pragma._; const pragma._(this.name, [this.options]); } diff --git a/sdk/lib/core/bigint.dart b/sdk/lib/core/bigint.dart index c3f261bec08..94a9445ebca 100644 --- a/sdk/lib/core/bigint.dart +++ b/sdk/lib/core/bigint.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.core; /** @@ -37,7 +35,7 @@ abstract class BigInt implements Comparable { * Throws a [FormatException] if the [source] is not a valid integer literal, * optionally prefixed by a sign. */ - external static BigInt parse(String source, {int radix}); + external static BigInt parse(String source, {int? radix}); /** * Parses [source] as a, possibly signed, integer literal and returns its @@ -46,7 +44,7 @@ abstract class BigInt implements Comparable { * As [parse] except that this method returns `null` if the input is not * valid */ - external static BigInt tryParse(String source, {int radix}); + external static BigInt? tryParse(String source, {int? radix}); /// Allocates a big integer from the provided [value] number. external factory BigInt.from(num value); diff --git a/sdk/lib/core/bool.dart b/sdk/lib/core/bool.dart index ae8341ba8a3..3d35d8011cd 100644 --- a/sdk/lib/core/bool.dart +++ b/sdk/lib/core/bool.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.core; /** @@ -85,21 +83,20 @@ class bool { /// The logical conjunction ("and") of this and [other]. /// /// Returns `true` if both this and [other] are `true`, and `false` otherwise. - //TODO(lrn): Remove "as bool" in Dart 2. @Since("2.1") - bool operator &(bool other) => (other as bool) && this; + bool operator &(bool other) => other && this; /// The logical disjunction ("inclusive or") of this and [other]. /// /// Returns `true` if either this or [other] is `true`, and `false` otherwise. @Since("2.1") - bool operator |(bool other) => (other as bool) || this; + bool operator |(bool other) => other || this; /// The logical exclusive disjunction ("exclusive or") of this and [other]. /// /// Returns whether this and [other] are neither both `true` nor both `false`. @Since("2.1") - bool operator ^(bool other) => !(other as bool) == this; + bool operator ^(bool other) => !other == this; /** * Returns either `"true"` for `true` and `"false"` for `false`. diff --git a/sdk/lib/core/comparable.dart b/sdk/lib/core/comparable.dart index 08bb965535b..835aa34b1f6 100644 --- a/sdk/lib/core/comparable.dart +++ b/sdk/lib/core/comparable.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.core; /** diff --git a/sdk/lib/core/core.dart b/sdk/lib/core/core.dart index 7d671325bda..dc037a377df 100644 --- a/sdk/lib/core/core.dart +++ b/sdk/lib/core/core.dart @@ -2,8 +2,6 @@ // 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.6 - /** * * Built-in types, collections, @@ -169,7 +167,7 @@ import "dart:convert" StringConversionSink, utf8; import "dart:math" show Random; // Used by List.shuffle. -import "dart:typed_data" show Uint8List, Uint16List, Endian; +import "dart:typed_data" show Uint8List; @Since("2.1") export "dart:async" show Future, Stream; diff --git a/sdk/lib/core/date_time.dart b/sdk/lib/core/date_time.dart index b36aa3f186e..ae139229566 100644 --- a/sdk/lib/core/date_time.dart +++ b/sdk/lib/core/date_time.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.core; /** @@ -279,9 +277,9 @@ class DateTime implements Comparable { // Or not, that may be a breaking change. static DateTime parse(String formattedString) { var re = _parseFormat; - Match match = re.firstMatch(formattedString); + Match? match = re.firstMatch(formattedString); if (match != null) { - int parseIntOrZero(String matched) { + int parseIntOrZero(String? matched) { if (matched == null) return 0; return int.parse(matched); } @@ -289,7 +287,7 @@ class DateTime implements Comparable { // Parses fractional second digits of '.(\d+)' into the combined // microseconds. We only use the first 6 digits because of DateTime // precision of 999 milliseconds and 999 microseconds. - int parseMilliAndMicroseconds(String matched) { + int parseMilliAndMicroseconds(String? matched) { if (matched == null) return 0; int length = matched.length; assert(length >= 1); @@ -303,31 +301,32 @@ class DateTime implements Comparable { return result; } - int years = int.parse(match[1]); - int month = int.parse(match[2]); - int day = int.parse(match[3]); + int years = int.parse(match[1]!); + int month = int.parse(match[2]!); + int day = int.parse(match[3]!); int hour = parseIntOrZero(match[4]); int minute = parseIntOrZero(match[5]); int second = parseIntOrZero(match[6]); int milliAndMicroseconds = parseMilliAndMicroseconds(match[7]); int millisecond = milliAndMicroseconds ~/ Duration.microsecondsPerMillisecond; - int microsecond = - milliAndMicroseconds.remainder(Duration.microsecondsPerMillisecond); + int microsecond = milliAndMicroseconds + .remainder(Duration.microsecondsPerMillisecond) as int; bool isUtc = false; if (match[8] != null) { // timezone part isUtc = true; - if (match[9] != null) { + String? tzSign = match[9]; + if (tzSign != null) { // timezone other than 'Z' and 'z'. - int sign = (match[9] == '-') ? -1 : 1; - int hourDifference = int.parse(match[10]); + int sign = (tzSign == '-') ? -1 : 1; + int hourDifference = int.parse(match[10]!); int minuteDifference = parseIntOrZero(match[11]); minuteDifference += 60 * hourDifference; minute -= sign * minuteDifference; } } - int value = _brokenDownDateToValue(years, month, day, hour, minute, + int? value = _brokenDownDateToValue(years, month, day, hour, minute, second, millisecond, microsecond, isUtc); if (value == null) { throw FormatException("Time out of range", formattedString); @@ -344,7 +343,7 @@ class DateTime implements Comparable { * Works like [parse] except that this function returns `null` * where [parse] would throw a [FormatException]. */ - static DateTime tryParse(String formattedString) { + static DateTime? tryParse(String formattedString) { // TODO: Optimize to avoid throwing. try { return parse(formattedString); @@ -386,13 +385,14 @@ class DateTime implements Comparable { * * If [isUtc] is false then the date is in the local time zone. */ - DateTime._withValue(this._value, {this.isUtc}) { + DateTime._withValue(this._value, {required this.isUtc}) { if (millisecondsSinceEpoch.abs() > _maxMillisecondsSinceEpoch || (millisecondsSinceEpoch.abs() == _maxMillisecondsSinceEpoch && microsecond != 0)) { throw ArgumentError( "DateTime is outside valid range: $millisecondsSinceEpoch"); } + // For backwards compatibility with legacy mode. ArgumentError.checkNotNull(isUtc, "isUtc"); } @@ -411,7 +411,7 @@ class DateTime implements Comparable { * See [isAtSameMomentAs] for a comparison that compares moments in time * independently of their zones. */ - external bool operator ==(dynamic other); + external bool operator ==(Object other); /** * Returns true if [this] occurs before [other]. @@ -693,7 +693,7 @@ class DateTime implements Comparable { /// Returns the time as value (millisecond or microsecond since epoch), or /// null if the values are out of range. - external static int _brokenDownDateToValue( + external static int? _brokenDownDateToValue( int year, int month, int day, diff --git a/sdk/lib/core/double.dart b/sdk/lib/core/double.dart index 18f782fbc35..42ff5661f99 100644 --- a/sdk/lib/core/double.dart +++ b/sdk/lib/core/double.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.core; // TODO: Convert this abstract class into a concrete class double @@ -208,7 +206,7 @@ abstract class double extends num { * you should use `double.tryParse(string) ?? (...)`. */ external static double parse(String source, - [@deprecated double onError(String source)]); + [@deprecated double onError(String source)?]); /** * Parse [source] as an double literal and return its value. @@ -216,5 +214,5 @@ abstract class double extends num { * Like [parse] except that this function returns `null` for invalid inputs * instead of throwing, and the [source] must still not be `null`. */ - external static double tryParse(String source); + external static double? tryParse(String source); } diff --git a/sdk/lib/core/duration.dart b/sdk/lib/core/duration.dart index eeb03374e9a..2a1f406c35d 100644 --- a/sdk/lib/core/duration.dart +++ b/sdk/lib/core/duration.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.core; /** @@ -215,7 +213,7 @@ class Duration implements Comparable { /** * Returns `true` if this [Duration] has the same value as [other]. */ - bool operator ==(dynamic other) => + bool operator ==(Object other) => other is Duration && _duration == other.inMicroseconds; int get hashCode => _duration.hashCode; @@ -260,10 +258,12 @@ class Duration implements Comparable { if (inMicroseconds < 0) { return "-${-this}"; } - String twoDigitMinutes = twoDigits(inMinutes.remainder(minutesPerHour)); - String twoDigitSeconds = twoDigits(inSeconds.remainder(secondsPerMinute)); + String twoDigitMinutes = + twoDigits(inMinutes.remainder(minutesPerHour) as int); + String twoDigitSeconds = + twoDigits(inSeconds.remainder(secondsPerMinute) as int); String sixDigitUs = - sixDigits(inMicroseconds.remainder(microsecondsPerSecond)); + sixDigits(inMicroseconds.remainder(microsecondsPerSecond) as int); return "$inHours:$twoDigitMinutes:$twoDigitSeconds.$sixDigitUs"; } diff --git a/sdk/lib/core/errors.dart b/sdk/lib/core/errors.dart index ac585de8ae5..a84c6ee35f6 100644 --- a/sdk/lib/core/errors.dart +++ b/sdk/lib/core/errors.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.core; /** @@ -76,7 +74,7 @@ class Error { * The conversion is guaranteed to not throw, so it won't use the object's * toString method. */ - static String safeToString(Object object) { + static String safeToString(Object? object) { if (object is num || object is bool || null == object) { return object.toString(); } @@ -91,7 +89,7 @@ class Error { external static String _objectToString(Object object); - external StackTrace get stackTrace; + external StackTrace? get stackTrace; } /** @@ -99,7 +97,7 @@ class Error { */ class AssertionError extends Error { /** Message describing the assertion error. */ - final Object message; + final Object? message; AssertionError([this.message]); @@ -123,7 +121,7 @@ class TypeError extends Error {} class CastError extends Error {} /** - * Error thrown when attempting to throw [:null:]. + * Error thrown when attempting to throw `null`. */ class NullThrownError extends Error { @pragma("vm:entry-point") @@ -138,11 +136,11 @@ class ArgumentError extends Error { /** Whether value was provided. */ final bool _hasValue; /** The invalid value. */ - final invalidValue; + final dynamic invalidValue; /** Name of the invalid argument, if available. */ - final String name; + final String? name; /** Message describing the problem. */ - final message; + final dynamic message; /** * The [message] describes the erroneous argument. @@ -192,7 +190,7 @@ class ArgumentError extends Error { * Returns the [argument] if it is not null. */ @Since("2.1") - static T checkNotNull<@Since("2.8") T>(T argument, [String name]) { + static T checkNotNull<@Since("2.8") T>(T? argument, [String? name]) { if (argument == null) throw ArgumentError.notNull(name); return argument; } @@ -202,12 +200,11 @@ class ArgumentError extends Error { String get _errorExplanation => ""; String toString() { - String nameString = ""; - if (name != null) { - nameString = " ($name)"; - } - var message = (this.message == null) ? "" : ": ${this.message}"; - String prefix = "$_errorName$nameString$message"; + String? name = this.name; + String nameString = (name == null) ? "" : " ($name)"; + Object? message = this.message; + var messageString = (message == null) ? "" : ": ${message}"; + String prefix = "$_errorName$nameString$messageString"; if (!_hasValue) return prefix; // If we know the invalid value, we can try to describe the problem. String explanation = _errorExplanation; @@ -221,9 +218,9 @@ class ArgumentError extends Error { */ class RangeError extends ArgumentError { /** The minimum value that [value] is allowed to assume. */ - final num start; + final num? start; /** The maximum value that [value] is allowed to assume. */ - final num end; + final num? end; // TODO(lrn): This constructor should be called only with string values. // It currently isn't in all cases. @@ -243,11 +240,10 @@ class RangeError extends ArgumentError { * invalid value, and the [message] can override the default error * description. */ - RangeError.value(num value, [String name, String message]) + RangeError.value(num value, [String? name, String? message]) : start = null, end = null, - super.value( - value, name, (message != null) ? message : "Value not in range"); + super.value(value, name, message ?? "Value not in range"); /** * Create a new [RangeError] for a value being outside the valid range. @@ -264,12 +260,11 @@ class RangeError extends ArgumentError { * description. */ @pragma("vm:entry-point") - RangeError.range(num invalidValue, int minValue, int maxValue, - [String name, String message]) + RangeError.range(num invalidValue, int? minValue, int? maxValue, + [String? name, String? message]) : start = minValue, end = maxValue, - super.value( - invalidValue, name, (message != null) ? message : "Invalid value"); + super.value(invalidValue, name, message ?? "Invalid value"); /** * Creates a new [RangeError] stating that [index] is not a valid index @@ -283,7 +278,7 @@ class RangeError extends ArgumentError { * If `length` is omitted, it defaults to `indexable.length`. */ factory RangeError.index(int index, dynamic indexable, - [String name, String message, int length]) = IndexError; + [String? name, String? message, int? length]) = IndexError; /** * Check that an integer [value] lies in a specific interval. @@ -297,7 +292,7 @@ class RangeError extends ArgumentError { * Returns [value] if it is in the interval. */ static int checkValueInInterval(int value, int minValue, int maxValue, - [String name, String message]) { + [String? name, String? message]) { if (value < minValue || value > maxValue) { throw RangeError.range(value, minValue, maxValue, name, message); } @@ -322,8 +317,8 @@ class RangeError extends ArgumentError { * Returns [index] if it is a valid index. */ static int checkValidIndex(int index, dynamic indexable, - [String name, int length, String message]) { - length ??= indexable.length; + [String? name, int? length, String? message]) { + length ??= (indexable.length as int); // Comparing with `0` as receiver produces better dart2js type inference. if (0 > index || index >= length) { name ??= "index"; @@ -348,8 +343,8 @@ class RangeError extends ArgumentError { * Returns the actual `end` value, which is `length` if `end` is `null`, * and `end` otherwise. */ - static int checkValidRange(int start, int end, int length, - [String startName, String endName, String message]) { + static int checkValidRange(int start, int? end, int length, + [String? startName, String? endName, String? message]) { // Comparing with `0` as receiver produces better dart2js type inference. // Ditto `start > end` below. if (0 > start || start > length) { @@ -377,7 +372,7 @@ class RangeError extends ArgumentError { * * Returns [value] if it is not negative. */ - static int checkNotNegative(int value, [String name, String message]) { + static int checkNotNegative(int value, [String? name, String? message]) { if (value < 0) throw RangeError.range(value, 0, null, name, message); return value; } @@ -386,6 +381,8 @@ class RangeError extends ArgumentError { String get _errorExplanation { assert(_hasValue); String explanation = ""; + num? start = this.start; + num? end = this.end; if (start == null) { if (end != null) { explanation = ": Not less than or equal to $end"; @@ -428,11 +425,10 @@ class IndexError extends ArgumentError implements RangeError { * The message is used as part of the string representation of the error. */ IndexError(int invalidValue, dynamic indexable, - [String name, String message, int length]) + [String? name, String? message, int? length]) : this.indexable = indexable, this.length = length ?? indexable.length, - super.value(invalidValue, name, - (message != null) ? message : "Index out of range"); + super.value(invalidValue, name, message ?? "Index out of range"); // Getters inherited from RangeError. int get start => 0; @@ -492,7 +488,7 @@ class NoSuchMethodError extends Error { * should not be `null`. */ external NoSuchMethodError.withInvocation( - Object receiver, Invocation invocation); + Object? receiver, Invocation invocation); // Deprecated constructor to be removed after dart2js updates to the above. /** @@ -511,16 +507,16 @@ class NoSuchMethodError extends Error { * empty list. * * The [namedArguments] is a map from [Symbol]s to the values of named - * arguments that the method was called with. + * arguments that the method was called with. If null, it is considered + * equivalent to the empty map. * * This constructor does not handle type arguments. * To include type variables, create an [Invocation] and use * [NoSuchMethodError.withInvocation]. */ @Deprecated("Use NoSuchMethod.withInvocation instead") - external NoSuchMethodError(Object receiver, Symbol memberName, - List positionalArguments, Map namedArguments, - [@deprecated List existingArgumentNames]); + external NoSuchMethodError(Object? receiver, Symbol memberName, + List? positionalArguments, Map? namedArguments); external String toString(); } @@ -533,9 +529,9 @@ class NoSuchMethodError extends Error { */ @pragma("vm:entry-point") class UnsupportedError extends Error { - final String message; + final String? message; @pragma("vm:entry-point") - UnsupportedError(this.message); + UnsupportedError(String this.message); String toString() => "Unsupported operation: $message"; } @@ -550,11 +546,14 @@ class UnsupportedError extends Error { * use during development. */ class UnimplementedError extends Error implements UnsupportedError { - final String message; + final String? message; UnimplementedError([this.message]); - String toString() => (this.message != null - ? "UnimplementedError: $message" - : "UnimplementedError"); + String toString() { + var message = this.message; + return (message != null) + ? "UnimplementedError: $message" + : "UnimplementedError"; + } } /** @@ -578,7 +577,7 @@ class StateError extends Error { */ class ConcurrentModificationError extends Error { /** The object that was modified in an incompatible way. */ - final Object modifiedObject; + final Object? modifiedObject; ConcurrentModificationError([this.modifiedObject]); @@ -596,7 +595,7 @@ class OutOfMemoryError implements Error { const OutOfMemoryError(); String toString() => "Out of Memory"; - StackTrace get stackTrace => null; + StackTrace? get stackTrace => null; } class StackOverflowError implements Error { @@ -604,7 +603,7 @@ class StackOverflowError implements Error { const StackOverflowError(); String toString() => "Stack Overflow"; - StackTrace get stackTrace => null; + StackTrace? get stackTrace => null; } /** @@ -615,12 +614,15 @@ class StackOverflowError implements Error { * another read of the variable, this error is thrown. */ class CyclicInitializationError extends Error { - final String variableName; + final String? variableName; @pragma("vm:entry-point") CyclicInitializationError([this.variableName]); - String toString() => variableName == null - ? "Reading static variable during its initialization" - : "Reading static variable '$variableName' during its initialization"; + String toString() { + var variableName = this.variableName; + return variableName == null + ? "Reading static variable during its initialization" + : "Reading static variable '$variableName' during its initialization"; + } } /** diff --git a/sdk/lib/core/exceptions.dart b/sdk/lib/core/exceptions.dart index ef66d15b423..7d76a665504 100644 --- a/sdk/lib/core/exceptions.dart +++ b/sdk/lib/core/exceptions.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.core; // Exceptions are thrown either by the VM or from Dart code. @@ -26,11 +24,12 @@ abstract class Exception { /** Default implementation of [Exception] which carries a message. */ class _Exception implements Exception { - final message; + final dynamic message; _Exception([this.message]); String toString() { + Object? message = this.message; if (message == null) return "Exception"; return "Exception: $message"; } @@ -54,7 +53,7 @@ class FormatException implements Exception { * * The source is `null` if omitted or unknown. */ - final source; + final dynamic source; /** * The offset in [source] where the error was detected. @@ -69,7 +68,7 @@ class FormatException implements Exception { * * May be omitted. If present, [source] should also be present if possible. */ - final int offset; + final int? offset; /** * Creates a new FormatException with an optional error [message]. @@ -97,13 +96,13 @@ class FormatException implements Exception { */ String toString() { String report = "FormatException"; + Object? message = this.message; if (message != null && "" != message) { report = "$report: $message"; } - int offset = this.offset; - Object objectSource = this.source; - if (objectSource is String) { - String source = objectSource; + int? offset = this.offset; + Object? source = this.source; + if (source is String) { if (offset != null && (offset < 0 || offset > source.length)) { offset = null; } diff --git a/sdk/lib/core/expando.dart b/sdk/lib/core/expando.dart index 2ccb07d4e46..ac36b9b7a9d 100644 --- a/sdk/lib/core/expando.dart +++ b/sdk/lib/core/expando.dart @@ -2,14 +2,12 @@ // 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.6 - part of dart.core; /** * An [Expando] allows adding new properties to objects. * - * Does not work on numbers, strings, booleans or null. + * Does not work on numbers, strings, booleans or `null`. * * An `Expando` does not hold on to the added property value after an object * becomes inaccessible. @@ -17,19 +15,19 @@ part of dart.core; * Since you can always create a new number that is identical to an existing * number, it means that an expando property on a number could never be * released. To avoid this, expando properties cannot be added to numbers. - * The same argument applies to strings, booleans and null, which also have + * The same argument applies to strings, booleans and `null`, which also have * literals that evaluate to identical values when they occur more than once. * * There is no restriction on other classes, even for compile time constant * objects. Be careful if adding expando properties to compile time constants, * since they will stay alive forever. */ -class Expando { +class Expando { /** * The name of the this [Expando] as passed to the constructor. If - * no name was passed to the constructor, the name is [:null:]. + * no name was passed to the constructor, the name is `null`. */ - final String name; + final String? name; /** * Creates a new [Expando]. The optional name is only used for @@ -37,21 +35,21 @@ class Expando { * same name yields two [Expando]s that work on different properties * of the objects they are used on. */ - external Expando([String name]); + external Expando([String? name]); /** * Expando toString method override. */ - String toString() => "Expando:$name"; + String toString() => "Expando:${name.toString()}"; /** * Gets the value of this [Expando]'s property on the given * object. If the object hasn't been expanded, the method returns - * [:null:]. + * `null`. * * The object must not be a number, a string, a boolean or null. */ - external T operator [](Object object); + external T? operator [](Object object); /** * Sets the value of this [Expando]'s property on the given @@ -60,5 +58,5 @@ class Expando { * * The object must not be a number, a string, a boolean or null. */ - external void operator []=(Object object, T value); + external void operator []=(Object object, T? value); } diff --git a/sdk/lib/core/function.dart b/sdk/lib/core/function.dart index 4e026f88c91..b21f6759e45 100644 --- a/sdk/lib/core/function.dart +++ b/sdk/lib/core/function.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.core; /** @@ -36,8 +34,8 @@ abstract class Function { * If [positionalArguments] is null, it's considered an empty list. * If [namedArguments] is omitted or null, it is considered an empty map. */ - external static apply(Function function, List positionalArguments, - [Map namedArguments]); + external static apply(Function function, List? positionalArguments, + [Map? namedArguments]); /** * Returns a hash code value that is compatible with `operator==`. @@ -47,23 +45,26 @@ abstract class Function { /** * Test whether another object is equal to this function. * - * System-created function objects are only equal to other functions. + * Function objects are only equal to other function objects + * (an object satisfying `object is Function`), + * and never to non-function objects. * - * Two function objects are known to represent the same function if + * Some function objects are considered equal by `==` + * because they are recognized as representing the "same function": * * - It is the same object. Static and top-level functions are compile time * constants when used as values, so referring to the same function twice - * always give the same object, - * - or if they refer to the same member method extracted from the same object. - * Extracting a member method as a function value twice gives equal, but - * not necessarily identical, function values. + * always give the same object, as does referring to a local function + * declaration twice in the same scope where it was declared. + * - if they refer to the same member method extracted from the same object. + * Repeatedly extracting an instance method of an object as a function value + * gives equal, but not necessarily identical, function values. * - * Function expressions never give rise to equal function objects. Each time - * a function expression is evaluated, it creates a new closure value that - * is not known to be equal to other closures created by the same expression. - * - * Classes implementing `Function` by having a `call` method should have their - * own `operator==` and `hashCode` depending on the object. + * Different evaluations of function literals + * never give rise to equal function objects. + * Each time a function literal is evaluated, + * it creates a new function value that is not equal to any other function + * value, not even ones created by the same expression. */ bool operator ==(Object other); } diff --git a/sdk/lib/core/identical.dart b/sdk/lib/core/identical.dart index ec24609593f..20d331ea5ff 100644 --- a/sdk/lib/core/identical.dart +++ b/sdk/lib/core/identical.dart @@ -2,14 +2,12 @@ // 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.6 - part of dart.core; /** * Check whether two references are to the same object. */ -external bool identical(Object a, Object b); +external bool identical(Object? a, Object? b); /** * Returns the identity hash code of `object`. @@ -21,4 +19,4 @@ external bool identical(Object a, Object b); * This hash code is compatible with [identical]. */ @pragma("vm:entry-point") -external int identityHashCode(Object object); +external int identityHashCode(Object? object); diff --git a/sdk/lib/core/int.dart b/sdk/lib/core/int.dart index 5416d03ff06..b1203ed3f1a 100644 --- a/sdk/lib/core/int.dart +++ b/sdk/lib/core/int.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.core; /** @@ -345,7 +343,7 @@ abstract class int extends num { * and the result of that call is returned by [parse]. */ external static int parse(String source, - {int radix, @deprecated int onError(String source)}); + {int? radix, @deprecated int onError(String source)?}); /** * Parse [source] as a, possibly signed, integer literal and return its value. @@ -354,5 +352,5 @@ abstract class int extends num { * similar call to [parse] would throw a [FormatException], * and the [source] must still not be `null`. */ - external static int tryParse(String source, {int radix}); + external static int? tryParse(String source, {int? radix}); } diff --git a/sdk/lib/core/invocation.dart b/sdk/lib/core/invocation.dart index 8b7df367282..7d28cea9dfd 100644 --- a/sdk/lib/core/invocation.dart +++ b/sdk/lib/core/invocation.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.core; /** @@ -23,8 +21,8 @@ abstract class Invocation { * If the named arguments are omitted, they default to no named arguments. */ factory Invocation.method( - Symbol memberName, Iterable positionalArguments, - [Map namedArguments]) => + Symbol memberName, Iterable? positionalArguments, + [Map? namedArguments]) => _Invocation.method(memberName, null, positionalArguments, namedArguments); /** @@ -37,8 +35,8 @@ abstract class Invocation { * If the named arguments are omitted, they default to no named arguments. */ factory Invocation.genericMethod(Symbol memberName, - Iterable typeArguments, Iterable positionalArguments, - [Map namedArguments]) => + Iterable? typeArguments, Iterable? positionalArguments, + [Map? namedArguments]) => _Invocation.method( memberName, typeArguments, positionalArguments, namedArguments); @@ -57,7 +55,7 @@ abstract class Invocation { * Invocation.setter(const Symbol("member="), value) * ``` */ - factory Invocation.setter(Symbol memberName, Object argument) = + factory Invocation.setter(Symbol memberName, Object? argument) = _Invocation.setter; /** The name of the invoked member. */ @@ -114,26 +112,28 @@ class _Invocation implements Invocation { final Symbol memberName; final List typeArguments; // Positional arguments is `null` for getters only. - final List _positional; + final List? _positional; // Named arguments is `null` for accessors only. - final Map _named; + final Map? _named; - _Invocation.method(this.memberName, Iterable types, - Iterable positional, Map named) - : typeArguments = _ensureNonNullTypes(_makeUnmodifiable(types)), - _positional = _makeUnmodifiable(positional) ?? const [], + _Invocation.method(this.memberName, Iterable? types, + Iterable? positional, Map? named) + : typeArguments = _ensureNonNullTypes(types), + _positional = positional == null + ? const [] + : List.unmodifiable(positional), _named = (named == null || named.isEmpty) - ? const {} - : Map.unmodifiable(named); + ? const {} + : Map.unmodifiable(named); _Invocation.getter(this.memberName) : typeArguments = const [], _positional = null, _named = null; - _Invocation.setter(this.memberName, Object argument) + _Invocation.setter(this.memberName, Object? argument) : typeArguments = const [], - _positional = List.unmodifiable([argument]), + _positional = List.unmodifiable([argument]), _named = null; List get positionalArguments => _positional ?? const []; @@ -146,19 +146,15 @@ class _Invocation implements Invocation { bool get isAccessor => _named == null; /// Checks that the elements of [types] are not null. - static List _ensureNonNullTypes(List types) { + static List _ensureNonNullTypes(Iterable? types) { if (types == null) return const []; - for (int i = 0; i < types.length; i++) { - if (types[i] == null) { - throw ArgumentError( + List typeArguments = List.unmodifiable(types); + for (int i = 0; i < typeArguments.length; i++) { + if (typeArguments[i] == null) { + throw ArgumentError.value(types, "types", "Type arguments must be non-null, was null at index $i."); } } - return types; - } - - static List _makeUnmodifiable(Iterable elements) { - if (elements == null) return null; - return List.unmodifiable(elements); + return typeArguments; } } diff --git a/sdk/lib/core/iterable.dart b/sdk/lib/core/iterable.dart index 382b6d3688e..839792ec857 100644 --- a/sdk/lib/core/iterable.dart +++ b/sdk/lib/core/iterable.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.core; /** @@ -15,8 +13,12 @@ part of dart.core; * and if the call returns `true`, * the iterator has now moved to the next element, * which is then available as [Iterator.current]. - * If the call returns `false`, there are no more elements, - * and `iterator.current` returns `null`. + * If the call returns `false`, there are no more elements. + * The [Iterator.current] value must only be used when the most + * recent call to [Iterator.moveNext] has returned `true`. + * If it is used before calling [Iterator.moveNext] the first time + * on an iterator, or after a call has returned false or has thrown an error, + * reading [Iterator.current] may throw or may return an arbitrary value. * * You can create more than one iterator from the same `Iterable`. * Each time `iterator` is read, it returns a new iterator, @@ -101,7 +103,7 @@ abstract class Iterable { * As an `Iterable`, `new Iterable.generate(n, generator))` is equivalent to * `const [0, ..., n - 1].map(generator)`. */ - factory Iterable.generate(int count, [E generator(int index)]) { + factory Iterable.generate(int count, [E generator(int index)?]) { if (count <= 0) return EmptyIterable(); return _GeneratorIterable(count, generator); } @@ -166,6 +168,7 @@ abstract class Iterable { * the type [R], e.g., from [toList], it will have exactly the type [R]. */ Iterable cast() => Iterable.castFrom(this); + /** * Returns the lazy concatentation of this iterable and [other]. * @@ -174,8 +177,9 @@ abstract class Iterable { * original iterables. */ Iterable followedBy(Iterable other) { - if (this is EfficientLengthIterable) { - return FollowedByIterable.firstEfficient(this, other); + var self = this; // TODO(lrn): Remove when we can promote `this`. + if (self is EfficientLengthIterable) { + return FollowedByIterable.firstEfficient(self, other); } return FollowedByIterable(this, other); } @@ -264,7 +268,7 @@ abstract class Iterable { * Likewise the `Iterable` returned by a [Map.keys] call * should use the same equality that the `Map` uses for keys. */ - bool contains(Object element) { + bool contains(Object? element) { for (E e in this) { if (e == element) return true; } @@ -365,13 +369,13 @@ abstract class Iterable { StringBuffer buffer = StringBuffer(); if (separator == null || separator == "") { do { - buffer.write("${iterator.current}"); + buffer.write(iterator.current.toString()); } while (iterator.moveNext()); } else { - buffer.write("${iterator.current}"); + buffer.write(iterator.current.toString()); while (iterator.moveNext()) { buffer.write(separator); - buffer.write("${iterator.current}"); + buffer.write(iterator.current.toString()); } } return buffer.toString(); @@ -397,7 +401,7 @@ abstract class Iterable { * The list is fixed-length if [growable] is false. */ List toList({bool growable = true}) { - return List.from(this, growable: growable); + return List.of(this, growable: growable); } /** @@ -409,7 +413,7 @@ abstract class Iterable { * The order of the elements in the set is not guaranteed to be the same * as for the iterable. */ - Set toSet() => Set.from(this); + Set toSet() => Set.of(this); /** * Returns the number of elements in [this]. @@ -566,7 +570,7 @@ abstract class Iterable { * function is returned. * If [orElse] is omitted, it defaults to throwing a [StateError]. */ - E firstWhere(bool test(E element), {E orElse()}) { + E firstWhere(bool test(E element), {E orElse()?}) { for (E element in this) { if (test(element)) return element; } @@ -588,8 +592,8 @@ abstract class Iterable { * function is returned. * If [orElse] is omitted, it defaults to throwing a [StateError]. */ - E lastWhere(bool test(E element), {E orElse()}) { - E result; + E lastWhere(bool test(E element), {E orElse()?}) { + late E result; bool foundMatching = false; for (E element in this) { if (test(element)) { @@ -611,8 +615,8 @@ abstract class Iterable { * If no matching element is found, returns the result of [orElse]. * If [orElse] is omitted, it defaults to throwing a [StateError]. */ - E singleWhere(bool test(E element), {E orElse()}) { - E result; + E singleWhere(bool test(E element), {E orElse()?}) { + late E result; bool foundMatching = false; for (E element in this) { if (test(element)) { @@ -640,7 +644,6 @@ abstract class Iterable { * Some iterables may have a more efficient way to find the element. */ E elementAt(int index) { - ArgumentError.checkNotNull(index, "index"); RangeError.checkNotNegative(index, "index"); int elementIndex = 0; for (E element in this) { @@ -669,22 +672,20 @@ abstract class Iterable { String toString() => IterableBase.iterableToShortString(this, '(', ')'); } -typedef _Generator = E Function(int index); - class _GeneratorIterable extends ListIterable { /// The length of the generated iterable. final int length; /// The function mapping indices to values. - final _Generator _generator; + final E Function(int) _generator; /// Creates the generated iterable. /// /// If [generator] is `null`, it is checked that `int` is assignable to [E]. - _GeneratorIterable(this.length, E generator(int index)) + _GeneratorIterable(this.length, E generator(int index)?) : // The `as` below is used as check to make sure that `int` is assignable // to [E]. - _generator = (generator != null) ? generator : _id as _Generator; + _generator = generator ?? (_id as E Function(int)); E elementAt(int index) { RangeError.checkValidIndex(index, this); @@ -696,14 +697,15 @@ class _GeneratorIterable extends ListIterable { } /** - * An Iterator that allows moving backwards as well as forwards. + * An [Iterator] that allows moving backwards as well as forwards. */ abstract class BidirectionalIterator implements Iterator { /** * Move back to the previous element. * * Returns true and updates [current] if successful. Returns false - * and sets [current] to null if there is no previous element. + * and updates [current] to an implementation defined state if there is no + * previous element */ bool movePrevious(); } diff --git a/sdk/lib/core/iterator.dart b/sdk/lib/core/iterator.dart index 1860497551f..f116c1be722 100644 --- a/sdk/lib/core/iterator.dart +++ b/sdk/lib/core/iterator.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.core; /** @@ -18,8 +16,11 @@ part of dart.core; * The `Iterator` is initially positioned before the first element. * Before accessing the first element the iterator must thus be advanced using * [moveNext] to point to the first element. - * If no element is left, then [moveNext] returns false, [current] - * returns `null`, and all further calls to [moveNext] will also return false. + * If no element is left, then [moveNext] returns false, + * and all further calls to [moveNext] will also return false. + * + * The [current] value must not be accessed before calling [moveNext] + * or after a call to [moveNext] has returned false. * * A typical usage of an Iterator looks as follows: * @@ -57,9 +58,13 @@ abstract class Iterator { /** * Returns the current element. * - * Returns `null` if the iterator has not yet been moved to the first - * element, or if the iterator has been moved past the last element of the - * [Iterable]. + * If the iterator has not yet been moved to the first element + * ([moveNext] has not been called yet), + * or if the iterator has been moved past the last element of the [Iterable] + * ([moveNext] has returned false), + * then [current] is unspecified. + * An [Iterator] may either throw or return an iterator specific default value + * in that case. * * The `current` getter should keep its value until the next call to * [moveNext], even if an underlying collection changes. diff --git a/sdk/lib/core/list.dart b/sdk/lib/core/list.dart index 647f277d65e..afd7f1124f3 100644 --- a/sdk/lib/core/list.dart +++ b/sdk/lib/core/list.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.core; /** @@ -18,7 +16,7 @@ part of dart.core; * * * Growable list. Full implementation of the API defined in this class. * - * The default growable list, as returned by `new List()` or `[]`, keeps + * The default growable list, as created by `[]`, keeps * an internal buffer, and grows that buffer when necessary. This guarantees * that a sequence of [add] operations will each execute in amortized constant * time. Setting the length directly may take time proportional to the new @@ -57,6 +55,10 @@ abstract class List implements EfficientLengthIterable { /** * Creates a list of the given length. * + * This constructor will throw an exception if [E] is not a nullable type. + * In this case, another constructor such as [List.filled] must be used + * instead. + * * The created list is fixed-length if [length] is provided. * * List fixedLengthList = new List(3); @@ -65,18 +67,32 @@ abstract class List implements EfficientLengthIterable { * * The list has length 0 and is growable if [length] is omitted. * - * List growableList = new List(); + * List growableList = []; * growableList.length; // 0; * growableList.length = 3; * - * To create a growable list with a given length, just assign the length - * right after creation: + * To create a growable list with a given length, for a nullable element type, + * just assign the length right after creation: * - * List growableList = new List()..length = 500; + * List growableList = []..length = 500; + * + * For a non-nullable element type, an alternative is the following: + * + * List growableList = List.filled(500, 0, growable: true); * * The [length] must not be negative or null, if it is provided. + * + * If the element type is not nullable, [length] must not be greater than + * zero. + * + * This constructor cannot be used in null-safe code. + * Use [List.filled] to create a non-empty list. + * This requires a fill value to initialize the list elements with. + * To create an empty list, use `[]` for a growable list or + * `List.empty` for a fixed length list (or where growability is determined + * at run-time). */ - external factory List([int length]); + external factory List([int? length]); /** * Creates a list of the given length with [fill] at each position. @@ -112,6 +128,16 @@ abstract class List implements EfficientLengthIterable { */ external factory List.filled(int length, E fill, {bool growable = false}); + /** + * Creates a new empty list. + * + * If [growable] is `false`, which is the default, + * the list is a fixed-length list of length zero. + * If [growable] is `true`, the list is growable and equivalent to `[]`. + */ + @Since("2.8") + external factory List.empty({bool growable = false}); + /** * Creates a list containing all [elements]. * @@ -147,24 +173,15 @@ abstract class List implements EfficientLengthIterable { * Creates a list with [length] positions and fills it with values created by * calling [generator] for each index in the range `0` .. `length - 1` * in increasing order. + * ```dart + * List.generate(3, (int index) => index * index); // [0, 1, 4] + * ``` + * The created list is fixed-length if [growable] is set to false. * - * new List.generate(3, (int index) => index * index); // [0, 1, 4] - * - * The created list is fixed-length unless [growable] is true. + * The [length] must be non-negative. */ - factory List.generate(int length, E generator(int index), - {bool growable = true}) { - List result; - if (growable) { - result = []..length = length; - } else { - result = List(length); - } - for (int i = 0; i < length; i++) { - result[i] = generator(i); - } - return result; - } + external factory List.generate(int length, E generator(int index), + {bool growable = true}); /** * Creates an unmodifiable list containing all [elements]. @@ -210,9 +227,13 @@ abstract class List implements EfficientLengthIterable { * Otherwise the order of element copying is not guaranteed. */ static void copyRange(List target, int at, List source, - [int start, int end]) { + [int? start, int? end]) { start ??= 0; end = RangeError.checkValidRange(start, end, source.length); + if (end == null) { + // TODO(dart-lang/language#440): Remove when promotion works. + throw "unreachable"; + } int length = end - start; if (target.length < at + length) { throw ArgumentError.value(target, "target", @@ -270,6 +291,7 @@ abstract class List implements EfficientLengthIterable { * Typically implemented as `List.castFrom(this)`. */ List cast(); + /** * Returns the object at the given [index] in the list * or throws a [RangeError] if [index] is out of bounds. @@ -301,7 +323,7 @@ abstract class List implements EfficientLengthIterable { void set last(E value); /** - * Returns the number of objects in this list. + * The number of objects in this list. * * The valid indices for a list are `0` through `length - 1`. */ @@ -311,9 +333,11 @@ abstract class List implements EfficientLengthIterable { * Changes the length of this list. * * If [newLength] is greater than - * the current length, entries are initialized to [:null:]. + * the current length, entries are initialized to `null`. + * Increasing the length fails if the element type does not allow `null`. * - * Throws an [UnsupportedError] if the list is fixed-length. + * Throws an [UnsupportedError] if the list is fixed-length or + * if attempting tp enlarge the list when `null` is not a valid element. */ set length(int newLength); @@ -364,12 +388,12 @@ abstract class List implements EfficientLengthIterable { * numbers.sort((a, b) => a.length.compareTo(b.length)); * print(numbers); // [one, two, four, three] OR [two, one, four, three] */ - void sort([int compare(E a, E b)]); + void sort([int compare(E a, E b)?]); /** * Shuffles the elements of this list randomly. */ - void shuffle([Random random]); + void shuffle([Random? random]); /** * Returns the first index of [element] in this list. @@ -414,6 +438,7 @@ abstract class List implements EfficientLengthIterable { * Searches the list from index [start] to 0. * The first time an object `o` is encountered so that `test(o)` is true, * the index of `o` is returned. + * If [start] is omitted, it defaults to the [length] of the list. * * ``` * List notes = ['do', 're', 'mi', 're']; @@ -426,7 +451,7 @@ abstract class List implements EfficientLengthIterable { * notes.lastIndexWhere((note) => note.startsWith('k')); // -1 * ``` */ - int lastIndexWhere(bool test(E element), [int start]); + int lastIndexWhere(bool test(E element), [int? start]); /** * Returns the last index of [element] in this list. @@ -440,7 +465,7 @@ abstract class List implements EfficientLengthIterable { * notes.lastIndexOf('re', 2); // 1 * * If [start] is not provided, this method searches from the end of the - * list./Returns + * list. * * notes.lastIndexOf('re'); // 3 * @@ -448,7 +473,7 @@ abstract class List implements EfficientLengthIterable { * * notes.lastIndexOf('fa'); // -1 */ - int lastIndexOf(E element, [int start]); + int lastIndexOf(E element, [int? start]); /** * Removes all objects from this list; @@ -518,7 +543,7 @@ abstract class List implements EfficientLengthIterable { * * An [UnsupportedError] occurs if the list is fixed-length. */ - bool remove(Object value); + bool remove(Object? value); /** * Removes the object at position [index] from this list. @@ -604,7 +629,7 @@ abstract class List implements EfficientLengthIterable { * 0 ≤ `start` ≤ `end` ≤ `this.length` * If `end` is equal to `start`, then the returned list is empty. */ - List sublist(int start, [int end]); + List sublist(int start, [int? end]); /** * Returns an [Iterable] that iterates over the objects in the range @@ -685,8 +710,10 @@ abstract class List implements EfficientLengthIterable { * print(list); // [1, 1, null] * ``` * + * If the element type is not nullable, omitting [fillValue] or passing `null` + * as [fillValue] will make the `fillRange` fail. */ - void fillRange(int start, int end, [E fillValue]); + void fillRange(int start, int end, [E? fillValue]); /** * Removes the objects in the range [start] inclusive to [end] exclusive diff --git a/sdk/lib/core/map.dart b/sdk/lib/core/map.dart index 8f76dfdfcfc..a92d08d60c3 100644 --- a/sdk/lib/core/map.dart +++ b/sdk/lib/core/map.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.core; /** @@ -79,13 +77,13 @@ abstract class Map { * The resulting map behaves like the result of [Map.from], * except that the map returned by this constructor is not modifiable. */ - external factory Map.unmodifiable(Map other); + external factory Map.unmodifiable(Map other); /** * Creates an identity map with the default implementation, [LinkedHashMap]. * * An identity map uses [identical] for equality and [identityHashCode] - * for hash codes of keys instead of the intrinsic [Object.==] and + * for hash codes of keys instead of the intrinsic [Object.operator==] and * [Object.hashCode] of the keys. * * The returned map allows `null` as a key. @@ -131,7 +129,7 @@ abstract class Map { * last occurrence of a key will simply overwrite any previous value. */ factory Map.fromIterable(Iterable iterable, - {K key(element), V value(element)}) = LinkedHashMap.fromIterable; + {K key(element)?, V value(element)?}) = LinkedHashMap.fromIterable; /** * Creates a Map instance associating the given [keys] to [values]. @@ -201,13 +199,14 @@ abstract class Map { * `Map`. */ Map cast(); + /** * Returns true if this map contains the given [value]. * * Returns true if any of the values in the map are equal to `value` * according to the `==` operator. */ - bool containsValue(Object value); + bool containsValue(Object? value); /** * Returns true if this map contains the given [key]. @@ -215,7 +214,7 @@ abstract class Map { * Returns true if any of the keys in the map are equal to `key` * according to the equality used by the map. */ - bool containsKey(Object key); + bool containsKey(Object? key); /** * Returns the value for the given [key] or null if [key] is not in the map. @@ -226,7 +225,7 @@ abstract class Map { * Methods like [containsKey] or [putIfAbsent] can be used if the distinction * is important. */ - V operator [](Object key); + V? operator [](Object? key); /** * Associates the [key] with the given [value]. @@ -271,7 +270,7 @@ abstract class Map { * * It's an error if the key is not present and [ifAbsent] is not provided. */ - V update(K key, V update(V value), {V ifAbsent()}); + V update(K key, V update(V value), {V ifAbsent()?}); /** * Updates all values. @@ -325,7 +324,7 @@ abstract class Map { * Note that values can be `null` and a returned `null` value doesn't * always mean that the key was absent. */ - V remove(Object key); + V? remove(Object? key); /** * Removes all pairs from the map. @@ -402,5 +401,5 @@ class MapEntry { const MapEntry._(this.key, this.value); - String toString() => "MapEntry($key: $value)"; + String toString() => "MapEntry(${key.toString()}: ${value.toString()})"; } diff --git a/sdk/lib/core/null.dart b/sdk/lib/core/null.dart index 40140e8fd7f..f8588a173f1 100644 --- a/sdk/lib/core/null.dart +++ b/sdk/lib/core/null.dart @@ -2,16 +2,14 @@ // 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.6 - part of dart.core; /** - * The reserved word [:null:] denotes an object that is the sole instance of + * The reserved word `null` denotes an object that is the sole instance of * this class. - * + * * It is a compile-time error for a class to attempt to extend or implement - * Null. + * [Null]. */ @pragma("vm:entry-point") class Null { diff --git a/sdk/lib/core/num.dart b/sdk/lib/core/num.dart index 89f5fb5f9b1..55bb9106769 100644 --- a/sdk/lib/core/num.dart +++ b/sdk/lib/core/num.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.core; /** @@ -387,7 +385,7 @@ abstract class num implements Comparable { * 123456.toStringAsExponential(3); // 1.235e+5 * 123.toStringAsExponential(0); // 1e+2 */ - String toStringAsExponential([int fractionDigits]); + String toStringAsExponential([int? fractionDigits]); /** * Converts `this` to a double and returns a string representation with @@ -470,8 +468,8 @@ abstract class num implements Comparable { * Instead of `num.parse(string, (string) { ... })`, * you should use `num.tryParse(string) ?? (...)`. */ - static num parse(String input, [@deprecated num onError(String input)]) { - num result = tryParse(input); + static num parse(String input, [@deprecated num onError(String input)?]) { + num? result = tryParse(input); if (result != null) return result; if (onError == null) throw FormatException(input); return onError(input); @@ -483,13 +481,9 @@ abstract class num implements Comparable { * Like [parse] except that this function returns `null` for invalid inputs * instead of throwing. */ - static num tryParse(String input) { + static num? tryParse(String input) { String source = input.trim(); // TODO(lrn): Optimize to detect format and result type in one check. return int.tryParse(source) ?? double.tryParse(source); } - - /** Helper functions for [parse]. */ - static int _returnIntNull(String _) => null; - static double _returnDoubleNull(String _) => null; } diff --git a/sdk/lib/core/object.dart b/sdk/lib/core/object.dart index 08bf687216c..31602dfd96d 100644 --- a/sdk/lib/core/object.dart +++ b/sdk/lib/core/object.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.core; /** @@ -59,7 +57,7 @@ class Object { * If a subclass overrides the equality operator it should override * the [hashCode] method as well to maintain consistency. */ - external bool operator ==(other); + external bool operator ==(Object other); /** * The hash code for this object. diff --git a/sdk/lib/core/pattern.dart b/sdk/lib/core/pattern.dart index 8eb0371e5a0..7a3d933f8db 100644 --- a/sdk/lib/core/pattern.dart +++ b/sdk/lib/core/pattern.dart @@ -2,18 +2,12 @@ // 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.6 - part of dart.core; /** * An interface for basic searches within strings. */ abstract class Pattern { - // NOTE: When using "start" index from the language library, call - // without an argument if start is zero. This allows backwards compatibility - // with implementations of the older interface that didn't have the start - // index argument. /** * Match this pattern against the string repeatedly. * @@ -42,7 +36,7 @@ abstract class Pattern { * pattern can match a part of the string starting from position [start]. * Returns `null` if the pattern doesn't match. */ - Match matchAsPrefix(String string, [int start = 0]); + Match? matchAsPrefix(String string, [int start = 0]); } /** @@ -93,7 +87,7 @@ abstract class Match { * The result may be `null` if the pattern didn't assign a value to it * as part of this match. */ - String group(int group); + String? group(int group); /** * Returns the string matched by the given [group]. @@ -102,7 +96,7 @@ abstract class Match { * * Short alias for [Match.group]. */ - String operator [](int group); + String? operator [](int group); /** * Returns a list of the groups with the given indices. @@ -110,7 +104,7 @@ abstract class Match { * The list contains the strings returned by [group] for each index in * [groupIndices]. */ - List groups(List groupIndices); + List groups(List groupIndices); /** * Returns the number of captured groups in the match. diff --git a/sdk/lib/core/print.dart b/sdk/lib/core/print.dart index cc2f0ac16f7..d88ea7f3c4d 100644 --- a/sdk/lib/core/print.dart +++ b/sdk/lib/core/print.dart @@ -2,16 +2,15 @@ // 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.6 - part of dart.core; /// Prints a string representation of the object to the console. -void print(Object object) { - String line = "$object"; - if (printToZone == null) { +void print(Object? object) { + String line = object.toString(); + var toZone = printToZone; + if (toZone == null) { printToConsole(line); } else { - printToZone(line); + toZone(line); } } diff --git a/sdk/lib/core/regexp.dart b/sdk/lib/core/regexp.dart index 095e733783d..b75882d618f 100644 --- a/sdk/lib/core/regexp.dart +++ b/sdk/lib/core/regexp.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.core; /** @@ -90,7 +88,7 @@ abstract class RegExp implements Pattern { * Searches for the first match of the regular expression * in the string [input]. Returns `null` if there is no match. */ - RegExpMatch firstMatch(String input); + RegExpMatch? firstMatch(String input); /** * Returns an iterable of the matches of the regular expression on [input]. @@ -107,7 +105,7 @@ abstract class RegExp implements Pattern { /** * Returns the first substring match of this regular expression in [input]. */ - String stringMatch(String input); + String? stringMatch(String input); /** * The source regular expression string used to create this `RegExp`. @@ -154,7 +152,7 @@ abstract class RegExp implements Pattern { * character is a line terminator. When true, then the "." character will * match any single character including line terminators. * - * This feature is distinct from [isMultiLine], as they affect the behavior + * This feature is distinct from [isMultiline], as they affect the behavior * of different pattern characters, and so they can be used together or * separately. */ @@ -182,7 +180,7 @@ abstract class RegExpMatch implements Match { * expression creating this match (that is, the name must be in * [groupNames]). */ - String namedGroup(String name); + String? namedGroup(String name); /** * The names of the captured groups in the match. diff --git a/sdk/lib/core/set.dart b/sdk/lib/core/set.dart index 9e1a6de4063..ae1e381ee58 100644 --- a/sdk/lib/core/set.dart +++ b/sdk/lib/core/set.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.core; /** @@ -112,7 +110,7 @@ abstract class Set extends EfficientLengthIterable { * of [S], * then the returned set can be used as a `Set`. */ - static Set castFrom(Set source, {Set Function() newSet}) => + static Set castFrom(Set source, {Set Function()? newSet}) => CastSet(source, newSet); /** @@ -128,6 +126,7 @@ abstract class Set extends EfficientLengthIterable { * this set as well. */ Set cast(); + /** * Provides an iterator that iterates over the elements of this set. * @@ -139,7 +138,7 @@ abstract class Set extends EfficientLengthIterable { /** * Returns true if [value] is in the set. */ - bool contains(Object value); + bool contains(Object? value); /** * Adds [value] to the set. @@ -177,7 +176,7 @@ abstract class Set extends EfficientLengthIterable { * in the set. Returns false otherwise. The method has no effect * if [value] value was not in the set. */ - bool remove(Object value); + bool remove(Object? value); /** * If an object equal to [object] is in the set, return it. @@ -193,12 +192,12 @@ abstract class Set extends EfficientLengthIterable { * then there may not be a specific object instance representing the * set element. */ - E lookup(Object object); + E? lookup(Object? object); /** * Removes each element of [elements] from this set. */ - void removeAll(Iterable elements); + void removeAll(Iterable elements); /** * Removes all elements of this set that are not elements in [elements]. @@ -208,7 +207,7 @@ abstract class Set extends EfficientLengthIterable { * equal element in this set is retained, and elements that are not equal * to any element in `elements` are removed. */ - void retainAll(Iterable elements); + void retainAll(Iterable elements); /** * Removes all elements of this set that satisfy [test]. @@ -223,7 +222,7 @@ abstract class Set extends EfficientLengthIterable { /** * Returns whether this Set contains all the elements of [other]. */ - bool containsAll(Iterable other); + bool containsAll(Iterable other); /** * Returns a new set which is the intersection between this set and [other]. @@ -231,7 +230,7 @@ abstract class Set extends EfficientLengthIterable { * That is, the returned set contains all the elements of this [Set] that * are also elements of [other] according to `other.contains`. */ - Set intersection(Set other); + Set intersection(Set other); /** * Returns a new set which contains all the elements of this set and [other]. @@ -247,7 +246,7 @@ abstract class Set extends EfficientLengthIterable { * That is, the returned set contains all the elements of this [Set] that * are not elements of [other] according to `other.contains`. */ - Set difference(Set other); + Set difference(Set other); /** * Removes all elements in the set. diff --git a/sdk/lib/core/sink.dart b/sdk/lib/core/sink.dart index 80f9468dee3..c79214bbf5d 100644 --- a/sdk/lib/core/sink.dart +++ b/sdk/lib/core/sink.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.core; /** diff --git a/sdk/lib/core/stacktrace.dart b/sdk/lib/core/stacktrace.dart index 371573032cb..ef08f71433a 100644 --- a/sdk/lib/core/stacktrace.dart +++ b/sdk/lib/core/stacktrace.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.core; /** diff --git a/sdk/lib/core/stopwatch.dart b/sdk/lib/core/stopwatch.dart index 20316eb481a..311db3dc073 100644 --- a/sdk/lib/core/stopwatch.dart +++ b/sdk/lib/core/stopwatch.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.core; /** @@ -13,15 +11,15 @@ class Stopwatch { /** * Cached frequency of the system in Hz (ticks per second). * - * Must be initialized in [_initTicker]; + * Value must be returned by [_initTicker], which is called only once. */ - static int _frequency; + static final int _frequency = _initTicker(); // The _start and _stop fields capture the time when [start] and [stop] // are called respectively. // If _stop is null, the stopwatch is running. int _start = 0; - int _stop = 0; + int? _stop = 0; /** * Creates a [Stopwatch] in stopped state with a zero elapsed count. @@ -33,7 +31,7 @@ class Stopwatch { * ``` */ Stopwatch() { - if (_frequency == null) _initTicker(); + _frequency; // Ensures initialization before using any method. } /** @@ -51,10 +49,11 @@ class Stopwatch { * If the [Stopwatch] is currently running, then calling start does nothing. */ void start() { - if (_stop != null) { + int? stop = _stop; + if (stop != null) { // (Re)start this stopwatch. // Don't count the time while the stopwatch has been stopped. - _start += _now() - _stop; + _start += _now() - stop; _stop = null; } } @@ -117,9 +116,9 @@ class Stopwatch { bool get isRunning => _stop == null; /** - * Initializes the time-measuring system. *Must* initialize the [_frequency] - * variable. + * Initializes the time-measuring system. *Must* return the [_frequency] + * variable. May do other necessary initialization. */ - external static void _initTicker(); + external static int _initTicker(); external static int _now(); } diff --git a/sdk/lib/core/string.dart b/sdk/lib/core/string.dart index fbbd7d09ae8..4a353b2b8f1 100644 --- a/sdk/lib/core/string.dart +++ b/sdk/lib/core/string.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.core; /** @@ -122,7 +120,7 @@ abstract class String implements Comparable, Pattern { * `0 <= start <= end <= charCodes.length`. */ external factory String.fromCharCodes(Iterable charCodes, - [int start = 0, int end]); + [int start = 0, int? end]); /** * Allocates a new String for the specified [charCode]. @@ -132,7 +130,7 @@ abstract class String implements Comparable, Pattern { * the code units form a surrogate pair. See documentation for * [fromCharCodes]. * - * Creating a String with half of a surrogate pair is allowed. + * Creating a [String] with one half of a surrogate pair is allowed. */ external factory String.fromCharCode(int charCode); @@ -292,7 +290,7 @@ abstract class String implements Comparable, Pattern { * * [start] must be non-negative and not greater than [length]. */ - int indexOf(Pattern pattern, [int start]); + int indexOf(Pattern pattern, [int start = 0]); /** * Returns the starting position of the last match [pattern] in this string, @@ -306,9 +304,10 @@ abstract class String implements Comparable, Pattern { * * string.lastIndexOf(RegExp(r'DART')); // -1 * - * The [start] must be non-negative and not greater than [length]. + * If [start] is omitted, search starts from the end of the string. + * If supplied, [start] must be non-negative and not greater than [length]. */ - int lastIndexOf(Pattern pattern, [int start]); + int lastIndexOf(Pattern pattern, [int? start]); /** * Returns true if this string is empty. @@ -335,7 +334,7 @@ abstract class String implements Comparable, Pattern { * string.substring(1); // 'artlang' * string.substring(1, 4); // 'art' */ - String substring(int startIndex, [int endIndex]); + String substring(int startIndex, [int? endIndex]); /** * Returns the string without any leading and trailing whitespace. @@ -514,7 +513,7 @@ abstract class String implements Comparable, Pattern { * * pigLatin('I have a secret now!'); // 'Iway avehay away ecretsay ownay!' */ - String replaceAllMapped(Pattern from, String replace(Match match)); + String replaceAllMapped(Pattern from, String Function(Match match) replace); /** * Replaces the substring from [start] to [end] with [replacement]. @@ -527,7 +526,7 @@ abstract class String implements Comparable, Pattern { * That is `0 <= start <= end <= this.length`. * If [end] is `null`, it defaults to [length]. */ - String replaceRange(int start, int end, String replacement); + String replaceRange(int start, int? end, String replacement); /** * Splits the string at matches of [pattern] and returns a list of substrings. @@ -596,7 +595,7 @@ abstract class String implements Comparable, Pattern { * onNonMatch: (n) => '*'); // *shoots* */ String splitMapJoin(Pattern pattern, - {String onMatch(Match match), String onNonMatch(String nonMatch)}); + {String Function(Match)? onMatch, String Function(String)? onNonMatch}); /** * Returns an unmodifiable list of the UTF-16 code units of this string. @@ -614,7 +613,7 @@ abstract class String implements Comparable, Pattern { /** * Converts all characters in this string to lower case. - * If the string is already in all lower case, this method returns [:this:]. + * If the string is already in all lower case, this method returns `this`. * * 'ALPHABET'.toLowerCase(); // 'alphabet' * 'abc'.toLowerCase(); // 'abc' @@ -627,7 +626,7 @@ abstract class String implements Comparable, Pattern { /** * Converts all characters in this string to upper case. - * If the string is already in all upper case, this method returns [:this:]. + * If the string is already in all upper case, this method returns `this`. * * 'alphabet'.toUpperCase(); // 'ALPHABET' * 'ABC'.toUpperCase(); // 'ABC' @@ -676,8 +675,7 @@ int _combineSurrogatePair(int start, int end) { } /** - * [Iterator] for reading runes (integer Unicode code points) out of a Dart - * string. + * [Iterator] for reading runes (integer Unicode code points) of a Dart string. */ class RuneIterator implements BidirectionalIterator { /** String being iterated. */ @@ -690,7 +688,7 @@ class RuneIterator implements BidirectionalIterator { * Current code point. * * If the iterator has hit either end, the [_currentCodePoint] is -1 - * and [: _position == _nextPosition :]. + * and `_position == _nextPosition`. */ int _currentCodePoint = -1; @@ -729,7 +727,7 @@ class RuneIterator implements BidirectionalIterator { } /** - * Returns the starting position of the current rune in the string. + * The starting position of the current rune in the string. * * Returns -1 if there is no current rune ([current] is -1). */ @@ -739,10 +737,11 @@ class RuneIterator implements BidirectionalIterator { * Resets the iterator to the rune at the specified index of the string. * * Setting a negative [rawIndex], or one greater than or equal to - * [:string.length:], - * is an error. So is setting it in the middle of a surrogate pair. + * `string.length`, is an error. So is setting it in the middle of a surrogate + * pair. * - * Setting the position to the end of then string will set [current] to null. + * Setting the position to the end of then string means that there is no + * current rune. */ void set rawIndex(int rawIndex) { RangeError.checkValidIndex(rawIndex, string, "rawIndex"); @@ -757,8 +756,9 @@ class RuneIterator implements BidirectionalIterator { * You must call [moveNext] make the rune at the position current, * or [movePrevious] for the last rune before the position. * - * Setting a negative [rawIndex], or one greater than [:string.length:], - * is an error. So is setting it in the middle of a surrogate pair. + * The [rawIndex] must be non-negative and no greater than `string.length`. + * It must also not be the index of the trailing surrogate of a surrogate + * pair. */ void reset([int rawIndex = 0]) { RangeError.checkValueInInterval(rawIndex, 0, string.length, "rawIndex"); @@ -771,7 +771,7 @@ class RuneIterator implements BidirectionalIterator { * The rune (integer Unicode code point) starting at the current position in * the string. * - * If there is no current rune, the value -1 is used instead. + * The value is -1 if there is no current code point. */ int get current => _currentCodePoint; @@ -786,9 +786,9 @@ class RuneIterator implements BidirectionalIterator { * A string containing the current rune. * * For runes outside the basic multilingual plane, this will be - * a [String] of length 2, containing two code units. + * a String of length 2, containing two code units. * - * Returns an empty string if there is no current rune ([current] is -1). + * Returns an empty string if there is no [current] value. */ String get currentAsString { if (_position == _nextPosition) return ""; diff --git a/sdk/lib/core/string_buffer.dart b/sdk/lib/core/string_buffer.dart index d2a25abcf4b..d664101988c 100644 --- a/sdk/lib/core/string_buffer.dart +++ b/sdk/lib/core/string_buffer.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.core; /** @@ -33,14 +31,14 @@ class StringBuffer implements StringSink { bool get isNotEmpty => !isEmpty; /// Adds the contents of [obj], converted to a string, to the buffer. - external void write(Object obj); + external void write(Object? obj); /// Adds the string representation of [charCode] to the buffer. external void writeCharCode(int charCode); - external void writeAll(Iterable objects, [String separator = ""]); + external void writeAll(Iterable objects, [String separator = ""]); - external void writeln([Object obj = ""]); + external void writeln([Object? obj = ""]); /** * Clears the string buffer. diff --git a/sdk/lib/core/string_sink.dart b/sdk/lib/core/string_sink.dart index b0511adb39a..c507424713e 100644 --- a/sdk/lib/core/string_sink.dart +++ b/sdk/lib/core/string_sink.dart @@ -2,27 +2,25 @@ // 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.6 - part of dart.core; abstract class StringSink { /** - * Converts [obj] to a String by invoking [Object.toString] and + * Converts [obj] to a String by invoking [Object.toString] and * adds the result to `this`. */ - void write(Object obj); + void write(Object? obj); /** * Iterates over the given [objects] and [write]s them in sequence. */ - void writeAll(Iterable objects, [String separator = ""]); + void writeAll(Iterable objects, [String separator = ""]); /** - * Converts [obj] to a String by invoking [Object.toString] and + * Converts [obj] to a String by invoking [Object.toString] and * adds the result to `this`, followed by a newline. */ - void writeln([Object obj = ""]); + void writeln([Object? obj = ""]); /** * Writes the [charCode] to `this`. diff --git a/sdk/lib/core/symbol.dart b/sdk/lib/core/symbol.dart index 748d465710c..65e83ff6611 100644 --- a/sdk/lib/core/symbol.dart +++ b/sdk/lib/core/symbol.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.core; /// Opaque name used by mirrors, invocations and [Function.apply]. @@ -62,7 +60,7 @@ abstract class Symbol { * assert(new Symbol("[]=") == #[]=]); * assert(new Symbol("foo.bar") == #foo.bar); * assert(identical(const Symbol("foo"), #foo)); - * assert(identical(const Symbol("[]="), #[]=)); + * assert(identical(const Symbol("[]="), #[]=])); * assert(identical(const Symbol("foo.bar"), #foo.bar)); * ``` * @@ -95,5 +93,5 @@ abstract class Symbol { * Qualified member names, like `#foo.bar` are equal only if they have the * same identifiers before the same final member name. */ - bool operator ==(other); + bool operator ==(Object other); } diff --git a/sdk/lib/core/type.dart b/sdk/lib/core/type.dart index 48ac0e94412..d2e107b6b18 100644 --- a/sdk/lib/core/type.dart +++ b/sdk/lib/core/type.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.core; /** diff --git a/sdk/lib/core/uri.dart b/sdk/lib/core/uri.dart index a85eb67959f..234241c9c38 100644 --- a/sdk/lib/core/uri.dart +++ b/sdk/lib/core/uri.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.core; // Frequently used character codes. @@ -121,15 +119,15 @@ abstract class Uri { * If `fragment` is omitted or `null`, the URI has no fragment part. */ factory Uri( - {String scheme, - String userInfo, - String host, - int port, - String path, - Iterable pathSegments, - String query, - Map*/ > queryParameters, - String fragment}) = _Uri; + {String? scheme, + String? userInfo, + String? host, + int? port, + String? path, + Iterable? pathSegments, + String? query, + Map*/ >? queryParameters, + String? fragment}) = _Uri; /** * Creates a new `http` URI from authority, path and query. @@ -165,7 +163,7 @@ abstract class Uri { * argument. */ factory Uri.http(String authority, String unencodedPath, - [Map queryParameters]) = _Uri.http; + [Map? queryParameters]) = _Uri.http; /** * Creates a new `https` URI from authority, path and query. @@ -174,7 +172,7 @@ abstract class Uri { * which is set to `https`. */ factory Uri.https(String authority, String unencodedPath, - [Map queryParameters]) = _Uri.https; + [Map? queryParameters]) = _Uri.https; /** * Creates a new file URI from an absolute or relative file path. @@ -259,7 +257,7 @@ abstract class Uri { * * If the path passed is not a valid file path, an error is thrown. */ - factory Uri.file(String path, {bool windows}) = _Uri.file; + factory Uri.file(String path, {bool? windows}) = _Uri.file; /** * Like [Uri.file] except that a non-empty URI path ends in a slash. @@ -268,7 +266,7 @@ abstract class Uri { * then a slash is added to the returned URI's path. * In all other cases, the result is the same as returned by `Uri.file`. */ - factory Uri.directory(String path, {bool windows}) = _Uri.directory; + factory Uri.directory(String path, {bool? windows}) = _Uri.directory; /** * Creates a `data:` URI containing the [content] string. @@ -299,9 +297,9 @@ abstract class Uri { * To read the content back, use [UriData.contentAsString]. */ factory Uri.dataFromString(String content, - {String mimeType, - Encoding encoding, - Map parameters, + {String? mimeType, + Encoding? encoding, + Map? parameters, bool base64 = false}) { UriData data = UriData.fromString(content, mimeType: mimeType, @@ -328,9 +326,9 @@ abstract class Uri { * encoded. */ factory Uri.dataFromBytes(List bytes, - {mimeType = "application/octet-stream", - Map parameters, - percentEncoded = false}) { + {String mimeType = "application/octet-stream", + Map? parameters, + bool percentEncoded = false}) { UriData data = UriData.fromBytes(bytes, mimeType: mimeType, parameters: parameters, @@ -597,7 +595,7 @@ abstract class Uri { */ // TODO(lrn): Deprecate and move functionality to File class or similar. // The core libraries should not worry about the platform. - String toFilePath({bool windows}); + String toFilePath({bool? windows}); /** * Access the structure of a `data:` URI. @@ -607,7 +605,7 @@ abstract class Uri { * The [UriData] object can be used to access the media type and data * of a `data:` URI. */ - UriData get data; + UriData? get data; /// Returns a hash code computed as `toString().hashCode`. /// @@ -661,15 +659,15 @@ abstract class Uri { * from this `Uri` need not be checked for validity again. */ Uri replace( - {String scheme, - String userInfo, - String host, - int port, - String path, - Iterable pathSegments, - String query, - Map*/ > queryParameters, - String fragment}); + {String? scheme, + String? userInfo, + String? host, + int? port, + String? path, + Iterable? pathSegments, + String? query, + Map*/ >? queryParameters, + String? fragment}); /** * Returns a `Uri` that differs from this only in not having a fragment. @@ -734,7 +732,7 @@ abstract class Uri { * If the [uri] string is not valid as a URI or URI reference, * a [FormatException] is thrown. */ - static Uri parse(String uri, [int start = 0, int end]) { + static Uri parse(String uri, [int start = 0, int? end]) { // This parsing will not validate percent-encoding, IPv6, etc. // When done splitting into parts, it will call, e.g., [_makeFragment] // to do the final parsing. @@ -809,7 +807,7 @@ abstract class Uri { // The following index-normalization belongs with the scanning, but is // easier to do here because we already have extracted variables from the // indices list. - var indices = List(8); + var indices = List.filled(8, 0, growable: false); // Set default values for each position. // The value will either be correct in some cases where it isn't set @@ -851,8 +849,8 @@ abstract class Uri { int queryStart = indices[_queryStartIndex]; int fragmentStart = indices[_fragmentStartIndex]; - // We may discover scheme while handling special cases. - String scheme; + // We may discover the scheme while handling special cases. + String? scheme; // Derive some positions that weren't set to normalize the indices. if (fragmentStart < queryStart) queryStart = fragmentStart; @@ -1034,7 +1032,7 @@ abstract class Uri { * * Returns `null` if the [uri] string is not valid as a URI or URI reference. */ - static Uri tryParse(String uri, [int start = 0, int end]) { + static Uri? tryParse(String uri, [int start = 0, int? end]) { // TODO: Optimize to avoid throwing-and-recatching. try { return parse(uri, start, end); @@ -1262,7 +1260,7 @@ abstract class Uri { * * `::FFFF:129.144.52.38` * * `2010:836B:4179::836B:4179` */ - static List parseIPv6Address(String host, [int start = 0, int end]) { + static List parseIPv6Address(String host, [int start = 0, int? end]) { end ??= host.length; // An IPv6 address consists of exactly 8 parts of 1-4 hex digits, separated // by `:`'s, with the following exceptions: @@ -1385,7 +1383,7 @@ class _Uri implements Uri { * The host name is the only mandatory part of an authority, so we use * it to mark whether an authority part was present or not. */ - final String _host; + final String? _host; /** * The port number part of the authority. @@ -1393,7 +1391,7 @@ class _Uri implements Uri { * The port. Set to null if there is no port. Normalized to null if * the port is the default port for the scheme. */ - int _port; + int? _port; /** * The path of the URI. @@ -1402,44 +1400,38 @@ class _Uri implements Uri { */ final String path; - // The query content, or null if there is no query. - final String _query; + /// The query content, or null if there is no query. + final String? _query; // The fragment content, or null if there is no fragment. - final String _fragment; + final String? _fragment; - /** - * Cache the computed return value of [pathSegments]. - */ - List _pathSegments; + /// Cache of the full normalized text representation of the URI. + late final String _text = this._initializeText(); - /** - * Cache of the full normalized text representation of the URI. - */ - String _text; + /// Cache of the list of path segments. + late final List pathSegments = _computePathSegments(this.path); - /** - * Cache of the hashCode of [_text]. - * - * Is null until computed. - */ - int _hashCodeCache; + /// Lazily computed and cached hashCode of [_text]. + late final int hashCode = this._text.hashCode; - /** - * Cache the computed return value of [queryParameters]. - */ - Map _queryParameters; - Map> _queryParameterLists; + /// Cache the computed return value of [queryParameters]. + late final Map queryParameters = + UnmodifiableMapView(Uri.splitQueryString(this.query)); + + /// Cache the computed return value of [queryParametersAll]. + late final Map> queryParametersAll = + _computeQueryParametersAll(this.query); /// Internal non-verifying constructor. Only call with validated arguments. /// /// The components must be properly normalized. /// /// Use `null` for [_host] if there is no authority. In that case, always - /// pass `null` for [_port] and [_userInfo] as well. + /// pass `null` for [_port] and an empty string for [_userInfo] as well. /// - /// Use `null` for [_port], [_userInfo], [_query] and [_fragment] if there is - /// component of that type. + /// Use `null` for [_port], [_query] and [_fragment] if there is + /// component of that type, and empty string for [_userInfo]. /// /// The [path] and [scheme] are never empty. _Uri._internal(this.scheme, this._userInfo, this._host, this._port, this.path, @@ -1460,7 +1452,7 @@ class _Uri implements Uri { int pathStart, int queryStart, int fragmentStart, - String scheme) { + String? scheme) { if (scheme == null) { scheme = ""; if (schemeEnd > start) { @@ -1470,8 +1462,8 @@ class _Uri implements Uri { } } String userInfo = ""; - String host; - int port; + String? host; + int? port; if (hostStart > start) { int userInfoStart = schemeEnd + 3; if (userInfoStart < hostStart) { @@ -1479,20 +1471,19 @@ class _Uri implements Uri { } host = _makeHost(uri, hostStart, portStart, false); if (portStart + 1 < pathStart) { - // Should throw because invalid. - port = int.parse(uri.substring(portStart + 1, pathStart), onError: (_) { - throw FormatException("Invalid port", uri, portStart + 1); - }); - port = _makePort(port, scheme); + int portNumber = + int.tryParse(uri.substring(portStart + 1, pathStart)) ?? + (throw FormatException("Invalid port", uri, portStart + 1)); + port = _makePort(portNumber, scheme); } } String path = _makePath(uri, pathStart, queryStart, null, scheme, host != null); - String query; + String? query; if (queryStart < fragmentStart) { query = _makeQuery(uri, queryStart + 1, fragmentStart, null); } - String fragment; + String? fragment; if (fragmentStart < end) { fragment = _makeFragment(uri, fragmentStart + 1, end); } @@ -1501,17 +1492,25 @@ class _Uri implements Uri { /// Implementation of [Uri.Uri]. factory _Uri( - {String scheme, - String userInfo, - String host, - int port, - String path, - Iterable pathSegments, - String query, - Map*/ > queryParameters, - String fragment}) { - scheme = _makeScheme(scheme, 0, _stringOrNullLength(scheme)); + {String? scheme, + String? userInfo, + String? host, + int? port, + String? path, + Iterable? pathSegments, + String? query, + Map*/ >? queryParameters, + String? fragment}) { + if (scheme == null) { + scheme = ""; + } else { + scheme = _makeScheme(scheme, 0, scheme.length); + } userInfo = _makeUserInfo(userInfo, 0, _stringOrNullLength(userInfo)); + if (userInfo == null) { + // TODO(dart-lang/language#440): Remove when promotion works. + throw "unreachable"; + } host = _makeHost(host, 0, _stringOrNullLength(host), false); // Special case this constructor for backwards compatibility. if (query == "") query = null; @@ -1525,6 +1524,10 @@ class _Uri implements Uri { bool hasAuthority = (host != null); path = _makePath( path, 0, _stringOrNullLength(path), pathSegments, scheme, hasAuthority); + if (path == null) { + // TODO(dart-lang/language#440): Remove when promotion works. + throw "unreachable"; + } if (scheme.isEmpty && host == null && !path.startsWith('/')) { bool allowScheme = scheme.isNotEmpty || host != null; path = _normalizeRelativePath(path, allowScheme); @@ -1539,13 +1542,13 @@ class _Uri implements Uri { /// Implementation of [Uri.http]. factory _Uri.http(String authority, String unencodedPath, - [Map queryParameters]) { + [Map? queryParameters]) { return _makeHttpUri("http", authority, unencodedPath, queryParameters); } /// Implementation of [Uri.https]. factory _Uri.https(String authority, String unencodedPath, - [Map queryParameters]) { + [Map? queryParameters]) { return _makeHttpUri("https", authority, unencodedPath, queryParameters); } @@ -1559,19 +1562,19 @@ class _Uri implements Uri { String get userInfo => _userInfo; String get host { - if (_host == null) return ""; - if (_host.startsWith('[')) { - return _host.substring(1, _host.length - 1); + String? host = _host; + if (host == null) return ""; + if (host.startsWith('[')) { + return host.substring(1, host.length - 1); } - return _host; + return host; } int get port { - if (_port == null) return _defaultPort(scheme); - return _port; + return _port ?? _defaultPort(scheme); } - // The default port for the scheme of this Uri. + /// The default port for the scheme of this Uri. static int _defaultPort(String scheme) { if (scheme == "http") return 80; if (scheme == "https") return 443; @@ -1620,25 +1623,23 @@ class _Uri implements Uri { return true; } - // Report a parse failure. - static void _fail(String uri, int index, String message) { + /// Report a parse failure. + static Never _fail(String uri, int index, String message) { throw FormatException(message, uri, index); } - static Uri _makeHttpUri(String scheme, String authority, String unencodedPath, - Map queryParameters) { + static _Uri _makeHttpUri(String scheme, String? authority, + String unencodedPath, Map? queryParameters) { var userInfo = ""; - String host; - int port; + String? host; + int? port; if (authority != null && authority.isNotEmpty) { var hostStart = 0; // Split off the user info. - bool hasUserInfo = false; for (int i = 0; i < authority.length; i++) { const int atSign = 0x40; if (authority.codeUnitAt(i) == atSign) { - hasUserInfo = true; userInfo = authority.substring(0, i); hostStart = i + 1; break; @@ -1673,7 +1674,6 @@ class _Uri implements Uri { } } // Split host and port. - bool hasPort = false; for (; hostEnd < authority.length; hostEnd++) { if (authority.codeUnitAt(hostEnd) == _COLON) { var portString = authority.substring(hostEnd + 1); @@ -1684,7 +1684,7 @@ class _Uri implements Uri { } host = authority.substring(hostStart, hostEnd); } - return Uri( + return _Uri( scheme: scheme, userInfo: userInfo, host: host, @@ -1694,25 +1694,25 @@ class _Uri implements Uri { } /// Implementation of [Uri.file]. - factory _Uri.file(String path, {bool windows}) { - windows = (windows == null) ? _Uri._isWindows : windows; - return windows + factory _Uri.file(String path, {bool? windows}) { + return (windows ?? _Uri._isWindows) ? _makeWindowsFileUrl(path, false) : _makeFileUri(path, false); } /// Implementation of [Uri.directory]. - factory _Uri.directory(String path, {bool windows}) { - windows = (windows == null) ? _Uri._isWindows : windows; - return windows ? _makeWindowsFileUrl(path, true) : _makeFileUri(path, true); + factory _Uri.directory(String path, {bool? windows}) { + return (windows ?? _Uri._isWindows) + ? _makeWindowsFileUrl(path, true) + : _makeFileUri(path, true); } /// Used internally in path-related constructors. external static bool get _isWindows; - static _checkNonWindowsPathReservedCharacters( + static void _checkNonWindowsPathReservedCharacters( List segments, bool argumentError) { - segments.forEach((segment) { + for (var segment in segments) { if (segment.contains("/")) { if (argumentError) { throw ArgumentError("Illegal path character $segment"); @@ -1720,10 +1720,10 @@ class _Uri implements Uri { throw UnsupportedError("Illegal path character $segment"); } } - }); + } } - static _checkWindowsPathReservedCharacters( + static void _checkWindowsPathReservedCharacters( List segments, bool argumentError, [int firstSegment = 0]) { for (var segment in segments.skip(firstSegment)) { @@ -1737,7 +1737,7 @@ class _Uri implements Uri { } } - static _checkWindowsDriveLetter(int charCode, bool argumentError) { + static void _checkWindowsDriveLetter(int charCode, bool argumentError) { if ((_UPPER_CASE_A <= charCode && charCode <= _UPPER_CASE_Z) || (_LOWER_CASE_A <= charCode && charCode <= _LOWER_CASE_Z)) { return; @@ -1751,7 +1751,7 @@ class _Uri implements Uri { } } - static _makeFileUri(String path, bool slashTerminated) { + static Uri _makeFileUri(String path, bool slashTerminated) { const String sep = "/"; var segments = path.split(sep); if (slashTerminated && segments.isNotEmpty && segments.last.isNotEmpty) { @@ -1833,15 +1833,15 @@ class _Uri implements Uri { } Uri replace( - {String scheme, - String userInfo, - String host, - int port, - String path, - Iterable pathSegments, - String query, - Map*/ > queryParameters, - String fragment}) { + {String? scheme, + String? userInfo, + String? host, + int? port, + String? path, + Iterable? pathSegments, + String? query, + Map*/ >? queryParameters, + String? fragment}) { // Set to true if the scheme has (potentially) changed. // In that case, the default port may also have changed and we need // to check even the existing port. @@ -1852,12 +1852,14 @@ class _Uri implements Uri { } else { scheme = this.scheme; } + bool isFile = (scheme == "file"); if (userInfo != null) { userInfo = _makeUserInfo(userInfo, 0, userInfo.length); } else { userInfo = this._userInfo; } + if (port != null) { port = _makePort(port, scheme); } else { @@ -1880,11 +1882,12 @@ class _Uri implements Uri { path = _makePath(path, 0, _stringOrNullLength(path), pathSegments, scheme, hasAuthority); } else { - path = this.path; - if ((isFile || (hasAuthority && !path.isEmpty)) && - !path.startsWith('/')) { - path = "/" + path; + var currentPath = this.path; + if ((isFile || (hasAuthority && !currentPath.isEmpty)) && + !currentPath.startsWith('/')) { + currentPath = "/" + currentPath; } + path = currentPath; } if (query != null || queryParameters != null) { @@ -1907,39 +1910,21 @@ class _Uri implements Uri { return _Uri._internal(scheme, _userInfo, _host, _port, path, _query, null); } - List get pathSegments { - var result = _pathSegments; - if (result != null) return result; - - var pathToSplit = path; + static List _computePathSegments(String pathToSplit) { if (pathToSplit.isNotEmpty && pathToSplit.codeUnitAt(0) == _SLASH) { pathToSplit = pathToSplit.substring(1); } - result = (pathToSplit == "") + return (pathToSplit.isEmpty) ? const [] : List.unmodifiable( pathToSplit.split("/").map(Uri.decodeComponent)); - _pathSegments = result; - return result; } - Map get queryParameters { - _queryParameters ??= - UnmodifiableMapView(Uri.splitQueryString(query)); - return _queryParameters; - } - - Map> get queryParametersAll { - if (_queryParameterLists == null) { - Map queryParameterLists = _splitQueryStringAll(query); - for (var key in queryParameterLists.keys) { - queryParameterLists[key] = - List.unmodifiable(queryParameterLists[key]); - } - _queryParameterLists = - Map>.unmodifiable(queryParameterLists); - } - return _queryParameterLists; + static Map> _computeQueryParametersAll(String? query) { + if (query == null || query.isEmpty) return const >{}; + Map> queryParameterLists = _splitQueryStringAll(query); + queryParameterLists.updateAll(_toUnmodifiableStringList); + return Map>.unmodifiable(queryParameterLists); } Uri normalizePath() { @@ -1948,7 +1933,7 @@ class _Uri implements Uri { return this.replace(path: path); } - static int _makePort(int port, String scheme) { + static int? _makePort(int? port, String scheme) { // Perform scheme specific normalization. if (port != null && port == _defaultPort(scheme)) return null; return port; @@ -1965,7 +1950,7 @@ class _Uri implements Uri { * This escapes all characters not valid in a reg-name, * and converts all non-escape upper-case letters to lower-case. */ - static String _makeHost(String host, int start, int end, bool strictIPv6) { + static String? _makeHost(String? host, int start, int end, bool strictIPv6) { // TODO(lrn): Should we normalize IPv6 addresses according to RFC 5952? if (host == null) return null; if (start == end) return ""; @@ -2004,8 +1989,8 @@ class _Uri implements Uri { return _normalizeRegName(host, start, end); } - // RFC 6874 check for ZoneID - // Return the index of first appeared `%`. + /// RFC 6874 check for ZoneID + /// Return the index of first appeared `%`. static int _checkZoneID(String host, int start, int end) { int index = host.indexOf('%', start); index = (index >= start && index < end) ? index : end; @@ -2026,7 +2011,7 @@ class _Uri implements Uri { */ static String _normalizeZoneID(String host, int start, int end, [String prefix = '']) { - StringBuffer buffer; + StringBuffer? buffer; if (prefix != '') { buffer = StringBuffer(prefix); } @@ -2038,7 +2023,7 @@ class _Uri implements Uri { while (index < end) { int char = host.codeUnitAt(index); if (char == _PERCENT) { - String replacement = _normalizeEscape(host, index, true); + String? replacement = _normalizeEscape(host, index, true); if (replacement == null && isNormalized) { index += 3; continue; @@ -2076,10 +2061,8 @@ class _Uri implements Uri { sourceLength = 2; } } - buffer ??= StringBuffer(); String slice = host.substring(sectionStart, index); - buffer.write(slice); - buffer.write(_escapeChar(char)); + (buffer ??= StringBuffer())..write(slice)..write(_escapeChar(char)); index += sourceLength; sectionStart = index; } @@ -2104,7 +2087,7 @@ class _Uri implements Uri { * lower case unreserved characters or upper case escapes. */ static String _normalizeRegName(String host, int start, int end) { - StringBuffer buffer; + StringBuffer? buffer; int sectionStart = start; int index = start; // Whether all characters between sectionStart and index are normalized, @@ -2114,7 +2097,7 @@ class _Uri implements Uri { int char = host.codeUnitAt(index); if (char == _PERCENT) { // The _regNameTable contains "%", so we check that first. - String replacement = _normalizeEscape(host, index, true); + String? replacement = _normalizeEscape(host, index, true); if (replacement == null && isNormalized) { index += 3; continue; @@ -2156,11 +2139,9 @@ class _Uri implements Uri { sourceLength = 2; } } - buffer ??= StringBuffer(); String slice = host.substring(sectionStart, index); if (!isNormalized) slice = slice.toLowerCase(); - buffer.write(slice); - buffer.write(_escapeChar(char)); + (buffer ??= StringBuffer())..write(slice)..write(_escapeChar(char)); index += sourceLength; sectionStart = index; } @@ -2200,9 +2181,9 @@ class _Uri implements Uri { return _canonicalizeScheme(scheme); } - // Canonicalize a few often-used scheme strings. - // - // This improves memory usage and makes comparison faster. + /// Canonicalize a few often-used scheme strings. + /// + /// This improves memory usage and makes comparison faster. static String _canonicalizeScheme(String scheme) { if (scheme == "http") return "http"; if (scheme == "file") return "file"; @@ -2211,27 +2192,26 @@ class _Uri implements Uri { return scheme; } - static String _makeUserInfo(String userInfo, int start, int end) { + static String _makeUserInfo(String? userInfo, int start, int end) { if (userInfo == null) return ""; return _normalizeOrSubstring(userInfo, start, end, _userinfoTable); } - static String _makePath(String path, int start, int end, - Iterable pathSegments, String scheme, bool hasAuthority) { + static String _makePath(String? path, int start, int end, + Iterable? pathSegments, String scheme, bool hasAuthority) { bool isFile = (scheme == "file"); bool ensureLeadingSlash = isFile || hasAuthority; - if (path == null && pathSegments == null) return isFile ? "/" : ""; - if (path != null && pathSegments != null) { - throw ArgumentError('Both path and pathSegments specified'); - } String result; - if (path != null) { - result = _normalizeOrSubstring(path, start, end, _pathCharOrSlashTable, - escapeDelimiters: true); - } else { + if (path == null) { + if (pathSegments == null) return isFile ? "/" : ""; result = pathSegments .map((s) => _uriEncode(_pathCharTable, s, utf8, false)) .join("/"); + } else if (pathSegments != null) { + throw ArgumentError('Both path and pathSegments specified'); + } else { + result = _normalizeOrSubstring(path, start, end, _pathCharOrSlashTable, + escapeDelimiters: true); } if (result.isEmpty) { if (isFile) return "/"; @@ -2254,8 +2234,8 @@ class _Uri implements Uri { return _removeDotSegments(path); } - static String _makeQuery(String query, int start, int end, - Map*/ > queryParameters) { + static String? _makeQuery(String? query, int start, int end, + Map*/ >? queryParameters) { if (query != null) { if (queryParameters != null) { throw ArgumentError('Both query and queryParameters specified'); @@ -2268,7 +2248,7 @@ class _Uri implements Uri { var result = StringBuffer(); var separator = ""; - void writeParameter(String key, String value) { + void writeParameter(String key, String? value) { result.write(separator); separator = "&"; result.write(Uri.encodeQueryComponent(key)); @@ -2291,7 +2271,7 @@ class _Uri implements Uri { return result.toString(); } - static String _makeFragment(String fragment, int start, int end) { + static String? _makeFragment(String? fragment, int start, int end) { if (fragment == null) return null; return _normalizeOrSubstring(fragment, start, end, _queryCharTable, escapeDelimiters: true); @@ -2310,7 +2290,7 @@ class _Uri implements Uri { * * If [lowerCase] is true, a single character returned is always lower case, */ - static String _normalizeEscape(String source, int index, bool lowerCase) { + static String? _normalizeEscape(String source, int index, bool lowerCase) { assert(source.codeUnitAt(index) == _PERCENT); if (index + 2 >= source.length) { return "%"; // Marks the escape as invalid. @@ -2343,7 +2323,7 @@ class _Uri implements Uri { List codeUnits; if (char < 0x80) { // ASCII, a single percent encoded sequence. - codeUnits = List(3); + codeUnits = Uint8List(3); codeUnits[0] = _PERCENT; codeUnits[1] = _hexDigits.codeUnitAt(char >> 4); codeUnits[2] = _hexDigits.codeUnitAt(char & 0xf); @@ -2359,7 +2339,7 @@ class _Uri implements Uri { flag = 0xf0; } } - codeUnits = List(3 * encodedBytes); + codeUnits = Uint8List(3 * encodedBytes); int index = 0; while (--encodedBytes >= 0) { int byte = ((char >> (6 * encodedBytes)) & 0x3f) | flag; @@ -2398,10 +2378,10 @@ class _Uri implements Uri { * * Returns `null` if the original content was already normalized. */ - static String _normalize( + static String? _normalize( String component, int start, int end, List charTable, {bool escapeDelimiters = false}) { - StringBuffer buffer; + StringBuffer? buffer; int sectionStart = start; int index = start; // Loop while characters are valid and escapes correct and upper-case. @@ -2410,7 +2390,7 @@ class _Uri implements Uri { if (char < 127 && (charTable[char >> 4] & (1 << (char & 0x0f))) != 0) { index++; } else { - String replacement; + String? replacement; int sourceLength; if (char == _PERCENT) { replacement = _normalizeEscape(component, index, false); @@ -2428,6 +2408,7 @@ class _Uri implements Uri { } } else if (!escapeDelimiters && _isGeneralDelimiter(char)) { _fail(component, index, "Invalid character"); + throw "unreachable"; // TODO(lrn): Remove when Never-returning functions are recognized as throwing. } else { sourceLength = 1; if ((char & 0xFC00) == 0xD800) { @@ -2443,9 +2424,9 @@ class _Uri implements Uri { } replacement = _escapeChar(char); } - buffer ??= StringBuffer(); - buffer.write(component.substring(sectionStart, index)); - buffer.write(replacement); + (buffer ??= StringBuffer()) + ..write(component.substring(sectionStart, index)) + ..write(replacement); index += sourceLength; sectionStart = index; } @@ -2615,10 +2596,10 @@ class _Uri implements Uri { // From RFC 3986. String targetScheme; String targetUserInfo = ""; - String targetHost; - int targetPort; + String? targetHost; + int? targetPort; String targetPath; - String targetQuery; + String? targetQuery; if (reference.scheme.isNotEmpty) { targetScheme = reference.scheme; if (reference.hasAuthority) { @@ -2687,7 +2668,7 @@ class _Uri implements Uri { } } } - String fragment = reference.hasFragment ? reference.fragment : null; + String? fragment = reference.hasFragment ? reference.fragment : null; return _Uri._internal(targetScheme, targetUserInfo, targetHost, targetPort, targetPath, targetQuery, fragment); } @@ -2714,15 +2695,17 @@ class _Uri implements Uri { throw StateError( "Origin is only applicable schemes http and https: $this"); } - if (_host == null || _host == "") { + String? host = _host; + if (host == null || host == "") { throw StateError( "A $scheme: URI should have a non-empty host name: $this"); } - if (_port == null) return "$scheme://$_host"; - return "$scheme://$_host:$_port"; + int? port = _port; + if (port == null) return "$scheme://$host"; + return "$scheme://$host:$port"; } - String toFilePath({bool windows}) { + String toFilePath({bool? windows}) { if (scheme != "" && scheme != "file") { throw UnsupportedError("Cannot extract a file path from a $scheme URI"); } @@ -2734,8 +2717,7 @@ class _Uri implements Uri { throw UnsupportedError( "Cannot extract a file path from a URI with a fragment component"); } - windows ??= _isWindows; - return windows ? _toWindowsFilePath(this) : _toFilePath(); + return (windows ?? _isWindows) ? _toWindowsFilePath(this) : _toFilePath(); } String _toFilePath() { @@ -2780,10 +2762,6 @@ class _Uri implements Uri { return result.toString(); } - bool get _isPathAbsolute { - return path != null && path.startsWith('/'); - } - void _writeAuthority(StringSink ss) { if (_userInfo.isNotEmpty) { ss.write(_userInfo); @@ -2804,14 +2782,11 @@ class _Uri implements Uri { * The [UriData] object can be used to access the media type and data * of a `data:` URI. */ - UriData get data => (scheme == "data") ? UriData.fromUri(this) : null; + UriData? get data => (scheme == "data") ? UriData.fromUri(this) : null; - String toString() { - return _text ??= _initializeText(); - } + String toString() => _text; String _initializeText() { - assert(_text == null); StringBuffer sb = StringBuffer(); if (scheme.isNotEmpty) sb..write(scheme)..write(":"); if (hasAuthority || (scheme == "file")) { @@ -2841,10 +2816,6 @@ class _Uri implements Uri { fragment == other.fragment; } - int get hashCode { - return _hashCodeCache ??= toString().hashCode; - } - static List _createList() => []; static Map> _splitQueryStringAll(String query, @@ -2926,7 +2897,6 @@ class _Uri implements Uri { assert(0 <= start); assert(start <= end); assert(end <= text.length); - assert(encoding != null); // First check whether there is any characters which need special handling. bool simple = true; for (int i = start; i < end; i++) { @@ -2946,7 +2916,7 @@ class _Uri implements Uri { bytes = text.substring(start, end).codeUnits; } } else { - bytes = List(); + bytes = []; for (int i = start; i < end; i++) { var codeUnit = text.codeUnitAt(i); if (codeUnit > 127) { @@ -3062,50 +3032,6 @@ class _Uri implements Uri { 0x07ff, // 0x70 - 0x7f 1111111111100010 ]; - // Characters allowed in scheme except for upper case letters. - static const _schemeLowerTable = [ - // LSB MSB - // | | - 0x0000, // 0x00 - 0x0f 0000000000000000 - 0x0000, // 0x10 - 0x1f 0000000000000000 - // + -. - 0x6800, // 0x20 - 0x2f 0000000000010110 - // 0123456789 - 0x03ff, // 0x30 - 0x3f 1111111111000000 - // - 0x0000, // 0x40 - 0x4f 0111111111111111 - // - 0x0000, // 0x50 - 0x5f 1111111111100001 - // abcdefghijklmno - 0xfffe, // 0x60 - 0x6f 0111111111111111 - // pqrstuvwxyz - 0x07ff, // 0x70 - 0x7f 1111111111100010 - ]; - - // Sub delimiter characters combined with unreserved as of 3986. - // sub-delims = "!" / "$" / "&" / "'" / "(" / ")" - // / "*" / "+" / "," / ";" / "=" - // RFC 3986 section 2.3. - // unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" - static const _subDelimitersTable = [ - // LSB MSB - // | | - 0x0000, // 0x00 - 0x0f 0000000000000000 - 0x0000, // 0x10 - 0x1f 0000000000000000 - // ! $ &'()*+,-. - 0x7fd2, // 0x20 - 0x2f 0100101111111110 - // 0123456789 ; = - 0x2bff, // 0x30 - 0x3f 1111111111010100 - // ABCDEFGHIJKLMNO - 0xfffe, // 0x40 - 0x4f 0111111111111111 - // PQRSTUVWXYZ _ - 0x87ff, // 0x50 - 0x5f 1111111111100001 - // abcdefghijklmno - 0xfffe, // 0x60 - 0x6f 0111111111111111 - // pqrstuvwxyz ~ - 0x47ff, // 0x70 - 0x7f 1111111111100010 - ]; - // General delimiter characters, RFC 3986 section 2.2. // gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" // @@ -3310,7 +3236,7 @@ class UriData { /** * Cache of the result returned by [uri]. */ - Uri _uriCache; + Uri? _uriCache; UriData._(this._text, this._separatorIndices, this._uriCache); @@ -3324,15 +3250,14 @@ class UriData { * be more efficient if the [uri] itself isn't used. */ factory UriData.fromString(String content, - {String mimeType, - Encoding encoding, - Map parameters, + {String? mimeType, + Encoding? encoding, + Map? parameters, bool base64 = false}) { StringBuffer buffer = StringBuffer(); List indices = [_noScheme]; - String charsetName; - String encodingName; - if (parameters != null) charsetName = parameters["charset"]; + String? charsetName = parameters?.["charset"]; + String? encodingName; if (encoding == null) { if (charsetName != null) { encoding = Encoding.getByName(charsetName); @@ -3362,9 +3287,9 @@ class UriData { * be more efficient if the [uri] itself isn't used. */ factory UriData.fromBytes(List bytes, - {mimeType = "application/octet-stream", - Map parameters, - percentEncoded = false}) { + {String mimeType = "application/octet-stream", + Map? parameters, + bool percentEncoded = false}) { StringBuffer buffer = StringBuffer(); List indices = [_noScheme]; _writeUri(mimeType, null, parameters, buffer, indices); @@ -3405,7 +3330,7 @@ class UriData { return _parse(uri.path, 0, uri); } // Includes path and query (and leading "data:"). - return _parse("$uri", 5, uri); + return _parse(uri.toString(), 5, uri); } /** @@ -3416,11 +3341,16 @@ class UriData { * Of an [indices] list is passed, separator indices are stored in that * list. */ - static void _writeUri(String mimeType, String charsetName, - Map parameters, StringBuffer buffer, List indices) { + static void _writeUri( + String? mimeType, + String? charsetName, + Map? parameters, + StringBuffer buffer, + List? indices) { if (mimeType == null || mimeType == "text/plain") { mimeType = ""; } + if (mimeType.isEmpty || identical(mimeType, "application/octet-stream")) { buffer.write(mimeType); // Common cases need no escaping. } else { @@ -3435,9 +3365,8 @@ class UriData { _tokenCharTable, mimeType.substring(slashIndex + 1), utf8, false)); } if (charsetName != null) { - if (indices != null) { - indices..add(buffer.length)..add(buffer.length + 8); - } + // TODO(39209): Use ?.. when sequences are properly supported. + if (indices != null) indices..add(buffer.length)..add(buffer.length + 8); buffer.write(";charset="); buffer.write(_Uri._uriEncode(_tokenCharTable, charsetName, utf8, false)); } @@ -3449,11 +3378,11 @@ class UriData { throw ArgumentError.value( "", "Parameter values must not be empty", 'parameters["$key"]'); } - if (indices != null) indices.add(buffer.length); + indices?.add(buffer.length); buffer.write(';'); // Encode any non-RFC2045-token character and both '%' and '#'. buffer.write(_Uri._uriEncode(_tokenCharTable, key, utf8, false)); - if (indices != null) indices.add(buffer.length); + indices?.add(buffer.length); buffer.write('='); buffer.write(_Uri._uriEncode(_tokenCharTable, value, utf8, false)); }); @@ -3533,9 +3462,12 @@ class UriData { * as path. */ Uri get uri { - if (_uriCache != null) return _uriCache; + return _uriCache ??= _computeUri(); + } + + Uri _computeUri() { String path = _text; - String query; + String? query; int colonIndex = _separatorIndices[0]; int queryIndex = _text.indexOf('?', colonIndex + 1); int end = _text.length; @@ -3546,8 +3478,7 @@ class UriData { } path = _Uri._normalizeOrSubstring( _text, colonIndex + 1, end, _Uri._pathCharOrSlashTable); - _uriCache = _DataUri(this, path, query); - return _uriCache; + return _DataUri(this, path, query); } /** @@ -3686,7 +3617,7 @@ class UriData { * converted to bytes and then the character codes and byte values are * decoded using [encoding]. */ - String contentAsString({Encoding encoding}) { + String contentAsString({Encoding? encoding}) { if (encoding == null) { var charset = this.charset; // Returns "US-ASCII" if not present. encoding = Encoding.getByName(charset); @@ -3730,7 +3661,7 @@ class UriData { return result; } - static UriData _parse(String text, int start, Uri sourceUri) { + static UriData _parse(String text, int start, Uri? sourceUri) { assert(start == 0 || start == 5); assert((start == 5) == text.startsWith("data:")); @@ -3872,26 +3803,6 @@ class UriData { // // This is the same characters as in a URI query (which is URI pchar plus '?') static const _uricTable = _Uri._queryCharTable; - - // Characters allowed in base-64 encoding (alphanumeric, '/', '+' and '='). - static const _base64Table = [ - // LSB MSB - // | | - 0x0000, // 0x00 - 0x0f 00000000 00000000 - 0x0000, // 0x10 - 0x1f 00000000 00000000 - // + / - 0x8800, // 0x20 - 0x2f 00000000 00010001 - // 01234567 89 - 0x03ff, // 0x30 - 0x3f 11111111 11000000 - // ABCDEFG HIJKLMNO - 0xfffe, // 0x40 - 0x4f 01111111 11111111 - // PQRSTUVW XYZ - 0x07ff, // 0x50 - 0x5f 11111111 11100000 - // abcdefg hijklmno - 0xfffe, // 0x60 - 0x6f 01111111 11111111 - // pqrstuvw xyz - 0x07ff, // 0x70 - 0x7f 11111111 11100000 - ]; } // -------------------------------------------------------------------- @@ -4295,8 +4206,8 @@ class _SimpleUri implements Uri { /// The scheme is often used to distinguish URIs. /// To make comparisons more efficient, we cache the value, and /// canonicalize a few known types. - String _schemeCache; - int _hashCodeCache; + String? _schemeCache; + int? _hashCodeCache; _SimpleUri( this._uri, @@ -4336,20 +4247,16 @@ class _SimpleUri implements Uri { } String get scheme { + return _schemeCache ??= _computeScheme(); + } + + String _computeScheme() { if (_schemeEnd <= 0) return ""; - if (_schemeCache != null) return _schemeCache; - if (_isHttp) { - _schemeCache = "http"; - } else if (_isHttps) { - _schemeCache = "https"; - } else if (_isFile) { - _schemeCache = "file"; - } else if (_isPackage) { - _schemeCache = "package"; - } else { - _schemeCache = _uri.substring(0, _schemeEnd); - } - return _schemeCache; + if (_isHttp) return "http"; + if (_isHttps) return "https"; + if (_isFile) return "file"; + if (_isPackage) return "package"; + return _uri.substring(0, _schemeEnd); } String get authority => @@ -4419,11 +4326,9 @@ class _SimpleUri implements Uri { Map> get queryParametersAll { if (!hasQuery) return const >{}; - Map queryParameterLists = _Uri._splitQueryStringAll(query); - for (var key in queryParameterLists.keys) { - queryParameterLists[key] = - List.unmodifiable(queryParameterLists[key]); - } + Map> queryParameterLists = + _Uri._splitQueryStringAll(query); + queryParameterLists.updateAll(_toUnmodifiableStringList); return Map>.unmodifiable(queryParameterLists); } @@ -4442,15 +4347,15 @@ class _SimpleUri implements Uri { } Uri replace( - {String scheme, - String userInfo, - String host, - int port, - String path, - Iterable pathSegments, - String query, - Map*/ > queryParameters, - String fragment}) { + {String? scheme, + String? userInfo, + String? host, + int? port, + String? path, + Iterable? pathSegments, + String? query, + Map*/ >? queryParameters, + String? fragment}) { bool schemeChanged = false; if (scheme != null) { scheme = _Uri._makeScheme(scheme, 0, scheme.length); @@ -4702,7 +4607,7 @@ class _SimpleUri implements Uri { base._schemeCache); } - String toFilePath({bool windows}) { + String toFilePath({bool? windows}) { if (_schemeEnd >= 0 && !_isFile) { throw UnsupportedError("Cannot extract a file path from a $scheme URI"); } @@ -4714,8 +4619,9 @@ class _SimpleUri implements Uri { throw UnsupportedError( "Cannot extract a file path from a URI with a fragment component"); } - windows ??= _Uri._isWindows; - return windows ? _Uri._toWindowsFilePath(this) : _toFilePath(); + return (windows ?? _Uri._isWindows) + ? _Uri._toWindowsFilePath(this) + : _toFilePath(); } String _toFilePath() { @@ -4728,7 +4634,7 @@ class _SimpleUri implements Uri { return this.path; } - UriData get data { + UriData? get data { assert(scheme != "data"); return null; } @@ -4758,10 +4664,10 @@ class _SimpleUri implements Uri { class _DataUri extends _Uri { final UriData _data; - _DataUri(this._data, String path, String query) - : super._internal("data", null, null, null, path, query, null); + _DataUri(this._data, String path, String? query) + : super._internal("data", "", null, null, path, query, null); - UriData get data => _data; + UriData? get data => _data; } /// Checks whether [text] starts with "data:" at position [start]. @@ -4783,4 +4689,7 @@ int _startsWithData(String text, int start) { } /// Helper function returning the length of a string, or `0` for `null`. -int _stringOrNullLength(String s) => (s == null) ? 0 : s.length; +int _stringOrNullLength(String? s) => (s == null) ? 0 : s.length; + +List _toUnmodifiableStringList(String key, List list) => + List.unmodifiable(list); diff --git a/sdk/lib/developer/developer.dart b/sdk/lib/developer/developer.dart index 4490499604c..e9df841ba85 100644 --- a/sdk/lib/developer/developer.dart +++ b/sdk/lib/developer/developer.dart @@ -2,8 +2,6 @@ // 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.6 - /// Interact with developer tools such as the debugger and inspector. /// /// This library is platform dependent and has separate implementations for @@ -36,12 +34,12 @@ part 'timeline.dart'; /// regardless of whether or not a debugger is connected. When compiled to /// JavaScript, this uses the "debugger" statement, and behaves exactly as /// that does. -external bool debugger({bool when: true, String message}); +external bool debugger({bool when = true, String? message}); /// Send a reference to [object] to any attached debuggers. /// /// Debuggers may open an inspector on the object. Returns the argument. -external Object inspect(Object object); +external Object? inspect(Object? object); /// Emit a log event. /// @@ -59,11 +57,11 @@ external Object inspect(Object object); /// - [stackTrace] (optional) a stack trace associated with this log event external void log( String message, { - DateTime time, - int sequenceNumber, - int level: 0, - String name: '', - Zone zone, - Object error, - StackTrace stackTrace, + DateTime? time, + int? sequenceNumber, + int level = 0, + String name = '', + Zone? zone, + Object? error, + StackTrace? stackTrace, }); diff --git a/sdk/lib/developer/extension.dart b/sdk/lib/developer/extension.dart index 5d0da2a1b09..184a00f956b 100644 --- a/sdk/lib/developer/extension.dart +++ b/sdk/lib/developer/extension.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.developer; /// A response to a service protocol extension RPC. @@ -12,13 +10,13 @@ part of dart.developer; /// use [ServiceExtensionResponse.error]. class ServiceExtensionResponse { /// The result of a successful service protocol extension RPC. - final String result; + final String? result; /// The error code associated with a failed service protocol extension RPC. - final int errorCode; + final int? errorCode; /// The details of a failed service protocol extension RPC. - final String errorDetail; + final String? errorDetail; /// Creates a successful response to a service protocol extension RPC. /// @@ -28,6 +26,7 @@ class ServiceExtensionResponse { : result = result, errorCode = null, errorDetail = null { + // TODO: When NNBD is complete, delete the following line. ArgumentError.checkNotNull(result, "result"); } @@ -42,6 +41,7 @@ class ServiceExtensionResponse { errorCode = errorCode, errorDetail = errorDetail { _validateErrorCode(errorCode); + // TODO: When NNBD is complete, delete the following line. ArgumentError.checkNotNull(errorDetail, "errorDetail"); } @@ -82,6 +82,7 @@ class ServiceExtensionResponse { } static _validateErrorCode(int errorCode) { + // TODO: When NNBD is complete, delete the following line. ArgumentError.checkNotNull(errorCode, "errorCode"); if (errorCode == invalidParams) return; if ((errorCode >= extensionErrorMin) && (errorCode <= extensionErrorMax)) { @@ -95,17 +96,12 @@ class ServiceExtensionResponse { // ignore: unused_element, called from runtime/lib/developer.dart String _toString() { - if (result != null) { - return result; - } else { - assert(errorCode != null); - assert(errorDetail != null); - return json.encode({ - 'code': errorCode, - 'message': _errorCodeMessage(errorCode), - 'data': {'details': errorDetail} - }); - } + return result ?? + json.encode({ + 'code': errorCode!, + 'message': _errorCodeMessage(errorCode!), + 'data': {'details': errorDetail!} + }); } } @@ -132,6 +128,7 @@ typedef Future ServiceExtensionHandler( /// Because service extensions are isolate specific, clients using extensions /// must always include an 'isolateId' parameter with each RPC. void registerExtension(String method, ServiceExtensionHandler handler) { + // TODO: When NNBD is complete, delete the following line. ArgumentError.checkNotNull(method, 'method'); if (!method.startsWith('ext.')) { throw new ArgumentError.value(method, 'method', 'Must begin with ext.'); @@ -139,6 +136,7 @@ void registerExtension(String method, ServiceExtensionHandler handler) { if (_lookupExtension(method) != null) { throw new ArgumentError('Extension already registered: $method'); } + // TODO: When NNBD is complete, delete the following line. ArgumentError.checkNotNull(handler, 'handler'); _registerExtension(method, handler); } @@ -146,6 +144,7 @@ void registerExtension(String method, ServiceExtensionHandler handler) { /// Post an event of [eventKind] with payload of [eventData] to the `Extension` /// event stream. void postEvent(String eventKind, Map eventData) { + // TODO: When NNBD is complete, delete the following two lines. ArgumentError.checkNotNull(eventKind, 'eventKind'); ArgumentError.checkNotNull(eventData, 'eventData'); String eventDataAsString = json.encode(eventData); @@ -159,5 +158,5 @@ external void _postEvent(String eventKind, String eventData); // these into Dart code unless you can ensure that the operations will can be // done atomically. Native code lives in vm/isolate.cc- // LookupServiceExtensionHandler and RegisterServiceExtensionHandler. -external ServiceExtensionHandler _lookupExtension(String method); +external ServiceExtensionHandler? _lookupExtension(String method); external _registerExtension(String method, ServiceExtensionHandler handler); diff --git a/sdk/lib/developer/profiler.dart b/sdk/lib/developer/profiler.dart index 8104bbb4e6d..07fb6255fe7 100644 --- a/sdk/lib/developer/profiler.dart +++ b/sdk/lib/developer/profiler.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.developer; /// A UserTag can be used to group samples in the Observatory profiler. @@ -65,11 +63,12 @@ class Gauge extends Metric { } Gauge(String name, String description, this.min, this.max) - : super(name, description) { + : _value = min, + super(name, description) { + // TODO: When NNBD is complete, delete the following two lines. ArgumentError.checkNotNull(min, 'min'); ArgumentError.checkNotNull(max, 'max'); if (!(min < max)) throw new ArgumentError('min must be less than max'); - _value = min; } Map _toJSON() { @@ -113,6 +112,7 @@ class Metrics { /// Register [Metric]s to make them visible to Observatory. static void register(Metric metric) { + // TODO: When NNBD is complete, delete the following line. ArgumentError.checkNotNull(metric, 'metric'); if (_metrics[metric.name] != null) { throw new ArgumentError('Registered metrics have unique names'); @@ -122,13 +122,14 @@ class Metrics { /// Deregister [Metric]s to make them not visible to Observatory. static void deregister(Metric metric) { + // TODO: When NNBD is complete, delete the following line. ArgumentError.checkNotNull(metric, 'metric'); _metrics.remove(metric.name); } // ignore: unused_element, called from native code @pragma("vm:entry-point", !const bool.fromEnvironment("dart.vm.product")) - static String _printMetric(String id) { + static String? _printMetric(String id) { var metric = _metrics[id]; if (metric == null) { return null; diff --git a/sdk/lib/developer/service.dart b/sdk/lib/developer/service.dart index 81d0540a2df..6d90667441c 100644 --- a/sdk/lib/developer/service.dart +++ b/sdk/lib/developer/service.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.developer; /// Service protocol is the protocol that a client like the Observatory @@ -21,7 +19,7 @@ class ServiceProtocolInfo { /// The Uri to access the service. If the web server is not running, this /// will be null. - final Uri serverUri; + final Uri? serverUri; ServiceProtocolInfo(this.serverUri); @@ -44,12 +42,12 @@ class Service { static Future getInfo() async { // Port to receive response from service isolate. final RawReceivePort receivePort = new RawReceivePort(); - final Completer uriCompleter = new Completer(); - receivePort.handler = (Uri uri) => uriCompleter.complete(uri); + final Completer uriCompleter = new Completer(); + receivePort.handler = (Uri? uri) => uriCompleter.complete(uri); // Request the information from the service isolate. _getServerInfo(receivePort.sendPort); // Await the response from the service isolate. - Uri uri = await uriCompleter.future; + Uri? uri = await uriCompleter.future; // Close the port. receivePort.close(); return new ServiceProtocolInfo(uri); @@ -60,6 +58,7 @@ class Service { /// enable (true) or disable (false) the web server servicing requests. static Future controlWebServer( {bool enable: false}) async { + // TODO: When NNBD is complete, delete the following line. ArgumentError.checkNotNull(enable, 'enable'); // Port to receive response from service isolate. final RawReceivePort receivePort = new RawReceivePort(); @@ -78,7 +77,8 @@ class Service { /// /// Returns null if the running Dart environment does not support the service /// protocol. - static String getIsolateID(Isolate isolate) { + static String? getIsolateID(Isolate isolate) { + // TODO: When NNBD is complete, delete the following line. ArgumentError.checkNotNull(isolate, 'isolate'); return _getIsolateIDFromSendPort(isolate.controlPort); } @@ -97,4 +97,4 @@ external int _getServiceMajorVersion(); external int _getServiceMinorVersion(); /// Returns the service id for the isolate that owns [sendPort]. -external String _getIsolateIDFromSendPort(SendPort sendPort); +external String? _getIsolateIDFromSendPort(SendPort sendPort); diff --git a/sdk/lib/developer/timeline.dart b/sdk/lib/developer/timeline.dart index cd1b43d95a2..cc9cf4045ee 100644 --- a/sdk/lib/developer/timeline.dart +++ b/sdk/lib/developer/timeline.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.developer; const bool _hasTimeline = @@ -58,7 +56,7 @@ class Flow { /// When passed to a [Timeline] method, generates a "begin" Flow event. /// If [id] is not provided, an id that conflicts with no other Dart-generated /// flow id's will be generated. - static Flow begin({int id}) { + static Flow begin({int? id}) { return new Flow._(_begin, id ?? _getNextAsyncId()); } @@ -102,8 +100,9 @@ class Timeline { /// a [Map] of [arguments]. This slice may also optionally be associated with /// a [Flow] event. This operation must be finished before /// returning to the event queue. - static void startSync(String name, {Map arguments, Flow flow}) { + static void startSync(String name, {Map? arguments, Flow? flow}) { if (!_hasTimeline) return; + // TODO: When NNBD is complete, delete the following line. ArgumentError.checkNotNull(name, 'name'); if (!_isDartStreamEnabled()) { // Push a null onto the stack and return. @@ -140,14 +139,15 @@ class Timeline { } /// Emit an instant event. - static void instantSync(String name, {Map arguments}) { + static void instantSync(String name, {Map? arguments}) { if (!_hasTimeline) return; + // TODO: When NNBD is complete, delete the following line. ArgumentError.checkNotNull(name, 'name'); if (!_isDartStreamEnabled()) { // Stream is disabled. return; } - Map instantArguments; + Map? instantArguments; if (arguments != null) { instantArguments = new Map.from(arguments); } @@ -157,7 +157,7 @@ class Timeline { /// A utility method to time a synchronous [function]. Internally calls /// [function] bracketed by calls to [startSync] and [finishSync]. static T timeSync(String name, TimelineSyncFunction function, - {Map arguments, Flow flow}) { + {Map? arguments, Flow? flow}) { startSync(name, arguments: arguments, flow: flow); try { return function(); @@ -172,7 +172,7 @@ class Timeline { /// When run on the Dart VM, uses the same monotonic clock as the embedding /// API's `Dart_TimelineGetMicros`. static int get now => _getTraceClock(); - static final List<_SyncBlock> _stack = new List<_SyncBlock>(); + static final List<_SyncBlock?> _stack = []; } /// An asynchronous task on the timeline. An asynchronous task can have many @@ -190,7 +190,7 @@ class TimelineTask { /// If [filterKey] is provided, a property named `filterKey` will be inserted /// into the arguments of each event associated with this task. The /// `filterKey` will be set to the value of [filterKey]. - TimelineTask({TimelineTask parent, String filterKey}) + TimelineTask({TimelineTask? parent, String? filterKey}) : _parent = parent, _filterKey = filterKey, _taskId = _getNextAsyncId() {} @@ -205,33 +205,44 @@ class TimelineTask { /// If [filterKey] is provided, a property named `filterKey` will be inserted /// into the arguments of each event associated with this task. The /// `filterKey` will be set to the value of [filterKey]. - TimelineTask.withTaskId(int taskId, {String filterKey}) + TimelineTask.withTaskId(int taskId, {String? filterKey}) : _parent = null, _filterKey = filterKey, _taskId = taskId { + // TODO: When NNBD is complete, delete the following line. ArgumentError.checkNotNull(taskId, 'taskId'); } /// Start a synchronous operation within this task named [name]. /// Optionally takes a [Map] of [arguments]. - void start(String name, {Map arguments}) { + void start(String name, {Map? arguments}) { if (!_hasTimeline) return; + // TODO: When NNBD is complete, delete the following line. ArgumentError.checkNotNull(name, 'name'); var block = new _AsyncBlock._(name, _taskId); _stack.add(block); - block._start({ - if (arguments != null) ...arguments, - if (_parent != null) 'parentId': _parent._taskId.toRadixString(16), - if (_filterKey != null) _kFilterKey: _filterKey, - }); + // TODO(39115): Spurious error about collection literal ambiguity. + // TODO(39117): Spurious error about typing of `...?arguments`. + // TODO(39120): Spurious error even about `...arguments`. + // When these TODOs are done, we can use spread and if elements. + var map = {}; + if (arguments != null) { + for (var key in arguments.keys) { + map[key] = arguments[key]; + } + } + if (_parent != null) map['parentId'] = _parent!._taskId.toRadixString(16); + if (_filterKey != null) map[_kFilterKey] = _filterKey; + block._start(map); } /// Emit an instant event for this task. /// Optionally takes a [Map] of [arguments]. - void instant(String name, {Map arguments}) { + void instant(String name, {Map? arguments}) { if (!_hasTimeline) return; + // TODO: When NNBD is complete, delete the following line. ArgumentError.checkNotNull(name, 'name'); - Map instantArguments; + Map? instantArguments; if (arguments != null) { instantArguments = new Map.from(arguments); } @@ -245,7 +256,7 @@ class TimelineTask { /// Finish the last synchronous operation that was started. /// Optionally takes a [Map] of [arguments]. - void finish({Map arguments}) { + void finish({Map? arguments}) { if (!_hasTimeline) { return; } @@ -274,8 +285,8 @@ class TimelineTask { } static const String _kFilterKey = 'filterKey'; - final TimelineTask _parent; - final String _filterKey; + final TimelineTask? _parent; + final String? _filterKey; final int _taskId; final List<_AsyncBlock> _stack = []; } @@ -300,7 +311,7 @@ class _AsyncBlock { } // Emit the finish event. - void _finish(Map arguments) { + void _finish(Map? arguments) { _reportTaskEvent(_taskId, 'e', category, name, _argumentsAsJson(arguments)); } } @@ -316,10 +327,10 @@ class _SyncBlock { /// An (optional) set of arguments which will be serialized to JSON and /// associated with this block. - Map _arguments; + Map? _arguments; /// An (optional) flow event associated with this block. - Flow _flow; + Flow? _flow; _SyncBlock._(this.name); @@ -334,7 +345,7 @@ class _SyncBlock { // Report event to runtime. _reportTaskEvent(0, 'E', category, name, _argumentsAsJson(_arguments)); if (_flow != null) { - _reportFlowEvent(category, "${_flow.id}", _flow._type, _flow.id, + _reportFlowEvent(category, "${_flow!.id}", _flow!._type, _flow!.id, _argumentsAsJson(null)); } } @@ -344,7 +355,7 @@ class _SyncBlock { } } -String _argumentsAsJson(Map arguments) { +String _argumentsAsJson(Map? arguments) { if ((arguments == null) || (arguments.length == 0)) { // Fast path no arguments. Avoid calling jsonEncode. return '{}'; diff --git a/sdk/lib/ffi/annotations.dart b/sdk/lib/ffi/annotations.dart index 1466c352a0e..f68e5250753 100644 --- a/sdk/lib/ffi/annotations.dart +++ b/sdk/lib/ffi/annotations.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.ffi; class DartRepresentationOf { diff --git a/sdk/lib/ffi/dynamic_library.dart b/sdk/lib/ffi/dynamic_library.dart index 8cc5789618e..d11c945cb72 100644 --- a/sdk/lib/ffi/dynamic_library.dart +++ b/sdk/lib/ffi/dynamic_library.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.ffi; /// Represents a dynamically loaded C library. @@ -31,7 +29,7 @@ class DynamicLibrary { external Pointer lookup(String symbolName); /// Dynamic libraries are equal if they load the same library. - external bool operator ==(other); + external bool operator ==(Object other); /// The hash code for a DynamicLibrary only depends on the loaded library external int get hashCode; diff --git a/sdk/lib/ffi/ffi.dart b/sdk/lib/ffi/ffi.dart index 770d1bfdcf8..3b6e236b74b 100644 --- a/sdk/lib/ffi/ffi.dart +++ b/sdk/lib/ffi/ffi.dart @@ -2,8 +2,6 @@ // 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.6 - /** * Foreign Function Interface for interoperability with the C programming language. * @@ -15,8 +13,8 @@ */ library dart.ffi; -import 'dart:typed_data'; import 'dart:isolate'; +import 'dart:typed_data'; part "native_type.dart"; part "annotations.dart"; @@ -30,7 +28,7 @@ external int sizeOf(); /// Represents a pointer into the native C memory corresponding to "NULL", e.g. /// a pointer with address 0. -final Pointer nullptr = Pointer.fromAddress(0); +final Pointer nullptr = Pointer.fromAddress(0); /// Represents a pointer into the native C memory. Cannot be extended. @pragma("vm:entry-point") @@ -56,7 +54,7 @@ class Pointer extends NativeType { /// [dynamic]. external static Pointer> fromFunction( @DartRepresentationOf("T") Function f, - [Object exceptionalReturn]); + [Object? exceptionalReturn]); /// Access to the raw pointer value. /// On 32-bit systems, the upper 32-bits of the result are 0. @@ -69,9 +67,10 @@ class Pointer extends NativeType { external Pointer cast(); /// Equality for Pointers only depends on their address. - bool operator ==(other) { - if (other == null) return false; - return address == other.address; + bool operator ==(Object other) { + if (other is! Pointer) return false; + Pointer otherPointer = other; + return address == otherPointer.address; } /// The hash code for a Pointer only depends on its address. diff --git a/sdk/lib/ffi/native_type.dart b/sdk/lib/ffi/native_type.dart index 84961458c91..e3193423912 100644 --- a/sdk/lib/ffi/native_type.dart +++ b/sdk/lib/ffi/native_type.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.ffi; /// [NativeType]'s subtypes represent a native type in C. diff --git a/sdk/lib/ffi/struct.dart b/sdk/lib/ffi/struct.dart index 5d807b0a15c..c6605d8ce03 100644 --- a/sdk/lib/ffi/struct.dart +++ b/sdk/lib/ffi/struct.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.ffi; /// This class is extended to define structs. diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart index 77a36ed1898..04dcc3d96ea 100644 --- a/sdk/lib/html/dart2js/html_dart2js.dart +++ b/sdk/lib/html/dart2js/html_dart2js.dart @@ -1,5 +1,3 @@ -// @dart = 2.6 - /** * HTML elements and other resources for web-based applications that need to * interact with the browser and the DOM (Document Object Model). @@ -98,7 +96,7 @@ HtmlDocument get document => /// On a successful result the native JS result will be converted to a Dart Map. /// See [convertNativeToDart_Dictionary]. On a rejected promise the error is /// forwarded without change. -Future> promiseToFutureAsMap(jsPromise) => +Future?> promiseToFutureAsMap(jsPromise) => promiseToFuture(jsPromise).then(convertNativeToDart_Dictionary); // Workaround for tags like that lack their own Element subclass -- @@ -117,8 +115,8 @@ class HtmlElement extends Element implements NoncedElement { HtmlElement.created() : super.created(); // From NoncedElement - String get nonce native; - set nonce(String value) native; + String? get nonce native; + set nonce(String? value) native; } /** @@ -160,7 +158,7 @@ class AbsoluteOrientationSensor extends OrientationSensor { throw new UnsupportedError("Not supported"); } - factory AbsoluteOrientationSensor([Map sensorOptions]) { + factory AbsoluteOrientationSensor([Map? sensorOptions]) { if (sensorOptions != null) { var sensorOptions_1 = convertDartToNative_Dictionary(sensorOptions); return AbsoluteOrientationSensor._create_1(sensorOptions_1); @@ -207,7 +205,7 @@ class Accelerometer extends Sensor { throw new UnsupportedError("Not supported"); } - factory Accelerometer([Map sensorOptions]) { + factory Accelerometer([Map? sensorOptions]) { if (sensorOptions != null) { var sensorOptions_1 = convertDartToNative_Dictionary(sensorOptions); return Accelerometer._create_1(sensorOptions_1); @@ -219,11 +217,11 @@ class Accelerometer extends Sensor { static Accelerometer _create_2() => JS('Accelerometer', 'new Accelerometer()'); - num get x native; + num? get x native; - num get y native; + num? get y native; - num get z native; + num? get z native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -260,193 +258,193 @@ class AccessibleNode extends EventTarget { static AccessibleNode _create_1() => JS('AccessibleNode', 'new AccessibleNode()'); - AccessibleNode get activeDescendant native; + AccessibleNode? get activeDescendant native; - set activeDescendant(AccessibleNode value) native; + set activeDescendant(AccessibleNode? value) native; - bool get atomic native; + bool? get atomic native; - set atomic(bool value) native; + set atomic(bool? value) native; - String get autocomplete native; + String? get autocomplete native; - set autocomplete(String value) native; + set autocomplete(String? value) native; - bool get busy native; + bool? get busy native; - set busy(bool value) native; + set busy(bool? value) native; - String get checked native; + String? get checked native; - set checked(String value) native; + set checked(String? value) native; - int get colCount native; + int? get colCount native; - set colCount(int value) native; + set colCount(int? value) native; - int get colIndex native; + int? get colIndex native; - set colIndex(int value) native; + set colIndex(int? value) native; - int get colSpan native; + int? get colSpan native; - set colSpan(int value) native; + set colSpan(int? value) native; - AccessibleNodeList get controls native; + AccessibleNodeList? get controls native; - set controls(AccessibleNodeList value) native; + set controls(AccessibleNodeList? value) native; - String get current native; + String? get current native; - set current(String value) native; + set current(String? value) native; - AccessibleNodeList get describedBy native; + AccessibleNodeList? get describedBy native; - set describedBy(AccessibleNodeList value) native; + set describedBy(AccessibleNodeList? value) native; - AccessibleNode get details native; + AccessibleNode? get details native; - set details(AccessibleNode value) native; + set details(AccessibleNode? value) native; - bool get disabled native; + bool? get disabled native; - set disabled(bool value) native; + set disabled(bool? value) native; - AccessibleNode get errorMessage native; + AccessibleNode? get errorMessage native; - set errorMessage(AccessibleNode value) native; + set errorMessage(AccessibleNode? value) native; - bool get expanded native; + bool? get expanded native; - set expanded(bool value) native; + set expanded(bool? value) native; - AccessibleNodeList get flowTo native; + AccessibleNodeList? get flowTo native; - set flowTo(AccessibleNodeList value) native; + set flowTo(AccessibleNodeList? value) native; - String get hasPopUp native; + String? get hasPopUp native; - set hasPopUp(String value) native; + set hasPopUp(String? value) native; - bool get hidden native; + bool? get hidden native; - set hidden(bool value) native; + set hidden(bool? value) native; - String get invalid native; + String? get invalid native; - set invalid(String value) native; + set invalid(String? value) native; - String get keyShortcuts native; + String? get keyShortcuts native; - set keyShortcuts(String value) native; + set keyShortcuts(String? value) native; - String get label native; + String? get label native; - set label(String value) native; + set label(String? value) native; - AccessibleNodeList get labeledBy native; + AccessibleNodeList? get labeledBy native; - set labeledBy(AccessibleNodeList value) native; + set labeledBy(AccessibleNodeList? value) native; - int get level native; + int? get level native; - set level(int value) native; + set level(int? value) native; - String get live native; + String? get live native; - set live(String value) native; + set live(String? value) native; - bool get modal native; + bool? get modal native; - set modal(bool value) native; + set modal(bool? value) native; - bool get multiline native; + bool? get multiline native; - set multiline(bool value) native; + set multiline(bool? value) native; - bool get multiselectable native; + bool? get multiselectable native; - set multiselectable(bool value) native; + set multiselectable(bool? value) native; - String get orientation native; + String? get orientation native; - set orientation(String value) native; + set orientation(String? value) native; - AccessibleNodeList get owns native; + AccessibleNodeList? get owns native; - set owns(AccessibleNodeList value) native; + set owns(AccessibleNodeList? value) native; - String get placeholder native; + String? get placeholder native; - set placeholder(String value) native; + set placeholder(String? value) native; - int get posInSet native; + int? get posInSet native; - set posInSet(int value) native; + set posInSet(int? value) native; - String get pressed native; + String? get pressed native; - set pressed(String value) native; + set pressed(String? value) native; - bool get readOnly native; + bool? get readOnly native; - set readOnly(bool value) native; + set readOnly(bool? value) native; - String get relevant native; + String? get relevant native; - set relevant(String value) native; + set relevant(String? value) native; - bool get required native; + bool? get required native; - set required(bool value) native; + set required(bool? value) native; - String get role native; + String? get role native; - set role(String value) native; + set role(String? value) native; - String get roleDescription native; + String? get roleDescription native; - set roleDescription(String value) native; + set roleDescription(String? value) native; - int get rowCount native; + int? get rowCount native; - set rowCount(int value) native; + set rowCount(int? value) native; - int get rowIndex native; + int? get rowIndex native; - set rowIndex(int value) native; + set rowIndex(int? value) native; - int get rowSpan native; + int? get rowSpan native; - set rowSpan(int value) native; + set rowSpan(int? value) native; - bool get selected native; + bool? get selected native; - set selected(bool value) native; + set selected(bool? value) native; - int get setSize native; + int? get setSize native; - set setSize(int value) native; + set setSize(int? value) native; - String get sort native; + String? get sort native; - set sort(String value) native; + set sort(String? value) native; - num get valueMax native; + num? get valueMax native; - set valueMax(num value) native; + set valueMax(num? value) native; - num get valueMin native; + num? get valueMin native; - set valueMin(num value) native; + set valueMin(num? value) native; - num get valueNow native; + num? get valueNow native; - set valueNow(num value) native; + set valueNow(num? value) native; - String get valueText native; + String? get valueText native; - set valueText(String value) native; + set valueText(String? value) native; void appendChild(AccessibleNode child) native; @@ -477,7 +475,7 @@ class AccessibleNodeList extends Interceptor { throw new UnsupportedError("Not supported"); } - factory AccessibleNodeList([List nodes]) { + factory AccessibleNodeList([List? nodes]) { if (nodes != null) { return AccessibleNodeList._create_1(nodes); } @@ -494,9 +492,9 @@ class AccessibleNodeList extends Interceptor { void __setter__(int index, AccessibleNode node) native; - void add(AccessibleNode node, AccessibleNode before) native; + void add(AccessibleNode node, AccessibleNode? before) native; - AccessibleNode item(int index) native; + AccessibleNode? item(int index) native; void remove(int index) native; } @@ -511,7 +509,7 @@ class AmbientLightSensor extends Sensor { throw new UnsupportedError("Not supported"); } - factory AmbientLightSensor([Map sensorOptions]) { + factory AmbientLightSensor([Map? sensorOptions]) { if (sensorOptions != null) { var sensorOptions_1 = convertDartToNative_Dictionary(sensorOptions); return AmbientLightSensor._create_1(sensorOptions_1); @@ -523,7 +521,7 @@ class AmbientLightSensor extends Sensor { static AmbientLightSensor _create_2() => JS('AmbientLightSensor', 'new AmbientLightSensor()'); - num get illuminance native; + num? get illuminance native; } // 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 @@ -536,9 +534,12 @@ class AnchorElement extends HtmlElement implements HtmlHyperlinkElementUtils { throw new UnsupportedError("Not supported"); } - factory AnchorElement({String href}) { - AnchorElement e = JS('returns:AnchorElement;creates:AnchorElement;new:true', - '#.createElement(#)', document, "a"); + factory AnchorElement({String? href}) { + AnchorElement e = JS( + 'returns:AnchorElement;creates:AnchorElement;new:true', + '#.createElement(#)', + document, + "a"); if (href != null) e.href = href; return e; } @@ -637,7 +638,7 @@ class Animation extends EventTarget { const EventStreamProvider('finish'); factory Animation( - [AnimationEffectReadOnly effect, AnimationTimeline timeline]) { + [AnimationEffectReadOnly? effect, AnimationTimeline? timeline]) { if (timeline != null) { return Animation._create_1(effect, timeline); } @@ -655,13 +656,13 @@ class Animation extends EventTarget { /// Checks if this type is supported on the current platform. static bool get supported => JS('bool', '!!(document.body.animate)'); - num get currentTime native; + num? get currentTime native; - set currentTime(num value) native; + set currentTime(num? value) native; - AnimationEffectReadOnly get effect native; + AnimationEffectReadOnly? get effect native; - set effect(AnimationEffectReadOnly value) native; + set effect(AnimationEffectReadOnly? value) native; Future get finished => promiseToFuture(JS("", "#.finished", this)); @@ -679,11 +680,11 @@ class Animation extends EventTarget { Future get ready => promiseToFuture(JS("", "#.ready", this)); - num get startTime native; + num? get startTime native; - set startTime(num value) native; + set startTime(num? value) native; - AnimationTimeline get timeline native; + AnimationTimeline? get timeline native; void cancel() native; @@ -713,7 +714,7 @@ class AnimationEffectReadOnly extends Interceptor { AnimationEffectTimingReadOnly get timing native; Map getComputedTiming() { - return convertNativeToDart_Dictionary(_getComputedTiming_1()); + return convertNativeToDart_Dictionary(_getComputedTiming_1())!; } @JSName('getComputedTiming') @@ -745,9 +746,9 @@ class AnimationEffectTiming extends AnimationEffectTimingReadOnly { // Shadowing definition. @Returns('num|String|Null') - Object get duration native; + Object? get duration native; - set duration(Object value) native; + set duration(Object? value) native; // Shadowing definition. @@ -794,7 +795,7 @@ class AnimationEffectTimingReadOnly extends Interceptor { String get direction native; - Object get duration native; + Object? get duration native; String get easing native; @@ -817,7 +818,7 @@ class AnimationEvent extends Event { throw new UnsupportedError("Not supported"); } - factory AnimationEvent(String type, [Map eventInitDict]) { + factory AnimationEvent(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return AnimationEvent._create_1(type, eventInitDict_1); @@ -844,7 +845,7 @@ class AnimationPlaybackEvent extends Event { throw new UnsupportedError("Not supported"); } - factory AnimationPlaybackEvent(String type, [Map eventInitDict]) { + factory AnimationPlaybackEvent(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return AnimationPlaybackEvent._create_1(type, eventInitDict_1); @@ -859,9 +860,9 @@ class AnimationPlaybackEvent extends Event { static AnimationPlaybackEvent _create_2(type) => JS('AnimationPlaybackEvent', 'new AnimationPlaybackEvent(#)', type); - num get currentTime native; + num? get currentTime native; - num get timelineTime native; + num? get timelineTime native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -874,7 +875,7 @@ class AnimationTimeline extends Interceptor { throw new UnsupportedError("Not supported"); } - num get currentTime native; + num? get currentTime native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -1039,7 +1040,7 @@ class ApplicationCacheErrorEvent extends Event { throw new UnsupportedError("Not supported"); } - factory ApplicationCacheErrorEvent(String type, [Map eventInitDict]) { + factory ApplicationCacheErrorEvent(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return ApplicationCacheErrorEvent._create_1(type, eventInitDict_1); @@ -1083,7 +1084,7 @@ class AreaElement extends HtmlElement implements HtmlHyperlinkElementUtils { throw new UnsupportedError("Not supported"); } - factory AreaElement() => JS( + factory AreaElement() => JS( 'returns:AreaElement;creates:AreaElement;new:true', '#.createElement(#)', document, @@ -1175,7 +1176,7 @@ class AreaElement extends HtmlElement implements HtmlHyperlinkElementUtils { @Native("HTMLAudioElement") class AudioElement extends MediaElement { - factory AudioElement._([String src]) { + factory AudioElement._([String? src]) { if (src != null) { return AudioElement._create_1(src); } @@ -1190,7 +1191,7 @@ class AudioElement extends MediaElement { */ AudioElement.created() : super.created(); - factory AudioElement([String src]) => new AudioElement._(src); + factory AudioElement([String? src]) => new AudioElement._(src); } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -1245,8 +1246,11 @@ class BRElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory BRElement() => JS('returns:BRElement;creates:BRElement;new:true', - '#.createElement(#)', document, "br"); + factory BRElement() => JS( + 'returns:BRElement;creates:BRElement;new:true', + '#.createElement(#)', + document, + "br"); /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -1345,7 +1349,7 @@ class BackgroundFetchManager extends Interceptor { } Future fetch(String id, Object requests, - [Map options]) { + [Map? options]) { var options_dict = null; if (options != null) { options_dict = convertDartToNative_Dictionary(options); @@ -1408,7 +1412,7 @@ class BackgroundFetchSettledFetch extends BackgroundFetchFetch { request, response); - _Response get response native; + _Response? get response native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -1479,7 +1483,7 @@ class BaseElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory BaseElement() => JS( + factory BaseElement() => JS( 'returns:BaseElement;creates:BaseElement;new:true', '#.createElement(#)', document, @@ -1529,7 +1533,7 @@ class BeforeInstallPromptEvent extends Event { throw new UnsupportedError("Not supported"); } - factory BeforeInstallPromptEvent(String type, [Map eventInitDict]) { + factory BeforeInstallPromptEvent(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return BeforeInstallPromptEvent._create_1(type, eventInitDict_1); @@ -1546,7 +1550,7 @@ class BeforeInstallPromptEvent extends Event { List get platforms native; - Future> get userChoice => + Future?> get userChoice => promiseToFutureAsMap(JS("", "#.userChoice", this)); Future prompt() => promiseToFuture(JS("", "#.prompt()", this)); @@ -1583,9 +1587,9 @@ class Blob extends Interceptor { String get type native; - Blob slice([int start, int end, String contentType]) native; + Blob slice([int? start, int? end, String? contentType]) native; - factory Blob(List blobParts, [String type, String endings]) { + factory Blob(List blobParts, [String? type, String? endings]) { // TODO: validate that blobParts is a JS Array and convert if not. // TODO: any coercions on the elements of blobParts, e.g. coerce a typed // array to ArrayBuffer if it is a total view. @@ -1612,7 +1616,7 @@ class Blob extends Interceptor { // WARNING: Do not edit - generated code. -typedef void BlobCallback(Blob blob); +typedef void BlobCallback(Blob? blob); // Copyright (c) 2012, 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. @@ -1650,7 +1654,7 @@ class BluetoothRemoteGattDescriptor extends Interceptor { String get uuid native; - ByteData get value native; + ByteData? get value native; Future readValue() => promiseToFuture(JS("", "#.readValue()", this)); @@ -1803,7 +1807,7 @@ class BodyElement extends HtmlElement implements WindowEventHandlers { static const EventStreamProvider unloadEvent = const EventStreamProvider('unload'); - factory BodyElement() => JS( + factory BodyElement() => JS( 'returns:BodyElement;creates:BodyElement;new:true', '#.createElement(#)', document, @@ -1907,7 +1911,7 @@ class ButtonElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory ButtonElement() => JS( + factory ButtonElement() => JS( 'returns:ButtonElement;creates:ButtonElement;new:true', '#.createElement(#)', document, @@ -1927,7 +1931,7 @@ class ButtonElement extends HtmlElement { set disabled(bool value) native; - FormElement get form native; + FormElement? get form native; String get formAction native; @@ -1950,7 +1954,7 @@ class ButtonElement extends HtmlElement { set formTarget(String value) native; @Unstable() - @Returns('NodeList|Null') + @Returns('NodeList') @Creates('NodeList') List get labels native; @@ -2010,7 +2014,7 @@ class CacheStorage extends Interceptor { Future keys() => promiseToFuture(JS("", "#.keys()", this)); - Future match(/*RequestInfo*/ request, [Map options]) { + Future match(/*RequestInfo*/ request, [Map? options]) { var options_dict = null; if (options != null) { options_dict = convertDartToNative_Dictionary(options); @@ -2097,9 +2101,12 @@ class CanvasElement extends HtmlElement implements CanvasImageSource { static const EventStreamProvider webGlContextRestoredEvent = const EventStreamProvider('webglcontextrestored'); - factory CanvasElement({int width, int height}) { - CanvasElement e = JS('returns:CanvasElement;creates:CanvasElement;new:true', - '#.createElement(#)', document, "canvas"); + factory CanvasElement({int? width, int? height}) { + CanvasElement e = JS( + 'returns:CanvasElement;creates:CanvasElement;new:true', + '#.createElement(#)', + document, + "canvas"); if (width != null) e.width = width; if (height != null) e.height = height; return e; @@ -2123,11 +2130,11 @@ class CanvasElement extends HtmlElement implements CanvasImageSource { set width(int value) native; - MediaStream captureStream([num frameRate]) native; + MediaStream captureStream([num? frameRate]) native; @Creates('CanvasRenderingContext2D|RenderingContext|RenderingContext2') @Returns('CanvasRenderingContext2D|RenderingContext|RenderingContext2|Null') - Object getContext(String contextId, [Map attributes]) { + Object? getContext(String contextId, [Map? attributes]) { if (attributes != null) { var attributes_1 = convertDartToNative_Dictionary(attributes); return _getContext_1(contextId, attributes_1); @@ -2138,14 +2145,14 @@ class CanvasElement extends HtmlElement implements CanvasImageSource { @JSName('getContext') @Creates('CanvasRenderingContext2D|RenderingContext|RenderingContext2') @Returns('CanvasRenderingContext2D|RenderingContext|RenderingContext2|Null') - Object _getContext_1(contextId, attributes) native; + Object? _getContext_1(contextId, attributes) native; @JSName('getContext') @Creates('CanvasRenderingContext2D|RenderingContext|RenderingContext2') @Returns('CanvasRenderingContext2D|RenderingContext|RenderingContext2|Null') - Object _getContext_2(contextId) native; + Object? _getContext_2(contextId) native; @JSName('toDataURL') - String _toDataUrl(String type, [arguments_OR_quality]) native; + String _toDataUrl(String? type, [arguments_OR_quality]) native; OffscreenCanvas transferControlToOffscreen() native; @@ -2191,7 +2198,7 @@ class CanvasElement extends HtmlElement implements CanvasImageSource { if (context == null) { context = getContext('experimental-webgl', options); } - return context; + return context as gl.RenderingContext; } /** @@ -2235,13 +2242,13 @@ class CanvasElement extends HtmlElement implements CanvasImageSource { * * * [toDataUrl](http://dev.w3.org/html5/spec/the-canvas-element.html#dom-canvas-todataurl) from W3C. */ - String toDataUrl([String type = 'image/png', num quality]) => + String toDataUrl([String type = 'image/png', num? quality]) => _toDataUrl(type, quality); @JSName('toBlob') - void _toBlob(BlobCallback callback, [String type, Object arguments]) native; + void _toBlob(BlobCallback callback, [String? type, Object? arguments]) native; - Future toBlob([String type, Object arguments]) { + Future toBlob([String? type, Object? arguments]) { var completer = new Completer(); _toBlob((value) { completer.complete(value); @@ -2370,9 +2377,9 @@ class CanvasRenderingContext2D extends Interceptor @Creates('String|CanvasGradient|CanvasPattern') @Returns('String|CanvasGradient|CanvasPattern') - Object get fillStyle native; + Object? get fillStyle native; - set fillStyle(Object value) native; + set fillStyle(Object? value) native; String get filter native; @@ -2443,9 +2450,9 @@ class CanvasRenderingContext2D extends Interceptor @Creates('String|CanvasGradient|CanvasPattern') @Returns('String|CanvasGradient|CanvasPattern') - Object get strokeStyle native; + Object? get strokeStyle native; - set strokeStyle(Object value) native; + set strokeStyle(Object? value) native; String get textAlign native; @@ -2455,7 +2462,7 @@ class CanvasRenderingContext2D extends Interceptor set textBaseline(String value) native; - void addHitRegion([Map options]) { + void addHitRegion([Map? options]) { if (options != null) { var options_1 = convertDartToNative_Dictionary(options); _addHitRegion_1(options_1); @@ -2476,13 +2483,13 @@ class CanvasRenderingContext2D extends Interceptor void clearRect(num x, num y, num width, num height) native; - void clip([path_OR_winding, String winding]) native; + void clip([path_OR_winding, String? winding]) native; @Creates('ImageData|=Object') ImageData createImageData(data_OR_imagedata_OR_sw, - [int sh_OR_sw, + [int? sh_OR_sw, imageDataColorSettings_OR_sh, - Map imageDataColorSettings]) { + Map? imageDataColorSettings]) { if ((data_OR_imagedata_OR_sw is ImageData) && sh_OR_sw == null && imageDataColorSettings_OR_sh == null && @@ -2539,26 +2546,26 @@ class CanvasRenderingContext2D extends Interceptor _createImageData_3(int sw, sh, imageDataColorSettings) native; @JSName('createImageData') @Creates('ImageData|=Object') - _createImageData_4(data, sw, int sh) native; + _createImageData_4(data, sw, int? sh) native; @JSName('createImageData') @Creates('ImageData|=Object') - _createImageData_5(data, sw, int sh, imageDataColorSettings) native; + _createImageData_5(data, sw, int? sh, imageDataColorSettings) native; CanvasGradient createLinearGradient(num x0, num y0, num x1, num y1) native; - CanvasPattern createPattern(Object image, String repetitionType) native; + CanvasPattern? createPattern(Object image, String repetitionType) native; CanvasGradient createRadialGradient( num x0, num y0, num r0, num x1, num y1, num r1) native; - void drawFocusIfNeeded(element_OR_path, [Element element]) native; + void drawFocusIfNeeded(element_OR_path, [Element? element]) native; - void fill([path_OR_winding, String winding]) native; + void fill([path_OR_winding, String? winding]) native; void fillRect(num x, num y, num width, num height) native; Map getContextAttributes() { - return convertNativeToDart_Dictionary(_getContextAttributes_1()); + return convertNativeToDart_Dictionary(_getContextAttributes_1())!; } @JSName('getContextAttributes') @@ -2578,15 +2585,15 @@ class CanvasRenderingContext2D extends Interceptor bool isContextLost() native; - bool isPointInPath(path_OR_x, num x_OR_y, [winding_OR_y, String winding]) + bool isPointInPath(path_OR_x, num x_OR_y, [winding_OR_y, String? winding]) native; - bool isPointInStroke(path_OR_x, num x_OR_y, [num y]) native; + bool isPointInStroke(path_OR_x, num x_OR_y, [num? y]) native; TextMetrics measureText(String text) native; void putImageData(ImageData imagedata, int dx, int dy, - [int dirtyX, int dirtyY, int dirtyWidth, int dirtyHeight]) { + [int? dirtyX, int? dirtyY, int? dirtyWidth, int? dirtyHeight]) { if (dirtyX == null && dirtyY == null && dirtyWidth == null && @@ -2625,15 +2632,15 @@ class CanvasRenderingContext2D extends Interceptor void scale(num x, num y) native; - void scrollPathIntoView([Path2D path]) native; + void scrollPathIntoView([Path2D? path]) native; void setTransform(num a, num b, num c, num d, num e, num f) native; - void stroke([Path2D path]) native; + void stroke([Path2D? path]) native; void strokeRect(num x, num y, num width, num height) native; - void strokeText(String text, num x, num y, [num maxWidth]) native; + void strokeText(String text, num x, num y, [num? maxWidth]) native; void transform(num a, num b, num c, num d, num e, num f) native; @@ -2643,7 +2650,7 @@ class CanvasRenderingContext2D extends Interceptor @JSName('arc') void _arc(num x, num y, num radius, num startAngle, num endAngle, - bool anticlockwise) native; + bool? anticlockwise) native; void arcTo(num x1, num y1, num x2, num y2, num radius) native; @@ -2653,7 +2660,7 @@ class CanvasRenderingContext2D extends Interceptor void closePath() native; void ellipse(num x, num y, num radiusX, num radiusY, num rotation, - num startAngle, num endAngle, bool anticlockwise) native; + num startAngle, num endAngle, bool? anticlockwise) native; void lineTo(num x, num y) native; @@ -2754,7 +2761,7 @@ class CanvasRenderingContext2D extends Interceptor * from the WHATWG. */ void drawImageToRect(CanvasImageSource source, Rectangle destRect, - {Rectangle sourceRect}) { + {Rectangle? sourceRect}) { if (sourceRect == null) { drawImageScaled( source, destRect.left, destRect.top, destRect.width, destRect.height); @@ -2945,7 +2952,7 @@ class CanvasRenderingContext2D extends Interceptor * [CanvasRenderingContext2D.textBaseLine] properties are also applied to the * drawn text. */ - void fillText(String text, num x, num y, [num maxWidth]) { + void fillText(String text, num x, num y, [num? maxWidth]) { if (maxWidth != null) { JS('void', '#.fillText(#, #, #, #)', this, text, x, y, maxWidth); } else { @@ -2993,9 +3000,9 @@ class CharacterData extends Node // From NonDocumentTypeChildNode - Element get nextElementSibling native; + Element? get nextElementSibling native; - Element get previousElementSibling native; + Element? get previousElementSibling native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -3032,7 +3039,7 @@ class Client extends Interceptor { String get url native; - void postMessage(Object message, [List transfer]) native; + void postMessage(Object message, [List? transfer]) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -3049,7 +3056,7 @@ class Clients extends Interceptor { Future get(String id) => promiseToFuture(JS("", "#.get(#)", this, id)); - Future> matchAll([Map options]) { + Future> matchAll([Map? options]) { var options_dict = null; if (options != null) { options_dict = convertDartToNative_Dictionary(options); @@ -3072,7 +3079,7 @@ class ClipboardEvent extends Event { throw new UnsupportedError("Not supported"); } - factory ClipboardEvent(String type, [Map eventInitDict]) { + factory ClipboardEvent(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return ClipboardEvent._create_1(type, eventInitDict_1); @@ -3084,7 +3091,7 @@ class ClipboardEvent extends Event { static ClipboardEvent _create_2(type) => JS('ClipboardEvent', 'new ClipboardEvent(#)', type); - DataTransfer get clipboardData native; + DataTransfer? get clipboardData native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -3097,7 +3104,7 @@ class CloseEvent extends Event { throw new UnsupportedError("Not supported"); } - factory CloseEvent(String type, [Map eventInitDict]) { + factory CloseEvent(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return CloseEvent._create_1(type, eventInitDict_1); @@ -3121,7 +3128,7 @@ class CloseEvent extends Event { @Native("Comment") class Comment extends CharacterData { - factory Comment([String data]) { + factory Comment([String? data]) { return JS('returns:Comment;depends:none;effects:none;new:true', '#.createComment(#)', document, data == null ? "" : data); } @@ -3141,13 +3148,14 @@ class CompositionEvent extends UIEvent { factory CompositionEvent(String type, {bool canBubble: false, bool cancelable: false, - Window view, - String data, - String locale}) { + Window? view, + String? data, + String? locale}) { if (view == null) { view = window; } - CompositionEvent e = document._createEvent("CompositionEvent"); + CompositionEvent e = + document._createEvent("CompositionEvent") as CompositionEvent; if (Device.isFirefox) { // Firefox requires the locale parameter that isn't supported elsewhere. @@ -3160,7 +3168,7 @@ class CompositionEvent extends UIEvent { return e; } - factory CompositionEvent._(String type, [Map eventInitDict]) { + factory CompositionEvent._(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return CompositionEvent._create_1(type, eventInitDict_1); @@ -3175,8 +3183,8 @@ class CompositionEvent extends UIEvent { String get data native; @JSName('initCompositionEvent') - void _initCompositionEvent(String type, bool bubbles, bool cancelable, - Window view, String data) native; + void _initCompositionEvent(String? type, bool? bubbles, bool? cancelable, + Window? view, String? data) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -3190,7 +3198,8 @@ class ContentElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory ContentElement() => document.createElement("content"); + factory ContentElement() => + document.createElement("content") as ContentElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -3205,7 +3214,7 @@ class ContentElement extends HtmlElement { set select(String value) native; - @Returns('NodeList|Null') + @Returns('NodeList') @Creates('NodeList') List getDistributedNodes() native; } @@ -3220,7 +3229,7 @@ class CookieStore extends Interceptor { throw new UnsupportedError("Not supported"); } - Future getAll([Map options]) { + Future getAll([Map? options]) { var options_dict = null; if (options != null) { options_dict = convertDartToNative_Dictionary(options); @@ -3228,7 +3237,7 @@ class CookieStore extends Interceptor { return promiseToFuture(JS("", "#.getAll(#)", this, options_dict)); } - Future set(String name, String value, [Map options]) { + Future set(String name, String value, [Map? options]) { var options_dict = null; if (options != null) { options_dict = convertDartToNative_Dictionary(options); @@ -3250,17 +3259,17 @@ class Coordinates extends Interceptor { num get accuracy native; - num get altitude native; + num? get altitude native; - num get altitudeAccuracy native; + num? get altitudeAccuracy native; - num get heading native; + num? get heading native; num get latitude native; num get longitude native; - num get speed native; + num? get speed native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -3304,7 +3313,7 @@ class CredentialsContainer extends Interceptor { throw new UnsupportedError("Not supported"); } - Future create([Map options]) { + Future create([Map? options]) { var options_dict = null; if (options != null) { options_dict = convertDartToNative_Dictionary(options); @@ -3312,7 +3321,7 @@ class CredentialsContainer extends Interceptor { return promiseToFuture(JS("", "#.create(#)", this, options_dict)); } - Future get([Map options]) { + Future get([Map? options]) { var options_dict = null; if (options != null) { options_dict = convertDartToNative_Dictionary(options); @@ -3515,7 +3524,7 @@ class CssGroupingRule extends CssRule { throw new UnsupportedError("Not supported"); } - @Returns('_CssRuleList|Null') + @Returns('_CssRuleList') @Creates('_CssRuleList') List get cssRules native; @@ -3534,11 +3543,11 @@ class CssImageValue extends CssResourceValue { throw new UnsupportedError("Not supported"); } - num get intrinsicHeight native; + num? get intrinsicHeight native; - num get intrinsicRatio native; + num? get intrinsicRatio native; - num get intrinsicWidth native; + num? get intrinsicWidth native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -3585,7 +3594,7 @@ class CssKeyframesRule extends CssRule { throw new UnsupportedError("Not supported"); } - @Returns('_CssRuleList|Null') + @Returns('_CssRuleList') @Creates('_CssRuleList') List get cssRules native; @@ -3599,7 +3608,7 @@ class CssKeyframesRule extends CssRule { void deleteRule(String select) native; - CssKeyframeRule findRule(String select) native; + CssKeyframeRule? findRule(String select) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -3633,7 +3642,7 @@ class CssMatrixComponent extends CssTransformComponent { throw new UnsupportedError("Not supported"); } - factory CssMatrixComponent(DomMatrixReadOnly matrix, [Map options]) { + factory CssMatrixComponent(DomMatrixReadOnly matrix, [Map? options]) { if (options != null) { var options_1 = convertDartToNative_Dictionary(options); return CssMatrixComponent._create_1(matrix, options_1); @@ -3788,7 +3797,8 @@ class CssRotation extends CssTransformComponent { throw new UnsupportedError("Not supported"); } - factory CssRotation(angleValue_OR_x, [num y, num z, CssNumericValue angle]) { + factory CssRotation(angleValue_OR_x, + [num? y, num? z, CssNumericValue? angle]) { if ((angleValue_OR_x is CssNumericValue) && y == null && z == null && @@ -3861,9 +3871,9 @@ class CssRule extends Interceptor { set cssText(String value) native; - CssRule get parentRule native; + CssRule? get parentRule native; - CssStyleSheet get parentStyleSheet native; + CssStyleSheet? get parentStyleSheet native; int get type native; } @@ -3878,7 +3888,7 @@ class CssScale extends CssTransformComponent { throw new UnsupportedError("Not supported"); } - factory CssScale(num x, num y, [num z]) { + factory CssScale(num x, num y, [num? z]) { if ((y is num) && (x is num) && z == null) { return CssScale._create_1(x, y); } @@ -3978,13 +3988,13 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { return JS('bool', '# in #', propertyName, this); } - void setProperty(String propertyName, String value, [String priority]) { + void setProperty(String propertyName, String? value, [String? priority]) { return _setPropertyHelper( _browserPropertyName(propertyName), value, priority); } String _browserPropertyName(String propertyName) { - String name = _readCache(propertyName); + String? name = _readCache(propertyName); if (name is String) return name; name = _supportedBrowserPropertyName(propertyName); _writeCache(propertyName, name); @@ -4004,7 +4014,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { } static final _propertyCache = JS('', '{}'); - static String _readCache(String key) => + static String? _readCache(String key) => JS('String|Null', '#[#]', _propertyCache, key); static void _writeCache(String key, String value) { JS('void', '#[#] = #', _propertyCache, key, value); @@ -4019,8 +4029,8 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { replacedMs); } - void _setPropertyHelper(String propertyName, String value, - [String priority]) { + void _setPropertyHelper(String propertyName, String? value, + [String? priority]) { if (value == null) value = ''; if (priority == null) priority = ''; JS('void', '#.setProperty(#, #, #)', this, propertyName, value, priority); @@ -4030,7 +4040,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { * Checks to see if CSS Transitions are supported. */ static bool get supportsTransitions { - return document.body.style.supportsProperty('transition'); + return document.body!.style.supportsProperty('transition'); } // To suppress missing implicit constructor warnings. @@ -4040,7 +4050,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get cssFloat native; - set cssFloat(String value) native; + set cssFloat(String? value) native; String get cssText native; @@ -4048,7 +4058,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { int get length native; - CssRule get parentRule native; + CssRule? get parentRule native; String getPropertyPriority(String property) native; @@ -4063,7 +4073,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get background => this._background; /** Sets the value of "background" */ - set background(String value) { + set background(String? value) { _background = value == null ? '' : value; } @@ -4078,7 +4088,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get backgroundAttachment => this._backgroundAttachment; /** Sets the value of "background-attachment" */ - set backgroundAttachment(String value) { + set backgroundAttachment(String? value) { _backgroundAttachment = value == null ? '' : value; } @@ -4093,7 +4103,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get backgroundColor => this._backgroundColor; /** Sets the value of "background-color" */ - set backgroundColor(String value) { + set backgroundColor(String? value) { _backgroundColor = value == null ? '' : value; } @@ -4108,7 +4118,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get backgroundImage => this._backgroundImage; /** Sets the value of "background-image" */ - set backgroundImage(String value) { + set backgroundImage(String? value) { _backgroundImage = value == null ? '' : value; } @@ -4123,7 +4133,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get backgroundPosition => this._backgroundPosition; /** Sets the value of "background-position" */ - set backgroundPosition(String value) { + set backgroundPosition(String? value) { _backgroundPosition = value == null ? '' : value; } @@ -4138,7 +4148,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get backgroundRepeat => this._backgroundRepeat; /** Sets the value of "background-repeat" */ - set backgroundRepeat(String value) { + set backgroundRepeat(String? value) { _backgroundRepeat = value == null ? '' : value; } @@ -4153,7 +4163,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get border => this._border; /** Sets the value of "border" */ - set border(String value) { + set border(String? value) { _border = value == null ? '' : value; } @@ -4168,7 +4178,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get borderBottom => this._borderBottom; /** Sets the value of "border-bottom" */ - set borderBottom(String value) { + set borderBottom(String? value) { _borderBottom = value == null ? '' : value; } @@ -4183,7 +4193,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get borderBottomColor => this._borderBottomColor; /** Sets the value of "border-bottom-color" */ - set borderBottomColor(String value) { + set borderBottomColor(String? value) { _borderBottomColor = value == null ? '' : value; } @@ -4198,7 +4208,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get borderBottomStyle => this._borderBottomStyle; /** Sets the value of "border-bottom-style" */ - set borderBottomStyle(String value) { + set borderBottomStyle(String? value) { _borderBottomStyle = value == null ? '' : value; } @@ -4213,7 +4223,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get borderBottomWidth => this._borderBottomWidth; /** Sets the value of "border-bottom-width" */ - set borderBottomWidth(String value) { + set borderBottomWidth(String? value) { _borderBottomWidth = value == null ? '' : value; } @@ -4228,7 +4238,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get borderCollapse => this._borderCollapse; /** Sets the value of "border-collapse" */ - set borderCollapse(String value) { + set borderCollapse(String? value) { _borderCollapse = value == null ? '' : value; } @@ -4243,7 +4253,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get borderColor => this._borderColor; /** Sets the value of "border-color" */ - set borderColor(String value) { + set borderColor(String? value) { _borderColor = value == null ? '' : value; } @@ -4258,7 +4268,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get borderLeft => this._borderLeft; /** Sets the value of "border-left" */ - set borderLeft(String value) { + set borderLeft(String? value) { _borderLeft = value == null ? '' : value; } @@ -4273,7 +4283,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get borderLeftColor => this._borderLeftColor; /** Sets the value of "border-left-color" */ - set borderLeftColor(String value) { + set borderLeftColor(String? value) { _borderLeftColor = value == null ? '' : value; } @@ -4288,7 +4298,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get borderLeftStyle => this._borderLeftStyle; /** Sets the value of "border-left-style" */ - set borderLeftStyle(String value) { + set borderLeftStyle(String? value) { _borderLeftStyle = value == null ? '' : value; } @@ -4303,7 +4313,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get borderLeftWidth => this._borderLeftWidth; /** Sets the value of "border-left-width" */ - set borderLeftWidth(String value) { + set borderLeftWidth(String? value) { _borderLeftWidth = value == null ? '' : value; } @@ -4318,7 +4328,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get borderRight => this._borderRight; /** Sets the value of "border-right" */ - set borderRight(String value) { + set borderRight(String? value) { _borderRight = value == null ? '' : value; } @@ -4333,7 +4343,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get borderRightColor => this._borderRightColor; /** Sets the value of "border-right-color" */ - set borderRightColor(String value) { + set borderRightColor(String? value) { _borderRightColor = value == null ? '' : value; } @@ -4348,7 +4358,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get borderRightStyle => this._borderRightStyle; /** Sets the value of "border-right-style" */ - set borderRightStyle(String value) { + set borderRightStyle(String? value) { _borderRightStyle = value == null ? '' : value; } @@ -4363,7 +4373,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get borderRightWidth => this._borderRightWidth; /** Sets the value of "border-right-width" */ - set borderRightWidth(String value) { + set borderRightWidth(String? value) { _borderRightWidth = value == null ? '' : value; } @@ -4378,7 +4388,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get borderSpacing => this._borderSpacing; /** Sets the value of "border-spacing" */ - set borderSpacing(String value) { + set borderSpacing(String? value) { _borderSpacing = value == null ? '' : value; } @@ -4393,7 +4403,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get borderStyle => this._borderStyle; /** Sets the value of "border-style" */ - set borderStyle(String value) { + set borderStyle(String? value) { _borderStyle = value == null ? '' : value; } @@ -4408,7 +4418,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get borderTop => this._borderTop; /** Sets the value of "border-top" */ - set borderTop(String value) { + set borderTop(String? value) { _borderTop = value == null ? '' : value; } @@ -4423,7 +4433,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get borderTopColor => this._borderTopColor; /** Sets the value of "border-top-color" */ - set borderTopColor(String value) { + set borderTopColor(String? value) { _borderTopColor = value == null ? '' : value; } @@ -4438,7 +4448,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get borderTopStyle => this._borderTopStyle; /** Sets the value of "border-top-style" */ - set borderTopStyle(String value) { + set borderTopStyle(String? value) { _borderTopStyle = value == null ? '' : value; } @@ -4453,7 +4463,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get borderTopWidth => this._borderTopWidth; /** Sets the value of "border-top-width" */ - set borderTopWidth(String value) { + set borderTopWidth(String? value) { _borderTopWidth = value == null ? '' : value; } @@ -4468,7 +4478,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get borderWidth => this._borderWidth; /** Sets the value of "border-width" */ - set borderWidth(String value) { + set borderWidth(String? value) { _borderWidth = value == null ? '' : value; } @@ -4483,7 +4493,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get bottom => this._bottom; /** Sets the value of "bottom" */ - set bottom(String value) { + set bottom(String? value) { _bottom = value == null ? '' : value; } @@ -4498,7 +4508,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get captionSide => this._captionSide; /** Sets the value of "caption-side" */ - set captionSide(String value) { + set captionSide(String? value) { _captionSide = value == null ? '' : value; } @@ -4513,7 +4523,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get clear => this._clear; /** Sets the value of "clear" */ - set clear(String value) { + set clear(String? value) { _clear = value == null ? '' : value; } @@ -4528,7 +4538,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get clip => this._clip; /** Sets the value of "clip" */ - set clip(String value) { + set clip(String? value) { _clip = value == null ? '' : value; } @@ -4543,7 +4553,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get color => this._color; /** Sets the value of "color" */ - set color(String value) { + set color(String? value) { _color = value == null ? '' : value; } @@ -4558,7 +4568,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get content => this._content; /** Sets the value of "content" */ - set content(String value) { + set content(String? value) { _content = value == null ? '' : value; } @@ -4573,7 +4583,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get cursor => this._cursor; /** Sets the value of "cursor" */ - set cursor(String value) { + set cursor(String? value) { _cursor = value == null ? '' : value; } @@ -4588,7 +4598,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get direction => this._direction; /** Sets the value of "direction" */ - set direction(String value) { + set direction(String? value) { _direction = value == null ? '' : value; } @@ -4603,7 +4613,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get display => this._display; /** Sets the value of "display" */ - set display(String value) { + set display(String? value) { _display = value == null ? '' : value; } @@ -4618,7 +4628,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get emptyCells => this._emptyCells; /** Sets the value of "empty-cells" */ - set emptyCells(String value) { + set emptyCells(String? value) { _emptyCells = value == null ? '' : value; } @@ -4633,7 +4643,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get font => this._font; /** Sets the value of "font" */ - set font(String value) { + set font(String? value) { _font = value == null ? '' : value; } @@ -4648,7 +4658,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get fontFamily => this._fontFamily; /** Sets the value of "font-family" */ - set fontFamily(String value) { + set fontFamily(String? value) { _fontFamily = value == null ? '' : value; } @@ -4663,7 +4673,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get fontSize => this._fontSize; /** Sets the value of "font-size" */ - set fontSize(String value) { + set fontSize(String? value) { _fontSize = value == null ? '' : value; } @@ -4678,7 +4688,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get fontStyle => this._fontStyle; /** Sets the value of "font-style" */ - set fontStyle(String value) { + set fontStyle(String? value) { _fontStyle = value == null ? '' : value; } @@ -4693,7 +4703,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get fontVariant => this._fontVariant; /** Sets the value of "font-variant" */ - set fontVariant(String value) { + set fontVariant(String? value) { _fontVariant = value == null ? '' : value; } @@ -4708,7 +4718,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get fontWeight => this._fontWeight; /** Sets the value of "font-weight" */ - set fontWeight(String value) { + set fontWeight(String? value) { _fontWeight = value == null ? '' : value; } @@ -4723,7 +4733,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get height => this._height; /** Sets the value of "height" */ - set height(String value) { + set height(String? value) { _height = value == null ? '' : value; } @@ -4738,7 +4748,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get left => this._left; /** Sets the value of "left" */ - set left(String value) { + set left(String? value) { _left = value == null ? '' : value; } @@ -4753,7 +4763,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get letterSpacing => this._letterSpacing; /** Sets the value of "letter-spacing" */ - set letterSpacing(String value) { + set letterSpacing(String? value) { _letterSpacing = value == null ? '' : value; } @@ -4768,7 +4778,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get lineHeight => this._lineHeight; /** Sets the value of "line-height" */ - set lineHeight(String value) { + set lineHeight(String? value) { _lineHeight = value == null ? '' : value; } @@ -4783,7 +4793,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get listStyle => this._listStyle; /** Sets the value of "list-style" */ - set listStyle(String value) { + set listStyle(String? value) { _listStyle = value == null ? '' : value; } @@ -4798,7 +4808,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get listStyleImage => this._listStyleImage; /** Sets the value of "list-style-image" */ - set listStyleImage(String value) { + set listStyleImage(String? value) { _listStyleImage = value == null ? '' : value; } @@ -4813,7 +4823,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get listStylePosition => this._listStylePosition; /** Sets the value of "list-style-position" */ - set listStylePosition(String value) { + set listStylePosition(String? value) { _listStylePosition = value == null ? '' : value; } @@ -4828,7 +4838,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get listStyleType => this._listStyleType; /** Sets the value of "list-style-type" */ - set listStyleType(String value) { + set listStyleType(String? value) { _listStyleType = value == null ? '' : value; } @@ -4843,7 +4853,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get margin => this._margin; /** Sets the value of "margin" */ - set margin(String value) { + set margin(String? value) { _margin = value == null ? '' : value; } @@ -4858,7 +4868,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get marginBottom => this._marginBottom; /** Sets the value of "margin-bottom" */ - set marginBottom(String value) { + set marginBottom(String? value) { _marginBottom = value == null ? '' : value; } @@ -4873,7 +4883,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get marginLeft => this._marginLeft; /** Sets the value of "margin-left" */ - set marginLeft(String value) { + set marginLeft(String? value) { _marginLeft = value == null ? '' : value; } @@ -4888,7 +4898,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get marginRight => this._marginRight; /** Sets the value of "margin-right" */ - set marginRight(String value) { + set marginRight(String? value) { _marginRight = value == null ? '' : value; } @@ -4903,7 +4913,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get marginTop => this._marginTop; /** Sets the value of "margin-top" */ - set marginTop(String value) { + set marginTop(String? value) { _marginTop = value == null ? '' : value; } @@ -4918,7 +4928,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get maxHeight => this._maxHeight; /** Sets the value of "max-height" */ - set maxHeight(String value) { + set maxHeight(String? value) { _maxHeight = value == null ? '' : value; } @@ -4933,7 +4943,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get maxWidth => this._maxWidth; /** Sets the value of "max-width" */ - set maxWidth(String value) { + set maxWidth(String? value) { _maxWidth = value == null ? '' : value; } @@ -4948,7 +4958,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get minHeight => this._minHeight; /** Sets the value of "min-height" */ - set minHeight(String value) { + set minHeight(String? value) { _minHeight = value == null ? '' : value; } @@ -4963,7 +4973,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get minWidth => this._minWidth; /** Sets the value of "min-width" */ - set minWidth(String value) { + set minWidth(String? value) { _minWidth = value == null ? '' : value; } @@ -4978,7 +4988,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get outline => this._outline; /** Sets the value of "outline" */ - set outline(String value) { + set outline(String? value) { _outline = value == null ? '' : value; } @@ -4993,7 +5003,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get outlineColor => this._outlineColor; /** Sets the value of "outline-color" */ - set outlineColor(String value) { + set outlineColor(String? value) { _outlineColor = value == null ? '' : value; } @@ -5008,7 +5018,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get outlineStyle => this._outlineStyle; /** Sets the value of "outline-style" */ - set outlineStyle(String value) { + set outlineStyle(String? value) { _outlineStyle = value == null ? '' : value; } @@ -5023,7 +5033,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get outlineWidth => this._outlineWidth; /** Sets the value of "outline-width" */ - set outlineWidth(String value) { + set outlineWidth(String? value) { _outlineWidth = value == null ? '' : value; } @@ -5038,7 +5048,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get overflow => this._overflow; /** Sets the value of "overflow" */ - set overflow(String value) { + set overflow(String? value) { _overflow = value == null ? '' : value; } @@ -5053,7 +5063,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get padding => this._padding; /** Sets the value of "padding" */ - set padding(String value) { + set padding(String? value) { _padding = value == null ? '' : value; } @@ -5068,7 +5078,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get paddingBottom => this._paddingBottom; /** Sets the value of "padding-bottom" */ - set paddingBottom(String value) { + set paddingBottom(String? value) { _paddingBottom = value == null ? '' : value; } @@ -5083,7 +5093,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get paddingLeft => this._paddingLeft; /** Sets the value of "padding-left" */ - set paddingLeft(String value) { + set paddingLeft(String? value) { _paddingLeft = value == null ? '' : value; } @@ -5098,7 +5108,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get paddingRight => this._paddingRight; /** Sets the value of "padding-right" */ - set paddingRight(String value) { + set paddingRight(String? value) { _paddingRight = value == null ? '' : value; } @@ -5113,7 +5123,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get paddingTop => this._paddingTop; /** Sets the value of "padding-top" */ - set paddingTop(String value) { + set paddingTop(String? value) { _paddingTop = value == null ? '' : value; } @@ -5128,7 +5138,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get pageBreakAfter => this._pageBreakAfter; /** Sets the value of "page-break-after" */ - set pageBreakAfter(String value) { + set pageBreakAfter(String? value) { _pageBreakAfter = value == null ? '' : value; } @@ -5143,7 +5153,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get pageBreakBefore => this._pageBreakBefore; /** Sets the value of "page-break-before" */ - set pageBreakBefore(String value) { + set pageBreakBefore(String? value) { _pageBreakBefore = value == null ? '' : value; } @@ -5158,7 +5168,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get pageBreakInside => this._pageBreakInside; /** Sets the value of "page-break-inside" */ - set pageBreakInside(String value) { + set pageBreakInside(String? value) { _pageBreakInside = value == null ? '' : value; } @@ -5173,7 +5183,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get position => this._position; /** Sets the value of "position" */ - set position(String value) { + set position(String? value) { _position = value == null ? '' : value; } @@ -5188,7 +5198,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get quotes => this._quotes; /** Sets the value of "quotes" */ - set quotes(String value) { + set quotes(String? value) { _quotes = value == null ? '' : value; } @@ -5203,7 +5213,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get right => this._right; /** Sets the value of "right" */ - set right(String value) { + set right(String? value) { _right = value == null ? '' : value; } @@ -5218,7 +5228,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get tableLayout => this._tableLayout; /** Sets the value of "table-layout" */ - set tableLayout(String value) { + set tableLayout(String? value) { _tableLayout = value == null ? '' : value; } @@ -5233,7 +5243,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get textAlign => this._textAlign; /** Sets the value of "text-align" */ - set textAlign(String value) { + set textAlign(String? value) { _textAlign = value == null ? '' : value; } @@ -5248,7 +5258,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get textDecoration => this._textDecoration; /** Sets the value of "text-decoration" */ - set textDecoration(String value) { + set textDecoration(String? value) { _textDecoration = value == null ? '' : value; } @@ -5263,7 +5273,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get textIndent => this._textIndent; /** Sets the value of "text-indent" */ - set textIndent(String value) { + set textIndent(String? value) { _textIndent = value == null ? '' : value; } @@ -5278,7 +5288,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get textTransform => this._textTransform; /** Sets the value of "text-transform" */ - set textTransform(String value) { + set textTransform(String? value) { _textTransform = value == null ? '' : value; } @@ -5293,7 +5303,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get top => this._top; /** Sets the value of "top" */ - set top(String value) { + set top(String? value) { _top = value == null ? '' : value; } @@ -5308,7 +5318,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get unicodeBidi => this._unicodeBidi; /** Sets the value of "unicode-bidi" */ - set unicodeBidi(String value) { + set unicodeBidi(String? value) { _unicodeBidi = value == null ? '' : value; } @@ -5323,7 +5333,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get verticalAlign => this._verticalAlign; /** Sets the value of "vertical-align" */ - set verticalAlign(String value) { + set verticalAlign(String? value) { _verticalAlign = value == null ? '' : value; } @@ -5338,7 +5348,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get visibility => this._visibility; /** Sets the value of "visibility" */ - set visibility(String value) { + set visibility(String? value) { _visibility = value == null ? '' : value; } @@ -5353,7 +5363,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get whiteSpace => this._whiteSpace; /** Sets the value of "white-space" */ - set whiteSpace(String value) { + set whiteSpace(String? value) { _whiteSpace = value == null ? '' : value; } @@ -5368,7 +5378,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get width => this._width; /** Sets the value of "width" */ - set width(String value) { + set width(String? value) { _width = value == null ? '' : value; } @@ -5383,7 +5393,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get wordSpacing => this._wordSpacing; /** Sets the value of "word-spacing" */ - set wordSpacing(String value) { + set wordSpacing(String? value) { _wordSpacing = value == null ? '' : value; } @@ -5398,7 +5408,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { String get zIndex => this._zIndex; /** Sets the value of "z-index" */ - set zIndex(String value) { + set zIndex(String? value) { _zIndex = value == null ? '' : value; } @@ -5412,7 +5422,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase { class _CssStyleDeclarationSet extends Object with CssStyleDeclarationBase { final Iterable _elementIterable; - Iterable _elementCssStyleDeclarationSetIterable; + Iterable? _elementCssStyleDeclarationSetIterable; _CssStyleDeclarationSet(this._elementIterable) { _elementCssStyleDeclarationSetIterable = @@ -5420,15 +5430,15 @@ class _CssStyleDeclarationSet extends Object with CssStyleDeclarationBase { } String getPropertyValue(String propertyName) => - _elementCssStyleDeclarationSetIterable.first + _elementCssStyleDeclarationSetIterable!.first .getPropertyValue(propertyName); - void setProperty(String propertyName, String value, [String priority]) { - _elementCssStyleDeclarationSetIterable + void setProperty(String propertyName, String? value, [String? priority]) { + _elementCssStyleDeclarationSetIterable! .forEach((e) => e.setProperty(propertyName, value, priority)); } - void _setAll(String propertyName, String value) { + void _setAll(String propertyName, String? value) { value = value == null ? '' : value; for (Element element in _elementIterable) { JS('void', '#.style[#] = #', element, propertyName, value); @@ -5894,7 +5904,7 @@ class _CssStyleDeclarationSet extends Object with CssStyleDeclarationBase { abstract class CssStyleDeclarationBase { String getPropertyValue(String propertyName); - void setProperty(String propertyName, String value, [String priority]); + void setProperty(String propertyName, String? value, [String? priority]); /** Gets the value of "align-content" */ String get alignContent => getPropertyValue('align-content'); @@ -8681,23 +8691,23 @@ class CssStyleSheet extends StyleSheet { throw new UnsupportedError("Not supported"); } - @Returns('_CssRuleList|Null') + @Returns('_CssRuleList') @Creates('_CssRuleList') List get cssRules native; - CssRule get ownerRule native; + CssRule? get ownerRule native; - @Returns('_CssRuleList|Null') + @Returns('_CssRuleList') @Creates('_CssRuleList') List get rules native; - int addRule(String selector, String style, [int index]) native; + int addRule(String? selector, String? style, [int? index]) native; void deleteRule(int index) native; - int insertRule(String rule, [int index]) native; + int insertRule(String rule, [int? index]) native; - void removeRule(int index) native; + void removeRule(int? index) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -8710,7 +8720,7 @@ class CssStyleValue extends Interceptor { throw new UnsupportedError("Not supported"); } - static Object parse(String property, String cssText) native; + static Object? parse(String property, String cssText) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -8749,7 +8759,8 @@ class CssTransformValue extends CssStyleValue { throw new UnsupportedError("Not supported"); } - factory CssTransformValue([List transformComponents]) { + factory CssTransformValue( + [List? transformComponents]) { if (transformComponents == null) { return CssTransformValue._create_1(); } @@ -8783,7 +8794,7 @@ class CssTranslation extends CssTransformComponent { } factory CssTranslation(CssNumericValue x, CssNumericValue y, - [CssNumericValue z]) { + [CssNumericValue? z]) { if ((y is CssNumericValue) && (x is CssNumericValue) && z == null) { return CssTranslation._create_1(x, y); } @@ -8851,7 +8862,7 @@ class CssUnparsedValue extends CssStyleValue { int get length native; - Object fragmentAtIndex(int index) native; + Object? fragmentAtIndex(int index) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -8920,7 +8931,7 @@ class CustomElementRegistry extends Interceptor { throw new UnsupportedError("Not supported"); } - void define(String name, Object constructor, [Map options]) { + void define(String name, Object constructor, [Map? options]) { if (options != null) { var options_1 = convertDartToNative_Dictionary(options); _define_1(name, constructor, options_1); @@ -8935,7 +8946,7 @@ class CustomElementRegistry extends Interceptor { @JSName('define') void _define_2(name, constructor) native; - Object get(String name) native; + Object? get(String name) native; Future whenDefined(String name) => promiseToFuture(JS("", "#.whenDefined(#)", this, name)); @@ -8952,8 +8963,8 @@ class CustomEvent extends Event { var _dartDetail; factory CustomEvent(String type, - {bool canBubble: true, bool cancelable: true, Object detail}) { - final CustomEvent e = document._createEvent('CustomEvent'); + {bool canBubble: true, bool cancelable: true, Object? detail}) { + final CustomEvent e = document._createEvent('CustomEvent') as CustomEvent; e._dartDetail = detail; @@ -8980,7 +8991,7 @@ class CustomEvent extends Event { return _detail; } - factory CustomEvent._(String type, [Map eventInitDict]) { + factory CustomEvent._(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return CustomEvent._create_1(type, eventInitDict_1); @@ -9000,7 +9011,7 @@ class CustomEvent extends Event { @JSName('initCustomEvent') void _initCustomEvent(String type, - [bool bubbles, bool cancelable, Object detail]) native; + [bool? bubbles, bool? cancelable, Object? detail]) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -9013,7 +9024,7 @@ class DListElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory DListElement() => JS( + factory DListElement() => JS( 'returns:DListElement;creates:DListElement;new:true', '#.createElement(#)', document, @@ -9061,7 +9072,8 @@ class DataListElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory DataListElement() => document.createElement("datalist"); + factory DataListElement() => + document.createElement("datalist") as DataListElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -9072,7 +9084,7 @@ class DataListElement extends HtmlElement { /// Checks if this type is supported on the current platform. static bool get supported => Element.isTagSupported('datalist'); - @Returns('HtmlCollection|Null') + @Returns('HtmlCollection') @Creates('HtmlCollection') List get options native; } @@ -9100,7 +9112,7 @@ class DataTransfer extends Interceptor { set effectAllowed(String value) native; - @Returns('FileList|Null') + @Returns('FileList') @Creates('FileList') List get files native; @@ -9108,7 +9120,7 @@ class DataTransfer extends Interceptor { List get types native; - void clearData([String format]) native; + void clearData([String? format]) native; String getData(String format) native; @@ -9123,7 +9135,7 @@ class DataTransfer extends Interceptor { @Native("DataTransferItem") class DataTransferItem extends Interceptor { Entry getAsEntry() { - Entry entry = _webkitGetAsEntry(); + Entry entry = _webkitGetAsEntry() as Entry; if (entry.isFile) applyExtension('FileEntry', entry); @@ -9144,12 +9156,12 @@ class DataTransferItem extends Interceptor { String get type native; - File getAsFile() native; + File? getAsFile() native; @JSName('webkitGetAsEntry') @SupportedBrowser(SupportedBrowser.CHROME) @SupportedBrowser(SupportedBrowser.SAFARI) - Entry _webkitGetAsEntry() native; + Entry? _webkitGetAsEntry() native; } // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -9164,13 +9176,13 @@ class DataTransferItemList extends Interceptor { int get length native; - DataTransferItem add(data_OR_file, [String type]) native; + DataTransferItem? add(data_OR_file, [String? type]) native; @JSName('add') - DataTransferItem addData(String data, String type) native; + DataTransferItem? addData(String data, String type) native; @JSName('add') - DataTransferItem addFile(File file) native; + DataTransferItem? addFile(File file) native; void clear() native; @@ -9229,7 +9241,7 @@ class DedicatedWorkerGlobalScope extends WorkerGlobalScope { void close() native; - void postMessage(/*any*/ message, [List transfer]) { + void postMessage(/*any*/ message, [List? transfer]) { if (transfer != null) { var message_1 = convertDartToNative_SerializedScriptValue(message); _postMessage_1(message_1, transfer); @@ -9249,8 +9261,8 @@ class DedicatedWorkerGlobalScope extends WorkerGlobalScope { @SupportedBrowser(SupportedBrowser.CHROME) @SupportedBrowser(SupportedBrowser.SAFARI) void _webkitRequestFileSystem(int type, int size, - [_FileSystemCallback successCallback, - _ErrorCallback errorCallback]) native; + [_FileSystemCallback? successCallback, + _ErrorCallback? errorCallback]) native; @JSName('webkitRequestFileSystemSync') @SupportedBrowser(SupportedBrowser.CHROME) @@ -9267,7 +9279,7 @@ class DedicatedWorkerGlobalScope extends WorkerGlobalScope { @SupportedBrowser(SupportedBrowser.SAFARI) void _webkitResolveLocalFileSystemUrl( String url, _EntryCallback successCallback, - [_ErrorCallback errorCallback]) native; + [_ErrorCallback? errorCallback]) native; /// Stream of `message` events handled by this [DedicatedWorkerGlobalScope]. Stream get onMessage => messageEvent.forTarget(this); @@ -9293,12 +9305,12 @@ class DeprecatedStorageInfo extends Interceptor { static const int TEMPORARY = 0; void queryUsageAndQuota(int storageType, - [StorageUsageCallback usageCallback, - StorageErrorCallback errorCallback]) native; + [StorageUsageCallback? usageCallback, + StorageErrorCallback? errorCallback]) native; void requestQuota(int storageType, int newQuotaInBytes, - [StorageQuotaCallback quotaCallback, - StorageErrorCallback errorCallback]) native; + [StorageQuotaCallback? quotaCallback, + StorageErrorCallback? errorCallback]) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -9312,11 +9324,11 @@ class DeprecatedStorageQuota extends Interceptor { } void queryUsageAndQuota(StorageUsageCallback usageCallback, - [StorageErrorCallback errorCallback]) native; + [StorageErrorCallback? errorCallback]) native; void requestQuota(int newQuotaInBytes, - [StorageQuotaCallback quotaCallback, - StorageErrorCallback errorCallback]) native; + [StorageQuotaCallback? quotaCallback, + StorageErrorCallback? errorCallback]) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -9348,7 +9360,8 @@ class DetailsElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory DetailsElement() => document.createElement("details"); + factory DetailsElement() => + document.createElement("details") as DetailsElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -9439,11 +9452,11 @@ class DeviceAcceleration extends Interceptor { throw new UnsupportedError("Not supported"); } - num get x native; + num? get x native; - num get y native; + num? get y native; - num get z native; + num? get z native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -9456,7 +9469,7 @@ class DeviceMotionEvent extends Event { throw new UnsupportedError("Not supported"); } - factory DeviceMotionEvent(String type, [Map eventInitDict]) { + factory DeviceMotionEvent(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return DeviceMotionEvent._create_1(type, eventInitDict_1); @@ -9468,13 +9481,13 @@ class DeviceMotionEvent extends Event { static DeviceMotionEvent _create_2(type) => JS('DeviceMotionEvent', 'new DeviceMotionEvent(#)', type); - DeviceAcceleration get acceleration native; + DeviceAcceleration? get acceleration native; - DeviceAcceleration get accelerationIncludingGravity native; + DeviceAcceleration? get accelerationIncludingGravity native; num get interval native; - DeviceRotationRate get rotationRate native; + DeviceRotationRate? get rotationRate native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -9487,7 +9500,7 @@ class DeviceOrientationEvent extends Event { throw new UnsupportedError("Not supported"); } - factory DeviceOrientationEvent(String type, [Map eventInitDict]) { + factory DeviceOrientationEvent(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return DeviceOrientationEvent._create_1(type, eventInitDict_1); @@ -9504,11 +9517,11 @@ class DeviceOrientationEvent extends Event { bool get absolute native; - num get alpha native; + num? get alpha native; - num get beta native; + num? get beta native; - num get gamma native; + num? get gamma native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -9521,11 +9534,11 @@ class DeviceRotationRate extends Interceptor { throw new UnsupportedError("Not supported"); } - num get alpha native; + num? get alpha native; - num get beta native; + num? get beta native; - num get gamma native; + num? get gamma native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -9553,7 +9566,7 @@ class DialogElement extends HtmlElement { set returnValue(String value) native; - void close([String returnValue]) native; + void close([String? returnValue]) native; void show() native; @@ -9616,10 +9629,10 @@ class DirectoryEntry extends Entry { @JSName('createReader') DirectoryReader _createReader() native; - void __getDirectory(String path, - [Map options, - _EntryCallback successCallback, - _ErrorCallback errorCallback]) { + void __getDirectory(String? path, + [Map? options, + _EntryCallback? successCallback, + _ErrorCallback? errorCallback]) { if (errorCallback != null) { var options_1 = convertDartToNative_Dictionary(options); __getDirectory_1(path, options_1, successCallback, errorCallback); @@ -9640,17 +9653,17 @@ class DirectoryEntry extends Entry { } @JSName('getDirectory') - void __getDirectory_1(path, options, _EntryCallback successCallback, - _ErrorCallback errorCallback) native; + void __getDirectory_1(path, options, _EntryCallback? successCallback, + _ErrorCallback? errorCallback) native; @JSName('getDirectory') - void __getDirectory_2(path, options, _EntryCallback successCallback) native; + void __getDirectory_2(path, options, _EntryCallback? successCallback) native; @JSName('getDirectory') void __getDirectory_3(path, options) native; @JSName('getDirectory') void __getDirectory_4(path) native; @JSName('getDirectory') - Future _getDirectory(String path, {Map options}) { + Future _getDirectory(String? path, {Map? options}) { var completer = new Completer(); __getDirectory(path, options, (value) { completer.complete(value); @@ -9660,10 +9673,10 @@ class DirectoryEntry extends Entry { return completer.future; } - void __getFile(String path, - [Map options, - _EntryCallback successCallback, - _ErrorCallback errorCallback]) { + void __getFile(String? path, + [Map? options, + _EntryCallback? successCallback, + _ErrorCallback? errorCallback]) { if (errorCallback != null) { var options_1 = convertDartToNative_Dictionary(options); __getFile_1(path, options_1, successCallback, errorCallback); @@ -9684,17 +9697,17 @@ class DirectoryEntry extends Entry { } @JSName('getFile') - void __getFile_1(path, options, _EntryCallback successCallback, - _ErrorCallback errorCallback) native; + void __getFile_1(path, options, _EntryCallback? successCallback, + _ErrorCallback? errorCallback) native; @JSName('getFile') - void __getFile_2(path, options, _EntryCallback successCallback) native; + void __getFile_2(path, options, _EntryCallback? successCallback) native; @JSName('getFile') void __getFile_3(path, options) native; @JSName('getFile') void __getFile_4(path) native; @JSName('getFile') - Future _getFile(String path, {Map options}) { + Future _getFile(String? path, {Map? options}) { var completer = new Completer(); __getFile(path, options, (value) { applyExtension('FileEntry', value); @@ -9707,7 +9720,7 @@ class DirectoryEntry extends Entry { @JSName('removeRecursively') void _removeRecursively(VoidCallback successCallback, - [_ErrorCallback errorCallback]) native; + [_ErrorCallback? errorCallback]) native; @JSName('removeRecursively') Future removeRecursively() { @@ -9733,7 +9746,7 @@ class DirectoryReader extends Interceptor { @JSName('readEntries') void _readEntries(_EntriesCallback successCallback, - [_ErrorCallback errorCallback]) native; + [_ErrorCallback? errorCallback]) native; Future> readEntries() { var completer = new Completer>(); @@ -9786,8 +9799,11 @@ class DivElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory DivElement() => JS('returns:DivElement;creates:DivElement;new:true', - '#.createElement(#)', document, "div"); + factory DivElement() => JS( + 'returns:DivElement;creates:DivElement;new:true', + '#.createElement(#)', + document, + "div"); /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -9858,10 +9874,10 @@ class Document extends Node { String get addressSpace native; @JSName('body') - HtmlElement get _body native; + HtmlElement? get _body native; @JSName('body') - set _body(HtmlElement value) native; + set _body(HtmlElement? value) native; String get contentType native; @@ -9869,9 +9885,9 @@ class Document extends Node { set cookie(String value) native; - ScriptElement get currentScript native; + ScriptElement? get currentScript native; - WindowBase get window => _convertNativeToDart_Window(this._get_window); + WindowBase? get window => _convertNativeToDart_Window(this._get_window); @JSName('defaultView') @Creates('Window|=Object') @Returns('Window|=Object') @@ -9879,14 +9895,14 @@ class Document extends Node { @Returns('Window|=Object|Null') dynamic get _get_window native; - Element get documentElement native; + Element? get documentElement native; String get domain native; bool get fullscreenEnabled native; @JSName('head') - HeadElement get _head native; + HeadElement? get _head native; bool get hidden native; @@ -9898,7 +9914,7 @@ class Document extends Node { String get origin native; @JSName('preferredStylesheetSet') - String get _preferredStylesheetSet native; + String? get _preferredStylesheetSet native; String get readyState native; @@ -9907,17 +9923,17 @@ class Document extends Node { SvgSvgElement get rootElement native; - Element get rootScroller native; + Element? get rootScroller native; - set rootScroller(Element value) native; + set rootScroller(Element? value) native; - Element get scrollingElement native; + Element? get scrollingElement native; @JSName('selectedStylesheetSet') - String get _selectedStylesheetSet native; + String? get _selectedStylesheetSet native; @JSName('selectedStylesheetSet') - set _selectedStylesheetSet(String value) native; + set _selectedStylesheetSet(String? value) native; String get suborigin native; @@ -9955,7 +9971,7 @@ class Document extends Node { Node adoptNode(Node node) native; @JSName('caretRangeFromPoint') - Range _caretRangeFromPoint(int x, int y) native; + Range _caretRangeFromPoint(int? x, int? y) native; DocumentFragment createDocumentFragment() native; @@ -9964,7 +9980,7 @@ class Document extends Node { [options_OR_typeExtension]) native; @JSName('createElementNS') - Element _createElementNS(String namespaceURI, String qualifiedName, + Element _createElementNS(String? namespaceURI, String qualifiedName, [options_OR_typeExtension]) native; @JSName('createEvent') @@ -9977,7 +9993,7 @@ class Document extends Node { Touch _createTouch(Window view, EventTarget target, int identifier, num pageX, num pageY, num screenX, num screenY, - [num radiusX, num radiusY, num rotationAngle, num force]) { + [num? radiusX, num? radiusY, num? rotationAngle, num? force]) { if (force != null) { var target_1 = _convertDartToNative_EventTarget(target); return _createTouch_1(view, target_1, identifier, pageX, pageY, screenX, @@ -10022,7 +10038,7 @@ class Document extends Node { @JSName('createTouchList') TouchList _createTouchList(Touch touches) native; - bool execCommand(String commandId, [bool showUI, String value]) native; + bool execCommand(String commandId, [bool? showUI, String? value]) native; void exitFullscreen() native; @@ -10042,7 +10058,7 @@ class Document extends Node { @Returns('NodeList|HtmlCollection') List getElementsByTagName(String localName) native; - Node importNode(Node node, [bool deep]) native; + Node importNode(Node node, [bool? deep]) native; bool queryCommandEnabled(String commandId) native; @@ -10054,7 +10070,7 @@ class Document extends Node { String queryCommandValue(String commandId) native; - Function registerElement2(String type, [Map options]) { + Function registerElement2(String type, [Map? options]) { if (options != null) { var options_1 = convertDartToNative_Dictionary(options); return _registerElement2_1(type, options_1); @@ -10074,23 +10090,23 @@ class Document extends Node { // From NonElementParentNode - Element getElementById(String elementId) native; + Element? getElementById(String elementId) native; // From DocumentOrShadowRoot - Element get activeElement native; + Element? get activeElement native; - Element get fullscreenElement native; + Element? get fullscreenElement native; - Element get pointerLockElement native; + Element? get pointerLockElement native; @JSName('styleSheets') - @Returns('_StyleSheetList|Null') + @Returns('_StyleSheetList') @Creates('_StyleSheetList') List get _styleSheets native; @JSName('elementFromPoint') - Element _elementFromPoint(int x, int y) native; + Element? _elementFromPoint(int x, int y) native; List elementsFromPoint(int x, int y) native; @@ -10104,15 +10120,15 @@ class Document extends Node { int get _childElementCount native; @JSName('children') - @Returns('HtmlCollection|Null') + @Returns('HtmlCollection') @Creates('HtmlCollection') List get _children native; @JSName('firstElementChild') - Element get _firstElementChild native; + Element? get _firstElementChild native; @JSName('lastElementChild') - Element get _lastElementChild native; + Element? get _lastElementChild native; /** * Finds the first descendant element of this document that matches the @@ -10131,7 +10147,7 @@ class Document extends Node { * For details about CSS selector syntax, see the * [CSS selector specification](http://www.w3.org/TR/css3-selectors/). */ - Element querySelector(String selectors) native; + Element? querySelector(String selectors) native; @JSName('querySelectorAll') @Creates('NodeList') @@ -10373,13 +10389,13 @@ class Document extends Node { bool get supportsRegister => supportsRegisterElement; void registerElement(String tag, Type customElementClass, - {String extendsTag}) { + {String? extendsTag}) { registerElement2( tag, {'prototype': customElementClass, 'extends': extendsTag}); } @pragma('dart2js:tryInline') // Almost all call sites have one argument. - Element createElement(String tagName, [String typeExtension]) { + Element createElement(String tagName, [String? typeExtension]) { return (typeExtension == null) ? _createElement_2(tagName) : _createElement(tagName, typeExtension); @@ -10396,19 +10412,19 @@ class Document extends Node { 'Element', '#.createElementNS(#, #)', this, namespaceURI, qualifiedName); Element createElementNS(String namespaceURI, String qualifiedName, - [String typeExtension]) { + [String? typeExtension]) { return (typeExtension == null) ? _createElementNS_2(namespaceURI, qualifiedName) : _createElementNS(namespaceURI, qualifiedName, typeExtension); } NodeIterator _createNodeIterator(Node root, - [int whatToShow, NodeFilter filter]) => + [int? whatToShow, NodeFilter? filter]) => JS('NodeIterator', '#.createNodeIterator(#, #, #, false)', this, root, whatToShow, filter); TreeWalker _createTreeWalker(Node root, - [int whatToShow, NodeFilter filter]) => + [int? whatToShow, NodeFilter? filter]) => JS('TreeWalker', '#.createTreeWalker(#, #, #, false)', this, root, whatToShow, filter); @@ -10433,14 +10449,14 @@ class DocumentFragment extends Node implements NonElementParentNode, ParentNode { factory DocumentFragment() => document.createDocumentFragment(); - factory DocumentFragment.html(String html, - {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) { - return document.body.createFragment(html, + factory DocumentFragment.html(String? html, + {NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) { + return document.body!.createFragment(html, validator: validator, treeSanitizer: treeSanitizer); } - factory DocumentFragment.svg(String svgContent, - {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) { + factory DocumentFragment.svg(String? svgContent, + {NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) { return new svg.SvgSvgElement().createFragment(svgContent, validator: validator, treeSanitizer: treeSanitizer); } @@ -10451,13 +10467,13 @@ class DocumentFragment extends Node // Native field is used only by Dart code so does not lead to instantiation // of native classes @Creates('Null') - List _docChildren; + List? _docChildren; List get children { if (_docChildren == null) { _docChildren = new FilteredElementList(this); } - return _docChildren; + return _docChildren!; } set children(List value) { @@ -10488,14 +10504,14 @@ class DocumentFragment extends Node return e.innerHtml; } - set innerHtml(String value) { + set innerHtml(String? value) { this.setInnerHtml(value); } - void setInnerHtml(String html, - {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) { + void setInnerHtml(String? html, + {NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) { this.nodes.clear(); - append(document.body.createFragment(html, + append(document.body!.createFragment(html, validator: validator, treeSanitizer: treeSanitizer)); } @@ -10512,7 +10528,7 @@ class DocumentFragment extends Node * last child of this document fragment. */ void appendHtml(String text, - {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) { + {NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) { this.append(new DocumentFragment.html(text, validator: validator, treeSanitizer: treeSanitizer)); } @@ -10524,7 +10540,7 @@ class DocumentFragment extends Node // From NonElementParentNode - Element getElementById(String elementId) native; + Element? getElementById(String elementId) native; // From ParentNode @@ -10532,10 +10548,10 @@ class DocumentFragment extends Node int get _childElementCount native; @JSName('firstElementChild') - Element get _firstElementChild native; + Element? get _firstElementChild native; @JSName('lastElementChild') - Element get _lastElementChild native; + Element? get _lastElementChild native; /** * Finds the first descendant element of this document fragment that matches @@ -10549,7 +10565,7 @@ class DocumentFragment extends Node * For details about CSS selector syntax, see the * [CSS selector specification](http://www.w3.org/TR/css3-selectors/). */ - Element querySelector(String selectors) native; + Element? querySelector(String selectors) native; @JSName('querySelectorAll') @Creates('NodeList') @@ -10567,21 +10583,21 @@ class DocumentOrShadowRoot extends Interceptor { throw new UnsupportedError("Not supported"); } - Element get activeElement native; + Element? get activeElement native; - Element get fullscreenElement native; + Element? get fullscreenElement native; - Element get pointerLockElement native; + Element? get pointerLockElement native; - @Returns('_StyleSheetList|Null') + @Returns('_StyleSheetList') @Creates('_StyleSheetList') List get styleSheets native; - Element elementFromPoint(int x, int y) native; + Element? elementFromPoint(int x, int y) native; List elementsFromPoint(int x, int y) native; - Selection getSelection() native; + Selection? getSelection() native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -10594,7 +10610,7 @@ class DocumentTimeline extends AnimationTimeline { throw new UnsupportedError("Not supported"); } - factory DocumentTimeline([Map options]) { + factory DocumentTimeline([Map? options]) { if (options != null) { var options_1 = convertDartToNative_Dictionary(options); return DocumentTimeline._create_1(options_1); @@ -10617,7 +10633,7 @@ class DomError extends Interceptor { throw new UnsupportedError("Not supported"); } - factory DomError(String name, [String message]) { + factory DomError(String name, [String? message]) { if (message != null) { return DomError._create_1(name, message); } @@ -10679,7 +10695,7 @@ class DomException extends Interceptor { // Chrome release still uses old string, remove this line when Chrome stable // also prints out SyntaxError. if (Device.isWebKit && errorName == 'SYNTAX_ERR') return 'SyntaxError'; - return errorName; + return errorName as String; } // To suppress missing implicit constructor warnings. @@ -10702,14 +10718,14 @@ class DomImplementation extends Interceptor { throw new UnsupportedError("Not supported"); } - XmlDocument createDocument( - String namespaceURI, String qualifiedName, _DocumentType doctype) native; + XmlDocument createDocument(String? namespaceURI, String qualifiedName, + _DocumentType? doctype) native; _DocumentType createDocumentType( String qualifiedName, String publicId, String systemId) native; @JSName('createHTMLDocument') - HtmlDocument createHtmlDocument([String title]) native; + HtmlDocument createHtmlDocument([String? title]) native; bool hasFeature() native; } @@ -10724,7 +10740,7 @@ class DomIterator extends Interceptor { throw new UnsupportedError("Not supported"); } - Object next([Object value]) native; + Object? next([Object? value]) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -10737,7 +10753,7 @@ class DomMatrix extends DomMatrixReadOnly { throw new UnsupportedError("Not supported"); } - factory DomMatrix([Object init]) { + factory DomMatrix([Object? init]) { if (init != null) { return DomMatrix._create_1(init); } @@ -10882,7 +10898,7 @@ class DomMatrix extends DomMatrixReadOnly { static DomMatrix fromFloat64Array(Float64List array64) native; - static DomMatrix fromMatrix([Map other]) { + static DomMatrix fromMatrix([Map? other]) { if (other != null) { var other_1 = convertDartToNative_Dictionary(other); return _fromMatrix_1(other_1); @@ -10897,7 +10913,7 @@ class DomMatrix extends DomMatrixReadOnly { DomMatrix invertSelf() native; - DomMatrix multiplySelf([Map other]) { + DomMatrix multiplySelf([Map? other]) { if (other != null) { var other_1 = convertDartToNative_Dictionary(other); return _multiplySelf_1(other_1); @@ -10910,7 +10926,7 @@ class DomMatrix extends DomMatrixReadOnly { @JSName('multiplySelf') DomMatrix _multiplySelf_2() native; - DomMatrix preMultiplySelf([Map other]) { + DomMatrix preMultiplySelf([Map? other]) { if (other != null) { var other_1 = convertDartToNative_Dictionary(other); return _preMultiplySelf_1(other_1); @@ -10923,30 +10939,30 @@ class DomMatrix extends DomMatrixReadOnly { @JSName('preMultiplySelf') DomMatrix _preMultiplySelf_2() native; - DomMatrix rotateAxisAngleSelf([num x, num y, num z, num angle]) native; + DomMatrix rotateAxisAngleSelf([num? x, num? y, num? z, num? angle]) native; - DomMatrix rotateFromVectorSelf([num x, num y]) native; + DomMatrix rotateFromVectorSelf([num? x, num? y]) native; - DomMatrix rotateSelf([num rotX, num rotY, num rotZ]) native; + DomMatrix rotateSelf([num? rotX, num? rotY, num? rotZ]) native; - DomMatrix scale3dSelf([num scale, num originX, num originY, num originZ]) + DomMatrix scale3dSelf([num? scale, num? originX, num? originY, num? originZ]) native; DomMatrix scaleSelf( - [num scaleX, - num scaleY, - num scaleZ, - num originX, - num originY, - num originZ]) native; + [num? scaleX, + num? scaleY, + num? scaleZ, + num? originX, + num? originY, + num? originZ]) native; DomMatrix setMatrixValue(String transformList) native; - DomMatrix skewXSelf([num sx]) native; + DomMatrix skewXSelf([num? sx]) native; - DomMatrix skewYSelf([num sy]) native; + DomMatrix skewYSelf([num? sy]) native; - DomMatrix translateSelf([num tx, num ty, num tz]) native; + DomMatrix translateSelf([num? tx, num? ty, num? tz]) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -10959,7 +10975,7 @@ class DomMatrixReadOnly extends Interceptor { throw new UnsupportedError("Not supported"); } - factory DomMatrixReadOnly([Object init]) { + factory DomMatrixReadOnly([Object? init]) { if (init != null) { return DomMatrixReadOnly._create_1(init); } @@ -11026,7 +11042,7 @@ class DomMatrixReadOnly extends Interceptor { static DomMatrixReadOnly fromFloat64Array(Float64List array64) native; - static DomMatrixReadOnly fromMatrix([Map other]) { + static DomMatrixReadOnly fromMatrix([Map? other]) { if (other != null) { var other_1 = convertDartToNative_Dictionary(other); return _fromMatrix_1(other_1); @@ -11041,7 +11057,7 @@ class DomMatrixReadOnly extends Interceptor { DomMatrix inverse() native; - DomMatrix multiply([Map other]) { + DomMatrix multiply([Map? other]) { if (other != null) { var other_1 = convertDartToNative_Dictionary(other); return _multiply_1(other_1); @@ -11054,31 +11070,32 @@ class DomMatrixReadOnly extends Interceptor { @JSName('multiply') DomMatrix _multiply_2() native; - DomMatrix rotate([num rotX, num rotY, num rotZ]) native; + DomMatrix rotate([num? rotX, num? rotY, num? rotZ]) native; - DomMatrix rotateAxisAngle([num x, num y, num z, num angle]) native; + DomMatrix rotateAxisAngle([num? x, num? y, num? z, num? angle]) native; - DomMatrix rotateFromVector([num x, num y]) native; + DomMatrix rotateFromVector([num? x, num? y]) native; DomMatrix scale( - [num scaleX, - num scaleY, - num scaleZ, - num originX, - num originY, - num originZ]) native; + [num? scaleX, + num? scaleY, + num? scaleZ, + num? originX, + num? originY, + num? originZ]) native; - DomMatrix scale3d([num scale, num originX, num originY, num originZ]) native; + DomMatrix scale3d([num? scale, num? originX, num? originY, num? originZ]) + native; - DomMatrix skewX([num sx]) native; + DomMatrix skewX([num? sx]) native; - DomMatrix skewY([num sy]) native; + DomMatrix skewY([num? sy]) native; Float32List toFloat32Array() native; Float64List toFloat64Array() native; - DomPoint transformPoint([Map point]) { + DomPoint transformPoint([Map? point]) { if (point != null) { var point_1 = convertDartToNative_Dictionary(point); return _transformPoint_1(point_1); @@ -11091,7 +11108,7 @@ class DomMatrixReadOnly extends Interceptor { @JSName('transformPoint') DomPoint _transformPoint_2() native; - DomMatrix translate([num tx, num ty, num tz]) native; + DomMatrix translate([num? tx, num? ty, num? tz]) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -11122,7 +11139,7 @@ class DomPoint extends DomPointReadOnly { throw new UnsupportedError("Not supported"); } - factory DomPoint([num x, num y, num z, num w]) { + factory DomPoint([num? x, num? y, num? z, num? w]) { if (w != null) { return DomPoint._create_1(x, y, z, w); } @@ -11173,7 +11190,7 @@ class DomPoint extends DomPointReadOnly { set z(num value) native; - static DomPoint fromPoint([Map other]) { + static DomPoint fromPoint([Map? other]) { if (other != null) { var other_1 = convertDartToNative_Dictionary(other); return _fromPoint_1(other_1); @@ -11197,7 +11214,7 @@ class DomPointReadOnly extends Interceptor { throw new UnsupportedError("Not supported"); } - factory DomPointReadOnly([num x, num y, num z, num w]) { + factory DomPointReadOnly([num? x, num? y, num? z, num? w]) { if (w != null) { return DomPointReadOnly._create_1(x, y, z, w); } @@ -11231,7 +11248,7 @@ class DomPointReadOnly extends Interceptor { num get z native; - static DomPointReadOnly fromPoint([Map other]) { + static DomPointReadOnly fromPoint([Map? other]) { if (other != null) { var other_1 = convertDartToNative_Dictionary(other); return _fromPoint_1(other_1); @@ -11244,7 +11261,7 @@ class DomPointReadOnly extends Interceptor { @JSName('fromPoint') static DomPointReadOnly _fromPoint_2() native; - DomPoint matrixTransform([Map matrix]) { + DomPoint matrixTransform([Map? matrix]) { if (matrix != null) { var matrix_1 = convertDartToNative_Dictionary(matrix); return _matrixTransform_1(matrix_1); @@ -11268,7 +11285,7 @@ class DomQuad extends Interceptor { throw new UnsupportedError("Not supported"); } - factory DomQuad([Map p1, Map p2, Map p3, Map p4]) { + factory DomQuad([Map? p1, Map? p2, Map? p3, Map? p4]) { if (p4 != null) { var p1_1 = convertDartToNative_Dictionary(p1); var p2_2 = convertDartToNative_Dictionary(p2); @@ -11309,7 +11326,7 @@ class DomQuad extends Interceptor { DomPoint get p4 native; - static DomQuad fromQuad([Map other]) { + static DomQuad fromQuad([Map? other]) { if (other != null) { var other_1 = convertDartToNative_Dictionary(other); return _fromQuad_1(other_1); @@ -11322,7 +11339,7 @@ class DomQuad extends Interceptor { @JSName('fromQuad') static DomQuad _fromQuad_2() native; - static DomQuad fromRect([Map other]) { + static DomQuad fromRect([Map? other]) { if (other != null) { var other_1 = convertDartToNative_Dictionary(other); return _fromRect_1(other_1); @@ -11395,7 +11412,7 @@ class DomRectList extends Interceptor Rectangle elementAt(int index) => this[index]; // -- end List mixins. - Rectangle item(int index) native; + Rectangle? item(int index) native; } // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -11427,7 +11444,7 @@ class DomRectReadOnly extends Interceptor implements Rectangle { * Returns the intersection of this and `other`, or null if they don't * intersect. */ - Rectangle intersection(Rectangle other) { + Rectangle? intersection(Rectangle other) { var x0 = max(left, other.left); var x1 = min(left + width, other.left + other.width); @@ -11496,7 +11513,7 @@ class DomRectReadOnly extends Interceptor implements Rectangle { throw new UnsupportedError("Not supported"); } - factory DomRectReadOnly([num x, num y, num width, num height]) { + factory DomRectReadOnly([num? x, num? y, num? width, num? height]) { if (height != null) { return DomRectReadOnly._create_1(x, y, width, height); } @@ -11538,7 +11555,7 @@ class DomRectReadOnly extends Interceptor implements Rectangle { num get y native; - static DomRectReadOnly fromRect([Map other]) { + static DomRectReadOnly fromRect([Map? other]) { if (other != null) { var other_1 = convertDartToNative_Dictionary(other); return _fromRect_1(other_1); @@ -11610,7 +11627,7 @@ class DomStringList extends Interceptor String elementAt(int index) => this[index]; // -- end List mixins. - String item(int index) native; + String? item(int index) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -11650,7 +11667,7 @@ class DomTokenList extends Interceptor { bool contains(String token) native; - String item(int index) native; + String? item(int index) native; void remove(String tokens) native; @@ -11658,7 +11675,7 @@ class DomTokenList extends Interceptor { bool supports(String token) native; - bool toggle(String token, [bool force]) native; + bool toggle(String token, [bool? force]) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -11671,10 +11688,10 @@ class _ChildrenElementList extends ListBase final HtmlCollection _childElements; _ChildrenElementList._wrap(Element element) - : _childElements = element._children, + : _childElements = element._children as HtmlCollection, _element = element; - bool contains(Object element) => _childElements.contains(element); + bool contains(Object? element) => _childElements.contains(element); bool get isEmpty { return _element._firstElementChild == null; @@ -11685,7 +11702,7 @@ class _ChildrenElementList extends ListBase } Element operator [](int index) { - return _childElements[index]; + return _childElements[index] as Element; } void operator []=(int index, Element value) { @@ -11714,11 +11731,11 @@ class _ChildrenElementList extends ListBase } } - void sort([int compare(Element a, Element b)]) { + void sort([int compare(Element a, Element b)?]) { throw new UnsupportedError('Cannot sort element lists'); } - void shuffle([Random random]) { + void shuffle([Random? random]) { throw new UnsupportedError('Cannot shuffle element lists'); } @@ -11740,7 +11757,7 @@ class _ChildrenElementList extends ListBase for (var e in removed) e.remove(); } - void fillRange(int start, int end, [Element fillValue]) { + void fillRange(int start, int end, [Element? fillValue]) { throw new UnimplementedError(); } @@ -11757,7 +11774,7 @@ class _ChildrenElementList extends ListBase throw new UnimplementedError(); } - bool remove(Object object) { + bool remove(Object? object) { if (object is Element) { Element element = object; if (identical(element.parentNode, _element)) { @@ -11793,6 +11810,7 @@ class _ChildrenElementList extends ListBase Element removeAt(int index) { final result = this[index]; + // TODO(41258): Remove null check after unfork/strong mode. if (result != null) { _element._removeChild(result); } @@ -11806,13 +11824,13 @@ class _ChildrenElementList extends ListBase } Element get first { - Element result = _element._firstElementChild; + Element? result = _element._firstElementChild; if (result == null) throw new StateError("No elements"); return result; } Element get last { - Element result = _element._lastElementChild; + Element? result = _element._lastElementChild; if (result == null) throw new StateError("No elements"); return result; } @@ -12218,7 +12236,7 @@ class _FrozenElementList extends ListBase int get length => _nodeList.length; - E operator [](int index) => _nodeList[index]; + E operator [](int index) => _nodeList[index] as E; void operator []=(int index, E value) { throw new UnsupportedError('Cannot modify list'); @@ -12228,19 +12246,19 @@ class _FrozenElementList extends ListBase throw new UnsupportedError('Cannot modify list'); } - void sort([Comparator compare]) { + void sort([Comparator? compare]) { throw new UnsupportedError('Cannot sort list'); } - void shuffle([Random random]) { + void shuffle([Random? random]) { throw new UnsupportedError('Cannot shuffle list'); } - E get first => _nodeList.first; + E get first => _nodeList.first as E; - E get last => _nodeList.last; + E get last => _nodeList.last as E; - E get single => _nodeList.single; + E get single => _nodeList.single as E; CssClassSet get classes => new _MultiElementCssClassSet(this); @@ -12647,12 +12665,12 @@ class Element extends Node * * [NodeValidator] * */ - factory Element.html(String html, - {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) { - var fragment = document.body.createFragment(html, + factory Element.html(String? html, + {NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) { + var fragment = document.body!.createFragment(html, validator: validator, treeSanitizer: treeSanitizer); - return fragment.nodes.where((e) => e is Element).single; + return fragment.nodes.where((e) => e is Element).single as Element; } /** @@ -12697,7 +12715,7 @@ class Element extends Node * * * [isTagSupported] */ - factory Element.tag(String tag, [String typeExtension]) => + factory Element.tag(String tag, [String? typeExtension]) => _ElementFactoryProvider.createElement_tag(tag, typeExtension); /// Creates a new `` element. @@ -12861,19 +12879,21 @@ class Element extends Node Map attributes = this.attributes; attributes.clear(); for (String key in value.keys) { - attributes[key] = value[key]; + attributes[key] = value[key]!; } } @pragma('dart2js:tryInline') - String getAttribute(String name) { + String? getAttribute(String name) { + // TODO(41258): Delete this assertion after forcing strong mode. // Protect [name] against string conversion to "null" or "undefined". assert(name != null, 'Attribute name cannot be null'); return _getAttribute(name); } @pragma('dart2js:tryInline') - String getAttributeNS(String namespaceURI, String name) { + String? getAttributeNS(String? namespaceURI, String name) { + // TODO(41258): Delete this assertion after forcing strong mode. // Protect [name] against string conversion to "null" or "undefined". // [namespaceURI] does not need protecting, both `null` and `undefined` map to `null`. assert(name != null, 'Attribute name cannot be null'); @@ -12882,13 +12902,15 @@ class Element extends Node @pragma('dart2js:tryInline') bool hasAttribute(String name) { + // TODO(41258): Delete this assertion after forcing strong mode. // Protect [name] against string conversion to "null" or "undefined". assert(name != null, 'Attribute name cannot be null'); return _hasAttribute(name); } @pragma('dart2js:tryInline') - bool hasAttributeNS(String namespaceURI, String name) { + bool hasAttributeNS(String? namespaceURI, String name) { + // TODO(41258): Delete this assertion after forcing strong mode. // Protect [name] against string conversion to "null" or "undefined". // [namespaceURI] does not need protecting, both `null` and `undefined` map to `null`. assert(name != null, 'Attribute name cannot be null'); @@ -12897,13 +12919,15 @@ class Element extends Node @pragma('dart2js:tryInline') void removeAttribute(String name) { + // TODO(41258): Delete this assertion after forcing strong mode. // Protect [name] against string conversion to "null" or "undefined". assert(name != null, 'Attribute name cannot be null'); _removeAttribute(name); } @pragma('dart2js:tryInline') - void removeAttributeNS(String namespaceURI, String name) { + void removeAttributeNS(String? namespaceURI, String name) { + // TODO(41258): Delete this assertion after forcing strong mode. // Protect [name] against string conversion to "null" or "undefined". assert(name != null, 'Attribute name cannot be null'); _removeAttributeNS(namespaceURI, name); @@ -12911,6 +12935,7 @@ class Element extends Node @pragma('dart2js:tryInline') void setAttribute(String name, String value) { + // TODO(41258): Delete these assertions after forcing strong mode. // Protect [name] against string conversion to "null" or "undefined". assert(name != null, 'Attribute name cannot be null'); // TODO(sra): assert(value != null, 'Attribute value cannot be null.'); @@ -12918,7 +12943,8 @@ class Element extends Node } @pragma('dart2js:tryInline') - void setAttributeNS(String namespaceURI, String name, String value) { + void setAttributeNS(String? namespaceURI, String name, String value) { + // TODO(41258): Delete these assertions after forcing strong mode. // Protect [name] against string conversion to "null" or "undefined". assert(name != null, 'Attribute name cannot be null'); // TODO(sra): assert(value != null, 'Attribute value cannot be null.'); @@ -13035,7 +13061,7 @@ class Element extends Node final data = this.dataset; data.clear(); for (String key in value.keys) { - data[key] = value[key]; + data[key] = value[key]!; } } @@ -13067,7 +13093,7 @@ class Element extends Node * * [Pseudo-elements](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements) * from MDN. */ - CssStyleDeclaration getComputedStyle([String pseudoElement]) { + CssStyleDeclaration getComputedStyle([String? pseudoElement]) { if (pseudoElement == null) { pseudoElement = ''; } @@ -13099,7 +13125,7 @@ class Element extends Node * last child of this element. */ void appendHtml(String text, - {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) { + {NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) { this.insertAdjacentHtml('beforeend', text, validator: validator, treeSanitizer: treeSanitizer); } @@ -13224,7 +13250,7 @@ class Element extends Node * * [Node.namespaceURI](http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-NodeNSname) * from W3C. */ - String get namespaceUri => _namespaceUri; + String? get namespaceUri => _namespaceUri; /** * The string representation of this element. @@ -13252,7 +13278,7 @@ class Element extends Node * * [scrollIntoViewIfNeeded](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoViewIfNeeded) * from MDN. */ - void scrollIntoView([ScrollAlignment alignment]) { + void scrollIntoView([ScrollAlignment? alignment]) { var hasScrollIntoViewIfNeeded = true; hasScrollIntoViewIfNeeded = JS('bool', '!!(#.scrollIntoViewIfNeeded)', this); @@ -13347,7 +13373,7 @@ class Element extends Node * * [insertAdjacentElement] */ void insertAdjacentHtml(String where, String html, - {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) { + {NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) { if (treeSanitizer is _TrustedHtmlTreeSanitizer) { _insertAdjacentHtml(where, html); } else { @@ -13386,7 +13412,7 @@ class Element extends Node void _insertAdjacentNode(String where, Node node) { switch (where.toLowerCase()) { case 'beforebegin': - this.parentNode.insertBefore(node, this); + this.parentNode!.insertBefore(node, this); break; case 'afterbegin': var first = this.nodes.length > 0 ? this.nodes[0] : null; @@ -13396,7 +13422,7 @@ class Element extends Node this.append(node); break; case 'afterend': - this.parentNode.insertBefore(node, this.nextNode); + this.parentNode!.insertBefore(node, this.nextNode); break; default: throw new ArgumentError("Invalid position ${where}"); @@ -13424,9 +13450,9 @@ class Element extends Node /** Checks if this element or any of its parents match the CSS selectors. */ bool matchesWithAncestors(String selectors) { - var elem = this; + var elem = this as Element?; do { - if (elem.matches(selectors)) return true; + if (elem!.matches(selectors)) return true; elem = elem.parent; } while (elem != null); return false; @@ -13462,7 +13488,7 @@ class Element extends Node * from W3C. */ @SupportedBrowser(SupportedBrowser.CHROME, '25') - ShadowRoot get shadowRoot => + ShadowRoot? get shadowRoot => JS('ShadowRoot|Null', '#.shadowRoot || #.webkitShadowRoot', this, this); /** @@ -13542,7 +13568,7 @@ class Element extends Node * This method is the Dart equivalent to jQuery's * [offset](http://api.jquery.com/offset/) method. */ - Point get documentOffset => offsetTo(document.documentElement); + Point get documentOffset => offsetTo(document.documentElement!); /** * Provides the offset of this element's [borderEdge] relative to the @@ -13559,7 +13585,7 @@ class Element extends Node return Element._offsetToHelper(this, parent); } - static Point _offsetToHelper(Element current, Element parent) { + static Point _offsetToHelper(Element? current, Element parent) { // We're hopping from _offsetParent_ to offsetParent (not just parent), so // offsetParent, "tops out" at BODY. But people could conceivably pass in // the document.documentElement and I want it to return an absolute offset, @@ -13571,15 +13597,15 @@ class Element extends Node throw new ArgumentError("Specified element is not a transitive offset " "parent of this element."); } - Element parentOffset = current.offsetParent; + Element? parentOffset = current.offsetParent; Point p = Element._offsetToHelper(parentOffset, parent); return new Point(p.x + current.offsetLeft, p.y + current.offsetTop); } - static HtmlDocument _parseDocument; - static Range _parseRange; - static NodeValidatorBuilder _defaultValidator; - static _ValidatingTreeSanitizer _defaultSanitizer; + static HtmlDocument? _parseDocument; + static Range? _parseRange; + static NodeValidatorBuilder? _defaultValidator; + static _ValidatingTreeSanitizer? _defaultSanitizer; /** * Create a DocumentFragment from the HTML fragment and ensure that it follows @@ -13601,8 +13627,8 @@ class Element extends Node * * [NodeValidator] * * [NodeTreeSanitizer] */ - DocumentFragment createFragment(String html, - {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) { + DocumentFragment createFragment(String? html, + {NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) { if (treeSanitizer == null) { if (validator == null) { if (_defaultValidator == null) { @@ -13611,9 +13637,9 @@ class Element extends Node validator = _defaultValidator; } if (_defaultSanitizer == null) { - _defaultSanitizer = new _ValidatingTreeSanitizer(validator); + _defaultSanitizer = new _ValidatingTreeSanitizer(validator!); } else { - _defaultSanitizer.validator = validator; + _defaultSanitizer!.validator = validator!; } treeSanitizer = _defaultSanitizer; } else if (validator != null) { @@ -13623,47 +13649,48 @@ class Element extends Node if (_parseDocument == null) { _parseDocument = document.implementation.createHtmlDocument(''); - _parseRange = _parseDocument.createRange(); + _parseRange = _parseDocument!.createRange(); // Workaround for Safari bug. Was also previously Chrome bug 229142 // - URIs are not resolved in new doc. - BaseElement base = _parseDocument.createElement('base'); + BaseElement base = _parseDocument!.createElement('base') as BaseElement; base.href = document.baseUri; - _parseDocument.head.append(base); + _parseDocument!.head!.append(base); } // TODO(terry): Fixes Chromium 50 change no body after createHtmlDocument() - if (_parseDocument.body == null) { - _parseDocument.body = _parseDocument.createElement("body"); + if (_parseDocument!.body == null) { + _parseDocument!.body = + _parseDocument!.createElement("body") as BodyElement; } var contextElement; if (this is BodyElement) { - contextElement = _parseDocument.body; + contextElement = _parseDocument!.body!; } else { - contextElement = _parseDocument.createElement(tagName); - _parseDocument.body.append(contextElement); + contextElement = _parseDocument!.createElement(tagName); + _parseDocument!.body!.append(contextElement); } var fragment; if (Range.supportsCreateContextualFragment && _canBeUsedToCreateContextualFragment) { - _parseRange.selectNodeContents(contextElement); + _parseRange!.selectNodeContents(contextElement); // createContextualFragment expects a non-nullable html string. // If null is passed, it gets converted to 'null' instead. - fragment = _parseRange.createContextualFragment(html ?? 'null'); + fragment = _parseRange!.createContextualFragment(html ?? 'null'); } else { contextElement._innerHtml = html; - fragment = _parseDocument.createDocumentFragment(); + fragment = _parseDocument!.createDocumentFragment(); while (contextElement.firstChild != null) { fragment.append(contextElement.firstChild); } } - if (contextElement != _parseDocument.body) { + if (contextElement != _parseDocument!.body) { contextElement.remove(); } - treeSanitizer.sanitizeTree(fragment); + treeSanitizer!.sanitizeTree(fragment); // Copy the fragment over to the main document (fix for 14184) document.adoptNode(fragment); @@ -13713,7 +13740,7 @@ class Element extends Node * This uses the default sanitization behavior to sanitize the HTML fragment, * use [setInnerHtml] to override the default behavior. */ - set innerHtml(String html) { + set innerHtml(String? html) { this.setInnerHtml(html); } @@ -13738,8 +13765,8 @@ class Element extends Node * * [NodeValidator] * * [NodeTreeSanitizer] */ - void setInnerHtml(String html, - {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) { + void setInnerHtml(String? html, + {NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) { text = null; if (treeSanitizer is _TrustedHtmlTreeSanitizer) { _innerHtml = html; @@ -13833,7 +13860,7 @@ class Element extends Node return result; } - Element get offsetParent native; + Element? get offsetParent native; int get offsetHeight => JS('num', '#.offsetHeight', this).round(); @@ -14507,9 +14534,9 @@ class Element extends Node void focus() native; - AccessibleNode get accessibleNode native; + AccessibleNode? get accessibleNode native; - SlotElement get assignedSlot native; + SlotElement? get assignedSlot native; @JSName('attributes') _NamedNodeMap get _attributes native; @@ -14526,9 +14553,9 @@ class Element extends Node int get clientWidth native; - String get computedName native; + String? get computedName native; - String get computedRole native; + String? get computedRole native; String get id native; @@ -14538,13 +14565,13 @@ class Element extends Node String get _innerHtml native; @JSName('innerHTML') - set _innerHtml(String value) native; + set _innerHtml(String? value) native; @JSName('localName') String get _localName native; @JSName('namespaceURI') - String get _namespaceUri native; + String? get _namespaceUri native; @JSName('outerHTML') String get outerHtml native; @@ -14584,15 +14611,15 @@ class Element extends Node @JSName('attachShadow') ShadowRoot _attachShadow_1(shadowRootInitDict) native; - Element closest(String selectors) native; + Element? closest(String selectors) native; List getAnimations() native; @JSName('getAttribute') - String _getAttribute(String name) native; + String? _getAttribute(String name) native; @JSName('getAttributeNS') - String _getAttributeNS(String namespaceURI, String localName) native; + String? _getAttributeNS(String? namespaceURI, String localName) native; List getAttributeNames() native; @@ -14639,7 +14666,7 @@ class Element extends Node * specification](https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html) * from W3C. */ - @Returns('NodeList|Null') + @Returns('NodeList') @Creates('NodeList') List getDestinationInsertionPoints() native; @@ -14665,7 +14692,7 @@ class Element extends Node bool _hasAttribute(String name) native; @JSName('hasAttributeNS') - bool _hasAttributeNS(String namespaceURI, String localName) native; + bool _hasAttributeNS(String? namespaceURI, String localName) native; bool hasPointerCapture(int pointerId) native; @@ -14675,11 +14702,11 @@ class Element extends Node void _removeAttribute(String name) native; @JSName('removeAttributeNS') - void _removeAttributeNS(String namespaceURI, String localName) native; + void _removeAttributeNS(String? namespaceURI, String localName) native; void requestPointerLock() native; - void scroll([options_OR_x, num y]) { + void scroll([options_OR_x, num? y]) { if (options_OR_x == null && y == null) { _scroll_1(); return; @@ -14701,9 +14728,9 @@ class Element extends Node @JSName('scroll') void _scroll_2(options) native; @JSName('scroll') - void _scroll_3(num x, y) native; + void _scroll_3(num? x, y) native; - void scrollBy([options_OR_x, num y]) { + void scrollBy([options_OR_x, num? y]) { if (options_OR_x == null && y == null) { _scrollBy_1(); return; @@ -14725,15 +14752,15 @@ class Element extends Node @JSName('scrollBy') void _scrollBy_2(options) native; @JSName('scrollBy') - void _scrollBy_3(num x, y) native; + void _scrollBy_3(num? x, y) native; @JSName('scrollIntoView') - void _scrollIntoView([Object arg]) native; + void _scrollIntoView([Object? arg]) native; @JSName('scrollIntoViewIfNeeded') - void _scrollIntoViewIfNeeded([bool centerIfNeeded]) native; + void _scrollIntoViewIfNeeded([bool? centerIfNeeded]) native; - void scrollTo([options_OR_x, num y]) { + void scrollTo([options_OR_x, num? y]) { if (options_OR_x == null && y == null) { _scrollTo_1(); return; @@ -14755,13 +14782,13 @@ class Element extends Node @JSName('scrollTo') void _scrollTo_2(options) native; @JSName('scrollTo') - void _scrollTo_3(num x, y) native; + void _scrollTo_3(num? x, y) native; @JSName('setAttribute') void _setAttribute(String name, String value) native; @JSName('setAttributeNS') - void _setAttributeNS(String namespaceURI, String name, String value) native; + void _setAttributeNS(String? namespaceURI, String name, String value) native; void setPointerCapture(int pointerId) native; @@ -14788,9 +14815,9 @@ class Element extends Node // From NonDocumentTypeChildNode - Element get nextElementSibling native; + Element? get nextElementSibling native; - Element get previousElementSibling native; + Element? get previousElementSibling native; // From ParentNode @@ -14798,15 +14825,15 @@ class Element extends Node int get _childElementCount native; @JSName('children') - @Returns('HtmlCollection|Null') + @Returns('HtmlCollection') @Creates('HtmlCollection') List get _children native; @JSName('firstElementChild') - Element get _firstElementChild native; + Element? get _firstElementChild native; @JSName('lastElementChild') - Element get _lastElementChild native; + Element? get _lastElementChild native; /** * Finds the first descendant element of this element that matches the @@ -14824,7 +14851,7 @@ class Element extends Node * For details about CSS selector syntax, see the * [CSS selector specification](http://www.w3.org/TR/css3-selectors/). */ - Element querySelector(String selectors) native; + Element? querySelector(String selectors) native; @JSName('querySelectorAll') @Creates('NodeList') @@ -15138,7 +15165,7 @@ class Element extends Node class _ElementFactoryProvider { // Optimization to improve performance until the dart2js compiler inlines this // method. - static dynamic createElement_tag(String tag, String typeExtension) { + static dynamic createElement_tag(String tag, String? typeExtension) { // Firefox may return a JS function for some types (Embed, Object). if (typeExtension != null) { return JS('Element|=Object', 'document.createElement(#, #)', tag, @@ -15184,7 +15211,7 @@ class EmbedElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory EmbedElement() => document.createElement("embed"); + factory EmbedElement() => document.createElement("embed") as EmbedElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -15249,12 +15276,12 @@ class Entry extends Interceptor { @JSName('copyTo') void _copyTo(DirectoryEntry parent, - [String name, - _EntryCallback successCallback, - _ErrorCallback errorCallback]) native; + [String? name, + _EntryCallback? successCallback, + _ErrorCallback? errorCallback]) native; @JSName('copyTo') - Future copyTo(DirectoryEntry parent, {String name}) { + Future copyTo(DirectoryEntry parent, {String? name}) { var completer = new Completer(); _copyTo(parent, name, (value) { completer.complete(value); @@ -15266,7 +15293,7 @@ class Entry extends Interceptor { @JSName('getMetadata') void _getMetadata(MetadataCallback successCallback, - [_ErrorCallback errorCallback]) native; + [_ErrorCallback? errorCallback]) native; @JSName('getMetadata') Future getMetadata() { @@ -15282,7 +15309,7 @@ class Entry extends Interceptor { @JSName('getParent') void _getParent( - [_EntryCallback successCallback, _ErrorCallback errorCallback]) native; + [_EntryCallback? successCallback, _ErrorCallback? errorCallback]) native; @JSName('getParent') Future getParent() { @@ -15298,12 +15325,12 @@ class Entry extends Interceptor { @JSName('moveTo') void _moveTo(DirectoryEntry parent, - [String name, - _EntryCallback successCallback, - _ErrorCallback errorCallback]) native; + [String? name, + _EntryCallback? successCallback, + _ErrorCallback? errorCallback]) native; @JSName('moveTo') - Future moveTo(DirectoryEntry parent, {String name}) { + Future moveTo(DirectoryEntry parent, {String? name}) { var completer = new Completer(); _moveTo(parent, name, (value) { completer.complete(value); @@ -15314,7 +15341,7 @@ class Entry extends Interceptor { } @JSName('remove') - void _remove(VoidCallback successCallback, [_ErrorCallback errorCallback]) + void _remove(VoidCallback successCallback, [_ErrorCallback? errorCallback]) native; @JSName('remove') @@ -15357,7 +15384,7 @@ class ErrorEvent extends Event { throw new UnsupportedError("Not supported"); } - factory ErrorEvent(String type, [Map eventInitDict]) { + factory ErrorEvent(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return ErrorEvent._create_1(type, eventInitDict_1); @@ -15372,7 +15399,7 @@ class ErrorEvent extends Event { int get colno native; @Creates('Null') - Object get error native; + Object? get error native; String get filename native; @@ -15415,8 +15442,8 @@ class Event extends Interceptor { } /** The CSS selector involved with event delegation. */ - String get _selector native; - set _selector(String value) native; + String? get _selector native; + set _selector(String? value) native; /** * A pointer to the element whose CSS selector matched within which an event @@ -15428,20 +15455,20 @@ class Event extends Interceptor { throw new UnsupportedError('Cannot call matchingTarget if this Event did' ' not arise as a result of event delegation.'); } - Element currentTarget = this.currentTarget; - Element target = this.target; + Element? currentTarget = this.currentTarget as Element?; + Element? target = this.target as Element?; var matchedTarget; do { - if (target.matches(_selector)) return target; + if (target!.matches(_selector!)) return target; target = target.parent; - } while (target != null && target != currentTarget.parent); + } while (target != null && target != currentTarget!.parent); throw new StateError('No selector matched for populating matchedTarget.'); } List get path => JS('bool', '!!#.composedPath', this) ? composedPath() : []; - factory Event._(String type, [Map eventInitDict]) { + factory Event._(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return Event._create_1(type, eventInitDict_1); @@ -15489,7 +15516,7 @@ class Event extends Interceptor { bool get composed native; - EventTarget get currentTarget => + EventTarget? get currentTarget => _convertNativeToDart_EventTarget(this._get_currentTarget); @JSName('currentTarget') @Creates('Null') @@ -15502,7 +15529,7 @@ class Event extends Interceptor { bool get isTrusted native; - EventTarget get target => _convertNativeToDart_EventTarget(this._get_target); + EventTarget? get target => _convertNativeToDart_EventTarget(this._get_target); @JSName('target') @Creates('Node') @Returns('EventTarget|=Object') @@ -15515,7 +15542,7 @@ class Event extends Interceptor { List composedPath() native; @JSName('initEvent') - void _initEvent(String type, [bool bubbles, bool cancelable]) native; + void _initEvent(String type, [bool? bubbles, bool? cancelable]) native; void preventDefault() native; @@ -15568,7 +15595,7 @@ class EventSource extends EventTarget { const EventStreamProvider('open'); static EventSource _factoryEventSource(String url, - [Map eventSourceInitDict]) { + [Map? eventSourceInitDict]) { if (eventSourceInitDict != null) { var eventSourceInitDict_1 = convertDartToNative_Dictionary(eventSourceInitDict); @@ -15704,8 +15731,8 @@ class EventTarget extends Interceptor { */ Events get on => new Events(this); - void addEventListener(String type, EventListener listener, - [bool useCapture]) { + void addEventListener(String type, EventListener? listener, + [bool? useCapture]) { // TODO(leafp): This check is avoid a bug in our dispatch code when // listener is null. The browser treats this call as a no-op in this // case, so it's fine to short-circuit it, but we should not have to. @@ -15714,8 +15741,8 @@ class EventTarget extends Interceptor { } } - void removeEventListener(String type, EventListener listener, - [bool useCapture]) { + void removeEventListener(String type, EventListener? listener, + [bool? useCapture]) { // TODO(leafp): This check is avoid a bug in our dispatch code when // listener is null. The browser treats this call as a no-op in this // case, so it's fine to short-circuit it, but we should not have to. @@ -15730,14 +15757,14 @@ class EventTarget extends Interceptor { } @JSName('addEventListener') - void _addEventListener(String type, EventListener listener, [bool options]) + void _addEventListener(String type, EventListener? listener, [bool? options]) native; bool dispatchEvent(Event event) native; @JSName('removeEventListener') - void _removeEventListener(String type, EventListener listener, [bool options]) - native; + void _removeEventListener(String type, EventListener? listener, + [bool? options]) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -15750,7 +15777,7 @@ class ExtendableEvent extends Event { throw new UnsupportedError("Not supported"); } - factory ExtendableEvent(String type, [Map eventInitDict]) { + factory ExtendableEvent(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return ExtendableEvent._create_1(type, eventInitDict_1); @@ -15777,7 +15804,7 @@ class ExtendableMessageEvent extends ExtendableEvent { @annotation_Creates_SerializedScriptValue @annotation_Returns_SerializedScriptValue - Object get data native; + Object? get data native; String get lastEventId native; @@ -15787,7 +15814,7 @@ class ExtendableMessageEvent extends ExtendableEvent { @Creates('Client|ServiceWorker|MessagePort') @Returns('Client|ServiceWorker|MessagePort|Null') - Object get source native; + Object? get source native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -15815,7 +15842,7 @@ class FaceDetector extends Interceptor { throw new UnsupportedError("Not supported"); } - factory FaceDetector([Map faceDetectorOptions]) { + factory FaceDetector([Map? faceDetectorOptions]) { if (faceDetectorOptions != null) { var faceDetectorOptions_1 = convertDartToNative_Dictionary(faceDetectorOptions); @@ -15848,7 +15875,7 @@ class FederatedCredential extends Credential implements CredentialUserData { static FederatedCredential _create_1(data) => JS('FederatedCredential', 'new FederatedCredential(#)', data); - String get protocol native; + String? get protocol native; String get provider native; @@ -15877,7 +15904,7 @@ class FetchEvent extends ExtendableEvent { static FetchEvent _create_1(type, eventInitDict) => JS('FetchEvent', 'new FetchEvent(#,#)', type, eventInitDict); - String get clientId native; + String? get clientId native; bool get isReload native; @@ -15900,7 +15927,7 @@ class FieldSetElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory FieldSetElement() => JS( + factory FieldSetElement() => JS( 'returns:FieldSetElement;creates:FieldSetElement;new:true', '#.createElement(#)', document, @@ -15916,11 +15943,11 @@ class FieldSetElement extends HtmlElement { set disabled(bool value) native; - @Returns('HtmlCollection|Null') + @Returns('HtmlCollection') @Creates('HtmlCollection') List get elements native; - FormElement get form native; + FormElement? get form native; String get name native; @@ -15951,7 +15978,7 @@ class File extends Blob { throw new UnsupportedError("Not supported"); } - factory File(List fileBits, String fileName, [Map options]) { + factory File(List fileBits, String fileName, [Map? options]) { if (options != null) { var options_1 = convertDartToNative_Dictionary(options); return File._create_1(fileBits, fileName, options_1); @@ -15984,7 +16011,7 @@ class File extends Blob { // WARNING: Do not edit - generated code. -typedef void _FileCallback(File file); +typedef void _FileCallback(File? file); // Copyright (c) 2012, 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. @@ -15998,7 +16025,7 @@ class FileEntry extends Entry { @JSName('createWriter') void _createWriter(_FileWriterCallback successCallback, - [_ErrorCallback errorCallback]) native; + [_ErrorCallback? errorCallback]) native; @JSName('createWriter') Future createWriter() { @@ -16013,7 +16040,7 @@ class FileEntry extends Entry { } @JSName('file') - void _file(_FileCallback successCallback, [_ErrorCallback errorCallback]) + void _file(_FileCallback successCallback, [_ErrorCallback? errorCallback]) native; @JSName('file') @@ -16086,7 +16113,7 @@ class FileList extends Interceptor File elementAt(int index) => this[index]; // -- end List mixins. - File item(int index) native; + File? item(int index) native; } // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -16094,7 +16121,7 @@ class FileList extends Interceptor @Native("FileReader") class FileReader extends EventTarget { - Object get result { + Object? get result { var res = JS('Null|String|NativeByteBuffer', '#.result', this); if (res is ByteBuffer) { return new Uint8List.view(res); @@ -16172,7 +16199,7 @@ class FileReader extends EventTarget { static const int LOADING = 1; - DomException get error native; + DomException? get error native; int get readyState native; @@ -16183,7 +16210,7 @@ class FileReader extends EventTarget { @JSName('readAsDataURL') void readAsDataUrl(Blob blob) native; - void readAsText(Blob blob, [String label]) native; + void readAsText(Blob blob, [String? label]) native; /// Stream of `abort` events handled by this [FileReader]. Stream get onAbort => abortEvent.forTarget(this); @@ -16300,7 +16327,7 @@ class FileWriter extends EventTarget { static const int WRITING = 1; - DomException get error native; + DomException? get error native; int get length native; @@ -16352,7 +16379,7 @@ class FocusEvent extends UIEvent { throw new UnsupportedError("Not supported"); } - factory FocusEvent(String type, [Map eventInitDict]) { + factory FocusEvent(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return FocusEvent._create_1(type, eventInitDict_1); @@ -16364,7 +16391,7 @@ class FocusEvent extends UIEvent { static FocusEvent _create_2(type) => JS('FocusEvent', 'new FocusEvent(#)', type); - EventTarget get relatedTarget => + EventTarget? get relatedTarget => _convertNativeToDart_EventTarget(this._get_relatedTarget); @JSName('relatedTarget') @Creates('Null') @@ -16381,7 +16408,7 @@ class FontFace extends Interceptor { throw new UnsupportedError("Not supported"); } - factory FontFace(String family, Object source, [Map descriptors]) { + factory FontFace(String family, Object source, [Map? descriptors]) { if (descriptors != null) { var descriptors_1 = convertDartToNative_Dictionary(descriptors); return FontFace._create_1(family, source, descriptors_1); @@ -16457,13 +16484,13 @@ class FontFaceSet extends EventTarget { FontFaceSet add(FontFace arg) native; - bool check(String font, [String text]) native; + bool check(String font, [String? text]) native; void clear() native; bool delete(FontFace arg) native; - void forEach(FontFaceSetForEachCallback callback, [Object thisArg]) native; + void forEach(FontFaceSetForEachCallback callback, [Object? thisArg]) native; bool has(FontFace arg) native; @@ -16486,7 +16513,7 @@ class FontFaceSetLoadEvent extends Event { throw new UnsupportedError("Not supported"); } - factory FontFaceSetLoadEvent(String type, [Map eventInitDict]) { + factory FontFaceSetLoadEvent(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return FontFaceSetLoadEvent._create_1(type, eventInitDict_1); @@ -16555,7 +16582,7 @@ class FormData extends Interceptor { throw new UnsupportedError("Not supported"); } - factory FormData([FormElement form]) { + factory FormData([FormElement? form]) { if (form != null) { return FormData._create_1(form); } @@ -16570,17 +16597,17 @@ class FormData extends Interceptor { void append(String name, String value) native; @JSName('append') - void appendBlob(String name, Blob value, [String filename]) native; + void appendBlob(String name, Blob value, [String? filename]) native; void delete(String name) native; - Object get(String name) native; + Object? get(String name) native; List getAll(String name) native; bool has(String name) native; - void set(String name, value, [String filename]) native; + void set(String name, value, [String? filename]) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -16593,7 +16620,7 @@ class FormElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory FormElement() => JS( + factory FormElement() => JS( 'returns:FormElement;creates:FormElement;new:true', '#.createElement(#)', document, @@ -16643,7 +16670,7 @@ class FormElement extends HtmlElement { set target(String value) native; - Object __getter__(String name) native; + Object? __getter__(String name) native; bool checkValidity() native; @@ -16651,7 +16678,7 @@ class FormElement extends HtmlElement { bool reportValidity() native; - void requestAutocomplete(Map details) { + void requestAutocomplete(Map? details) { var details_1 = convertDartToNative_Dictionary(details); _requestAutocomplete_1(details_1); return; @@ -16707,7 +16734,7 @@ class Gamepad extends Interceptor { String get mapping native; - GamepadPose get pose native; + GamepadPose? get pose native; int get timestamp native; } @@ -16739,7 +16766,7 @@ class GamepadEvent extends Event { throw new UnsupportedError("Not supported"); } - factory GamepadEvent(String type, [Map eventInitDict]) { + factory GamepadEvent(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return GamepadEvent._create_1(type, eventInitDict_1); @@ -16764,21 +16791,21 @@ class GamepadPose extends Interceptor { throw new UnsupportedError("Not supported"); } - Float32List get angularAcceleration native; + Float32List? get angularAcceleration native; - Float32List get angularVelocity native; + Float32List? get angularVelocity native; bool get hasOrientation native; bool get hasPosition native; - Float32List get linearAcceleration native; + Float32List? get linearAcceleration native; - Float32List get linearVelocity native; + Float32List? get linearVelocity native; - Float32List get orientation native; + Float32List? get orientation native; - Float32List get position native; + Float32List? get position native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -16788,7 +16815,7 @@ class GamepadPose extends Interceptor { @Native("Geolocation") class Geolocation extends Interceptor { Future getCurrentPosition( - {bool enableHighAccuracy, Duration timeout, Duration maximumAge}) { + {bool? enableHighAccuracy, Duration? timeout, Duration? maximumAge}) { var options = {}; if (enableHighAccuracy != null) { options['enableHighAccuracy'] = enableHighAccuracy; @@ -16813,7 +16840,7 @@ class Geolocation extends Interceptor { } Stream watchPosition( - {bool enableHighAccuracy, Duration timeout, Duration maximumAge}) { + {bool? enableHighAccuracy, Duration? timeout, Duration? maximumAge}) { var options = {}; if (enableHighAccuracy != null) { options['enableHighAccuracy'] = enableHighAccuracy; @@ -16825,13 +16852,13 @@ class Geolocation extends Interceptor { options['maximumAge'] = maximumAge.inMilliseconds; } - int watchId; + int? watchId; StreamController controller = new StreamController( sync: true, onCancel: () { assert(watchId != null); - _clearWatch(watchId); + _clearWatch(watchId!); }); controller.onListen = () { assert(watchId == null); @@ -16864,7 +16891,7 @@ class Geolocation extends Interceptor { void _clearWatch(int watchID) native; void _getCurrentPosition(_PositionCallback successCallback, - [_PositionErrorCallback errorCallback, Map options]) { + [_PositionErrorCallback? errorCallback, Map? options]) { if (options != null) { var successCallback_1 = convertDartClosureToJS(successCallback, 1); var options_2 = convertDartToNative_Dictionary(options); @@ -16883,15 +16910,15 @@ class Geolocation extends Interceptor { @JSName('getCurrentPosition') void _getCurrentPosition_1( - successCallback, _PositionErrorCallback errorCallback, options) native; + successCallback, _PositionErrorCallback? errorCallback, options) native; @JSName('getCurrentPosition') void _getCurrentPosition_2( - successCallback, _PositionErrorCallback errorCallback) native; + successCallback, _PositionErrorCallback? errorCallback) native; @JSName('getCurrentPosition') void _getCurrentPosition_3(successCallback) native; int _watchPosition(_PositionCallback successCallback, - [_PositionErrorCallback errorCallback, Map options]) { + [_PositionErrorCallback? errorCallback, Map? options]) { if (options != null) { var successCallback_1 = convertDartClosureToJS(successCallback, 1); var options_2 = convertDartToNative_Dictionary(options); @@ -16907,9 +16934,9 @@ class Geolocation extends Interceptor { @JSName('watchPosition') int _watchPosition_1( - successCallback, _PositionErrorCallback errorCallback, options) native; + successCallback, _PositionErrorCallback? errorCallback, options) native; @JSName('watchPosition') - int _watchPosition_2(successCallback, _PositionErrorCallback errorCallback) + int _watchPosition_2(successCallback, _PositionErrorCallback? errorCallback) native; @JSName('watchPosition') int _watchPosition_3(successCallback) native; @@ -16950,11 +16977,11 @@ class Geoposition extends Interceptor { // convince the scripts to make our instance methods abstract, and the bodies that // get generated require `this` to be an EventTarget. abstract class GlobalEventHandlers implements EventTarget { - void addEventListener(String type, dynamic listener(Event event), - [bool useCapture]); + void addEventListener(String type, dynamic listener(Event event)?, + [bool? useCapture]); bool dispatchEvent(Event event); - void removeEventListener(String type, dynamic listener(Event event), - [bool useCapture]); + void removeEventListener(String type, dynamic listener(Event event)?, + [bool? useCapture]); Events get on; // To suppress missing implicit constructor warnings. @@ -17260,7 +17287,7 @@ class Gyroscope extends Sensor { throw new UnsupportedError("Not supported"); } - factory Gyroscope([Map sensorOptions]) { + factory Gyroscope([Map? sensorOptions]) { if (sensorOptions != null) { var sensorOptions_1 = convertDartToNative_Dictionary(sensorOptions); return Gyroscope._create_1(sensorOptions_1); @@ -17271,11 +17298,11 @@ class Gyroscope extends Sensor { JS('Gyroscope', 'new Gyroscope(#)', sensorOptions); static Gyroscope _create_2() => JS('Gyroscope', 'new Gyroscope()'); - num get x native; + num? get x native; - num get y native; + num? get y native; - num get z native; + num? get z native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -17291,8 +17318,11 @@ class HRElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory HRElement() => JS('returns:HRElement;creates:HRElement;new:true', - '#.createElement(#)', document, "hr"); + factory HRElement() => JS( + 'returns:HRElement;creates:HRElement;new:true', + '#.createElement(#)', + document, + "hr"); /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -17319,8 +17349,8 @@ class HashChangeEvent extends Event { factory HashChangeEvent(String type, {bool canBubble: true, bool cancelable: true, - String oldUrl, - String newUrl}) { + String? oldUrl, + String? newUrl}) { var options = { 'canBubble': canBubble, 'cancelable': cancelable, @@ -17331,7 +17361,7 @@ class HashChangeEvent extends Event { convertDartToNative_Dictionary(options)); } - factory HashChangeEvent._(String type, [Map eventInitDict]) { + factory HashChangeEvent._(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return HashChangeEvent._create_1(type, eventInitDict_1); @@ -17363,7 +17393,7 @@ class HeadElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory HeadElement() => JS( + factory HeadElement() => JS( 'returns:HeadElement;creates:HeadElement;new:true', '#.createElement(#)', document, @@ -17386,7 +17416,7 @@ class Headers extends Interceptor { throw new UnsupportedError("Not supported"); } - factory Headers([Object init]) { + factory Headers([Object? init]) { if (init != null) { return Headers._create_1(init); } @@ -17406,37 +17436,37 @@ class HeadingElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory HeadingElement.h1() => JS( + factory HeadingElement.h1() => JS( 'returns:HeadingElement;creates:HeadingElement;new:true', '#.createElement(#)', document, "h1"); - factory HeadingElement.h2() => JS( + factory HeadingElement.h2() => JS( 'returns:HeadingElement;creates:HeadingElement;new:true', '#.createElement(#)', document, "h2"); - factory HeadingElement.h3() => JS( + factory HeadingElement.h3() => JS( 'returns:HeadingElement;creates:HeadingElement;new:true', '#.createElement(#)', document, "h3"); - factory HeadingElement.h4() => JS( + factory HeadingElement.h4() => JS( 'returns:HeadingElement;creates:HeadingElement;new:true', '#.createElement(#)', document, "h4"); - factory HeadingElement.h5() => JS( + factory HeadingElement.h5() => JS( 'returns:HeadingElement;creates:HeadingElement;new:true', '#.createElement(#)', document, "h5"); - factory HeadingElement.h6() => JS( + factory HeadingElement.h6() => JS( 'returns:HeadingElement;creates:HeadingElement;new:true', '#.createElement(#)', document, @@ -17486,13 +17516,13 @@ class History extends Interceptor implements HistoryBase { void forward() native; - void go([int delta]) native; + void go([int? delta]) native; @SupportedBrowser(SupportedBrowser.CHROME) @SupportedBrowser(SupportedBrowser.FIREFOX) @SupportedBrowser(SupportedBrowser.IE, '10') @SupportedBrowser(SupportedBrowser.SAFARI) - void pushState(/*SerializedScriptValue*/ data, String title, String url) { + void pushState(/*SerializedScriptValue*/ data, String title, String? url) { var data_1 = convertDartToNative_SerializedScriptValue(data); _pushState_1(data_1, title, url); return; @@ -17509,7 +17539,7 @@ class History extends Interceptor implements HistoryBase { @SupportedBrowser(SupportedBrowser.FIREFOX) @SupportedBrowser(SupportedBrowser.IE, '10') @SupportedBrowser(SupportedBrowser.SAFARI) - void replaceState(/*SerializedScriptValue*/ data, String title, String url) { + void replaceState(/*SerializedScriptValue*/ data, String title, String? url) { var data_1 = convertDartToNative_SerializedScriptValue(data); _replaceState_1(data_1, title, url); return; @@ -17580,9 +17610,9 @@ class HtmlCollection extends Interceptor Node elementAt(int index) => this[index]; // -- end List mixins. - Node item(int index) native; + Node? item(int? index) native; - Object namedItem(String name) native; + Object? namedItem(String name) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -17597,29 +17627,29 @@ class HtmlDocument extends Document { throw new UnsupportedError("Not supported"); } - BodyElement get body native; - set body(BodyElement value) native; + BodyElement? get body native; + set body(BodyElement? value) native; /// UNSTABLE: Chrome-only - create a Range from the given point. @Unstable() - Range caretRangeFromPoint(int x, int y) { + Range caretRangeFromPoint(int? x, int? y) { return _caretRangeFromPoint(x, y); } - Element elementFromPoint(int x, int y) { + Element? elementFromPoint(int x, int y) { return _elementFromPoint(x, y); } - HeadElement get head => _head; + HeadElement? get head => _head; String get lastModified => _lastModified; - String get preferredStylesheetSet => _preferredStylesheetSet; + String? get preferredStylesheetSet => _preferredStylesheetSet; String get referrer => _referrer; - String get selectedStylesheetSet => _selectedStylesheetSet; - set selectedStylesheetSet(String value) { + String? get selectedStylesheetSet => _selectedStylesheetSet; + set selectedStylesheetSet(String? value) { _selectedStylesheetSet = value; } @@ -17690,13 +17720,13 @@ class HtmlDocument extends Document { * `` * */ - Function registerElement2(String tag, [Map options]) { + Function registerElement2(String tag, [Map? options]) { return _registerCustomElement(JS('', 'window'), this, tag, options); } /** *Deprecated*: use [registerElement] instead. */ @deprecated - void register(String tag, Type customElementClass, {String extendsTag}) { + void register(String tag, Type customElementClass, {String? extendsTag}) { return registerElement(tag, customElementClass, extendsTag: extendsTag); } @@ -17740,7 +17770,7 @@ class HtmlDocument extends Document { /// /// If the type is not a direct subclass of HtmlElement then the extendsTag /// parameter must be provided. - ElementUpgrader createElementUpgrader(Type type, {String extendsTag}) { + ElementUpgrader createElementUpgrader(Type type, {String? extendsTag}) { return new _JSElementUpgrader(this, type, extendsTag); } } @@ -17755,7 +17785,7 @@ class HtmlFormControlsCollection extends HtmlCollection { throw new UnsupportedError("Not supported"); } - Object namedItem(String name) native; + Object? namedItem(String name) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -17768,7 +17798,7 @@ class HtmlHtmlElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory HtmlHtmlElement() => JS( + factory HtmlHtmlElement() => JS( 'returns:HtmlHtmlElement;creates:HtmlHtmlElement;new:true', '#.createElement(#)', document, @@ -17845,7 +17875,7 @@ class HtmlOptionsCollection extends HtmlCollection { } @JSName('item') - Element _item(int index) native; + Element? _item(int index) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -17920,7 +17950,7 @@ class HttpRequest extends HttpRequestEventTarget { * * [request] */ static Future getString(String url, - {bool withCredentials, void onProgress(ProgressEvent e)}) { + {bool? withCredentials, void onProgress(ProgressEvent e)?}) { return request(url, withCredentials: withCredentials, onProgress: onProgress) .then((HttpRequest xhr) => xhr.responseText); @@ -17952,10 +17982,10 @@ class HttpRequest extends HttpRequestEventTarget { * * [request] */ static Future postFormData(String url, Map data, - {bool withCredentials, - String responseType, - Map requestHeaders, - void onProgress(ProgressEvent e)}) { + {bool? withCredentials, + String? responseType, + Map? requestHeaders, + void onProgress(ProgressEvent e)?}) { var parts = []; data.forEach((key, value) { parts.add('${Uri.encodeQueryComponent(key)}=' @@ -18033,13 +18063,13 @@ class HttpRequest extends HttpRequestEventTarget { * See also: [authorization headers](http://en.wikipedia.org/wiki/Basic_access_authentication). */ static Future request(String url, - {String method, - bool withCredentials, - String responseType, - String mimeType, - Map requestHeaders, + {String? method, + bool? withCredentials, + String? responseType, + String? mimeType, + Map? requestHeaders, sendData, - void onProgress(ProgressEvent e)}) { + void onProgress(ProgressEvent e)?}) { var completer = new Completer(); var xhr = new HttpRequest(); @@ -18143,7 +18173,7 @@ class HttpRequest extends HttpRequestEventTarget { * cross-origin support is not required then [request] should be used instead. */ static Future requestCrossOrigin(String url, - {String method, String sendData}) { + {String? method, String? sendData}) { if (supportsCrossOrigin) { return request(url, method: method, sendData: sendData).then((xhr) { return xhr.responseText; @@ -18161,7 +18191,7 @@ class HttpRequest extends HttpRequestEventTarget { xhr, convertDartClosureToJS((e) { var response = JS('String', '#.responseText', xhr); - completer.complete(response); + completer.complete(response as FutureOr?); }, 1)); JS( '', @@ -18239,7 +18269,7 @@ class HttpRequest extends HttpRequestEventTarget { * finer-grained control is needed. */ void open(String method, String url, - {bool async, String user, String password}) native; + {bool? async, String? user, String? password}) native; // To suppress missing implicit constructor warnings. factory HttpRequest._() { @@ -18384,7 +18414,7 @@ class HttpRequest extends HttpRequestEventTarget { * synchronous. */ - Document get responseXml native; + Document? get responseXml native; /** * The HTTP result code from the request (200, 404, etc). @@ -18469,7 +18499,7 @@ class HttpRequest extends HttpRequestEventTarget { * for a list of common response headers. */ @Unstable() - String getResponseHeader(String name) native; + String? getResponseHeader(String name) native; /** * Specify a particular MIME type (such as `text/xml`) desired for the @@ -18649,7 +18679,7 @@ class IFrameElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory IFrameElement() => JS( + factory IFrameElement() => JS( 'returns:IFrameElement;creates:IFrameElement;new:true', '#.createElement(#)', document, @@ -18673,7 +18703,7 @@ class IFrameElement extends HtmlElement { set allowPaymentRequest(bool value) native; - WindowBase get contentWindow => + WindowBase? get contentWindow => _convertNativeToDart_Window(this._get_contentWindow); @JSName('contentWindow') @Creates('Window|=Object') @@ -18762,7 +18792,7 @@ class ImageBitmapRenderingContext extends Interceptor { CanvasElement get canvas native; - void transferFromImageBitmap(ImageBitmap bitmap) native; + void transferFromImageBitmap(ImageBitmap? bitmap) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -18787,7 +18817,7 @@ class ImageCapture extends Interceptor { promiseToFuture( JS("", "#.getPhotoCapabilities()", this)); - Future> getPhotoSettings() => + Future?> getPhotoSettings() => promiseToFutureAsMap(JS("", "#.getPhotoSettings()", this)); Future grabFrame() => @@ -18798,7 +18828,7 @@ class ImageCapture extends Interceptor { return promiseToFuture(JS("", "#.setOptions(#)", this, photoSettings_dict)); } - Future takePhoto([Map photoSettings]) { + Future takePhoto([Map? photoSettings]) { var photoSettings_dict = null; if (photoSettings != null) { photoSettings_dict = convertDartToNative_Dictionary(photoSettings); @@ -18818,7 +18848,7 @@ class ImageData extends Interceptor { throw new UnsupportedError("Not supported"); } - factory ImageData(data_OR_sw, int sh_OR_sw, [int sh]) { + factory ImageData(data_OR_sw, int sh_OR_sw, [int? sh]) { if ((sh_OR_sw is int) && (data_OR_sw is int) && sh == null) { return ImageData._create_1(data_OR_sw, sh_OR_sw); } @@ -18856,9 +18886,12 @@ class ImageElement extends HtmlElement implements CanvasImageSource { throw new UnsupportedError("Not supported"); } - factory ImageElement({String src, int width, int height}) { - ImageElement e = JS('returns:ImageElement;creates:ImageElement;new:true', - '#.createElement(#)', document, "img"); + factory ImageElement({String? src, int? width, int? height}) { + ImageElement e = JS( + 'returns:ImageElement;creates:ImageElement;new:true', + '#.createElement(#)', + document, + "img"); if (src != null) e.src = src; if (width != null) e.width = width; if (height != null) e.height = height; @@ -18881,9 +18914,9 @@ class ImageElement extends HtmlElement implements CanvasImageSource { bool get complete native; - String get crossOrigin native; + String? get crossOrigin native; - set crossOrigin(String value) native; + set crossOrigin(String? value) native; String get currentSrc native; @@ -18936,7 +18969,7 @@ class InputDeviceCapabilities extends Interceptor { throw new UnsupportedError("Not supported"); } - factory InputDeviceCapabilities([Map deviceInitDict]) { + factory InputDeviceCapabilities([Map? deviceInitDict]) { if (deviceInitDict != null) { var deviceInitDict_1 = convertDartToNative_Dictionary(deviceInitDict); return InputDeviceCapabilities._create_1(deviceInitDict_1); @@ -18980,8 +19013,8 @@ class InputElement extends HtmlElement ImageButtonInputElement, ResetButtonInputElement, ButtonInputElement { - factory InputElement({String type}) { - InputElement e = document.createElement("input"); + factory InputElement({String? type}) { + InputElement e = document.createElement("input") as InputElement; if (type != null) { try { // IE throws an exception for unknown types. @@ -19048,11 +19081,11 @@ class InputElement extends HtmlElement @Returns('FileList|Null') @Creates('FileList') - List get files native; + List? get files native; - set files(List value) native; + set files(List? value) native; - FormElement get form native; + FormElement? get form native; String get formAction native; @@ -19086,11 +19119,11 @@ class InputElement extends HtmlElement set indeterminate(bool value) native; - @Returns('NodeList|Null') + @Returns('NodeList') @Creates('NodeList') List get labels native; - HtmlElement get list native; + HtmlElement? get list native; String get max native; @@ -19132,17 +19165,17 @@ class InputElement extends HtmlElement set required(bool value) native; - String get selectionDirection native; + String? get selectionDirection native; - set selectionDirection(String value) native; + set selectionDirection(String? value) native; - int get selectionEnd native; + int? get selectionEnd native; - set selectionEnd(int value) native; + set selectionEnd(int? value) native; - int get selectionStart native; + int? get selectionStart native; - set selectionStart(int value) native; + set selectionStart(int? value) native; int get size native; @@ -19166,7 +19199,7 @@ class InputElement extends HtmlElement String get value native; - set value(String value) native; + set value(String? value) native; DateTime get valueAsDate => convertNativeToDart_DateTime(this._get_valueAsDate); @@ -19174,8 +19207,8 @@ class InputElement extends HtmlElement @Creates('Null') dynamic get _get_valueAsDate native; - set valueAsDate(DateTime value) { - this._set_valueAsDate = convertDartToNative_DateTime(value); + set valueAsDate(DateTime? value) { + this._set_valueAsDate = convertDartToNative_DateTime(value!); } set _set_valueAsDate(/*dynamic*/ value) { @@ -19214,13 +19247,13 @@ class InputElement extends HtmlElement void setCustomValidity(String error) native; void setRangeText(String replacement, - {int start, int end, String selectionMode}) native; + {int? start, int? end, String? selectionMode}) native; - void setSelectionRange(int start, int end, [String direction]) native; + void setSelectionRange(int start, int end, [String? direction]) native; - void stepDown([int n]) native; + void stepDown([int? n]) native; - void stepUp([int n]) native; + void stepUp([int? n]) native; } // Interfaces representing the InputElement APIs which are supported @@ -19247,7 +19280,7 @@ abstract class InputElementBase implements Element { set name(String value); String get value; - set value(String value); + set value(String? value); List get labels; @@ -19296,16 +19329,16 @@ abstract class TextInputElementBase implements InputElementBase { void select(); - String get selectionDirection; - set selectionDirection(String value); + String? get selectionDirection; + set selectionDirection(String? value); - int get selectionEnd; - set selectionEnd(int value); + int? get selectionEnd; + set selectionEnd(int? value); - int get selectionStart; - set selectionStart(int value); + int? get selectionStart; + set selectionStart(int? value); - void setSelectionRange(int start, int end, [String direction]); + void setSelectionRange(int start, int end, [String? direction]); } /** @@ -19324,7 +19357,7 @@ abstract class SearchInputElement implements TextInputElementBase { String get dirName; set dirName(String value); - Element get list; + Element? get list; /// Returns true if this input type is supported on the current platform. static bool get supported { @@ -19341,7 +19374,7 @@ abstract class TextInputElement implements TextInputElementBase { String get dirName; set dirName(String value); - Element get list; + Element? get list; } /** @@ -19356,7 +19389,7 @@ abstract class TextInputElement implements TextInputElementBase { abstract class UrlInputElement implements TextInputElementBase { factory UrlInputElement() => new InputElement(type: 'url'); - Element get list; + Element? get list; /// Returns true if this input type is supported on the current platform. static bool get supported { @@ -19379,7 +19412,7 @@ abstract class UrlInputElement implements TextInputElementBase { abstract class TelephoneInputElement implements TextInputElementBase { factory TelephoneInputElement() => new InputElement(type: 'tel'); - Element get list; + Element? get list; /// Returns true if this input type is supported on the current platform. static bool get supported { @@ -19405,7 +19438,7 @@ abstract class EmailInputElement implements TextInputElementBase { bool get autofocus; set autofocus(bool value); - Element get list; + Element? get list; int get maxLength; set maxLength(int value); @@ -19445,7 +19478,7 @@ abstract class PasswordInputElement implements TextInputElementBase { * Base interface for all input element types which involve ranges. */ abstract class RangeInputElementBase implements InputElementBase { - Element get list; + Element? get list; String get max; set max(String value); @@ -19459,9 +19492,9 @@ abstract class RangeInputElementBase implements InputElementBase { num get valueAsNumber; set valueAsNumber(num value); - void stepDown([int n]); + void stepDown([int? n]); - void stepUp([int n]); + void stepUp([int? n]); } /** @@ -19676,7 +19709,7 @@ abstract class FileUploadInputElement implements InputElementBase { bool get required; set required(bool value); - List files; + List? files; } /** @@ -19760,7 +19793,7 @@ class InstallEvent extends ExtendableEvent { throw new UnsupportedError("Not supported"); } - factory InstallEvent(String type, [Map eventInitDict]) { + factory InstallEvent(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return InstallEvent._create_1(type, eventInitDict_1); @@ -19793,7 +19826,7 @@ class IntersectionObserver extends Interceptor { } factory IntersectionObserver(IntersectionObserverCallback callback, - [Map options]) { + [Map? options]) { if (options != null) { var callback_1 = convertDartClosureToJS(callback, 2); var options_2 = convertDartToNative_Dictionary(options); @@ -19810,7 +19843,7 @@ class IntersectionObserver extends Interceptor { static IntersectionObserver _create_2(callback) => JS('IntersectionObserver', 'new IntersectionObserver(#)', callback); - Element get root native; + Element? get root native; String get rootMargin native; @@ -19851,7 +19884,7 @@ class IntersectionObserverEntry extends Interceptor { bool get isIntersecting native; - DomRectReadOnly get rootBounds native; + DomRectReadOnly? get rootBounds native; Element get target native; @@ -19900,11 +19933,11 @@ class KeyboardEvent extends UIEvent { * Event [KeyEvent]. */ factory KeyboardEvent(String type, - {Window view, + {Window? view, bool canBubble: true, bool cancelable: true, - int location, - int keyLocation, // Legacy alias for location + int? location, + int? keyLocation, // Legacy alias for location bool ctrlKey: false, bool altKey: false, bool shiftKey: false, @@ -19913,7 +19946,7 @@ class KeyboardEvent extends UIEvent { view = window; } location ??= keyLocation ?? 1; - KeyboardEvent e = document._createEvent("KeyboardEvent"); + KeyboardEvent e = document._createEvent("KeyboardEvent") as KeyboardEvent; e._initKeyboardEvent(type, canBubble, cancelable, view, "", location, ctrlKey, altKey, shiftKey, metaKey); return e; @@ -19923,9 +19956,9 @@ class KeyboardEvent extends UIEvent { String type, bool canBubble, bool cancelable, - Window view, + Window? view, String keyIdentifier, - int location, + int? location, bool ctrlKey, bool altKey, bool shiftKey, @@ -19962,7 +19995,7 @@ class KeyboardEvent extends UIEvent { int get which => _which; - factory KeyboardEvent._(String type, [Map eventInitDict]) { + factory KeyboardEvent._(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return KeyboardEvent._create_1(type, eventInitDict_1); @@ -20019,7 +20052,7 @@ class KeyframeEffect extends KeyframeEffectReadOnly { throw new UnsupportedError("Not supported"); } - factory KeyframeEffect(Element target, Object effect, [Object options]) { + factory KeyframeEffect(Element? target, Object? effect, [Object? options]) { if (options != null) { return KeyframeEffect._create_1(target, effect, options); } @@ -20041,8 +20074,8 @@ class KeyframeEffectReadOnly extends AnimationEffectReadOnly { throw new UnsupportedError("Not supported"); } - factory KeyframeEffectReadOnly(Element target, Object effect, - [Object options]) { + factory KeyframeEffectReadOnly(Element? target, Object? effect, + [Object? options]) { if (options != null) { return KeyframeEffectReadOnly._create_1(target, effect, options); } @@ -20071,8 +20104,11 @@ class LIElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory LIElement() => JS('returns:LIElement;creates:LIElement;new:true', - '#.createElement(#)', document, "li"); + factory LIElement() => JS( + 'returns:LIElement;creates:LIElement;new:true', + '#.createElement(#)', + document, + "li"); /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -20095,7 +20131,7 @@ class LabelElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory LabelElement() => JS( + factory LabelElement() => JS( 'returns:LabelElement;creates:LabelElement;new:true', '#.createElement(#)', document, @@ -20107,9 +20143,9 @@ class LabelElement extends HtmlElement { */ LabelElement.created() : super.created(); - HtmlElement get control native; + HtmlElement? get control native; - FormElement get form native; + FormElement? get form native; String get htmlFor native; @@ -20126,7 +20162,7 @@ class LegendElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory LegendElement() => JS( + factory LegendElement() => JS( 'returns:LegendElement;creates:LegendElement;new:true', '#.createElement(#)', document, @@ -20138,7 +20174,7 @@ class LegendElement extends HtmlElement { */ LegendElement.created() : super.created(); - FormElement get form native; + FormElement? get form native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -20151,7 +20187,7 @@ class LinearAccelerationSensor extends Accelerometer { throw new UnsupportedError("Not supported"); } - factory LinearAccelerationSensor([Map sensorOptions]) { + factory LinearAccelerationSensor([Map? sensorOptions]) { if (sensorOptions != null) { var sensorOptions_1 = convertDartToNative_Dictionary(sensorOptions); return LinearAccelerationSensor._create_1(sensorOptions_1); @@ -20176,7 +20212,7 @@ class LinkElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory LinkElement() => JS( + factory LinkElement() => JS( 'returns:LinkElement;creates:LinkElement;new:true', '#.createElement(#)', document, @@ -20192,9 +20228,9 @@ class LinkElement extends HtmlElement { set as(String value) native; - String get crossOrigin native; + String? get crossOrigin native; - set crossOrigin(String value) native; + set crossOrigin(String? value) native; bool get disabled native; @@ -20208,7 +20244,7 @@ class LinkElement extends HtmlElement { set hreflang(String value) native; - Document get import native; + Document? get import native; String get integrity native; @@ -20232,7 +20268,7 @@ class LinkElement extends HtmlElement { set scope(String value) native; - StyleSheet get sheet native; + StyleSheet? get sheet native; DomTokenList get sizes native; @@ -20256,7 +20292,7 @@ class Location extends Interceptor implements LocationBase { throw new UnsupportedError("Not supported"); } - @Returns('DomStringList|Null') + @Returns('DomStringList') @Creates('DomStringList') List get ancestorOrigins native; @@ -20296,11 +20332,11 @@ class Location extends Interceptor implements LocationBase { set trustedHref(TrustedUrl value) native; - void assign([String url]) native; + void assign([String? url]) native; void reload() native; - void replace(String url) native; + void replace(String? url) native; String get origin { if (JS('bool', '("origin" in #)', this)) { @@ -20322,7 +20358,7 @@ class Magnetometer extends Sensor { throw new UnsupportedError("Not supported"); } - factory Magnetometer([Map sensorOptions]) { + factory Magnetometer([Map? sensorOptions]) { if (sensorOptions != null) { var sensorOptions_1 = convertDartToNative_Dictionary(sensorOptions); return Magnetometer._create_1(sensorOptions_1); @@ -20333,11 +20369,11 @@ class Magnetometer extends Sensor { JS('Magnetometer', 'new Magnetometer(#)', sensorOptions); static Magnetometer _create_2() => JS('Magnetometer', 'new Magnetometer()'); - num get x native; + num? get x native; - num get y native; + num? get y native; - num get z native; + num? get z native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -20350,8 +20386,11 @@ class MapElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory MapElement() => JS('returns:MapElement;creates:MapElement;new:true', - '#.createElement(#)', document, "map"); + factory MapElement() => JS( + 'returns:MapElement;creates:MapElement;new:true', + '#.createElement(#)', + document, + "map"); /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -20359,7 +20398,7 @@ class MapElement extends HtmlElement { */ MapElement.created() : super.created(); - @Returns('HtmlCollection|Null') + @Returns('HtmlCollection') @Creates('HtmlCollection') List get areas native; @@ -20441,13 +20480,13 @@ class MediaDevices extends EventTarget { promiseToFuture>(JS("", "#.enumerateDevices()", this)); Map getSupportedConstraints() { - return convertNativeToDart_Dictionary(_getSupportedConstraints_1()); + return convertNativeToDart_Dictionary(_getSupportedConstraints_1())!; } @JSName('getSupportedConstraints') _getSupportedConstraints_1() native; - Future getUserMedia([Map constraints]) { + Future getUserMedia([Map? constraints]) { var constraints_dict = null; if (constraints != null) { constraints_dict = convertDartToNative_Dictionary(constraints); @@ -20506,9 +20545,9 @@ class MediaElement extends HtmlElement { DomTokenList get controlsList native; - String get crossOrigin native; + String? get crossOrigin native; - set crossOrigin(String value) native; + set crossOrigin(String? value) native; String get currentSrc native; @@ -20532,7 +20571,7 @@ class MediaElement extends HtmlElement { bool get ended native; - MediaError get error native; + MediaError? get error native; bool get loop native; @@ -20594,10 +20633,10 @@ class MediaElement extends HtmlElement { @SupportedBrowser(SupportedBrowser.SAFARI) int get videoDecodedByteCount native; - TextTrack addTextTrack(String kind, [String label, String language]) native; + TextTrack addTextTrack(String kind, [String? label, String? language]) native; @Unstable() - String canPlayType(String type, [String keySystem]) native; + String canPlayType(String? type, [String? keySystem]) native; MediaStream captureStream() native; @@ -20607,7 +20646,7 @@ class MediaElement extends HtmlElement { Future play() => promiseToFuture(JS("", "#.play()", this)); - Future setMediaKeys(MediaKeys mediaKeys) => + Future setMediaKeys(MediaKeys? mediaKeys) => promiseToFuture(JS("", "#.setMediaKeys(#)", this, mediaKeys)); Future setSinkId(String sinkId) => @@ -20624,7 +20663,7 @@ class MediaEncryptedEvent extends Event { throw new UnsupportedError("Not supported"); } - factory MediaEncryptedEvent(String type, [Map eventInitDict]) { + factory MediaEncryptedEvent(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return MediaEncryptedEvent._create_1(type, eventInitDict_1); @@ -20639,7 +20678,7 @@ class MediaEncryptedEvent extends Event { static MediaEncryptedEvent _create_2(type) => JS('MediaEncryptedEvent', 'new MediaEncryptedEvent(#)', type); - ByteBuffer get initData native; + ByteBuffer? get initData native; String get initDataType native; } @@ -20743,7 +20782,7 @@ class MediaKeyStatusMap extends Interceptor { int get size native; - Object get(/*BufferSource*/ keyId) native; + Object? get(/*BufferSource*/ keyId) native; bool has(/*BufferSource*/ keyId) native; } @@ -20764,7 +20803,7 @@ class MediaKeySystemAccess extends Interceptor { promiseToFuture(JS("", "#.createMediaKeys()", this)); Map getConfiguration() { - return convertNativeToDart_Dictionary(_getConfiguration_1()); + return convertNativeToDart_Dictionary(_getConfiguration_1())!; } @JSName('getConfiguration') @@ -20782,7 +20821,7 @@ class MediaKeys extends Interceptor { } @JSName('createSession') - MediaKeySession _createSession([String sessionType]) native; + MediaKeySession _createSession([String? sessionType]) native; Future getStatusForPolicy(MediaKeysPolicy policy) => promiseToFuture(JS("", "#.getStatusForPolicy(#)", this, policy)); @@ -20825,15 +20864,15 @@ class MediaList extends Interceptor { int get length native; - String get mediaText native; + String? get mediaText native; - set mediaText(String value) native; + set mediaText(String? value) native; void appendMedium(String medium) native; void deleteMedium(String medium) native; - String item(int index) native; + String? item(int index) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -20846,7 +20885,7 @@ class MediaMetadata extends Interceptor { throw new UnsupportedError("Not supported"); } - factory MediaMetadata([Map metadata]) { + factory MediaMetadata([Map? metadata]) { if (metadata != null) { var metadata_1 = convertDartToNative_Dictionary(metadata); return MediaMetadata._create_1(metadata_1); @@ -20893,9 +20932,9 @@ class MediaQueryList extends EventTarget { String get media native; - void addListener(EventListener listener) native; + void addListener(EventListener? listener) native; - void removeListener(EventListener listener) native; + void removeListener(EventListener? listener) native; Stream get onChange => changeEvent.forTarget(this); } @@ -20910,7 +20949,7 @@ class MediaQueryListEvent extends Event { throw new UnsupportedError("Not supported"); } - factory MediaQueryListEvent(String type, [Map eventInitDict]) { + factory MediaQueryListEvent(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return MediaQueryListEvent._create_1(type, eventInitDict_1); @@ -20946,7 +20985,7 @@ class MediaRecorder extends EventTarget { static const EventStreamProvider pauseEvent = const EventStreamProvider('pause'); - factory MediaRecorder(MediaStream stream, [Map options]) { + factory MediaRecorder(MediaStream stream, [Map? options]) { if (options != null) { var options_1 = convertDartToNative_Dictionary(options); return MediaRecorder._create_1(stream, options_1); @@ -20976,7 +21015,7 @@ class MediaRecorder extends EventTarget { void resume() native; - void start([int timeslice]) native; + void start([int? timeslice]) native; void stop() native; @@ -20995,15 +21034,15 @@ class MediaSession extends Interceptor { throw new UnsupportedError("Not supported"); } - MediaMetadata get metadata native; + MediaMetadata? get metadata native; - set metadata(MediaMetadata value) native; + set metadata(MediaMetadata? value) native; String get playbackState native; set playbackState(String value) native; - void setActionHandler(String action, MediaSessionActionHandler handler) + void setActionHandler(String action, MediaSessionActionHandler? handler) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file @@ -21065,7 +21104,7 @@ class MediaSource extends EventTarget { void clearLiveSeekableRange() native; - void endOfStream([String error]) native; + void endOfStream([String? error]) native; static bool isTypeSupported(String type) native; @@ -21133,7 +21172,7 @@ class MediaStream extends EventTarget { @Returns('JSExtendableArray') List getAudioTracks() native; - MediaStreamTrack getTrackById(String trackId) native; + MediaStreamTrack? getTrackById(String trackId) native; List getTracks() native; @@ -21177,7 +21216,7 @@ class MediaStreamEvent extends Event { throw new UnsupportedError("Not supported"); } - factory MediaStreamEvent(String type, [Map eventInitDict]) { + factory MediaStreamEvent(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return MediaStreamEvent._create_1(type, eventInitDict_1); @@ -21192,7 +21231,7 @@ class MediaStreamEvent extends Event { /// Checks if this type is supported on the current platform. static bool get supported => Device.isEventTypeSupported('MediaStreamEvent'); - MediaStream get stream native; + MediaStream? get stream native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -21251,7 +21290,7 @@ class MediaStreamTrack extends EventTarget { String get readyState native; - Future applyConstraints([Map constraints]) { + Future applyConstraints([Map? constraints]) { var constraints_dict = null; if (constraints != null) { constraints_dict = convertDartToNative_Dictionary(constraints); @@ -21263,21 +21302,21 @@ class MediaStreamTrack extends EventTarget { MediaStreamTrack clone() native; Map getCapabilities() { - return convertNativeToDart_Dictionary(_getCapabilities_1()); + return convertNativeToDart_Dictionary(_getCapabilities_1())!; } @JSName('getCapabilities') _getCapabilities_1() native; Map getConstraints() { - return convertNativeToDart_Dictionary(_getConstraints_1()); + return convertNativeToDart_Dictionary(_getConstraints_1())!; } @JSName('getConstraints') _getConstraints_1() native; Map getSettings() { - return convertNativeToDart_Dictionary(_getSettings_1()); + return convertNativeToDart_Dictionary(_getSettings_1())!; } @JSName('getSettings') @@ -21360,7 +21399,7 @@ class MenuElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory MenuElement() => JS( + factory MenuElement() => JS( 'returns:MenuElement;creates:MenuElement;new:true', '#.createElement(#)', document, @@ -21412,10 +21451,10 @@ class MessageEvent extends Event { factory MessageEvent(String type, {bool canBubble: false, bool cancelable: false, - Object data, - String origin, - String lastEventId, - Window source, + Object? data, + String? origin, + String? lastEventId, + Window? source, List messagePorts: const []}) { if (source == null) { source = window; @@ -21435,7 +21474,7 @@ class MessageEvent extends Event { source, messagePorts); } - MessageEvent event = document._createEvent("MessageEvent"); + MessageEvent event = document._createEvent("MessageEvent") as MessageEvent; event._initMessageEvent(type, canBubble, cancelable, data, origin, lastEventId, source, messagePorts); return event; @@ -21451,7 +21490,7 @@ class MessageEvent extends Event { @annotation_Returns_SerializedScriptValue dynamic get _get_data native; - factory MessageEvent._(String type, [Map eventInitDict]) { + factory MessageEvent._(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return MessageEvent._create_1(type, eventInitDict_1); @@ -21472,7 +21511,7 @@ class MessageEvent extends Event { @Creates('JSExtendableArray') List get ports native; - EventTarget get source => _convertNativeToDart_EventTarget(this._get_source); + EventTarget? get source => _convertNativeToDart_EventTarget(this._get_source); @JSName('source') @Creates('Null') @Returns('EventTarget|=Object') @@ -21481,14 +21520,14 @@ class MessageEvent extends Event { String get suborigin native; void _initMessageEvent( - String typeArg, - bool canBubbleArg, - bool cancelableArg, - Object dataArg, - String originArg, - String lastEventIdArg, - EventTarget sourceArg, - List portsArg) { + String? typeArg, + bool? canBubbleArg, + bool? cancelableArg, + Object? dataArg, + String? originArg, + String? lastEventIdArg, + EventTarget? sourceArg, + List? portsArg) { var sourceArg_1 = _convertDartToNative_EventTarget(sourceArg); _initMessageEvent_1(typeArg, canBubbleArg, cancelableArg, dataArg, originArg, lastEventIdArg, sourceArg_1, portsArg); @@ -21497,7 +21536,7 @@ class MessageEvent extends Event { @JSName('initMessageEvent') void _initMessageEvent_1(typeArg, canBubbleArg, cancelableArg, dataArg, - originArg, lastEventIdArg, sourceArg, List portsArg) native; + originArg, lastEventIdArg, sourceArg, List? portsArg) native; } // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -21508,8 +21547,8 @@ class MessageEvent extends Event { @Unstable() @Native("MessagePort") class MessagePort extends EventTarget { - void addEventListener(String type, EventListener listener, - [bool useCapture]) { + void addEventListener(String type, EventListener? listener, + [bool? useCapture]) { // Messages posted to ports are initially paused, allowing listeners to be // setup, start() needs to be explicitly invoked to begin handling messages. if (type == 'message') { @@ -21535,7 +21574,7 @@ class MessagePort extends EventTarget { void close() native; - void postMessage(/*any*/ message, [List transfer]) { + void postMessage(/*any*/ message, [List? transfer]) { if (transfer != null) { var message_1 = convertDartToNative_SerializedScriptValue(message); _postMessage_1(message_1, transfer); @@ -21569,7 +21608,7 @@ class MetaElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory MetaElement() => JS( + factory MetaElement() => JS( 'returns:MetaElement;creates:MetaElement;new:true', '#.createElement(#)', document, @@ -21634,7 +21673,7 @@ class MeterElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory MeterElement() => document.createElement("meter"); + factory MeterElement() => document.createElement("meter") as MeterElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -21650,7 +21689,7 @@ class MeterElement extends HtmlElement { set high(num value) native; @Unstable() - @Returns('NodeList|Null') + @Returns('NodeList') @Creates('NodeList') List get labels native; @@ -21702,7 +21741,7 @@ class MidiConnectionEvent extends Event { throw new UnsupportedError("Not supported"); } - factory MidiConnectionEvent(String type, [Map eventInitDict]) { + factory MidiConnectionEvent(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return MidiConnectionEvent._create_1(type, eventInitDict_1); @@ -21754,7 +21793,7 @@ class MidiInputMap extends Interceptor with MapMixin { throw new UnsupportedError("Not supported"); } - Map _getItem(String key) => + Map? _getItem(String key) => convertNativeToDart_Dictionary(JS('', '#.get(#)', this, key)); void addAll(Map other) { @@ -21765,7 +21804,7 @@ class MidiInputMap extends Interceptor with MapMixin { bool containsKey(dynamic key) => _getItem(key) != null; - Map operator [](dynamic key) => _getItem(key); + Map? operator [](dynamic key) => _getItem(key); void forEach(void f(String key, dynamic value)) { var entries = JS('', '#.entries()', this); @@ -21822,7 +21861,7 @@ class MidiMessageEvent extends Event { throw new UnsupportedError("Not supported"); } - factory MidiMessageEvent(String type, [Map eventInitDict]) { + factory MidiMessageEvent(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return MidiMessageEvent._create_1(type, eventInitDict_1); @@ -21847,7 +21886,7 @@ class MidiOutput extends MidiPort { throw new UnsupportedError("Not supported"); } - void send(Uint8List data, [num timestamp]) native; + void send(Uint8List data, [num? timestamp]) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -21860,7 +21899,7 @@ class MidiOutputMap extends Interceptor with MapMixin { throw new UnsupportedError("Not supported"); } - Map _getItem(String key) => + Map? _getItem(String key) => convertNativeToDart_Dictionary(JS('', '#.get(#)', this, key)); void addAll(Map other) { @@ -21871,7 +21910,7 @@ class MidiOutputMap extends Interceptor with MapMixin { bool containsKey(dynamic key) => _getItem(key) != null; - Map operator [](dynamic key) => _getItem(key); + Map? operator [](dynamic key) => _getItem(key); void forEach(void f(String key, dynamic value)) { var entries = JS('', '#.entries()', this); @@ -22023,9 +22062,9 @@ class MimeTypeArray extends Interceptor MimeType elementAt(int index) => this[index]; // -- end List mixins. - MimeType item(int index) native; + MimeType? item(int index) native; - MimeType namedItem(String name) native; + MimeType? namedItem(String name) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -22067,7 +22106,7 @@ typedef void MojoWatchCallback(int result); @Native("MouseEvent,DragEvent") class MouseEvent extends UIEvent { factory MouseEvent(String type, - {Window view, + {Window? view, int detail: 0, int screenX: 0, int screenY: 0, @@ -22080,11 +22119,11 @@ class MouseEvent extends UIEvent { bool altKey: false, bool shiftKey: false, bool metaKey: false, - EventTarget relatedTarget}) { + EventTarget? relatedTarget}) { if (view == null) { view = window; } - MouseEvent event = document._createEvent('MouseEvent'); + MouseEvent event = document._createEvent('MouseEvent') as MouseEvent; event._initMouseEvent( type, canBubble, @@ -22104,7 +22143,7 @@ class MouseEvent extends UIEvent { return event; } - factory MouseEvent._(String type, [Map eventInitDict]) { + factory MouseEvent._(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return MouseEvent._create_1(type, eventInitDict_1); @@ -22160,9 +22199,9 @@ class MouseEvent extends UIEvent { @JSName('pageY') num get _pageY native; - String get region native; + String? get region native; - EventTarget get relatedTarget => + EventTarget? get relatedTarget => _convertNativeToDart_EventTarget(this._get_relatedTarget); @JSName('relatedTarget') @Creates('Node') @@ -22190,21 +22229,21 @@ class MouseEvent extends UIEvent { bool getModifierState(String keyArg) native; void _initMouseEvent( - String type, - bool bubbles, - bool cancelable, - Window view, - int detail, - int screenX, - int screenY, - int clientX, - int clientY, - bool ctrlKey, - bool altKey, - bool shiftKey, - bool metaKey, - int button, - EventTarget relatedTarget) { + String? type, + bool? bubbles, + bool? cancelable, + Window? view, + int? detail, + int? screenX, + int? screenY, + int? clientX, + int? clientY, + bool? ctrlKey, + bool? altKey, + bool? shiftKey, + bool? metaKey, + int? button, + EventTarget? relatedTarget) { var relatedTarget_1 = _convertDartToNative_EventTarget(relatedTarget); _initMouseEvent_1( type, @@ -22230,7 +22269,7 @@ class MouseEvent extends UIEvent { type, bubbles, cancelable, - Window view, + Window? view, detail, screenX, screenY, @@ -22260,13 +22299,13 @@ class MouseEvent extends UIEvent { if (JS('bool', '!!#.offsetX', this)) { var x = JS('int', '#.offsetX', this); var y = JS('int', '#.offsetY', this); - return new Point(x, y); + return new Point(x as num, y as num); } else { // Firefox does not support offsetX. if (!(this.target is Element)) { throw new UnsupportedError('offsetX is only supported on elements'); } - Element target = this.target; + Element target = this.target as Element; var point = (this.client - target.getBoundingClientRect().topLeft); return new Point(point.x.toInt(), point.y.toInt()); } @@ -22315,17 +22354,17 @@ class MutationEvent extends Event { String get prevValue native; - Node get relatedNode native; + Node? get relatedNode native; void initMutationEvent( - String type, - bool bubbles, - bool cancelable, - Node relatedNode, - String prevValue, - String newValue, - String attrName, - int attrChange) native; + String? type, + bool? bubbles, + bool? cancelable, + Node? relatedNode, + String? prevValue, + String? newValue, + String? attrName, + int? attrChange) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -22338,7 +22377,7 @@ class MutationEvent extends Event { class MutationObserver extends Interceptor { void disconnect() native; - void _observe(Node target, [Map options]) { + void _observe(Node target, [Map? options]) { if (options != null) { var options_1 = convertDartToNative_Dictionary(options); _observe_1(target, options_1); @@ -22375,13 +22414,13 @@ class MutationObserver extends Interceptor { * * If characterDataOldValue is true then characterData must be true. */ void observe(Node target, - {bool childList, - bool attributes, - bool characterData, - bool subtree, - bool attributeOldValue, - bool characterDataOldValue, - List attributeFilter}) { + {bool? childList, + bool? attributes, + bool? characterData, + bool? subtree, + bool? attributeOldValue, + bool? characterDataOldValue, + List? attributeFilter}) { // Parse options into map of known type. var parsedOptions = _createDict(); @@ -22446,21 +22485,21 @@ class MutationRecord extends Interceptor { throw new UnsupportedError("Not supported"); } - @Returns('NodeList|Null') + @Returns('NodeList') @Creates('NodeList') List get addedNodes native; - String get attributeName native; + String? get attributeName native; - String get attributeNamespace native; + String? get attributeNamespace native; - Node get nextSibling native; + Node? get nextSibling native; - String get oldValue native; + String? get oldValue native; - Node get previousSibling native; + Node? get previousSibling native; - @Returns('NodeList|Null') + @Returns('NodeList') @Creates('NodeList') List get removedNodes native; @@ -22483,7 +22522,7 @@ class NavigationPreloadManager extends Interceptor { Future enable() => promiseToFuture(JS("", "#.enable()", this)); - Future> getState() => + Future?> getState() => promiseToFutureAsMap(JS("", "#.getState()", this)); } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file @@ -22498,7 +22537,7 @@ class Navigator extends NavigatorConcurrentHardware NavigatorOnLine, NavigatorAutomationInformation, NavigatorID { - List getGamepads() { + List getGamepads() { var gamepadList = _getGamepads(); // If no prototype we need one for the world to hookup to the proper Dart class. @@ -22591,13 +22630,13 @@ class Navigator extends NavigatorConcurrentHardware _Clipboard get clipboard native; - NetworkInformation get connection native; + NetworkInformation? get connection native; CredentialsContainer get credentials native; - num get deviceMemory native; + num? get deviceMemory native; - String get doNotTrack native; + String? get doNotTrack native; @Unstable() Geolocation get geolocation native; @@ -22648,9 +22687,9 @@ class Navigator extends NavigatorConcurrentHardware Future getBattery() => promiseToFuture(JS("", "#.getBattery()", this)); @JSName('getGamepads') - @Returns('_GamepadList|Null') + @Returns('_GamepadList') @Creates('_GamepadList') - List _getGamepads() native; + List _getGamepads() native; Future getInstalledRelatedApps() => promiseToFuture( @@ -22661,7 +22700,7 @@ class Navigator extends NavigatorConcurrentHardware @Unstable() void registerProtocolHandler(String scheme, String url, String title) native; - Future requestKeyboardLock([List keyCodes]) { + Future requestKeyboardLock([List? keyCodes]) { if (keyCodes != null) { List keyCodes_1 = convertDartToNative_StringArray(keyCodes); return _requestKeyboardLock_1(keyCodes_1); @@ -22677,7 +22716,7 @@ class Navigator extends NavigatorConcurrentHardware promiseToFuture(JS("", "#.requestKeyboardLock()", this)); @JSName('requestMIDIAccess') - Future requestMidiAccess([Map options]) { + Future requestMidiAccess([Map? options]) { var options_dict = null; if (options != null) { options_dict = convertDartToNative_Dictionary(options); @@ -22691,9 +22730,9 @@ class Navigator extends NavigatorConcurrentHardware promiseToFuture(JS("", "#.requestMediaKeySystemAccess(#, #)", this, keySystem, supportedConfigurations)); - bool sendBeacon(String url, Object data) native; + bool sendBeacon(String url, Object? data) native; - Future share([Map data]) { + Future share([Map? data]) { var data_dict = null; if (data != null) { data_dict = convertDartToNative_Dictionary(data); @@ -22870,7 +22909,7 @@ class NetworkInformation extends EventTarget { static const EventStreamProvider changeEvent = const EventStreamProvider('change'); - num get downlink native; + num? get downlink native; num get downlinkMax native; @@ -22897,13 +22936,13 @@ class _ChildNodeListLazy extends ListBase implements NodeListWrapper { _ChildNodeListLazy(this._this); Node get first { - Node result = JS('Node|Null', '#.firstChild', _this); + Node? result = JS('Node|Null', '#.firstChild', _this); if (result == null) throw new StateError("No elements"); return result; } Node get last { - Node result = JS('Node|Null', '#.lastChild', _this); + Node? result = JS('Node|Null', '#.lastChild', _this); if (result == null) throw new StateError("No elements"); return result; } @@ -22912,7 +22951,7 @@ class _ChildNodeListLazy extends ListBase implements NodeListWrapper { int l = this.length; if (l == 0) throw new StateError("No elements"); if (l > 1) throw new StateError("More than one element"); - return JS('Node|Null', '#.firstChild', _this); + return JS('Node|Null', '#.firstChild', _this)!; } void add(Node value) { @@ -22925,7 +22964,7 @@ class _ChildNodeListLazy extends ListBase implements NodeListWrapper { if (!identical(otherList._this, _this)) { // Optimized route for copying between nodes. for (var i = 0, len = otherList.length; i < len; ++i) { - _this.append(otherList._this.firstChild); + _this.append(otherList._this.firstChild!); } } return; @@ -22975,7 +23014,7 @@ class _ChildNodeListLazy extends ListBase implements NodeListWrapper { return result; } - bool remove(Object object) { + bool remove(Object? object) { if (object is! Node) return false; Node node = object; if (!identical(_this, node.parentNode)) return false; @@ -22987,9 +23026,9 @@ class _ChildNodeListLazy extends ListBase implements NodeListWrapper { // This implementation of removeWhere/retainWhere is more efficient // than the default in ListBase. Child nodes can be removed in constant // time. - Node child = _this.firstChild; + Node? child = _this.firstChild; while (child != null) { - Node nextChild = child.nextNode; + Node? nextChild = child.nextNode; if (test(child) == removeMatching) { _this._removeChild(child); } @@ -23019,11 +23058,11 @@ class _ChildNodeListLazy extends ListBase implements NodeListWrapper { // TODO(jacobr): this could be implemented for child node lists. // The exception we throw here is misleading. - void sort([Comparator compare]) { + void sort([Comparator? compare]) { throw new UnsupportedError("Cannot sort Node list"); } - void shuffle([Random random]) { + void shuffle([Random? random]) { throw new UnsupportedError("Cannot shuffle Node list"); } @@ -23033,7 +23072,7 @@ class _ChildNodeListLazy extends ListBase implements NodeListWrapper { throw new UnsupportedError("Cannot setRange on Node list"); } - void fillRange(int start, int end, [Node fill]) { + void fillRange(int start, int end, [Node? fill]) { throw new UnsupportedError("Cannot fillRange on Node list"); } @@ -23084,7 +23123,7 @@ class Node extends EventTarget { // TODO(jacobr): should we throw an exception if parent is already null? // TODO(vsm): Use the native remove when available. if (this.parentNode != null) { - final Node parent = this.parentNode; + final Node parent = this.parentNode!; parent._removeChild(this); } } @@ -23094,7 +23133,7 @@ class Node extends EventTarget { */ Node replaceWith(Node otherNode) { try { - final Node parent = this.parentNode; + final Node parent = this.parentNode!; parent._replaceChild(otherNode, this); } catch (e) {} return this; @@ -23116,7 +23155,7 @@ class Node extends EventTarget { // Optimized route for copying between nodes. for (var i = 0, len = otherList.length; i < len; ++i) { - this.insertBefore(otherList._this.firstChild, refChild); + this.insertBefore(otherList._this.firstChild!, refChild); } } else { for (var node in newNodes) { @@ -23127,7 +23166,7 @@ class Node extends EventTarget { void _clearChildren() { while (firstChild != null) { - _removeChild(firstChild); + _removeChild(firstChild!); } } @@ -23135,7 +23174,7 @@ class Node extends EventTarget { * Print out a String representation of this Node. */ String toString() { - String value = nodeValue; // Fetch DOM Node property once. + String? value = nodeValue; // Fetch DOM Node property once. return value == null ? super.toString() : value; } @@ -23192,7 +23231,7 @@ class Node extends EventTarget { * from MDN. */ - Node get firstChild native; + Node? get firstChild native; bool get isConnected native; @@ -23205,7 +23244,7 @@ class Node extends EventTarget { * from MDN. */ - Node get lastChild native; + Node? get lastChild native; @JSName('nextSibling') @@ -23218,7 +23257,7 @@ class Node extends EventTarget { * from MDN. */ - Node get nextNode native; + Node? get nextNode native; /** * The name of this node. @@ -23272,7 +23311,7 @@ class Node extends EventTarget { * [nodeType]. */ - String get nodeValue native; + String? get nodeValue native; /** * The document this node belongs to. @@ -23285,7 +23324,7 @@ class Node extends EventTarget { * from MDN. */ - Document get ownerDocument native; + Document? get ownerDocument native; @JSName('parentElement') @@ -23301,7 +23340,7 @@ class Node extends EventTarget { * from W3C. */ - Element get parent native; + Element? get parent native; /** * The parent node of this node. @@ -23312,7 +23351,7 @@ class Node extends EventTarget { * from MDN. */ - Node get parentNode native; + Node? get parentNode native; @JSName('previousSibling') @@ -23325,7 +23364,7 @@ class Node extends EventTarget { * from MDN. */ - Node get previousNode native; + Node? get previousNode native; @JSName('textContent') @@ -23338,10 +23377,10 @@ class Node extends EventTarget { * from MDN. */ - String get text native; + String? get text native; @JSName('textContent') - set text(String value) native; + set text(String? value) native; @JSName('appendChild') /** @@ -23367,7 +23406,7 @@ class Node extends EventTarget { * * [Node.cloneNode](https://developer.mozilla.org/en-US/docs/Web/API/Node.cloneNode) * from MDN. */ - Node clone(bool deep) native; + Node clone(bool? deep) native; /** * Returns true if this node contains the specified node. @@ -23377,9 +23416,9 @@ class Node extends EventTarget { * * [Node.contains](https://developer.mozilla.org/en-US/docs/Web/API/Node.contains) * from MDN. */ - bool contains(Node other) native; + bool contains(Node? other) native; - Node getRootNode([Map options]) { + Node getRootNode([Map? options]) { if (options != null) { var options_1 = convertDartToNative_Dictionary(options); return _getRootNode_1(options_1); @@ -23410,7 +23449,7 @@ class Node extends EventTarget { * * [Node.insertBefore](https://developer.mozilla.org/en-US/docs/Web/API/Node.insertBefore) * from MDN. */ - Node insertBefore(Node node, Node child) native; + Node insertBefore(Node node, Node? child) native; @JSName('removeChild') Node _removeChild(Node child) native; @@ -23477,9 +23516,9 @@ class NodeIterator extends Interceptor { void detach() native; - Node nextNode() native; + Node? nextNode() native; - Node previousNode() native; + Node? previousNode() native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -23540,7 +23579,7 @@ class NodeList extends Interceptor // -- end List mixins. @JSName('item') - Node _item(int index) native; + Node? _item(int index) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -23553,9 +23592,9 @@ class NonDocumentTypeChildNode extends Interceptor { throw new UnsupportedError("Not supported"); } - Element get nextElementSibling native; + Element? get nextElementSibling native; - Element get previousElementSibling native; + Element? get previousElementSibling native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -23568,7 +23607,7 @@ class NonElementParentNode extends Interceptor { throw new UnsupportedError("Not supported"); } - Element getElementById(String elementId) native; + Element? getElementById(String elementId) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -23581,9 +23620,9 @@ class NoncedElement extends Interceptor { throw new UnsupportedError("Not supported"); } - String get nonce native; + String? get nonce native; - set nonce(String value) native; + set nonce(String? value) native; } // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -23592,7 +23631,7 @@ class NoncedElement extends Interceptor { @Native("Notification") class Notification extends EventTarget { factory Notification(String title, - {String dir, String body, String lang, String tag, String icon}) { + {String? dir, String? body, String? lang, String? tag, String? icon}) { var parsedOptions = {}; if (dir != null) parsedOptions['dir'] = dir; if (body != null) parsedOptions['body'] = body; @@ -23642,7 +23681,7 @@ class Notification extends EventTarget { static const EventStreamProvider showEvent = const EventStreamProvider('show'); - static Notification _factoryNotification(String title, [Map options]) { + static Notification _factoryNotification(String title, [Map? options]) { if (options != null) { var options_1 = convertDartToNative_Dictionary(options); return Notification._create_1(title, options_1); @@ -23666,7 +23705,7 @@ class Notification extends EventTarget { @annotation_Creates_SerializedScriptValue @annotation_Returns_SerializedScriptValue - Object get data native; + Object? get data native; String get dir native; @@ -23698,7 +23737,7 @@ class Notification extends EventTarget { @JSName('requestPermission') static Future _requestPermission( - [_NotificationPermissionCallback deprecatedCallback]) native; + [_NotificationPermissionCallback? deprecatedCallback]) native; @JSName('requestPermission') static Future requestPermission() { @@ -23743,7 +23782,7 @@ class NotificationEvent extends ExtendableEvent { Notification get notification native; - String get reply native; + String? get reply native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -23763,7 +23802,7 @@ class OListElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory OListElement() => JS( + factory OListElement() => JS( 'returns:OListElement;creates:OListElement;new:true', '#.createElement(#)', document, @@ -23802,7 +23841,7 @@ class ObjectElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory ObjectElement() => document.createElement("object"); + factory ObjectElement() => document.createElement("object") as ObjectElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -23813,7 +23852,7 @@ class ObjectElement extends HtmlElement { /// Checks if this type is supported on the current platform. static bool get supported => Element.isTagSupported('object'); - WindowBase get contentWindow => + WindowBase? get contentWindow => _convertNativeToDart_Window(this._get_contentWindow); @JSName('contentWindow') @Creates('Window|=Object') @@ -23824,7 +23863,7 @@ class ObjectElement extends HtmlElement { set data(String value) native; - FormElement get form native; + FormElement? get form native; String get height native; @@ -23887,7 +23926,7 @@ class OffscreenCanvas extends EventTarget { set width(int value) native; - Future convertToBlob([Map options]) { + Future convertToBlob([Map? options]) { var options_dict = null; if (options != null) { options_dict = convertDartToNative_Dictionary(options); @@ -23896,7 +23935,7 @@ class OffscreenCanvas extends EventTarget { JS("", "#.convertToBlob(#)", this, options_dict)); } - Object getContext(String contextType, [Map attributes]) { + Object? getContext(String contextType, [Map? attributes]) { if (attributes != null) { var attributes_1 = convertDartToNative_Dictionary(attributes); return _getContext_1(contextType, attributes_1); @@ -23905,9 +23944,9 @@ class OffscreenCanvas extends EventTarget { } @JSName('getContext') - Object _getContext_1(contextType, attributes) native; + Object? _getContext_1(contextType, attributes) native; @JSName('getContext') - Object _getContext_2(contextType) native; + Object? _getContext_2(contextType) native; ImageBitmap transferToImageBitmap() native; } @@ -23929,9 +23968,9 @@ class OffscreenCanvasRenderingContext2D extends Interceptor set direction(String value) native; - Object get fillStyle native; + Object? get fillStyle native; - set fillStyle(Object value) native; + set fillStyle(Object? value) native; String get filter native; @@ -23993,9 +24032,9 @@ class OffscreenCanvasRenderingContext2D extends Interceptor set shadowOffsetY(num value) native; - Object get strokeStyle native; + Object? get strokeStyle native; - set strokeStyle(Object value) native; + set strokeStyle(Object? value) native; String get textAlign native; @@ -24009,14 +24048,14 @@ class OffscreenCanvasRenderingContext2D extends Interceptor void clearRect(num x, num y, num width, num height) native; - void clip([Path2D path]) native; + void clip([Path2D? path]) native; Future commit() => promiseToFuture(JS("", "#.commit()", this)); ImageData createImageData(data_OR_imagedata_OR_sw, - [int sh_OR_sw, + [int? sh_OR_sw, imageDataColorSettings_OR_sh, - Map imageDataColorSettings]) { + Map? imageDataColorSettings]) { if ((data_OR_imagedata_OR_sw is ImageData) && sh_OR_sw == null && imageDataColorSettings_OR_sh == null && @@ -24062,29 +24101,29 @@ class OffscreenCanvasRenderingContext2D extends Interceptor @JSName('createImageData') _createImageData_3(int sw, sh, imageDataColorSettings) native; @JSName('createImageData') - _createImageData_4(data, sw, int sh, imageDataColorSettings) native; + _createImageData_4(data, sw, int? sh, imageDataColorSettings) native; CanvasGradient createLinearGradient(num x0, num y0, num x1, num y1) native; - CanvasPattern createPattern( + CanvasPattern? createPattern( /*CanvasImageSource*/ image, String repetitionType) native; CanvasGradient createRadialGradient( num x0, num y0, num r0, num x1, num y1, num r1) native; void drawImage(/*CanvasImageSource*/ image, num sx_OR_x, num sy_OR_y, - [num sw_OR_width, - num height_OR_sh, - num dx, - num dy, - num dw, - num dh]) native; + [num? sw_OR_width, + num? height_OR_sh, + num? dx, + num? dy, + num? dw, + num? dh]) native; - void fill([path_OR_winding, String winding]) native; + void fill([path_OR_winding, String? winding]) native; void fillRect(num x, num y, num width, num height) native; - void fillText(String text, num x, num y, [num maxWidth]) native; + void fillText(String text, num x, num y, [num? maxWidth]) native; ImageData getImageData(int sx, int sy, int sw, int sh) { return convertNativeToDart_ImageData(_getImageData_1(sx, sy, sw, sh)); @@ -24095,15 +24134,15 @@ class OffscreenCanvasRenderingContext2D extends Interceptor List getLineDash() native; - bool isPointInPath(path_OR_x, num x_OR_y, [winding_OR_y, String winding]) + bool isPointInPath(path_OR_x, num x_OR_y, [winding_OR_y, String? winding]) native; - bool isPointInStroke(path_OR_x, num x_OR_y, [num y]) native; + bool isPointInStroke(path_OR_x, num x_OR_y, [num? y]) native; TextMetrics measureText(String text) native; void putImageData(ImageData imagedata, int dx, int dy, - [int dirtyX, int dirtyY, int dirtyWidth, int dirtyHeight]) { + [int? dirtyX, int? dirtyY, int? dirtyWidth, int? dirtyHeight]) { if (dirtyX == null && dirtyY == null && dirtyWidth == null && @@ -24144,11 +24183,11 @@ class OffscreenCanvasRenderingContext2D extends Interceptor void setTransform(num a, num b, num c, num d, num e, num f) native; - void stroke([Path2D path]) native; + void stroke([Path2D? path]) native; void strokeRect(num x, num y, num width, num height) native; - void strokeText(String text, num x, num y, [num maxWidth]) native; + void strokeText(String text, num x, num y, [num? maxWidth]) native; void transform(num a, num b, num c, num d, num e, num f) native; @@ -24157,7 +24196,7 @@ class OffscreenCanvasRenderingContext2D extends Interceptor // From CanvasPath void arc(num x, num y, num radius, num startAngle, num endAngle, - bool anticlockwise) native; + bool? anticlockwise) native; void arcTo(num x1, num y1, num x2, num y2, num radius) native; @@ -24167,7 +24206,7 @@ class OffscreenCanvasRenderingContext2D extends Interceptor void closePath() native; void ellipse(num x, num y, num radiusX, num radiusY, num rotation, - num startAngle, num endAngle, bool anticlockwise) native; + num startAngle, num endAngle, bool? anticlockwise) native; void lineTo(num x, num y) native; @@ -24188,7 +24227,7 @@ class OptGroupElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory OptGroupElement() => JS( + factory OptGroupElement() => JS( 'returns:OptGroupElement;creates:OptGroupElement;new:true', '#.createElement(#)', document, @@ -24220,7 +24259,7 @@ class OptionElement extends HtmlElement { } factory OptionElement._( - [String data, String value, bool defaultSelected, bool selected]) { + [String? data, String? value, bool? defaultSelected, bool? selected]) { if (selected != null) { return OptionElement._create_1(data, value, defaultSelected, selected); } @@ -24264,7 +24303,7 @@ class OptionElement extends HtmlElement { set disabled(bool value) native; - FormElement get form native; + FormElement? get form native; int get index native; @@ -24291,7 +24330,7 @@ class OrientationSensor extends Sensor { throw new UnsupportedError("Not supported"); } - List get quaternion native; + List? get quaternion native; void populateMatrix(Object targetBuffer) native; } @@ -24309,7 +24348,7 @@ class OutputElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory OutputElement() => document.createElement("output"); + factory OutputElement() => document.createElement("output") as OutputElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -24324,12 +24363,12 @@ class OutputElement extends HtmlElement { set defaultValue(String value) native; - FormElement get form native; + FormElement? get form native; DomTokenList get htmlFor native; @Unstable() - @Returns('NodeList|Null') + @Returns('NodeList') @Creates('NodeList') List get labels native; @@ -24375,9 +24414,9 @@ class OverconstrainedError extends Interceptor { constraint, message); - String get constraint native; + String? get constraint native; - String get message native; + String? get message native; String get name native; } @@ -24392,7 +24431,7 @@ class PageTransitionEvent extends Event { throw new UnsupportedError("Not supported"); } - factory PageTransitionEvent(String type, [Map eventInitDict]) { + factory PageTransitionEvent(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return PageTransitionEvent._create_1(type, eventInitDict_1); @@ -24424,9 +24463,9 @@ class PaintRenderingContext2D extends Interceptor implements _CanvasPath { set currentTransform(Matrix value) native; - Object get fillStyle native; + Object? get fillStyle native; - set fillStyle(Object value) native; + set fillStyle(Object? value) native; String get filter native; @@ -24484,42 +24523,42 @@ class PaintRenderingContext2D extends Interceptor implements _CanvasPath { set shadowOffsetY(num value) native; - Object get strokeStyle native; + Object? get strokeStyle native; - set strokeStyle(Object value) native; + set strokeStyle(Object? value) native; void beginPath() native; void clearRect(num x, num y, num width, num height) native; - void clip([path_OR_winding, String winding]) native; + void clip([path_OR_winding, String? winding]) native; CanvasGradient createLinearGradient(num x0, num y0, num x1, num y1) native; - CanvasPattern createPattern( + CanvasPattern? createPattern( /*CanvasImageSource*/ image, String repetitionType) native; CanvasGradient createRadialGradient( num x0, num y0, num r0, num x1, num y1, num r1) native; void drawImage(/*CanvasImageSource*/ image, num sx_OR_x, num sy_OR_y, - [num sw_OR_width, - num height_OR_sh, - num dx, - num dy, - num dw, - num dh]) native; + [num? sw_OR_width, + num? height_OR_sh, + num? dx, + num? dy, + num? dw, + num? dh]) native; - void fill([path_OR_winding, String winding]) native; + void fill([path_OR_winding, String? winding]) native; void fillRect(num x, num y, num width, num height) native; List getLineDash() native; - bool isPointInPath(path_OR_x, num x_OR_y, [winding_OR_y, String winding]) + bool isPointInPath(path_OR_x, num x_OR_y, [winding_OR_y, String? winding]) native; - bool isPointInStroke(path_OR_x, num x_OR_y, [num y]) native; + bool isPointInStroke(path_OR_x, num x_OR_y, [num? y]) native; void resetTransform() native; @@ -24535,7 +24574,7 @@ class PaintRenderingContext2D extends Interceptor implements _CanvasPath { void setTransform(num a, num b, num c, num d, num e, num f) native; - void stroke([Path2D path]) native; + void stroke([Path2D? path]) native; void strokeRect(num x, num y, num width, num height) native; @@ -24546,7 +24585,7 @@ class PaintRenderingContext2D extends Interceptor implements _CanvasPath { // From CanvasPath void arc(num x, num y, num radius, num startAngle, num endAngle, - bool anticlockwise) native; + bool? anticlockwise) native; void arcTo(num x1, num y1, num x2, num y2, num radius) native; @@ -24556,7 +24595,7 @@ class PaintRenderingContext2D extends Interceptor implements _CanvasPath { void closePath() native; void ellipse(num x, num y, num radiusX, num radiusY, num rotation, - num startAngle, num endAngle, bool anticlockwise) native; + num startAngle, num endAngle, bool? anticlockwise) native; void lineTo(num x, num y) native; @@ -24607,7 +24646,7 @@ class ParagraphElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory ParagraphElement() => JS( + factory ParagraphElement() => JS( 'returns:ParagraphElement;creates:ParagraphElement;new:true', '#.createElement(#)', document, @@ -24631,7 +24670,7 @@ class ParamElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory ParamElement() => JS( + factory ParamElement() => JS( 'returns:ParamElement;creates:ParamElement;new:true', '#.createElement(#)', document, @@ -24665,11 +24704,11 @@ abstract class ParentNode extends Interceptor { List get _children native; - Element get _firstElementChild native; + Element? get _firstElementChild native; - Element get _lastElementChild native; + Element? get _lastElementChild native; - Element querySelector(String selectors); + Element? querySelector(String selectors); List _querySelectorAll(String selectors); } @@ -24699,9 +24738,9 @@ class PasswordCredential extends Credential implements CredentialUserData { static PasswordCredential _create_2(data_OR_form) => JS('PasswordCredential', 'new PasswordCredential(#)', data_OR_form); - Object get additionalData native; + Object? get additionalData native; - set additionalData(Object value) native; + set additionalData(Object? value) native; String get idName native; @@ -24749,12 +24788,12 @@ class Path2D extends Interceptor implements _CanvasPath { static Path2D _create_3(path_OR_text) => JS('Path2D', 'new Path2D(#)', path_OR_text); - void addPath(Path2D path, [Matrix transform]) native; + void addPath(Path2D path, [Matrix? transform]) native; // From CanvasPath void arc(num x, num y, num radius, num startAngle, num endAngle, - bool anticlockwise) native; + bool? anticlockwise) native; void arcTo(num x1, num y1, num x2, num y2, num radius) native; @@ -24764,7 +24803,7 @@ class Path2D extends Interceptor implements _CanvasPath { void closePath() native; void ellipse(num x, num y, num radiusX, num radiusY, num rotation, - num startAngle, num endAngle, bool anticlockwise) native; + num startAngle, num endAngle, bool? anticlockwise) native; void lineTo(num x, num y) native; @@ -24823,7 +24862,7 @@ class PaymentInstruments extends Interceptor { Future delete(String instrumentKey) => promiseToFuture(JS("", "#.delete(#)", this, instrumentKey)); - Future> get(String instrumentKey) => + Future?> get(String instrumentKey) => promiseToFutureAsMap(JS("", "#.get(#)", this, instrumentKey)); Future has(String instrumentKey) => @@ -24861,7 +24900,7 @@ class PaymentManager extends Interceptor { @Native("PaymentRequest") class PaymentRequest extends EventTarget { - factory PaymentRequest(List methodData, Map details, [Map options]) { + factory PaymentRequest(List methodData, Map details, [Map? options]) { var methodData_1 = []; for (var i in methodData) { methodData_1.add(convertDartToNative_Dictionary(i)); @@ -24891,11 +24930,11 @@ class PaymentRequest extends EventTarget { String get id native; - PaymentAddress get shippingAddress native; + PaymentAddress? get shippingAddress native; - String get shippingOption native; + String? get shippingOption native; - String get shippingType native; + String? get shippingType native; Future abort() => promiseToFuture(JS("", "#.abort()", this)); @@ -24957,7 +24996,7 @@ class PaymentRequestUpdateEvent extends Event { throw new UnsupportedError("Not supported"); } - factory PaymentRequestUpdateEvent(String type, [Map eventInitDict]) { + factory PaymentRequestUpdateEvent(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return PaymentRequestUpdateEvent._create_1(type, eventInitDict_1); @@ -24989,19 +25028,19 @@ class PaymentResponse extends Interceptor { String get methodName native; - String get payerEmail native; + String? get payerEmail native; - String get payerName native; + String? get payerName native; - String get payerPhone native; + String? get payerPhone native; String get requestId native; - PaymentAddress get shippingAddress native; + PaymentAddress? get shippingAddress native; - String get shippingOption native; + String? get shippingOption native; - Future complete([String paymentResult]) => + Future complete([String? paymentResult]) => promiseToFuture(JS("", "#.complete(#)", this, paymentResult)); } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file @@ -25021,7 +25060,7 @@ class Performance extends EventTarget { /// Checks if this type is supported on the current platform. static bool get supported => JS('bool', '!!(window.performance)'); - MemoryInfo get memory native; + MemoryInfo? get memory native; PerformanceNavigation get navigation native; @@ -25029,21 +25068,22 @@ class Performance extends EventTarget { PerformanceTiming get timing native; - void clearMarks(String markName) native; + void clearMarks(String? markName) native; - void clearMeasures(String measureName) native; + void clearMeasures(String? measureName) native; void clearResourceTimings() native; List getEntries() native; - List getEntriesByName(String name, String entryType) native; + List getEntriesByName(String name, String? entryType) + native; List getEntriesByType(String entryType) native; void mark(String markName) native; - void measure(String measureName, String startMark, String endMark) native; + void measure(String measureName, String? startMark, String? endMark) native; double now() native; @@ -25208,7 +25248,8 @@ class PerformanceObserverEntryList extends Interceptor { List getEntries() native; - List getEntriesByName(String name, String entryType) native; + List getEntriesByName(String name, String? entryType) + native; List getEntriesByType(String entryType) native; } @@ -25447,9 +25488,9 @@ class Plugin extends Interceptor { String get name native; - MimeType item(int index) native; + MimeType? item(int index) native; - MimeType namedItem(String name) native; + MimeType? namedItem(String name) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -25509,11 +25550,11 @@ class PluginArray extends Interceptor Plugin elementAt(int index) => this[index]; // -- end List mixins. - Plugin item(int index) native; + Plugin? item(int index) native; - Plugin namedItem(String name) native; + Plugin? namedItem(String name) native; - void refresh(bool reload) native; + void refresh(bool? reload) native; } // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -25528,7 +25569,7 @@ class PointerEvent extends MouseEvent { throw new UnsupportedError("Not supported"); } - factory PointerEvent(String type, [Map eventInitDict]) { + factory PointerEvent(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return PointerEvent._create_1(type, eventInitDict_1); @@ -25588,7 +25629,7 @@ class PopStateEvent extends Event { throw new UnsupportedError("Not supported"); } - factory PopStateEvent(String type, [Map eventInitDict]) { + factory PopStateEvent(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return PopStateEvent._create_1(type, eventInitDict_1); @@ -25656,8 +25697,11 @@ class PreElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory PreElement() => JS('returns:PreElement;creates:PreElement;new:true', - '#.createElement(#)', document, "pre"); + factory PreElement() => JS( + 'returns:PreElement;creates:PreElement;new:true', + '#.createElement(#)', + document, + "pre"); /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -25676,11 +25720,11 @@ class Presentation extends Interceptor { throw new UnsupportedError("Not supported"); } - PresentationRequest get defaultRequest native; + PresentationRequest? get defaultRequest native; - set defaultRequest(PresentationRequest value) native; + set defaultRequest(PresentationRequest? value) native; - PresentationReceiver get receiver native; + PresentationReceiver? get receiver native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -25856,7 +25900,7 @@ class ProcessingInstruction extends CharacterData { throw new UnsupportedError("Not supported"); } - StyleSheet get sheet native; + StyleSheet? get sheet native; String get target native; } @@ -25875,7 +25919,8 @@ class ProgressElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory ProgressElement() => document.createElement("progress"); + factory ProgressElement() => + document.createElement("progress") as ProgressElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -25887,7 +25932,7 @@ class ProgressElement extends HtmlElement { static bool get supported => Element.isTagSupported('progress'); @Unstable() - @Returns('NodeList|Null') + @Returns('NodeList') @Creates('NodeList') List get labels native; @@ -25912,7 +25957,7 @@ class ProgressEvent extends Event { throw new UnsupportedError("Not supported"); } - factory ProgressEvent(String type, [Map eventInitDict]) { + factory ProgressEvent(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return ProgressEvent._create_1(type, eventInitDict_1); @@ -25953,7 +25998,7 @@ class PromiseRejectionEvent extends Event { Future get promise => promiseToFuture(JS("", "#.promise", this)); - Object get reason native; + Object? get reason native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -25981,7 +26026,7 @@ class PushEvent extends ExtendableEvent { throw new UnsupportedError("Not supported"); } - factory PushEvent(String type, [Map eventInitDict]) { + factory PushEvent(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return PushEvent._create_1(type, eventInitDict_1); @@ -25992,7 +26037,7 @@ class PushEvent extends ExtendableEvent { JS('PushEvent', 'new PushEvent(#,#)', type, eventInitDict); static PushEvent _create_2(type) => JS('PushEvent', 'new PushEvent(#)', type); - PushMessageData get data native; + PushMessageData? get data native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -26010,7 +26055,7 @@ class PushManager extends Interceptor { Future getSubscription() => promiseToFuture(JS("", "#.getSubscription()", this)); - Future permissionState([Map options]) { + Future permissionState([Map? options]) { var options_dict = null; if (options != null) { options_dict = convertDartToNative_Dictionary(options); @@ -26018,7 +26063,7 @@ class PushManager extends Interceptor { return promiseToFuture(JS("", "#.permissionState(#)", this, options_dict)); } - Future subscribe([Map options]) { + Future subscribe([Map? options]) { var options_dict = null; if (options != null) { options_dict = convertDartToNative_Dictionary(options); @@ -26063,7 +26108,7 @@ class PushSubscription extends Interceptor { PushSubscriptionOptions get options native; - ByteBuffer getKey(String name) native; + ByteBuffer? getKey(String name) native; Future unsubscribe() => promiseToFuture(JS("", "#.unsubscribe()", this)); @@ -26079,7 +26124,7 @@ class PushSubscriptionOptions extends Interceptor { throw new UnsupportedError("Not supported"); } - ByteBuffer get applicationServerKey native; + ByteBuffer? get applicationServerKey native; bool get userVisibleOnly native; } @@ -26094,7 +26139,7 @@ class QuoteElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory QuoteElement() => JS( + factory QuoteElement() => JS( 'returns:QuoteElement;creates:QuoteElement;new:true', '#.createElement(#)', document, @@ -26173,7 +26218,7 @@ class Range extends Interceptor { Range cloneRange() native; - void collapse([bool toStart]) native; + void collapse([bool? toStart]) native; int compareBoundaryPoints(int how, Range sourceRange) native; @@ -26185,14 +26230,14 @@ class Range extends Interceptor { void detach() native; - void expand(String unit) native; + void expand(String? unit) native; DocumentFragment extractContents() native; Rectangle getBoundingClientRect() native; @JSName('getClientRects') - @Returns('DomRectList|Null') + @Returns('DomRectList') @Creates('DomRectList') List _getClientRects() native; @@ -26270,7 +26315,7 @@ class RelativeOrientationSensor extends OrientationSensor { throw new UnsupportedError("Not supported"); } - factory RelativeOrientationSensor([Map sensorOptions]) { + factory RelativeOrientationSensor([Map? sensorOptions]) { if (sensorOptions != null) { var sensorOptions_1 = convertDartToNative_Dictionary(sensorOptions); return RelativeOrientationSensor._create_1(sensorOptions_1); @@ -26297,7 +26342,7 @@ class RemotePlayback extends EventTarget { String get state native; - Future cancelWatchAvailability([int id]) => + Future cancelWatchAvailability([int? id]) => promiseToFuture(JS("", "#.cancelWatchAvailability(#)", this, id)); Future prompt() => promiseToFuture(JS("", "#.prompt()", this)); @@ -26579,7 +26624,7 @@ class RtcDtmfSender extends EventTarget { MediaStreamTrack get track native; @JSName('insertDTMF') - void insertDtmf(String tones, [int duration, int interToneGap]) native; + void insertDtmf(String tones, [int? duration, int? interToneGap]) native; /// Stream of `tonechange` events handled by this [RtcDtmfSender]. Stream get onToneChange => @@ -26667,7 +26712,7 @@ class RtcLegacyStatsReport extends Interceptor { @SupportedBrowser(SupportedBrowser.CHROME) @Native("RTCPeerConnection,webkitRTCPeerConnection,mozRTCPeerConnection") class RtcPeerConnection extends EventTarget { - factory RtcPeerConnection(Map rtcIceServers, [Map mediaConstraints]) { + factory RtcPeerConnection(Map rtcIceServers, [Map? mediaConstraints]) { var constructorName = JS('RtcPeerConnection', 'window[#]', 'RTCPeerConnection'); if (mediaConstraints != null) { @@ -26709,7 +26754,7 @@ class RtcPeerConnection extends EventTarget { * Temporarily exposes _getStats and old getStats as getLegacyStats until Chrome fully supports * new getStats API. */ - Future getLegacyStats([MediaStreamTrack selector]) { + Future getLegacyStats([MediaStreamTrack? selector]) { var completer = new Completer(); _getStats((value) { completer.complete(value); @@ -26719,7 +26764,7 @@ class RtcPeerConnection extends EventTarget { @JSName('getStats') Future _getStats( - [RtcStatsCallback successCallback, MediaStreamTrack selector]) native; + [RtcStatsCallback? successCallback, MediaStreamTrack? selector]) native; static Future generateCertificate(/*AlgorithmIdentifier*/ keygenAlgorithm) => JS('dynamic', 'generateCertificate(#)', keygenAlgorithm); @@ -26806,19 +26851,19 @@ class RtcPeerConnection extends EventTarget { String get iceGatheringState native; - RtcSessionDescription get localDescription native; + RtcSessionDescription? get localDescription native; - RtcSessionDescription get remoteDescription native; + RtcSessionDescription? get remoteDescription native; String get signalingState native; Future addIceCandidate(Object candidate, - [VoidCallback successCallback, - RtcPeerConnectionErrorCallback failureCallback]) => + [VoidCallback? successCallback, + RtcPeerConnectionErrorCallback? failureCallback]) => promiseToFuture(JS("", "#.addIceCandidate(#, #, #)", this, candidate, successCallback, failureCallback)); - void addStream(MediaStream stream, [Map mediaConstraints]) { + void addStream(MediaStream? stream, [Map? mediaConstraints]) { if (mediaConstraints != null) { var mediaConstraints_1 = convertDartToNative_Dictionary(mediaConstraints); _addStream_1(stream, mediaConstraints_1); @@ -26829,15 +26874,15 @@ class RtcPeerConnection extends EventTarget { } @JSName('addStream') - void _addStream_1(MediaStream stream, mediaConstraints) native; + void _addStream_1(MediaStream? stream, mediaConstraints) native; @JSName('addStream') - void _addStream_2(MediaStream stream) native; + void _addStream_2(MediaStream? stream) native; RtcRtpSender addTrack(MediaStreamTrack track, MediaStream streams) native; void close() native; - Future createAnswer([Map options]) { + Future createAnswer([Map? options]) { var options_dict = null; if (options != null) { options_dict = convertDartToNative_Dictionary(options); @@ -26849,7 +26894,7 @@ class RtcPeerConnection extends EventTarget { @JSName('createDTMFSender') RtcDtmfSender createDtmfSender(MediaStreamTrack track) native; - RtcDataChannel createDataChannel(String label, [Map dataChannelDict]) { + RtcDataChannel createDataChannel(String label, [Map? dataChannelDict]) { if (dataChannelDict != null) { var dataChannelDict_1 = convertDartToNative_Dictionary(dataChannelDict); return _createDataChannel_1(label, dataChannelDict_1); @@ -26862,7 +26907,7 @@ class RtcPeerConnection extends EventTarget { @JSName('createDataChannel') RtcDataChannel _createDataChannel_2(label) native; - Future createOffer([Map options]) { + Future createOffer([Map? options]) { var options_dict = null; if (options != null) { options_dict = convertDartToNative_Dictionary(options); @@ -26882,7 +26927,7 @@ class RtcPeerConnection extends EventTarget { Future getStats() => promiseToFuture(JS("", "#.getStats()", this)); - void removeStream(MediaStream stream) native; + void removeStream(MediaStream? stream) native; void removeTrack(RtcRtpSender sender) native; @@ -26948,7 +26993,7 @@ class RtcPeerConnectionIceEvent extends Event { throw new UnsupportedError("Not supported"); } - factory RtcPeerConnectionIceEvent(String type, [Map eventInitDict]) { + factory RtcPeerConnectionIceEvent(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return RtcPeerConnectionIceEvent._create_1(type, eventInitDict_1); @@ -26963,7 +27008,7 @@ class RtcPeerConnectionIceEvent extends Event { static RtcPeerConnectionIceEvent _create_2(type) => JS('RtcPeerConnectionIceEvent', 'new RTCPeerConnectionIceEvent(#)', type); - RtcIceCandidate get candidate native; + RtcIceCandidate? get candidate native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -27006,7 +27051,7 @@ class RtcRtpSender extends Interceptor { throw new UnsupportedError("Not supported"); } - MediaStreamTrack get track native; + MediaStreamTrack? get track native; } // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -27025,13 +27070,13 @@ class RtcSessionDescription extends Interceptor { throw new UnsupportedError("Not supported"); } - String get sdp native; + String? get sdp native; - set sdp(String value) native; + set sdp(String? value) native; - String get type native; + String? get type native; - set type(String value) native; + set type(String? value) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -27044,7 +27089,7 @@ class RtcStatsReport extends Interceptor with MapMixin { throw new UnsupportedError("Not supported"); } - Map _getItem(String key) => + Map? _getItem(String key) => convertNativeToDart_Dictionary(JS('', '#.get(#)', this, key)); void addAll(Map other) { @@ -27055,7 +27100,7 @@ class RtcStatsReport extends Interceptor with MapMixin { bool containsKey(dynamic key) => _getItem(key) != null; - Map operator [](dynamic key) => _getItem(key); + Map? operator [](dynamic key) => _getItem(key); void forEach(void f(String key, dynamic value)) { var entries = JS('', '#.entries()', this); @@ -27112,7 +27157,7 @@ class RtcStatsResponse extends Interceptor { throw new UnsupportedError("Not supported"); } - RtcLegacyStatsReport namedItem(String name) native; + RtcLegacyStatsReport namedItem(String? name) native; List result() native; } @@ -27215,7 +27260,7 @@ class ScriptElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory ScriptElement() => JS( + factory ScriptElement() => JS( 'returns:ScriptElement;creates:ScriptElement;new:true', '#.createElement(#)', document, @@ -27235,9 +27280,9 @@ class ScriptElement extends HtmlElement { set charset(String value) native; - String get crossOrigin native; + String? get crossOrigin native; - set crossOrigin(String value) native; + set crossOrigin(String? value) native; bool get defer native; @@ -27270,7 +27315,7 @@ class ScrollState extends Interceptor { throw new UnsupportedError("Not supported"); } - factory ScrollState([Map scrollStateInit]) { + factory ScrollState([Map? scrollStateInit]) { if (scrollStateInit != null) { var scrollStateInit_1 = convertDartToNative_Dictionary(scrollStateInit); return ScrollState._create_1(scrollStateInit_1); @@ -27327,7 +27372,7 @@ class ScrollTimeline extends AnimationTimeline { throw new UnsupportedError("Not supported"); } - factory ScrollTimeline([Map options]) { + factory ScrollTimeline([Map? options]) { if (options != null) { var options_1 = convertDartToNative_Dictionary(options); return ScrollTimeline._create_1(options_1); @@ -27341,9 +27386,9 @@ class ScrollTimeline extends AnimationTimeline { String get orientation native; - Element get scrollSource native; + Element? get scrollSource native; - Object get timeRange native; + Object? get timeRange native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -27356,7 +27401,7 @@ class SecurityPolicyViolationEvent extends Event { throw new UnsupportedError("Not supported"); } - factory SecurityPolicyViolationEvent(String type, [Map eventInitDict]) { + factory SecurityPolicyViolationEvent(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return SecurityPolicyViolationEvent._create_1(type, eventInitDict_1); @@ -27410,7 +27455,7 @@ class SelectElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory SelectElement() => JS( + factory SelectElement() => JS( 'returns:SelectElement;creates:SelectElement;new:true', '#.createElement(#)', document, @@ -27430,10 +27475,10 @@ class SelectElement extends HtmlElement { set disabled(bool value) native; - FormElement get form native; + FormElement? get form native; @Unstable() - @Returns('NodeList|Null') + @Returns('NodeList') @Creates('NodeList') List get labels native; @@ -27473,15 +27518,15 @@ class SelectElement extends HtmlElement { bool get willValidate native; - void __setter__(int index, OptionElement option) native; + void __setter__(int index, OptionElement? option) native; - void add(Object element, Object before) native; + void add(Object element, Object? before) native; bool checkValidity() native; - Element item(int index) native; + Element? item(int index) native; - OptionElement namedItem(String name) native; + OptionElement? namedItem(String name) native; bool reportValidity() native; @@ -27515,19 +27560,19 @@ class Selection extends Interceptor { throw new UnsupportedError("Not supported"); } - Node get anchorNode native; + Node? get anchorNode native; int get anchorOffset native; - Node get baseNode native; + Node? get baseNode native; int get baseOffset native; - Node get extentNode native; + Node? get extentNode native; int get extentOffset native; - Node get focusNode native; + Node? get focusNode native; int get focusOffset native; @@ -27539,23 +27584,23 @@ class Selection extends Interceptor { void addRange(Range range) native; - void collapse(Node node, [int offset]) native; + void collapse(Node? node, [int? offset]) native; void collapseToEnd() native; void collapseToStart() native; - bool containsNode(Node node, [bool allowPartialContainment]) native; + bool containsNode(Node node, [bool? allowPartialContainment]) native; void deleteFromDocument() native; void empty() native; - void extend(Node node, [int offset]) native; + void extend(Node node, [int? offset]) native; Range getRangeAt(int index) native; - void modify(String alter, String direction, String granularity) native; + void modify(String? alter, String? direction, String? granularity) native; void removeAllRanges() native; @@ -27563,10 +27608,10 @@ class Selection extends Interceptor { void selectAllChildren(Node node) native; - void setBaseAndExtent( - Node baseNode, int baseOffset, Node extentNode, int extentOffset) native; + void setBaseAndExtent(Node? baseNode, int baseOffset, Node? extentNode, + int extentOffset) native; - void setPosition(Node node, [int offset]) native; + void setPosition(Node? node, [int? offset]) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -27633,7 +27678,7 @@ class ServiceWorker extends EventTarget implements AbstractWorker { String get state native; - void postMessage(/*any*/ message, [List transfer]) { + void postMessage(/*any*/ message, [List? transfer]) { if (transfer != null) { var message_1 = convertDartToNative_SerializedScriptValue(message); _postMessage_1(message_1, transfer); @@ -27645,7 +27690,7 @@ class ServiceWorker extends EventTarget implements AbstractWorker { } @JSName('postMessage') - void _postMessage_1(message, List transfer) native; + void _postMessage_1(message, List? transfer) native; @JSName('postMessage') void _postMessage_2(message) native; @@ -27665,19 +27710,19 @@ class ServiceWorkerContainer extends EventTarget { static const EventStreamProvider messageEvent = const EventStreamProvider('message'); - ServiceWorker get controller native; + ServiceWorker? get controller native; Future get ready => promiseToFuture(JS("", "#.ready", this)); - Future getRegistration([String documentURL]) => + Future getRegistration([String? documentURL]) => promiseToFuture( JS("", "#.getRegistration(#)", this, documentURL)); Future> getRegistrations() => promiseToFuture>(JS("", "#.getRegistrations()", this)); - Future register(String url, [Map options]) { + Future register(String url, [Map? options]) { var options_dict = null; if (options != null) { options_dict = convertDartToNative_Dictionary(options); @@ -27747,11 +27792,11 @@ class ServiceWorkerRegistration extends EventTarget { throw new UnsupportedError("Not supported"); } - ServiceWorker get active native; + ServiceWorker? get active native; BackgroundFetchManager get backgroundFetch native; - ServiceWorker get installing native; + ServiceWorker? get installing native; NavigationPreloadManager get navigationPreload native; @@ -27763,9 +27808,9 @@ class ServiceWorkerRegistration extends EventTarget { SyncManager get sync native; - ServiceWorker get waiting native; + ServiceWorker? get waiting native; - Future> getNotifications([Map filter]) { + Future> getNotifications([Map? filter]) { var filter_dict = null; if (filter != null) { filter_dict = convertDartToNative_Dictionary(filter); @@ -27774,7 +27819,7 @@ class ServiceWorkerRegistration extends EventTarget { JS("", "#.getNotifications(#)", this, filter_dict)); } - Future showNotification(String title, [Map options]) { + Future showNotification(String title, [Map? options]) { var options_dict = null; if (options != null) { options_dict = convertDartToNative_Dictionary(options); @@ -27800,7 +27845,7 @@ class ShadowElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory ShadowElement() => document.createElement("shadow"); + factory ShadowElement() => document.createElement("shadow") as ShadowElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -27811,7 +27856,7 @@ class ShadowElement extends HtmlElement { /// Checks if this type is supported on the current platform. static bool get supported => Element.isTagSupported('shadow'); - @Returns('NodeList|Null') + @Returns('NodeList') @Creates('NodeList') List getDistributedNodes() native; } @@ -27837,29 +27882,29 @@ class ShadowRoot extends DocumentFragment implements DocumentOrShadowRoot { String get innerHtml native; @JSName('innerHTML') - set innerHtml(String value) native; + set innerHtml(String? value) native; String get mode native; - ShadowRoot get olderShadowRoot native; + ShadowRoot? get olderShadowRoot native; // From DocumentOrShadowRoot - Element get activeElement native; + Element? get activeElement native; - Element get fullscreenElement native; + Element? get fullscreenElement native; - Element get pointerLockElement native; + Element? get pointerLockElement native; - @Returns('_StyleSheetList|Null') + @Returns('_StyleSheetList') @Creates('_StyleSheetList') List get styleSheets native; - Element elementFromPoint(int x, int y) native; + Element? elementFromPoint(int x, int y) native; List elementsFromPoint(int x, int y) native; - Selection getSelection() native; + Selection? getSelection() native; static bool get supported => JS( 'bool', @@ -27928,7 +27973,7 @@ class SharedWorker extends EventTarget implements AbstractWorker { static const EventStreamProvider errorEvent = const EventStreamProvider('error'); - factory SharedWorker(String scriptURL, [String name]) { + factory SharedWorker(String scriptURL, [String? name]) { if (name != null) { return SharedWorker._create_1(scriptURL, name); } @@ -27975,8 +28020,8 @@ class SharedWorkerGlobalScope extends WorkerGlobalScope { @SupportedBrowser(SupportedBrowser.CHROME) @SupportedBrowser(SupportedBrowser.SAFARI) void _webkitRequestFileSystem(int type, int size, - [_FileSystemCallback successCallback, - _ErrorCallback errorCallback]) native; + [_FileSystemCallback? successCallback, + _ErrorCallback? errorCallback]) native; @JSName('webkitRequestFileSystemSync') @SupportedBrowser(SupportedBrowser.CHROME) @@ -27993,7 +28038,7 @@ class SharedWorkerGlobalScope extends WorkerGlobalScope { @SupportedBrowser(SupportedBrowser.SAFARI) void _webkitResolveLocalFileSystemUrl( String url, _EntryCallback successCallback, - [_ErrorCallback errorCallback]) native; + [_ErrorCallback? errorCallback]) native; /// Stream of `connect` events handled by this [SharedWorkerGlobalScope]. Stream get onConnect => connectEvent.forTarget(this); @@ -28024,7 +28069,7 @@ class SlotElement extends HtmlElement { set name(String value) native; - List assignedNodes([Map options]) { + List assignedNodes([Map? options]) { if (options != null) { var options_1 = convertDartToNative_Dictionary(options); return _assignedNodes_1(options_1); @@ -28166,7 +28211,7 @@ class SourceElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory SourceElement() => JS( + factory SourceElement() => JS( 'returns:SourceElement;creates:SourceElement;new:true', '#.createElement(#)', document, @@ -28209,7 +28254,7 @@ class SpanElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory SpanElement() => JS( + factory SpanElement() => JS( 'returns:SpanElement;creates:SpanElement;new:true', '#.createElement(#)', document, @@ -28310,9 +28355,9 @@ class SpeechGrammarList extends Interceptor SpeechGrammar elementAt(int index) => this[index]; // -- end List mixins. - void addFromString(String string, [num weight]) native; + void addFromString(String string, [num? weight]) native; - void addFromUri(String src, [num weight]) native; + void addFromUri(String src, [num? weight]) native; SpeechGrammar item(int index) native; } @@ -28431,9 +28476,9 @@ class SpeechRecognition extends EventTarget { static bool get supported => JS( 'bool', '!!(window.SpeechRecognition || window.webkitSpeechRecognition)'); - MediaStreamTrack get audioTrack native; + MediaStreamTrack? get audioTrack native; - set audioTrack(MediaStreamTrack value) native; + set audioTrack(MediaStreamTrack? value) native; bool get continuous native; @@ -28527,7 +28572,7 @@ class SpeechRecognitionError extends Event { throw new UnsupportedError("Not supported"); } - factory SpeechRecognitionError(String type, [Map initDict]) { + factory SpeechRecognitionError(String type, [Map? initDict]) { if (initDict != null) { var initDict_1 = convertDartToNative_Dictionary(initDict); return SpeechRecognitionError._create_1(type, initDict_1); @@ -28558,7 +28603,7 @@ class SpeechRecognitionEvent extends Event { throw new UnsupportedError("Not supported"); } - factory SpeechRecognitionEvent(String type, [Map initDict]) { + factory SpeechRecognitionEvent(String type, [Map? initDict]) { if (initDict != null) { var initDict_1 = convertDartToNative_Dictionary(initDict); return SpeechRecognitionEvent._create_1(type, initDict_1); @@ -28573,15 +28618,15 @@ class SpeechRecognitionEvent extends Event { static SpeechRecognitionEvent _create_2(type) => JS('SpeechRecognitionEvent', 'new SpeechRecognitionEvent(#)', type); - Document get emma native; + Document? get emma native; - Document get interpretation native; + Document? get interpretation native; int get resultIndex native; @Returns('_SpeechRecognitionResultList|Null') @Creates('_SpeechRecognitionResultList') - List get results native; + List? get results native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -28728,7 +28773,7 @@ class SpeechSynthesisUtterance extends EventTarget { static const EventStreamProvider startEvent = const EventStreamProvider('start'); - factory SpeechSynthesisUtterance([String text]) { + factory SpeechSynthesisUtterance([String? text]) { if (text != null) { return SpeechSynthesisUtterance._create_1(text); } @@ -28755,9 +28800,9 @@ class SpeechSynthesisUtterance extends EventTarget { set text(String value) native; - SpeechSynthesisVoice get voice native; + SpeechSynthesisVoice? get voice native; - set voice(SpeechSynthesisVoice value) native; + set voice(SpeechSynthesisVoice? value) native; num get volume native; @@ -28867,11 +28912,11 @@ class Storage extends Interceptor with MapMixin { } // TODO(nweiz): update this when maps support lazy iteration - bool containsValue(Object value) => values.any((e) => e == value); + bool containsValue(Object? value) => values.any((e) => e == value); - bool containsKey(Object key) => _getItem(key) != null; + bool containsKey(Object? key) => _getItem(key as String) != null; - String operator [](Object key) => _getItem(key); + String? operator [](Object? key) => _getItem(key as String); void operator []=(String key, String value) { _setItem(key, value); @@ -28879,12 +28924,12 @@ class Storage extends Interceptor with MapMixin { String putIfAbsent(String key, String ifAbsent()) { if (!containsKey(key)) this[key] = ifAbsent(); - return this[key]; + return this[key] as String; } - String remove(Object key) { + String? remove(Object? key) { final value = this[key]; - _removeItem(key); + _removeItem(key as String); return value; } @@ -28895,7 +28940,7 @@ class Storage extends Interceptor with MapMixin { final key = _key(i); if (key == null) return; - f(key, this[key]); + f(key, this[key]!); } } @@ -28928,10 +28973,10 @@ class Storage extends Interceptor with MapMixin { void _clear() native; @JSName('getItem') - String _getItem(String key) native; + String? _getItem(String key) native; @JSName('key') - String _key(int index) native; + String? _key(int index) native; @JSName('removeItem') void _removeItem(String key) native; @@ -28958,18 +29003,18 @@ class StorageEvent extends Event { factory StorageEvent(String type, {bool canBubble: false, bool cancelable: false, - String key, - String oldValue, - String newValue, - String url, - Storage storageArea}) { - StorageEvent e = document._createEvent("StorageEvent"); + String? key, + String? oldValue, + String? newValue, + String? url, + Storage? storageArea}) { + StorageEvent e = document._createEvent("StorageEvent") as StorageEvent; e._initStorageEvent( type, canBubble, cancelable, key, oldValue, newValue, url, storageArea); return e; } - factory StorageEvent._(String type, [Map eventInitDict]) { + factory StorageEvent._(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return StorageEvent._create_1(type, eventInitDict_1); @@ -28981,26 +29026,26 @@ class StorageEvent extends Event { static StorageEvent _create_2(type) => JS('StorageEvent', 'new StorageEvent(#)', type); - String get key native; + String? get key native; - String get newValue native; + String? get newValue native; - String get oldValue native; + String? get oldValue native; - Storage get storageArea native; + Storage? get storageArea native; String get url native; @JSName('initStorageEvent') void _initStorageEvent( - String typeArg, - bool canBubbleArg, - bool cancelableArg, - String keyArg, - String oldValueArg, - String newValueArg, - String urlArg, - Storage storageAreaArg) native; + String? typeArg, + bool? canBubbleArg, + bool? cancelableArg, + String? keyArg, + String? oldValueArg, + String? newValueArg, + String? urlArg, + Storage? storageAreaArg) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -29013,7 +29058,7 @@ class StorageManager extends Interceptor { throw new UnsupportedError("Not supported"); } - Future> estimate() => + Future?> estimate() => promiseToFutureAsMap(JS("", "#.estimate()", this)); Future persist() => promiseToFuture(JS("", "#.persist()", this)); @@ -29047,7 +29092,7 @@ class StyleElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory StyleElement() => JS( + factory StyleElement() => JS( 'returns:StyleElement;creates:StyleElement;new:true', '#.createElement(#)', document, @@ -29067,7 +29112,7 @@ class StyleElement extends HtmlElement { set media(String value) native; - StyleSheet get sheet native; + StyleSheet? get sheet native; String get type native; @@ -29086,7 +29131,7 @@ class StyleMedia extends Interceptor { String get type native; - bool matchMedium(String mediaquery) native; + bool matchMedium(String? mediaquery) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -29116,7 +29161,7 @@ class StylePropertyMapReadonly extends Interceptor { throw new UnsupportedError("Not supported"); } - CssStyleValue get(String property) native; + CssStyleValue? get(String property) native; List getAll(String property) native; @@ -29139,15 +29184,15 @@ class StyleSheet extends Interceptor { set disabled(bool value) native; - String get href native; + String? get href native; MediaList get media native; - Node get ownerNode native; + Node? get ownerNode native; - StyleSheet get parentStyleSheet native; + StyleSheet? get parentStyleSheet native; - String get title native; + String? get title native; String get type native; } @@ -29201,7 +29246,7 @@ class TableCaptionElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory TableCaptionElement() => JS( + factory TableCaptionElement() => JS( 'returns:TableCaptionElement;creates:TableCaptionElement;new:true', '#.createElement(#)', document, @@ -29225,7 +29270,7 @@ class TableCellElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory TableCellElement() => JS( + factory TableCellElement() => JS( 'returns:TableCellElement;creates:TableCellElement;new:true', '#.createElement(#)', document, @@ -29245,7 +29290,7 @@ class TableCellElement extends HtmlElement { String get headers native; - set headers(String value) native; + set headers(String? value) native; int get rowSpan native; @@ -29262,7 +29307,7 @@ class TableColElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory TableColElement() => JS( + factory TableColElement() => JS( 'returns:TableColElement;creates:TableColElement;new:true', '#.createElement(#)', document, @@ -29305,14 +29350,14 @@ class TableElement extends HtmlElement { } var tbody = new Element.tag('tbody'); this.children.add(tbody); - return tbody; + return tbody as TableSectionElement; } @JSName('createTBody') TableSectionElement _nativeCreateTBody() native; - DocumentFragment createFragment(String html, - {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) { + DocumentFragment createFragment(String? html, + {NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) { if (Range.supportsCreateContextualFragment) { return super.createFragment(html, validator: validator, treeSanitizer: treeSanitizer); @@ -29332,7 +29377,7 @@ class TableElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory TableElement() => JS( + factory TableElement() => JS( 'returns:TableElement;creates:TableElement;new:true', '#.createElement(#)', document, @@ -29344,27 +29389,27 @@ class TableElement extends HtmlElement { */ TableElement.created() : super.created(); - TableCaptionElement get caption native; + TableCaptionElement? get caption native; - set caption(TableCaptionElement value) native; + set caption(TableCaptionElement? value) native; @JSName('rows') - @Returns('HtmlCollection|Null') + @Returns('HtmlCollection') @Creates('HtmlCollection') List get _rows native; @JSName('tBodies') - @Returns('HtmlCollection|Null') + @Returns('HtmlCollection') @Creates('HtmlCollection') List get _tBodies native; - TableSectionElement get tFoot native; + TableSectionElement? get tFoot native; - set tFoot(TableSectionElement value) native; + set tFoot(TableSectionElement? value) native; - TableSectionElement get tHead native; + TableSectionElement? get tHead native; - set tHead(TableSectionElement value) native; + set tHead(TableSectionElement? value) native; @JSName('createCaption') TableCaptionElement _createCaption() native; @@ -29384,7 +29429,7 @@ class TableElement extends HtmlElement { void deleteTHead() native; @JSName('insertRow') - TableRowElement _insertRow([int index]) native; + TableRowElement _insertRow([int? index]) native; } // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -29399,10 +29444,11 @@ class TableRowElement extends HtmlElement { return insertCell(-1); } - TableCellElement insertCell(int index) => _insertCell(index); + TableCellElement insertCell(int index) => + _insertCell(index) as TableCellElement; - DocumentFragment createFragment(String html, - {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) { + DocumentFragment createFragment(String? html, + {NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) { if (Range.supportsCreateContextualFragment) { return super.createFragment(html, validator: validator, treeSanitizer: treeSanitizer); @@ -29424,7 +29470,7 @@ class TableRowElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory TableRowElement() => JS( + factory TableRowElement() => JS( 'returns:TableRowElement;creates:TableRowElement;new:true', '#.createElement(#)', document, @@ -29437,7 +29483,7 @@ class TableRowElement extends HtmlElement { TableRowElement.created() : super.created(); @JSName('cells') - @Returns('HtmlCollection|Null') + @Returns('HtmlCollection') @Creates('HtmlCollection') List get _cells native; @@ -29448,7 +29494,7 @@ class TableRowElement extends HtmlElement { void deleteCell(int index) native; @JSName('insertCell') - HtmlElement _insertCell([int index]) native; + HtmlElement _insertCell([int? index]) native; } // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -29462,10 +29508,10 @@ class TableSectionElement extends HtmlElement { return insertRow(-1); } - TableRowElement insertRow(int index) => _insertRow(index); + TableRowElement insertRow(int index) => _insertRow(index) as TableRowElement; - DocumentFragment createFragment(String html, - {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) { + DocumentFragment createFragment(String? html, + {NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) { if (Range.supportsCreateContextualFragment) { return super.createFragment(html, validator: validator, treeSanitizer: treeSanitizer); @@ -29493,14 +29539,14 @@ class TableSectionElement extends HtmlElement { TableSectionElement.created() : super.created(); @JSName('rows') - @Returns('HtmlCollection|Null') + @Returns('HtmlCollection') @Creates('HtmlCollection') List get _rows native; void deleteRow(int index) native; @JSName('insertRow') - HtmlElement _insertRow([int index]) native; + HtmlElement _insertRow([int? index]) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -29538,7 +29584,8 @@ class TemplateElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory TemplateElement() => document.createElement("template"); + factory TemplateElement() => + document.createElement("template") as TemplateElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -29558,8 +29605,8 @@ class TemplateElement extends HtmlElement { * * * */ - void setInnerHtml(String html, - {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) { + void setInnerHtml(String? html, + {NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) { text = null; content.nodes.clear(); var fragment = createFragment(html, @@ -29586,11 +29633,11 @@ class Text extends CharacterData { throw new UnsupportedError("Not supported"); } - SlotElement get assignedSlot native; + SlotElement? get assignedSlot native; String get wholeText native; - @Returns('NodeList|Null') + @Returns('NodeList') @Creates('NodeList') List getDestinationInsertionPoints() native; @@ -29607,7 +29654,7 @@ class TextAreaElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory TextAreaElement() => JS( + factory TextAreaElement() => JS( 'returns:TextAreaElement;creates:TextAreaElement;new:true', '#.createElement(#)', document, @@ -29643,10 +29690,10 @@ class TextAreaElement extends HtmlElement { set disabled(bool value) native; - FormElement get form native; + FormElement? get form native; @Unstable() - @Returns('NodeList|Null') + @Returns('NodeList') @Creates('NodeList') List get labels native; @@ -29700,7 +29747,7 @@ class TextAreaElement extends HtmlElement { String get value native; - set value(String value) native; + set value(String? value) native; bool get willValidate native; @@ -29717,9 +29764,9 @@ class TextAreaElement extends HtmlElement { void setCustomValidity(String error) native; void setRangeText(String replacement, - {int start, int end, String selectionMode}) native; + {int? start, int? end, String? selectionMode}) native; - void setSelectionRange(int start, int end, [String direction]) native; + void setSelectionRange(int start, int end, [String? direction]) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -29752,12 +29799,12 @@ class TextEvent extends UIEvent { factory TextEvent(String type, {bool canBubble: false, bool cancelable: false, - Window view, - String data}) { + Window? view, + String? data}) { if (view == null) { view = window; } - TextEvent e = document._createEvent("TextEvent"); + TextEvent e = document._createEvent("TextEvent") as TextEvent; e._initTextEvent(type, canBubble, cancelable, view, data); return e; } @@ -29769,8 +29816,8 @@ class TextEvent extends UIEvent { String get data native; @JSName('initTextEvent') - void _initTextEvent(String type, bool bubbles, bool cancelable, Window view, - String data) native; + void _initTextEvent(String? type, bool? bubbles, bool? cancelable, + Window? view, String? data) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -29827,9 +29874,9 @@ class TextTrack extends EventTarget { static const EventStreamProvider cueChangeEvent = const EventStreamProvider('cuechange'); - TextTrackCueList get activeCues native; + TextTrackCueList? get activeCues native; - TextTrackCueList get cues native; + TextTrackCueList? get cues native; String get id native; @@ -29895,7 +29942,7 @@ class TextTrackCue extends EventTarget { set startTime(num value) native; - TextTrack get track native; + TextTrack? get track native; /// Stream of `enter` events handled by this [TextTrackCue]. Stream get onEnter => enterEvent.forTarget(this); @@ -29963,7 +30010,7 @@ class TextTrackCueList extends Interceptor TextTrackCue __getter__(int index) native; - TextTrackCue getCueById(String id) native; + TextTrackCue? getCueById(String id) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -30037,7 +30084,7 @@ class TextTrackList extends EventTarget TextTrack __getter__(int index) native; - TextTrack getTrackById(String id) native; + TextTrack? getTrackById(String id) native; /// Stream of `addtrack` events handled by this [TextTrackList]. Stream get onAddTrack => addTrackEvent.forTarget(this); @@ -30101,7 +30148,7 @@ class TitleElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory TitleElement() => JS( + factory TitleElement() => JS( 'returns:TitleElement;creates:TitleElement;new:true', '#.createElement(#)', document, @@ -30152,7 +30199,7 @@ class Touch extends Interceptor { @JSName('radiusY') num get _radiusY native; - String get region native; + String? get region native; num get rotationAngle native; @@ -30162,7 +30209,7 @@ class Touch extends Interceptor { @JSName('screenY') num get _screenY native; - EventTarget get target => _convertNativeToDart_EventTarget(this._get_target); + EventTarget? get target => _convertNativeToDart_EventTarget(this._get_target); @JSName('target') @Creates('Element|Document') @Returns('Element|Document') @@ -30206,7 +30253,7 @@ class TouchEvent extends UIEvent { throw new UnsupportedError("Not supported"); } - factory TouchEvent(String type, [Map eventInitDict]) { + factory TouchEvent(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return TouchEvent._create_1(type, eventInitDict_1); @@ -30304,7 +30351,7 @@ class TouchList extends Interceptor Touch elementAt(int index) => this[index]; // -- end List mixins. - Touch item(int index) native; + Touch? item(int index) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -30319,7 +30366,7 @@ class TrackDefault extends Interceptor { factory TrackDefault( String type, String language, String label, List kinds, - [String byteStreamTrackID]) { + [String? byteStreamTrackID]) { if (byteStreamTrackID != null) { List kinds_1 = convertDartToNative_StringArray(kinds); return TrackDefault._create_1( @@ -30361,7 +30408,7 @@ class TrackDefaultList extends Interceptor { throw new UnsupportedError("Not supported"); } - factory TrackDefaultList([List trackDefaults]) { + factory TrackDefaultList([List? trackDefaults]) { if (trackDefaults != null) { return TrackDefaultList._create_1(trackDefaults); } @@ -30390,7 +30437,7 @@ class TrackElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory TrackElement() => document.createElement("track"); + factory TrackElement() => document.createElement("track") as TrackElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -30447,7 +30494,7 @@ class TrackEvent extends Event { throw new UnsupportedError("Not supported"); } - factory TrackEvent(String type, [Map eventInitDict]) { + factory TrackEvent(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return TrackEvent._create_1(type, eventInitDict_1); @@ -30460,7 +30507,7 @@ class TrackEvent extends Event { JS('TrackEvent', 'new TrackEvent(#)', type); @Creates('Null') - Object get track native; + Object? get track native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -30473,7 +30520,7 @@ class TransitionEvent extends Event { throw new UnsupportedError("Not supported"); } - factory TransitionEvent(String type, [Map eventInitDict]) { + factory TransitionEvent(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return TransitionEvent._create_1(type, eventInitDict_1); @@ -30510,25 +30557,25 @@ class TreeWalker extends Interceptor { set currentNode(Node value) native; - NodeFilter get filter native; + NodeFilter? get filter native; Node get root native; int get whatToShow native; - Node firstChild() native; + Node? firstChild() native; - Node lastChild() native; + Node? lastChild() native; - Node nextNode() native; + Node? nextNode() native; - Node nextSibling() native; + Node? nextSibling() native; - Node parentNode() native; + Node? parentNode() native; - Node previousNode() native; + Node? previousNode() native; - Node previousSibling() native; + Node? previousSibling() native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -30588,19 +30635,19 @@ class UIEvent extends Event { // Contrary to JS, we default canBubble and cancelable to true, since that's // what people want most of the time anyway. factory UIEvent(String type, - {Window view, + {Window? view, int detail: 0, bool canBubble: true, bool cancelable: true}) { if (view == null) { view = window; } - UIEvent e = document._createEvent("UIEvent"); + UIEvent e = document._createEvent("UIEvent") as UIEvent; e._initUIEvent(type, canBubble, cancelable, view, detail); return e; } - factory UIEvent._(String type, [Map eventInitDict]) { + factory UIEvent._(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return UIEvent._create_1(type, eventInitDict_1); @@ -30613,9 +30660,9 @@ class UIEvent extends Event { int get detail native; - InputDeviceCapabilities get sourceCapabilities native; + InputDeviceCapabilities? get sourceCapabilities native; - WindowBase get view => _convertNativeToDart_Window(this._get_view); + WindowBase? get view => _convertNativeToDart_Window(this._get_view); @JSName('view') @Creates('Window|=Object') @Returns('Window|=Object') @@ -30626,7 +30673,7 @@ class UIEvent extends Event { int get _which native; @JSName('initUIEvent') - void _initUIEvent(String type, bool bubbles, bool cancelable, Window view, + void _initUIEvent(String type, bool bubbles, bool cancelable, Window? view, int detail) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file @@ -30640,7 +30687,7 @@ class UListElement extends HtmlElement { throw new UnsupportedError("Not supported"); } - factory UListElement() => JS( + factory UListElement() => JS( 'returns:UListElement;creates:UListElement;new:true', '#.createElement(#)', document, @@ -30663,7 +30710,7 @@ class UnderlyingSourceBase extends Interceptor { throw new UnsupportedError("Not supported"); } - Future cancel(Object reason) => + Future cancel(Object? reason) => promiseToFuture(JS("", "#.cancel(#)", this, reason)); void notifyLockAcquired() native; @@ -30777,7 +30824,7 @@ class UrlSearchParams extends Interceptor { throw new UnsupportedError("Not supported"); } - factory UrlSearchParams([Object init]) { + factory UrlSearchParams([Object? init]) { if (init != null) { return UrlSearchParams._create_1(init); } @@ -30792,7 +30839,7 @@ class UrlSearchParams extends Interceptor { void delete(String name) native; - String get(String name) native; + String? get(String name) native; List getAll(String name) native; @@ -30854,7 +30901,7 @@ class VRCoordinateSystem extends Interceptor { throw new UnsupportedError("Not supported"); } - Float32List getTransformTo(VRCoordinateSystem other) native; + Float32List? getTransformTo(VRCoordinateSystem other) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -30871,7 +30918,7 @@ class VRDevice extends EventTarget { bool get isExternal native; - Future requestSession([Map options]) { + Future requestSession([Map? options]) { var options_dict = null; if (options != null) { options_dict = convertDartToNative_Dictionary(options); @@ -30879,7 +30926,7 @@ class VRDevice extends EventTarget { return promiseToFuture(JS("", "#.requestSession(#)", this, options_dict)); } - Future supportsSession([Map options]) { + Future supportsSession([Map? options]) { var options_dict = null; if (options != null) { options_dict = convertDartToNative_Dictionary(options); @@ -30983,7 +31030,7 @@ class VRDisplayEvent extends Event { throw new UnsupportedError("Not supported"); } - factory VRDisplayEvent(String type, [Map eventInitDict]) { + factory VRDisplayEvent(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return VRDisplayEvent._create_1(type, eventInitDict_1); @@ -31053,7 +31100,7 @@ class VRFrameOfReference extends VRCoordinateSystem { throw new UnsupportedError("Not supported"); } - VRStageBounds get bounds native; + VRStageBounds? get bounds native; num get emulatedHeight native; } @@ -31068,17 +31115,17 @@ class VRPose extends Interceptor { throw new UnsupportedError("Not supported"); } - Float32List get angularAcceleration native; + Float32List? get angularAcceleration native; - Float32List get angularVelocity native; + Float32List? get angularVelocity native; - Float32List get linearAcceleration native; + Float32List? get linearAcceleration native; - Float32List get linearVelocity native; + Float32List? get linearVelocity native; - Float32List get orientation native; + Float32List? get orientation native; - Float32List get position native; + Float32List? get position native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -31111,7 +31158,7 @@ class VRSession extends EventTarget { Future end() => promiseToFuture(JS("", "#.end()", this)); - Future requestFrameOfReference(String type, [Map options]) { + Future requestFrameOfReference(String type, [Map? options]) { var options_dict = null; if (options != null) { options_dict = convertDartToNative_Dictionary(options); @@ -31233,7 +31280,7 @@ class VideoElement extends MediaElement implements CanvasImageSource { throw new UnsupportedError("Not supported"); } - factory VideoElement() => JS( + factory VideoElement() => JS( 'returns:VideoElement;creates:VideoElement;new:true', '#.createElement(#)', document, @@ -31325,7 +31372,7 @@ class VideoTrack extends Interceptor { set selected(bool value) native; - SourceBuffer get sourceBuffer native; + SourceBuffer? get sourceBuffer native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -31347,7 +31394,7 @@ class VideoTrackList extends EventTarget { VideoTrack __getter__(int index) native; - VideoTrack getTrackById(String id) native; + VideoTrack? getTrackById(String id) native; Stream get onChange => changeEvent.forTarget(this); } @@ -31416,19 +31463,19 @@ class VttCue extends TextTrackCue { @Creates('Null') @Returns('num|String') - Object get line native; + Object? get line native; - set line(Object value) native; + set line(Object? value) native; @Creates('Null') @Returns('num|String') - Object get position native; + Object? get position native; - set position(Object value) native; + set position(Object? value) native; - VttRegion get region native; + VttRegion? get region native; - set region(VttRegion value) native; + set region(VttRegion? value) native; num get size native; @@ -31583,7 +31630,7 @@ class WebSocket extends EventTarget { static const EventStreamProvider openEvent = const EventStreamProvider('open'); - factory WebSocket(String url, [Object protocols]) { + factory WebSocket(String url, [Object? protocols]) { if (protocols != null) { return WebSocket._create_1(url, protocols); } @@ -31619,7 +31666,7 @@ class WebSocket extends EventTarget { String get url native; - void close([int code, String reason]) native; + void close([int? code, String? reason]) native; /** * Transmit data to the server over this connection. @@ -31689,7 +31736,7 @@ class WebSocket extends EventTarget { @Native("WheelEvent") class WheelEvent extends MouseEvent { factory WheelEvent(String type, - {Window view, + {Window? view, num deltaX: 0, num deltaY: 0, num deltaZ: 0, @@ -31706,7 +31753,7 @@ class WheelEvent extends MouseEvent { bool altKey: false, bool shiftKey: false, bool metaKey: false, - EventTarget relatedTarget}) { + EventTarget? relatedTarget}) { var options = { 'view': view, 'deltaMode': deltaMode, @@ -31736,7 +31783,7 @@ class WheelEvent extends MouseEvent { convertDartToNative_Dictionary(options)); } - factory WheelEvent._(String type, [Map eventInitDict]) { + factory WheelEvent._(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return WheelEvent._create_1(type, eventInitDict_1); @@ -31927,10 +31974,10 @@ class Window extends EventTarget */ Document get document => JS('Document', '#.document', this); - WindowBase _open2(url, name) => + WindowBase? _open2(url, name) => JS('Window|Null', '#.open(#,#)', this, url, name); - WindowBase _open3(url, name, options) => + WindowBase? _open3(url, name, options) => JS('Window|Null', '#.open(#,#,#)', this, url, name, options); /** @@ -31941,7 +31988,7 @@ class Window extends EventTarget * * [Window.open](https://developer.mozilla.org/en-US/docs/Web/API/Window.open) * from MDN. */ - WindowBase open(String url, String name, [String options]) { + WindowBase open(String url, String name, [String? options]) { if (options == null) { return _DOMWindowCrossFrame._createSafe(_open2(url, name)); } else { @@ -31992,7 +32039,7 @@ class Window extends EventTarget */ int requestAnimationFrame(FrameRequestCallback callback) { _ensureRequestAnimationFrame(); - return _requestAnimationFrame(_wrapZone(callback)); + return _requestAnimationFrame(_wrapZone(callback)!); } /** @@ -32052,7 +32099,7 @@ class Window extends EventTarget @SupportedBrowser(SupportedBrowser.CHROME, '23.0') @SupportedBrowser(SupportedBrowser.FIREFOX, '15.0') @SupportedBrowser(SupportedBrowser.IE, '10.0') - IdbFactory get indexedDB => JS( + IdbFactory? get indexedDB => JS( 'IdbFactory|Null', // If not supported, returns null. '#.indexedDB || #.webkitIndexedDB || #.mozIndexedDB', this, @@ -32433,13 +32480,13 @@ class Window extends EventTarget bool get offscreenBuffering native; - WindowBase get opener => _convertNativeToDart_Window(this._get_opener); + WindowBase? get opener => _convertNativeToDart_Window(this._get_opener); @JSName('opener') @Creates('Window|=Object') @Returns('Window|=Object') dynamic get _get_opener native; - set opener(WindowBase value) native; + set opener(WindowBase? value) native; int get orientation native; @@ -32503,7 +32550,7 @@ class Window extends EventTarget num get _pageYOffset native; - WindowBase get parent => _convertNativeToDart_Window(this._get_parent); + WindowBase? get parent => _convertNativeToDart_Window(this._get_parent); @JSName('parent') @Creates('Window|=Object') @Returns('Window|=Object') @@ -32601,7 +32648,7 @@ class Window extends EventTarget * * [Window.self](https://developer.mozilla.org/en-US/docs/Web/API/Window.self) * from MDN. */ - WindowBase get self => _convertNativeToDart_Window(this._get_self); + WindowBase? get self => _convertNativeToDart_Window(this._get_self); @JSName('self') /** * The current window. @@ -32685,13 +32732,13 @@ class Window extends EventTarget BarProp get toolbar native; - WindowBase get top => _convertNativeToDart_Window(this._get_top); + WindowBase? get top => _convertNativeToDart_Window(this._get_top); @JSName('top') @Creates('Window|=Object') @Returns('Window|=Object') dynamic get _get_top native; - VisualViewport get visualViewport native; + VisualViewport? get visualViewport native; /** * The current window. @@ -32701,7 +32748,7 @@ class Window extends EventTarget * * [Window.window](https://developer.mozilla.org/en-US/docs/Web/API/Window.window) * from MDN. */ - WindowBase get window => _convertNativeToDart_Window(this._get_window); + WindowBase? get window => _convertNativeToDart_Window(this._get_window); @JSName('window') /** * The current window. @@ -32719,10 +32766,10 @@ class Window extends EventTarget @Returns('Window|=Object') WindowBase __getter__(index_OR_name) { if ((index_OR_name is int)) { - return _convertNativeToDart_Window(__getter___1(index_OR_name)); + return _convertNativeToDart_Window(__getter___1(index_OR_name))!; } if ((index_OR_name is String)) { - return _convertNativeToDart_Window(__getter___2(index_OR_name)); + return _convertNativeToDart_Window(__getter___2(index_OR_name))!; } throw new ArgumentError("Incorrect number or type of arguments"); } @@ -32744,7 +32791,7 @@ class Window extends EventTarget * * [User prompts](https://html.spec.whatwg.org/multipage/webappapis.html#user-prompts) * from WHATWG. */ - void alert([String message]) native; + void alert([String? message]) native; void cancelIdleCallback(int handle) native; @@ -32758,9 +32805,9 @@ class Window extends EventTarget * * [User prompts](https://html.spec.whatwg.org/multipage/webappapis.html#user-prompts) * from WHATWG. */ - bool confirm([String message]) native; + bool confirm([String? message]) native; - Future fetch(/*RequestInfo*/ input, [Map init]) { + Future fetch(/*RequestInfo*/ input, [Map? init]) { var init_dict = null; if (init != null) { init_dict = convertDartToNative_Dictionary(init); @@ -32776,22 +32823,23 @@ class Window extends EventTarget * * [Window.find](https://developer.mozilla.org/en-US/docs/Web/API/Window.find) * from MDN. */ - bool find(String string, bool caseSensitive, bool backwards, bool wrap, - bool wholeWord, bool searchInFrames, bool showDialog) native; + bool find(String? string, bool? caseSensitive, bool? backwards, bool? wrap, + bool? wholeWord, bool? searchInFrames, bool? showDialog) native; @JSName('getComputedStyle') - CssStyleDeclaration _getComputedStyle(Element elt, [String pseudoElt]) native; + CssStyleDeclaration _getComputedStyle(Element elt, [String? pseudoElt]) + native; StylePropertyMapReadonly getComputedStyleMap( - Element element, String pseudoElement) native; + Element element, String? pseudoElement) native; @JSName('getMatchedCSSRules') /** * Returns all CSS rules that apply to the element's pseudo-element. */ - @Returns('_CssRuleList|Null') + @Returns('_CssRuleList') @Creates('_CssRuleList') - List getMatchedCssRules(Element element, String pseudoElement) + List getMatchedCssRules(Element? element, String? pseudoElement) native; /** @@ -32802,7 +32850,7 @@ class Window extends EventTarget * * [Window.getSelection](https://developer.mozilla.org/en-US/docs/Web/API/Window.getSelection) * from MDN. */ - Selection getSelection() native; + Selection? getSelection() native; /** * Returns a list of media queries for the given query string. @@ -32841,10 +32889,10 @@ class Window extends EventTarget @Creates('SqlDatabase') SqlDatabase _openDatabase( String name, String version, String displayName, int estimatedSize, - [DatabaseCallback creationCallback]) native; + [DatabaseCallback? creationCallback]) native; void postMessage(/*any*/ message, String targetOrigin, - [List transfer]) { + [List? transfer]) { if (transfer != null) { var message_1 = convertDartToNative_SerializedScriptValue(message); _postMessage_1(message_1, targetOrigin, transfer); @@ -32870,7 +32918,7 @@ class Window extends EventTarget */ void print() native; - int requestIdleCallback(IdleRequestCallback callback, [Map options]) { + int requestIdleCallback(IdleRequestCallback callback, [Map? options]) { if (options != null) { var callback_1 = convertDartClosureToJS(callback, 1); var options_2 = convertDartToNative_Dictionary(options); @@ -32915,7 +32963,7 @@ class Window extends EventTarget * * [Window.scroll](https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll) * from MDN. */ - void scroll([options_OR_x, y, Map scrollOptions]) { + void scroll([options_OR_x, y, Map? scrollOptions]) { if (options_OR_x == null && y == null && scrollOptions == null) { _scroll_1(); return; @@ -32976,7 +33024,7 @@ class Window extends EventTarget * * [Window.scroll](https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll) * from MDN. */ - void _scroll_3(num x, num y) native; + void _scroll_3(num? x, num? y) native; @JSName('scroll') /** * Scrolls the page horizontally and vertically to a specific point. @@ -32988,7 +33036,7 @@ class Window extends EventTarget * * [Window.scroll](https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll) * from MDN. */ - void _scroll_4(int x, int y) native; + void _scroll_4(int? x, int? y) native; @JSName('scroll') /** * Scrolls the page horizontally and vertically to a specific point. @@ -33000,7 +33048,7 @@ class Window extends EventTarget * * [Window.scroll](https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll) * from MDN. */ - void _scroll_5(int x, int y, scrollOptions) native; + void _scroll_5(int? x, int? y, scrollOptions) native; /** * Scrolls the page horizontally and vertically by an offset. @@ -33010,7 +33058,7 @@ class Window extends EventTarget * * [Window.scrollBy](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy) * from MDN. */ - void scrollBy([options_OR_x, y, Map scrollOptions]) { + void scrollBy([options_OR_x, y, Map? scrollOptions]) { if (options_OR_x == null && y == null && scrollOptions == null) { _scrollBy_1(); return; @@ -33065,7 +33113,7 @@ class Window extends EventTarget * * [Window.scrollBy](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy) * from MDN. */ - void _scrollBy_3(num x, num y) native; + void _scrollBy_3(num? x, num? y) native; @JSName('scrollBy') /** * Scrolls the page horizontally and vertically by an offset. @@ -33075,7 +33123,7 @@ class Window extends EventTarget * * [Window.scrollBy](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy) * from MDN. */ - void _scrollBy_4(int x, int y) native; + void _scrollBy_4(int? x, int? y) native; @JSName('scrollBy') /** * Scrolls the page horizontally and vertically by an offset. @@ -33085,7 +33133,7 @@ class Window extends EventTarget * * [Window.scrollBy](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy) * from MDN. */ - void _scrollBy_5(int x, int y, scrollOptions) native; + void _scrollBy_5(int? x, int? y, scrollOptions) native; /** * Scrolls the page horizontally and vertically to a specific point. @@ -33097,7 +33145,7 @@ class Window extends EventTarget * * [Window.scrollTo](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo) * from MDN. */ - void scrollTo([options_OR_x, y, Map scrollOptions]) { + void scrollTo([options_OR_x, y, Map? scrollOptions]) { if (options_OR_x == null && y == null && scrollOptions == null) { _scrollTo_1(); return; @@ -33158,7 +33206,7 @@ class Window extends EventTarget * * [Window.scrollTo](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo) * from MDN. */ - void _scrollTo_3(num x, num y) native; + void _scrollTo_3(num? x, num? y) native; @JSName('scrollTo') /** * Scrolls the page horizontally and vertically to a specific point. @@ -33170,7 +33218,7 @@ class Window extends EventTarget * * [Window.scrollTo](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo) * from MDN. */ - void _scrollTo_4(int x, int y) native; + void _scrollTo_4(int? x, int? y) native; @JSName('scrollTo') /** * Scrolls the page horizontally and vertically to a specific point. @@ -33182,7 +33230,7 @@ class Window extends EventTarget * * [Window.scrollTo](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo) * from MDN. */ - void _scrollTo_5(int x, int y, scrollOptions) native; + void _scrollTo_5(int? x, int? y, scrollOptions) native; /** * Stops the window from loading. @@ -33199,7 +33247,7 @@ class Window extends EventTarget @SupportedBrowser(SupportedBrowser.CHROME) void __requestFileSystem( int type, int size, _FileSystemCallback successCallback, - [_ErrorCallback errorCallback]) native; + [_ErrorCallback? errorCallback]) native; @JSName('webkitRequestFileSystem') @SupportedBrowser(SupportedBrowser.CHROME) @@ -33227,7 +33275,7 @@ class Window extends EventTarget */ @SupportedBrowser(SupportedBrowser.CHROME) void _resolveLocalFileSystemUrl(String url, _EntryCallback successCallback, - [_ErrorCallback errorCallback]) native; + [_ErrorCallback? errorCallback]) native; @JSName('webkitResolveLocalFileSystemURL') /** @@ -33259,24 +33307,24 @@ class Window extends EventTarget // From WindowTimers @JSName('setInterval') - int _setInterval_String(String handler, [int timeout, Object arguments]) + int _setInterval_String(String handler, [int? timeout, Object? arguments]) native; @JSName('setTimeout') - int _setTimeout_String(String handler, [int timeout, Object arguments]) + int _setTimeout_String(String handler, [int? timeout, Object? arguments]) native; @JSName('clearInterval') - void _clearInterval([int handle]) native; + void _clearInterval([int? handle]) native; @JSName('clearTimeout') - void _clearTimeout([int handle]) native; + void _clearTimeout([int? handle]) native; @JSName('setInterval') - int _setInterval(Object handler, [int timeout]) native; + int _setInterval(Object handler, [int? timeout]) native; @JSName('setTimeout') - int _setTimeout(Object handler, [int timeout]) native; + int _setTimeout(Object handler, [int? timeout]) native; /// Stream of `contentloaded` events handled by this [Window]. Stream get onContentLoaded => contentLoadedEvent.forTarget(this); @@ -33536,7 +33584,7 @@ class Window extends EventTarget @Creates('SqlDatabase') SqlDatabase openDatabase( String name, String version, String displayName, int estimatedSize, - [DatabaseCallback creationCallback]) { + [DatabaseCallback? creationCallback]) { var db; if (creationCallback == null) db = _openDatabase(name, version, displayName, estimatedSize); @@ -33565,7 +33613,7 @@ class Window extends EventTarget */ int get scrollX => JS('bool', '("scrollX" in #)', this) ? JS('num', '#.scrollX', this).round() - : document.documentElement.scrollLeft; + : document.documentElement!.scrollLeft; /** * The distance this window has been scrolled vertically. @@ -33579,13 +33627,15 @@ class Window extends EventTarget */ int get scrollY => JS('bool', '("scrollY" in #)', this) ? JS('num', '#.scrollY', this).round() - : document.documentElement.scrollTop; + : document.documentElement!.scrollTop; } class _BeforeUnloadEvent extends _WrappedEvent implements BeforeUnloadEvent { String _returnValue; - _BeforeUnloadEvent(Event base) : super(base); + _BeforeUnloadEvent(Event base) + : _returnValue = '', + super(base); String get returnValue => _returnValue; @@ -33605,7 +33655,8 @@ class _BeforeUnloadEventStreamProvider const _BeforeUnloadEventStreamProvider(this._eventType); - Stream forTarget(EventTarget e, {bool useCapture: false}) { + Stream forTarget(EventTarget? e, + {bool useCapture: false}) { // Specify the generic type for EventStream only in dart2js. var stream = new _EventStream(e, _eventType, useCapture); var controller = new StreamController(sync: true); @@ -33759,7 +33810,7 @@ class Worker extends EventTarget implements AbstractWorker { static bool get supported => JS('bool', '(typeof window.Worker != "undefined")'); - void postMessage(/*any*/ message, [List transfer]) { + void postMessage(/*any*/ message, [List? transfer]) { if (transfer != null) { var message_1 = convertDartToNative_SerializedScriptValue(message); _postMessage_1(message_1, transfer); @@ -33771,7 +33822,7 @@ class Worker extends EventTarget implements AbstractWorker { } @JSName('postMessage') - void _postMessage_1(message, List transfer) native; + void _postMessage_1(message, List? transfer) native; @JSName('postMessage') void _postMessage_2(message) native; @@ -33824,7 +33875,7 @@ class WorkerGlobalScope extends EventTarget WorkerGlobalScope get self native; - Future fetch(/*RequestInfo*/ input, [Map init]) { + Future fetch(/*RequestInfo*/ input, [Map? init]) { var init_dict = null; if (init != null) { init_dict = convertDartToNative_Dictionary(init); @@ -33843,24 +33894,24 @@ class WorkerGlobalScope extends EventTarget // From WindowTimers @JSName('setInterval') - int _setInterval_String(String handler, [int timeout, Object arguments]) + int _setInterval_String(String handler, [int? timeout, Object? arguments]) native; @JSName('setTimeout') - int _setTimeout_String(String handler, [int timeout, Object arguments]) + int _setTimeout_String(String handler, [int? timeout, Object? arguments]) native; @JSName('clearInterval') - void _clearInterval([int handle]) native; + void _clearInterval([int? handle]) native; @JSName('clearTimeout') - void _clearTimeout([int handle]) native; + void _clearTimeout([int? handle]) native; @JSName('setInterval') - int _setInterval(Object handler, [int timeout]) native; + int _setInterval(Object handler, [int? timeout]) native; @JSName('setTimeout') - int _setTimeout(Object handler, [int timeout]) native; + int _setTimeout(Object handler, [int? timeout]) native; /// Stream of `error` events handled by this [WorkerGlobalScope]. Stream get onError => errorEvent.forTarget(this); @@ -33883,21 +33934,22 @@ class WorkerPerformance extends EventTarget { num get timeOrigin native; - void clearMarks(String markName) native; + void clearMarks(String? markName) native; - void clearMeasures(String measureName) native; + void clearMeasures(String? measureName) native; void clearResourceTimings() native; List getEntries() native; - List getEntriesByName(String name, String entryType) native; + List getEntriesByName(String name, String? entryType) + native; List getEntriesByType(String entryType) native; void mark(String markName) native; - void measure(String measureName, String startMark, String endMark) native; + void measure(String measureName, String? startMark, String? endMark) native; double now() native; @@ -33964,14 +34016,14 @@ class XPathEvaluator extends Interceptor { static XPathEvaluator _create_1() => JS('XPathEvaluator', 'new XPathEvaluator()'); - XPathExpression createExpression(String expression, XPathNSResolver resolver) + XPathExpression createExpression(String expression, XPathNSResolver? resolver) native; XPathNSResolver createNSResolver(Node nodeResolver) native; XPathResult evaluate( - String expression, Node contextNode, XPathNSResolver resolver, - [int type, Object inResult]) native; + String expression, Node contextNode, XPathNSResolver? resolver, + [int? type, Object? inResult]) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -33986,7 +34038,7 @@ class XPathExpression extends Interceptor { throw new UnsupportedError("Not supported"); } - XPathResult evaluate(Node contextNode, [int type, Object inResult]) native; + XPathResult evaluate(Node contextNode, [int? type, Object? inResult]) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -34002,7 +34054,7 @@ class XPathNSResolver extends Interceptor { } @JSName('lookupNamespaceURI') - String lookupNamespaceUri(String prefix) native; + String? lookupNamespaceUri(String? prefix) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -34051,9 +34103,9 @@ class XPathResult extends Interceptor { String get stringValue native; - Node iterateNext() native; + Node? iterateNext() native; - Node snapshotItem(int index) native; + Node? snapshotItem(int index) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -34113,19 +34165,20 @@ class XsltProcessor extends Interceptor { void clearParameters() native; - String getParameter(String namespaceURI, String localName) native; + String? getParameter(String? namespaceURI, String localName) native; void importStylesheet(Node style) native; - void removeParameter(String namespaceURI, String localName) native; + void removeParameter(String? namespaceURI, String localName) native; void reset() native; - void setParameter(String namespaceURI, String localName, String value) native; + void setParameter(String? namespaceURI, String localName, String value) + native; - Document transformToDocument(Node source) native; + Document? transformToDocument(Node source) native; - DocumentFragment transformToFragment(Node source, Document output) native; + DocumentFragment? transformToFragment(Node source, Document output) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -34144,7 +34197,7 @@ class _Attr extends Node { String get name native; @JSName('namespaceURI') - String get _namespaceUri native; + String? get _namespaceUri native; String get value native; @@ -34349,7 +34402,7 @@ class _CssRuleList extends Interceptor CssRule elementAt(int index) => this[index]; // -- end List mixins. - CssRule item(int index) native; + CssRule? item(int index) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -34432,7 +34485,7 @@ class _DomRect extends DomRectReadOnly implements Rectangle { * Returns the intersection of this and `other`, or null if they don't * intersect. */ - Rectangle intersection(Rectangle other) { + Rectangle? intersection(Rectangle other) { var x0 = max(left, other.left); var x1 = min(left + width, other.left + other.width); @@ -34501,7 +34554,7 @@ class _DomRect extends DomRectReadOnly implements Rectangle { throw new UnsupportedError("Not supported"); } - factory _DomRect([num x, num y, num width, num height]) { + factory _DomRect([num? x, num? y, num? width, num? height]) { if (height != null) { return _DomRect._create_1(x, y, width, height); } @@ -34641,8 +34694,8 @@ abstract class _FileWriterSync extends Interceptor { @Native("GamepadList") class _GamepadList extends Interceptor - with ListMixin, ImmutableListMixin - implements List, JavaScriptIndexingBehavior { + with ListMixin, ImmutableListMixin + implements List, JavaScriptIndexingBehavior { // To suppress missing implicit constructor warnings. factory _GamepadList._() { throw new UnsupportedError("Not supported"); @@ -34650,30 +34703,30 @@ class _GamepadList extends Interceptor int get length => JS("int", "#.length", this); - Gamepad operator [](int index) { + Gamepad? operator [](int index) { if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length)) throw new RangeError.index(index, this); return JS("Gamepad|Null", "#[#]", this, index); } - void operator []=(int index, Gamepad value) { + void operator []=(int index, Gamepad? value) { throw new UnsupportedError("Cannot assign element of immutable List."); } - // -- start List mixins. - // Gamepad is the element type. + // -- start List mixins. + // Gamepad? is the element type. set length(int value) { throw new UnsupportedError("Cannot resize immutable List."); } - Gamepad get first { + Gamepad? get first { if (this.length > 0) { return JS('Gamepad|Null', '#[0]', this); } throw new StateError("No elements"); } - Gamepad get last { + Gamepad? get last { int len = this.length; if (len > 0) { return JS('Gamepad|Null', '#[#]', this, len - 1); @@ -34681,7 +34734,7 @@ class _GamepadList extends Interceptor throw new StateError("No elements"); } - Gamepad get single { + Gamepad? get single { int len = this.length; if (len == 1) { return JS('Gamepad|Null', '#[0]', this); @@ -34690,10 +34743,10 @@ class _GamepadList extends Interceptor throw new StateError("More than one element"); } - Gamepad elementAt(int index) => this[index]; - // -- end List mixins. + Gamepad? elementAt(int index) => this[index]; + // -- end List mixins. - Gamepad item(int index) native; + Gamepad item(int? index) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -34709,7 +34762,7 @@ abstract class _HTMLAllCollection extends Interceptor { } @JSName('item') - Element _item(int index) native; + Element _item(int? index) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -34841,7 +34894,7 @@ abstract class _MojoInterfaceInterceptor extends EventTarget { throw new UnsupportedError("Not supported"); } - factory _MojoInterfaceInterceptor(String interfaceName, [String scope]) { + factory _MojoInterfaceInterceptor(String interfaceName, [String? scope]) { if (scope != null) { return _MojoInterfaceInterceptor._create_1(interfaceName, scope); } @@ -34868,7 +34921,7 @@ abstract class _MojoInterfaceRequestEvent extends Event { throw new UnsupportedError("Not supported"); } - factory _MojoInterfaceRequestEvent(String type, [Map eventInitDict]) { + factory _MojoInterfaceRequestEvent(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return _MojoInterfaceRequestEvent._create_1(type, eventInitDict_1); @@ -34965,19 +35018,19 @@ class _NamedNodeMap extends Interceptor Node elementAt(int index) => this[index]; // -- end List mixins. - _Attr getNamedItem(String name) native; + _Attr? getNamedItem(String name) native; - _Attr getNamedItemNS(String namespaceURI, String localName) native; + _Attr? getNamedItemNS(String? namespaceURI, String localName) native; - _Attr item(int index) native; + _Attr? item(int index) native; _Attr removeNamedItem(String name) native; - _Attr removeNamedItemNS(String namespaceURI, String localName) native; + _Attr removeNamedItemNS(String? namespaceURI, String localName) native; - _Attr setNamedItem(_Attr attr) native; + _Attr? setNamedItem(_Attr attr) native; - _Attr setNamedItemNS(_Attr attr) native; + _Attr? setNamedItemNS(_Attr attr) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -35010,7 +35063,7 @@ class _Report extends Interceptor { throw new UnsupportedError("Not supported"); } - ReportBody get body native; + ReportBody? get body native; String get type native; @@ -35027,7 +35080,7 @@ class _Request extends Body { throw new UnsupportedError("Not supported"); } - factory _Request(Object input, [Map requestInitDict]) { + factory _Request(Object input, [Map? requestInitDict]) { if (requestInitDict != null) { var requestInitDict_1 = convertDartToNative_Dictionary(requestInitDict); return _Request._create_1(input, requestInitDict_1); @@ -35082,7 +35135,7 @@ abstract class _Response extends Body { throw new UnsupportedError("Not supported"); } - factory _Response([Object body, Map init]) { + factory _Response([Object? body, Map? init]) { if (init != null) { var init_1 = convertDartToNative_Dictionary(init); return _Response._create_1(body, init_1); @@ -35221,7 +35274,7 @@ class _StyleSheetList extends Interceptor CssStyleSheet __getter__(String name) native; - StyleSheet item(int index) native; + StyleSheet? item(int index) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -35349,7 +35402,7 @@ abstract class _USBInTransferResult extends Interceptor { throw new UnsupportedError("Not supported"); } - factory _USBInTransferResult(String status, [ByteData data]) { + factory _USBInTransferResult(String status, [ByteData? data]) { if (data != null) { return _USBInTransferResult._create_1(status, data); } @@ -35388,7 +35441,7 @@ abstract class _USBIsochronousInTransferPacket extends Interceptor { throw new UnsupportedError("Not supported"); } - factory _USBIsochronousInTransferPacket(String status, [ByteData data]) { + factory _USBIsochronousInTransferPacket(String status, [ByteData? data]) { if (data != null) { return _USBIsochronousInTransferPacket._create_1(status, data); } @@ -35417,7 +35470,7 @@ abstract class _USBIsochronousInTransferResult extends Interceptor { factory _USBIsochronousInTransferResult( List<_USBIsochronousInTransferPacket> packets, - [ByteData data]) { + [ByteData? data]) { if (data != null) { return _USBIsochronousInTransferResult._create_1(packets, data); } @@ -35444,7 +35497,7 @@ abstract class _USBIsochronousOutTransferPacket extends Interceptor { throw new UnsupportedError("Not supported"); } - factory _USBIsochronousOutTransferPacket(String status, [int bytesWritten]) { + factory _USBIsochronousOutTransferPacket(String status, [int? bytesWritten]) { if (bytesWritten != null) { return _USBIsochronousOutTransferPacket._create_1(status, bytesWritten); } @@ -35491,7 +35544,7 @@ abstract class _USBOutTransferResult extends Interceptor { throw new UnsupportedError("Not supported"); } - factory _USBOutTransferResult(String status, [int bytesWritten]) { + factory _USBOutTransferResult(String status, [int? bytesWritten]) { if (bytesWritten != null) { return _USBOutTransferResult._create_1(status, bytesWritten); } @@ -35515,17 +35568,17 @@ abstract class _WindowTimers extends Interceptor { throw new UnsupportedError("Not supported"); } - int _setInterval_String(String handler, [int timeout, Object arguments]); + int _setInterval_String(String handler, [int? timeout, Object? arguments]); - int _setTimeout_String(String handler, [int timeout, Object arguments]); + int _setTimeout_String(String handler, [int? timeout, Object? arguments]); - void _clearInterval([int handle]); + void _clearInterval([int? handle]); - void _clearTimeout([int handle]); + void _clearTimeout([int? handle]); - int _setInterval(Object handler, [int timeout]); + int _setInterval(Object handler, [int? timeout]); - int _setTimeout(Object handler, [int timeout]); + int _setTimeout(Object handler, [int? timeout]); } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -35587,7 +35640,7 @@ abstract class _AttributeMap extends MapBase { } Map cast() => Map.castFrom(this); - bool containsValue(Object value) { + bool containsValue(Object? value) { for (var v in this.values) { if (value == v) { return true; @@ -35600,7 +35653,7 @@ abstract class _AttributeMap extends MapBase { if (!containsKey(key)) { this[key] = ifAbsent(); } - return this[key]; + return this[key] as String; } void clear() { @@ -35612,7 +35665,7 @@ abstract class _AttributeMap extends MapBase { void forEach(void f(String key, String value)) { for (var key in keys) { var value = this[key]; - f(key, value); + f(key, value as String); } } @@ -35621,7 +35674,7 @@ abstract class _AttributeMap extends MapBase { var attributes = _element._attributes; var keys = []; for (int i = 0, len = attributes.length; i < len; i++) { - _Attr attr = attributes[i]; + _Attr attr = attributes[i] as _Attr; if (_matches(attr)) { keys.add(attr.name); } @@ -35634,7 +35687,7 @@ abstract class _AttributeMap extends MapBase { var attributes = _element._attributes; var values = []; for (int i = 0, len = attributes.length; i < len; i++) { - _Attr attr = attributes[i]; + _Attr attr = attributes[i] as _Attr; if (_matches(attr)) { values.add(attr.value); } @@ -35666,12 +35719,12 @@ abstract class _AttributeMap extends MapBase { class _ElementAttributeMap extends _AttributeMap { _ElementAttributeMap(Element element) : super(element); - bool containsKey(Object key) { - return _element._hasAttribute(key); + bool containsKey(Object? key) { + return key is String && _element._hasAttribute(key); } - String operator [](Object key) { - return _element.getAttribute(key); + String? operator [](Object? key) { + return _element.getAttribute(key as String); } void operator []=(String key, String value) { @@ -35679,7 +35732,7 @@ class _ElementAttributeMap extends _AttributeMap { } @pragma('dart2js:tryInline') - String remove(Object key) => key is String ? _remove(_element, key) : null; + String? remove(Object? key) => key is String ? _remove(_element, key) : null; /** * The number of {key, value} pairs in the map. @@ -35693,8 +35746,8 @@ class _ElementAttributeMap extends _AttributeMap { // Inline this because almost all call sites of [remove] do not use [value], // and the annotations on the `getAttribute` call allow it to be removed. @pragma('dart2js:tryInline') - static String _remove(Element element, String key) { - String value = JS( + static String? _remove(Element element, String key) { + String? value = JS( // throws:null(1) is not accurate since [key] could be malformed, but // [key] is checked again by `removeAttributeNS`. 'returns:String|Null;depends:all;effects:none;throws:null(1)', @@ -35710,16 +35763,16 @@ class _ElementAttributeMap extends _AttributeMap { * Wrapper to expose namespaced attributes as a typed map. */ class _NamespacedAttributeMap extends _AttributeMap { - final String _namespace; + final String? _namespace; _NamespacedAttributeMap(Element element, this._namespace) : super(element); - bool containsKey(Object key) { - return _element._hasAttributeNS(_namespace, key); + bool containsKey(Object? key) { + return key is String && _element._hasAttributeNS(_namespace, key); } - String operator [](Object key) { - return _element.getAttributeNS(_namespace, key); + String? operator [](Object? key) { + return _element.getAttributeNS(_namespace, key as String); } void operator []=(String key, String value) { @@ -35727,7 +35780,7 @@ class _NamespacedAttributeMap extends _AttributeMap { } @pragma('dart2js:tryInline') - String remove(Object key) => + String? remove(Object? key) => key is String ? _remove(_namespace, _element, key) : null; /** @@ -35743,8 +35796,8 @@ class _NamespacedAttributeMap extends _AttributeMap { // returned [value], and the annotations on the `getAttributeNS` call allow it // to be removed. @pragma('dart2js:tryInline') - static String _remove(String namespace, Element element, String key) { - String value = JS( + static String? _remove(String? namespace, Element element, String key) { + String? value = JS( // throws:null(1) is not accurate since [key] could be malformed, but // [key] is checked again by `removeAttributeNS`. 'returns:String|Null;depends:all;effects:none;throws:null(1)', @@ -35776,11 +35829,12 @@ class _DataAttributeMap extends MapBase { Map cast() => Map.castFrom(this); // TODO: Use lazy iterator when it is available on Map. - bool containsValue(Object value) => values.any((v) => v == value); + bool containsValue(Object? value) => values.any((v) => v == value); - bool containsKey(Object key) => _attributes.containsKey(_attr(key)); + bool containsKey(Object? key) => + _attributes.containsKey(_attr(key as String)); - String operator [](Object key) => _attributes[_attr(key)]; + String? operator [](Object? key) => _attributes[_attr(key as String)]; void operator []=(String key, String value) { _attributes[_attr(key)] = value; @@ -35789,7 +35843,7 @@ class _DataAttributeMap extends MapBase { String putIfAbsent(String key, String ifAbsent()) => _attributes.putIfAbsent(_attr(key), ifAbsent); - String remove(Object key) => _attributes.remove(_attr(key)); + String? remove(Object? key) => _attributes.remove(_attr(key as String)); void clear() { // Needs to operate on a snapshot since we are mutating the collection. @@ -35968,7 +36022,7 @@ abstract class WindowBase implements EventTarget { * WindowBase otherWindow = thisWindow.open('http://www.example.com/', 'foo'); * print(otherWindow.opener == thisWindow); // 'true' */ - WindowBase get opener; + WindowBase? get opener; /** * A reference to the parent of this window. @@ -35982,7 +36036,7 @@ abstract class WindowBase implements EventTarget { * * print(window.parent == window) // 'true' */ - WindowBase get parent; + WindowBase? get parent; /** * A reference to the topmost window in the window hierarchy. @@ -36003,7 +36057,7 @@ abstract class WindowBase implements EventTarget { * * print(window.top == window) // 'true' */ - WindowBase get top; + WindowBase? get top; // Methods. /** @@ -36049,7 +36103,7 @@ abstract class WindowBase implements EventTarget { * from WHATWG. */ void postMessage(var message, String targetOrigin, - [List messagePorts]); + [List? messagePorts]); } abstract class LocationBase { @@ -36085,7 +36139,7 @@ abstract class CssClassSet implements Set { * non-empty string containing no whitespace. To toggle multiple classes, use * [toggleAll]. */ - bool toggle(String value, [bool shouldAdd]); + bool toggle(String value, [bool? shouldAdd]); /** * Returns [:true:] if classes cannot be added or removed from this @@ -36102,7 +36156,7 @@ abstract class CssClassSet implements Set { * [value] must be a valid 'token' representing a single class, i.e. a * non-empty string containing no whitespace. */ - bool contains(Object value); + bool contains(Object? value); /** * Add the class [value] to element. @@ -36133,7 +36187,7 @@ abstract class CssClassSet implements Set { * non-empty string containing no whitespace. To remove multiple classes, use * [removeAll]. */ - bool remove(Object value); + bool remove(Object? value); /** * Add all classes specified in [iterable] to element. @@ -36155,7 +36209,7 @@ abstract class CssClassSet implements Set { * Each element of [iterable] must be a valid 'token' representing a single * class, i.e. a non-empty string containing no whitespace. */ - void removeAll(Iterable iterable); + void removeAll(Iterable iterable); /** * Toggles all classes specified in [iterable] on element. @@ -36170,7 +36224,7 @@ abstract class CssClassSet implements Set { * Each element of [iterable] must be a valid 'token' representing a single * class, i.e. a non-empty string containing no whitespace. */ - void toggleAll(Iterable iterable, [bool shouldAdd]); + void toggleAll(Iterable iterable, [bool? shouldAdd]); } // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -36247,9 +36301,9 @@ class _ContentCssRect extends CssRect { class _ContentCssListRect extends _ContentCssRect { List _elementList; - _ContentCssListRect(List elementList) : super(elementList.first) { - _elementList = elementList; - } + _ContentCssListRect(List elementList) + : _elementList = elementList, + super(elementList.first); /** * Set the height to `newHeight`. @@ -36471,7 +36525,7 @@ abstract class CssRect implements Rectangle { * Returns the intersection of this and `other`, or `null` if they don't * intersect. */ - Rectangle intersection(Rectangle other) { + Rectangle? intersection(Rectangle other) { var x0 = max(left, other.left); var x1 = min(left + width, other.left + other.width); @@ -36596,7 +36650,7 @@ class _MultiElementCssClassSet extends CssClassSetImpl { * TODO(sra): It seems wrong to collect a 'changed' flag like this when the * underlying toggle returns an 'is set' flag. */ - bool toggle(String value, [bool shouldAdd]) => _sets.fold( + bool toggle(String value, [bool? shouldAdd]) => _sets.fold( false, (bool changed, CssClassSetImpl e) => e.toggle(value, shouldAdd) || changed); @@ -36608,7 +36662,7 @@ class _MultiElementCssClassSet extends CssClassSetImpl { * This is the Dart equivalent of jQuery's * [removeClass](http://api.jquery.com/removeClass/). */ - bool remove(Object value) => _sets.fold( + bool remove(Object? value) => _sets.fold( false, (bool changed, CssClassSetImpl e) => e.remove(value) || changed); } @@ -36642,7 +36696,7 @@ class _ElementCssClassSet extends CssClassSetImpl { _element.className = ''; } - bool contains(Object value) { + bool contains(Object? value) { return _contains(_element, value); } @@ -36650,11 +36704,11 @@ class _ElementCssClassSet extends CssClassSetImpl { return _add(_element, value); } - bool remove(Object value) { + bool remove(Object? value) { return value is String && _remove(_element, value); } - bool toggle(String value, [bool shouldAdd]) { + bool toggle(String value, [bool? shouldAdd]) { return _toggle(_element, value, shouldAdd); } @@ -36662,11 +36716,11 @@ class _ElementCssClassSet extends CssClassSetImpl { _addAll(_element, iterable); } - void removeAll(Iterable iterable) { + void removeAll(Iterable iterable) { _removeAll(_element, iterable); } - void retainAll(Iterable iterable) { + void retainAll(Iterable iterable) { _removeWhere(_element, iterable.toSet().contains, false); } @@ -36678,7 +36732,7 @@ class _ElementCssClassSet extends CssClassSetImpl { _removeWhere(_element, test, false); } - static bool _contains(Element _element, Object value) { + static bool _contains(Element _element, Object? value) { return value is String && _classListContains(_classListOf(_element), value); } @@ -36699,7 +36753,7 @@ class _ElementCssClassSet extends CssClassSetImpl { return removed; } - static bool _toggle(Element _element, String value, bool shouldAdd) { + static bool _toggle(Element _element, String value, bool? shouldAdd) { // There is no value that can be passed as the second argument of // DomTokenList.toggle that behaves the same as passing one argument. // `null` is seen as false, meaning 'remove'. @@ -36713,13 +36767,13 @@ class _ElementCssClassSet extends CssClassSetImpl { return _classListToggle1(list, value); } - static bool _toggleOnOff(Element _element, String value, bool shouldAdd) { + static bool _toggleOnOff(Element _element, String value, bool? shouldAdd) { DomTokenList list = _classListOf(_element); // IE's toggle does not take a second parameter. We would prefer: // // return _classListToggle2(list, value, shouldAdd); // - if (shouldAdd) { + if (shouldAdd ?? false) { _classListAdd(list, value); return true; } else { @@ -36735,10 +36789,10 @@ class _ElementCssClassSet extends CssClassSetImpl { } } - static void _removeAll(Element _element, Iterable iterable) { + static void _removeAll(Element _element, Iterable iterable) { DomTokenList list = _classListOf(_element); - for (String value in iterable) { - _classListRemove(list, value); + for (Object? value in iterable) { + _classListRemove(list, value as String); } } @@ -36747,7 +36801,7 @@ class _ElementCssClassSet extends CssClassSetImpl { DomTokenList list = _classListOf(_element); int i = 0; while (i < _classListLength(list)) { - String item = list.item(i); + String item = list.item(i)!; if (doRemove == test(item)) { _classListRemove(list, item); } else { @@ -36796,7 +36850,7 @@ class _ElementCssClassSet extends CssClassSetImpl { } static bool _classListToggle2( - DomTokenList list, String value, bool shouldAdd) { + DomTokenList list, String value, bool? shouldAdd) { return JS('bool', '#.toggle(#, #)', list, value, shouldAdd); } } @@ -36858,7 +36912,9 @@ class Dimension { * `inherit` or invalid CSS will cause this constructor to throw a * FormatError. */ - Dimension.css(String cssValue) { + Dimension.css(String cssValue) + : _unit = '', + _value = 0 { if (cssValue == '') cssValue = '0px'; if (cssValue.endsWith('%')) { _unit = '%'; @@ -36920,7 +36976,7 @@ class EventStreamProvider { * * [EventTarget.addEventListener](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener) * from MDN. */ - Stream forTarget(EventTarget e, {bool useCapture: false}) => + Stream forTarget(EventTarget? e, {bool useCapture: false}) => new _EventStream(e, _eventType, useCapture); /** @@ -37012,7 +37068,7 @@ abstract class ElementStream implements Stream { * Adapter for exposing DOM events as Dart streams. */ class _EventStream extends Stream { - final EventTarget _target; + final EventTarget? _target; final String _eventType; final bool _useCapture; @@ -37020,16 +37076,16 @@ class _EventStream extends Stream { // DOM events are inherently multi-subscribers. Stream asBroadcastStream( - {void onListen(StreamSubscription subscription), - void onCancel(StreamSubscription subscription)}) => + {void onListen(StreamSubscription subscription)?, + void onCancel(StreamSubscription subscription)?}) => this; bool get isBroadcast => true; // TODO(9757): Inlining should be smart and inline only when inlining would // enable scalar replacement of an immediately allocated receiver. @pragma('dart2js:tryInline') - StreamSubscription listen(void onData(T event), - {Function onError, void onDone(), bool cancelOnError}) { + StreamSubscription listen(void onData(T event)?, + {Function? onError, void onDone()?, bool? cancelOnError}) { return new _EventStreamSubscription( this._target, this._eventType, onData, this._useCapture); } @@ -37080,8 +37136,8 @@ class _ElementListEventStreamImpl extends Stream }); // Delegate all regular Stream behavior to a wrapped Stream. - StreamSubscription listen(void onData(T event), - {Function onError, void onDone(), bool cancelOnError}) { + StreamSubscription listen(void onData(T event)?, + {Function? onError, void onDone()?, bool? cancelOnError}) { var pool = new _StreamPool.broadcast(); for (var target in _targetList) { pool.add(new _EventStream(target, _eventType, _useCapture)); @@ -37099,8 +37155,8 @@ class _ElementListEventStreamImpl extends Stream } Stream asBroadcastStream( - {void onListen(StreamSubscription subscription), - void onCancel(StreamSubscription subscription)}) => + {void onListen(StreamSubscription subscription)?, + void onCancel(StreamSubscription subscription)?}) => this; bool get isBroadcast => true; } @@ -37111,9 +37167,9 @@ typedef _EventListener(T event); class _EventStreamSubscription extends StreamSubscription { int _pauseCount = 0; - EventTarget _target; + EventTarget? _target; final String _eventType; - EventListener _onData; + EventListener? _onData; final bool _useCapture; // TODO(leafp): It would be better to write this as @@ -37126,7 +37182,7 @@ class _EventStreamSubscription extends StreamSubscription { // which are typed correctly. But this currently runs afoul of restrictions // on is checks for compatibility with the VM. _EventStreamSubscription( - this._target, this._eventType, void onData(T event), this._useCapture) + this._target, this._eventType, void onData(T event)?, this._useCapture) : _onData = onData == null ? null : _wrapZone((e) => (onData as dynamic)(e)) { @@ -37134,18 +37190,23 @@ class _EventStreamSubscription extends StreamSubscription { } Future cancel() { - if (_canceled) return null; + // Check for strong mode. This function can no longer return null in strong + // mode, so only return null in weak mode to preserve synchronous timing. + // See issue 41653 for more details. + dynamic emptyFuture = + typeAcceptsNull() ? null : Future.value(); + if (_canceled) return emptyFuture as Future; _unlisten(); // Clear out the target to indicate this is complete. _target = null; _onData = null; - return null; + return emptyFuture as Future; } bool get _canceled => _target == null; - void onData(void handleData(T event)) { + void onData(void handleData(T event)?) { if (_canceled) { throw new StateError("Subscription has been canceled."); } @@ -37158,12 +37219,12 @@ class _EventStreamSubscription extends StreamSubscription { } /// Has no effect. - void onError(Function handleError) {} + void onError(Function? handleError) {} /// Has no effect. - void onDone(void handleDone()) {} + void onDone(void handleDone()?) {} - void pause([Future resumeSignal]) { + void pause([Future? resumeSignal]) { if (_canceled) return; ++_pauseCount; _unlisten(); @@ -37183,17 +37244,17 @@ class _EventStreamSubscription extends StreamSubscription { void _tryResume() { if (_onData != null && !isPaused) { - _target.addEventListener(_eventType, _onData, _useCapture); + _target!.addEventListener(_eventType, _onData, _useCapture); } } void _unlisten() { if (_onData != null) { - _target.removeEventListener(_eventType, _onData, _useCapture); + _target!.removeEventListener(_eventType, _onData, _useCapture); } } - Future asFuture([E futureValue]) { + Future asFuture([E? futureValue]) { // We just need a future that will never succeed or fail. var completer = new Completer(); return completer.future; @@ -37218,21 +37279,20 @@ class _CustomEventStreamImpl extends Stream /** The type of event this stream is providing (e.g. "keydown"). */ String _type; - _CustomEventStreamImpl(String type) { - _type = type; - _streamController = new StreamController.broadcast(sync: true); - } + _CustomEventStreamImpl(String type) + : _type = type, + _streamController = new StreamController.broadcast(sync: true); // Delegate all regular Stream behavior to our wrapped Stream. - StreamSubscription listen(void onData(T event), - {Function onError, void onDone(), bool cancelOnError}) { + StreamSubscription listen(void onData(T event)?, + {Function? onError, void onDone()?, bool? cancelOnError}) { return _streamController.stream.listen(onData, onError: onError, onDone: onDone, cancelOnError: cancelOnError); } Stream asBroadcastStream( - {void onListen(StreamSubscription subscription), - void onCancel(StreamSubscription subscription)}) => + {void onListen(StreamSubscription subscription)?, + void onCancel(StreamSubscription subscription)?}) => _streamController.stream; bool get isBroadcast => true; @@ -37248,7 +37308,7 @@ class _CustomKeyEventStreamImpl extends _CustomEventStreamImpl void add(KeyEvent event) { if (event.type == _type) { - event.currentTarget.dispatchEvent(event._parent); + event.currentTarget!.dispatchEvent(event._parent); _streamController.add(event); } } @@ -37260,7 +37320,7 @@ class _CustomKeyEventStreamImpl extends _CustomEventStreamImpl */ // TODO (efortuna): Remove this when Issue 12218 is addressed. class _StreamPool { - StreamController _controller; + StreamController? _controller; /// Subscriptions to the streams that make up the pool. var _subscriptions = new Map, StreamSubscription>(); @@ -37280,7 +37340,7 @@ class _StreamPool { /** * The stream through which all events from streams in the pool are emitted. */ - Stream get stream => _controller.stream; + Stream get stream => _controller!.stream; /** * Adds [stream] as a member of this pool. @@ -37291,8 +37351,8 @@ class _StreamPool { */ void add(Stream stream) { if (_subscriptions.containsKey(stream)) return; - _subscriptions[stream] = stream.listen(_controller.add, - onError: _controller.addError, onDone: () => remove(stream)); + _subscriptions[stream] = stream.listen(_controller!.add, + onError: _controller!.addError, onDone: () => remove(stream)); } /** Removes [stream] as a member of this pool. */ @@ -37307,7 +37367,7 @@ class _StreamPool { subscription.cancel(); } _subscriptions.clear(); - _controller.close(); + _controller!.close(); } } @@ -37320,7 +37380,7 @@ class _CustomEventStreamProvider final _eventTypeGetter; const _CustomEventStreamProvider(this._eventTypeGetter); - Stream forTarget(EventTarget e, {bool useCapture: false}) { + Stream forTarget(EventTarget? e, {bool useCapture: false}) { return new _EventStream(e, _eventTypeGetter(e), useCapture); } @@ -37749,8 +37809,8 @@ class _Html5NodeValidator implements NodeValidator { * All known URI attributes will be validated against the UriPolicy, if * [uriPolicy] is null then a default UriPolicy will be used. */ - _Html5NodeValidator({UriPolicy uriPolicy}) - : uriPolicy = uriPolicy != null ? uriPolicy : new UriPolicy() { + _Html5NodeValidator({UriPolicy? uriPolicy}) + : uriPolicy = uriPolicy ?? UriPolicy() { if (_attributeValidators.isEmpty) { for (var attr in _standardAttributes) { _attributeValidators[attr] = _standardAttributeValidator; @@ -37810,11 +37870,11 @@ abstract class ImmutableListMixin implements List { throw new UnsupportedError("Cannot add to immutable List."); } - void sort([int compare(E a, E b)]) { + void sort([int compare(E a, E b)?]) { throw new UnsupportedError("Cannot sort immutable List."); } - void shuffle([Random random]) { + void shuffle([Random? random]) { throw new UnsupportedError("Cannot shuffle immutable List."); } @@ -37838,7 +37898,7 @@ abstract class ImmutableListMixin implements List { throw new UnsupportedError("Cannot remove from immutable List."); } - bool remove(Object object) { + bool remove(Object? object) { throw new UnsupportedError("Cannot remove from immutable List."); } @@ -37862,7 +37922,7 @@ abstract class ImmutableListMixin implements List { throw new UnsupportedError("Cannot modify an immutable List."); } - void fillRange(int start, int end, [E fillValue]) { + void fillRange(int start, int end, [E? fillValue]) { throw new UnsupportedError("Cannot modify an immutable List."); } } @@ -38753,7 +38813,7 @@ class _KeyboardEventHandler extends EventStreamProvider { final String _type; /** The element we are watching for events to happen on. */ - final EventTarget _target; + final EventTarget? _target; // The distance to shift from upper case alphabet Roman letters to lower case. static final int _ROMAN_ALPHABET_OFFSET = "a".codeUnits[0] - "A".codeUnits[0]; @@ -38796,7 +38856,7 @@ class _KeyboardEventHandler extends EventStreamProvider { /** Return a stream for KeyEvents for the specified target. */ // Note: this actually functions like a factory constructor. - CustomStream forTarget(EventTarget e, {bool useCapture: false}) { + CustomStream forTarget(EventTarget? e, {bool useCapture: false}) { var handler = new _KeyboardEventHandler.initializeAllEventListeners(_type, e); return handler._stream; @@ -38816,7 +38876,8 @@ class _KeyboardEventHandler extends EventStreamProvider { * and charcodes when they are not provided. */ _KeyboardEventHandler.initializeAllEventListeners(this._type, this._target) - : super(_EVENT_TYPE) { + : _stream = new _CustomKeyEventStreamImpl(_type), + super(_EVENT_TYPE) { Element.keyDownEvent .forTarget(_target, useCapture: true) .listen(processKeyDown); @@ -38826,7 +38887,6 @@ class _KeyboardEventHandler extends EventStreamProvider { Element.keyUpEvent .forTarget(_target, useCapture: true) .listen(processKeyUp); - _stream = new _CustomKeyEventStreamImpl(_type); } /** Determine if caps lock is one of the currently depressed keys. */ @@ -39068,7 +39128,7 @@ class _KeyboardEventHandler extends EventStreamProvider { _keyIdentifier.containsKey(e._shadowKeyIdentifier)) { // This is needed for Safari Windows because it currently doesn't give a // keyCode/which for non printable keys. - e._shadowKeyCode = _keyIdentifier[e._shadowKeyIdentifier]; + e._shadowKeyCode = _keyIdentifier[e._shadowKeyIdentifier]!; } e._shadowAltKey = _keyDownList.any((var element) => element.altKey); _stream.add(e); @@ -39077,7 +39137,7 @@ class _KeyboardEventHandler extends EventStreamProvider { /** Handle keyup events. */ void processKeyUp(KeyboardEvent event) { var e = new KeyEvent.wrap(event); - KeyboardEvent toRemove = null; + KeyboardEvent? toRemove = null; for (var key in _keyDownList) { if (key.keyCode == e.keyCode) { toRemove = key; @@ -39181,7 +39241,7 @@ class NodeValidatorBuilder implements NodeValidator { * The UriPolicy can be used to restrict the locations the navigation elements * are allowed to direct to. By default this will use the default [UriPolicy]. */ - void allowNavigation([UriPolicy uriPolicy]) { + void allowNavigation([UriPolicy? uriPolicy]) { if (uriPolicy == null) { uriPolicy = new UriPolicy(); } @@ -39194,7 +39254,7 @@ class NodeValidatorBuilder implements NodeValidator { * The UriPolicy can be used to restrict the locations the images may be * loaded from. By default this will use the default [UriPolicy]. */ - void allowImages([UriPolicy uriPolicy]) { + void allowImages([UriPolicy? uriPolicy]) { if (uriPolicy == null) { uriPolicy = new UriPolicy(); } @@ -39235,7 +39295,7 @@ class NodeValidatorBuilder implements NodeValidator { * If [tagName] is not specified then this allows inline styles on all * elements. Otherwise tagName limits the styles to the specified elements. */ - void allowInlineStyles({String tagName}) { + void allowInlineStyles({String? tagName}) { if (tagName == null) { tagName = '*'; } else { @@ -39253,7 +39313,7 @@ class NodeValidatorBuilder implements NodeValidator { * Common things which are not allowed are script elements, style attributes * and any script handlers. */ - void allowHtml5({UriPolicy uriPolicy}) { + void allowHtml5({UriPolicy? uriPolicy}) { add(new _Html5NodeValidator(uriPolicy: uriPolicy)); } @@ -39272,9 +39332,9 @@ class NodeValidatorBuilder implements NodeValidator { * tag extensions. */ void allowCustomElement(String tagName, - {UriPolicy uriPolicy, - Iterable attributes, - Iterable uriAttributes}) { + {UriPolicy? uriPolicy, + Iterable? attributes, + Iterable? uriAttributes}) { var tagNameUpper = tagName.toUpperCase(); var attrs = attributes ?.map((name) => '$tagNameUpper::${name.toLowerCase()}'); @@ -39297,9 +39357,9 @@ class NodeValidatorBuilder implements NodeValidator { * custom tags. */ void allowTagExtension(String tagName, String baseName, - {UriPolicy uriPolicy, - Iterable attributes, - Iterable uriAttributes}) { + {UriPolicy? uriPolicy, + Iterable? attributes, + Iterable? uriAttributes}) { var baseNameUpper = baseName.toUpperCase(); var tagNameUpper = tagName.toUpperCase(); var attrs = attributes @@ -39315,9 +39375,9 @@ class NodeValidatorBuilder implements NodeValidator { } void allowElement(String tagName, - {UriPolicy uriPolicy, - Iterable attributes, - Iterable uriAttributes}) { + {UriPolicy? uriPolicy, + Iterable? attributes, + Iterable? uriAttributes}) { allowCustomElement(tagName, uriPolicy: uriPolicy, attributes: attributes, @@ -39359,7 +39419,7 @@ class _SimpleNodeValidator implements NodeValidator { final Set allowedElements = new Set(); final Set allowedAttributes = new Set(); final Set allowedUriAttributes = new Set(); - final UriPolicy uriPolicy; + final UriPolicy? uriPolicy; factory _SimpleNodeValidator.allowNavigation(UriPolicy uriPolicy) { return new _SimpleNodeValidator(uriPolicy, allowedElements: const [ @@ -39434,9 +39494,9 @@ class _SimpleNodeValidator implements NodeValidator { * lowercase attribute name. For example `'IMG:src'`. */ _SimpleNodeValidator(this.uriPolicy, - {Iterable allowedElements, - Iterable allowedAttributes, - Iterable allowedUriAttributes}) { + {Iterable? allowedElements, + Iterable? allowedAttributes, + Iterable? allowedUriAttributes}) { this.allowedElements.addAll(allowedElements ?? const []); allowedAttributes = allowedAttributes ?? const []; allowedUriAttributes = allowedUriAttributes ?? const []; @@ -39456,9 +39516,9 @@ class _SimpleNodeValidator implements NodeValidator { bool allowsAttribute(Element element, String attributeName, String value) { var tagName = Element._safeTagName(element); if (allowedUriAttributes.contains('$tagName::$attributeName')) { - return uriPolicy.allowsUri(value); + return uriPolicy!.allowsUri(value); } else if (allowedUriAttributes.contains('*::$attributeName')) { - return uriPolicy.allowsUri(value); + return uriPolicy!.allowsUri(value); } else if (allowedAttributes.contains('$tagName::$attributeName')) { return true; } else if (allowedAttributes.contains('*::$attributeName')) { @@ -39479,8 +39539,8 @@ class _CustomElementNodeValidator extends _SimpleNodeValidator { _CustomElementNodeValidator( UriPolicy uriPolicy, Iterable allowedElements, - Iterable allowedAttributes, - Iterable allowedUriAttributes, + Iterable? allowedAttributes, + Iterable? allowedUriAttributes, bool allowTypeExtension, bool allowCustomTag) : this.allowTypeExtension = allowTypeExtension == true, @@ -39625,7 +39685,7 @@ class _WrappedList extends ListBase _list.add(element); } - bool remove(Object element) => _list.remove(element); + bool remove(Object? element) => _list.remove(element); void clear() { _list.clear(); @@ -39633,7 +39693,7 @@ class _WrappedList extends ListBase // List APIs - E operator [](int index) => _list[index]; + E operator [](int index) => _list[index] as E; void operator []=(int index, E value) { _list[index] = value; @@ -39643,19 +39703,23 @@ class _WrappedList extends ListBase _list.length = newLength; } - void sort([int compare(E a, E b)]) { - // Implicit downcast on argument from Node to E-extends-Node. - _list.sort((Node a, Node b) => compare(a, b)); + void sort([int compare(E a, E b)?]) { + if (compare == null) { + _list.sort(); + } else { + _list.sort((Node a, Node b) => compare(a as E, b as E)); + } } - int indexOf(Object element, [int start = 0]) => _list.indexOf(element, start); + int indexOf(Object? element, [int start = 0]) => + _list.indexOf(element as Node, start); - int lastIndexOf(Object element, [int start]) => - _list.lastIndexOf(element, start); + int lastIndexOf(Object? element, [int? start]) => + _list.lastIndexOf(element as Node, start); void insert(int index, E element) => _list.insert(index, element); - E removeAt(int index) => _list.removeAt(index); + E removeAt(int index) => _list.removeAt(index) as E; void setRange(int start, int end, Iterable iterable, [int skipCount = 0]) { _list.setRange(start, end, iterable, skipCount); @@ -39669,7 +39733,7 @@ class _WrappedList extends ListBase _list.replaceRange(start, end, iterable); } - void fillRange(int start, int end, [E fillValue]) { + void fillRange(int start, int end, [E? fillValue]) { _list.fillRange(start, end, fillValue); } @@ -39688,7 +39752,7 @@ class _WrappedIterator implements Iterator { return _iterator.moveNext(); } - E get current => _iterator.current; + E get current => _iterator.current as E; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -39723,7 +39787,7 @@ class FixedSizeListIterator implements Iterator { final List _array; final int _length; // Cache array length for faster access. int _position; - T _current; + T? _current; FixedSizeListIterator(List array) : _array = array, @@ -39742,14 +39806,14 @@ class FixedSizeListIterator implements Iterator { return false; } - T get current => _current; + T get current => _current as T; } // Iterator for arrays with variable size. class _VariableSizeListIterator implements Iterator { final List _array; int _position; - T _current; + T? _current; _VariableSizeListIterator(List array) : _array = array, @@ -39767,7 +39831,7 @@ class _VariableSizeListIterator implements Iterator { return false; } - T get current => _current; + T get current => _current as T; } // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -39779,7 +39843,7 @@ class Console { bool get _isConsoleDefined => JS('bool', 'typeof console != "undefined"'); - MemoryInfo get memory => + MemoryInfo? get memory => _isConsoleDefined ? JS('MemoryInfo', 'window.console.memory') : null; void assertCondition(bool condition, Object arg) => _isConsoleDefined @@ -39859,12 +39923,12 @@ class Console { // We omit an unwrapper for Window as no methods take a non-local // window as a parameter. -WindowBase _convertNativeToDart_Window(win) { +WindowBase? _convertNativeToDart_Window(win) { if (win == null) return null; return _DOMWindowCrossFrame._createSafe(win); } -EventTarget _convertNativeToDart_EventTarget(e) { +EventTarget? _convertNativeToDart_EventTarget(e) { if (e == null) { return null; } @@ -39882,7 +39946,7 @@ EventTarget _convertNativeToDart_EventTarget(e) { return e; } -EventTarget _convertDartToNative_EventTarget(e) { +EventTarget? _convertDartToNative_EventTarget(e) { if (e is _DOMWindowCrossFrame) { return e._window; } else { @@ -39962,7 +40026,7 @@ void _checkExtendsNativeClassOrTemplate( } } -Function _registerCustomElement(context, document, String tag, [Map options]) { +Function _registerCustomElement(context, document, String tag, [Map? options]) { // Function follows the same pattern as the following JavaScript code for // registering a custom element. // @@ -39978,7 +40042,7 @@ Function _registerCustomElement(context, document, String tag, [Map options]) { // var e = document.createElement('x-foo'); var extendsTagName = ''; - Type type; + Type? type; if (options != null) { extendsTagName = options['extends']; type = options['prototype']; @@ -40058,7 +40122,7 @@ class _JSElementUpgrader implements ElementUpgrader { var _constructor; var _nativeType; - _JSElementUpgrader(Document document, Type type, String extendsTag) { + _JSElementUpgrader(Document document, Type type, String? extendsTag) { var interceptorClass = findInterceptorConstructorForType(type); if (interceptorClass == null) { throw new ArgumentError(type); @@ -40138,8 +40202,7 @@ class _DOMWindowCrossFrame implements WindowBase { // Methods. void close() => JS('void', '#.close()', _window); - void postMessage(var message, String targetOrigin, - [List messagePorts = null]) { + void postMessage(var message, String targetOrigin, [List? messagePorts]) { if (messagePorts == null) { JS('void', '#.postMessage(#,#)', _window, convertDartToNative_SerializedScriptValue(message), targetOrigin); @@ -40171,26 +40234,26 @@ class _DOMWindowCrossFrame implements WindowBase { Events get on => throw new UnsupportedError( 'You can only attach EventListeners to your own window.'); // TODO(efortuna): Remove this method. dartbug.com/16814 - void _addEventListener(String type, EventListener listener, - [bool useCapture]) => + void _addEventListener(String? type, EventListener? listener, + [bool? useCapture]) => throw new UnsupportedError( 'You can only attach EventListeners to your own window.'); // TODO(efortuna): Remove this method. dartbug.com/16814 - void addEventListener(String type, EventListener listener, - [bool useCapture]) => + void addEventListener(String type, EventListener? listener, + [bool? useCapture]) => throw new UnsupportedError( 'You can only attach EventListeners to your own window.'); // TODO(efortuna): Remove this method. dartbug.com/16814 bool dispatchEvent(Event event) => throw new UnsupportedError( 'You can only attach EventListeners to your own window.'); // TODO(efortuna): Remove this method. dartbug.com/16814 - void _removeEventListener(String type, EventListener listener, - [bool useCapture]) => + void _removeEventListener(String? type, EventListener? listener, + [bool? useCapture]) => throw new UnsupportedError( 'You can only attach EventListeners to your own window.'); // TODO(efortuna): Remove this method. dartbug.com/16814 - void removeEventListener(String type, EventListener listener, - [bool useCapture]) => + void removeEventListener(String type, EventListener? listener, + [bool? useCapture]) => throw new UnsupportedError( 'You can only attach EventListeners to your own window.'); } @@ -40306,9 +40369,10 @@ class KeyEvent extends _WrappedEvent implements KeyboardEvent { bool get _realAltKey => JS('bool', '#.altKey', _parent); /** Shadows on top of the parent's currentTarget. */ - EventTarget _currentTarget; + EventTarget? _currentTarget; - final InputDeviceCapabilities sourceCapabilities; + InputDeviceCapabilities? get sourceCapabilities => + JS('InputDeviceCapabilities', '#.sourceCapabilities', this); /** * The value we want to use for this object's dispatch. Created here so it is @@ -40323,7 +40387,12 @@ class KeyEvent extends _WrappedEvent implements KeyboardEvent { } /** Construct a KeyEvent with [parent] as the event we're emulating. */ - KeyEvent.wrap(KeyboardEvent parent) : super(parent) { + KeyEvent.wrap(KeyboardEvent parent) + : _parent = parent, + _shadowAltKey = false, + _shadowCharCode = 0, + _shadowKeyCode = 0, + super(parent) { _parent = parent; _shadowAltKey = _realAltKey; _shadowCharCode = _realCharCode; @@ -40333,7 +40402,7 @@ class KeyEvent extends _WrappedEvent implements KeyboardEvent { /** Programmatically create a new KeyEvent (and KeyboardEvent). */ factory KeyEvent(String type, - {Window view, + {Window? view, bool canBubble: true, bool cancelable: true, int keyCode: 0, @@ -40343,12 +40412,12 @@ class KeyEvent extends _WrappedEvent implements KeyboardEvent { bool altKey: false, bool shiftKey: false, bool metaKey: false, - EventTarget currentTarget}) { + EventTarget? currentTarget}) { if (view == null) { view = window; } - var eventObj; + dynamic eventObj; // Currently this works on everything but Safari. Safari throws an // "Attempting to change access mechanism for an unconfigurable property" @@ -40401,7 +40470,7 @@ class KeyEvent extends _WrappedEvent implements KeyboardEvent { '&& document.body.dispatchEvent.length > 0'); /** The currently registered target for this event. */ - EventTarget get currentTarget => _currentTarget; + EventTarget? get currentTarget => _currentTarget; // This is an experimental method to be sure. static String _convertToHexString(int charCode, int keyCode) { @@ -40444,9 +40513,9 @@ class KeyEvent extends _WrappedEvent implements KeyboardEvent { bool get metaKey => _parent.metaKey; /** True if the shift key was pressed during this event. */ bool get shiftKey => _parent.shiftKey; - Window get view => _parent.view; + WindowBase? get view => _parent.view; void _initUIEvent( - String type, bool canBubble, bool cancelable, Window view, int detail) { + String type, bool canBubble, bool cancelable, Window? view, int detail) { throw new UnsupportedError("Cannot initialize a UI Event from a KeyEvent."); } @@ -40464,9 +40533,9 @@ class KeyEvent extends _WrappedEvent implements KeyboardEvent { String type, bool canBubble, bool cancelable, - Window view, + Window? view, String keyIdentifier, - int location, + int? location, bool ctrlKey, bool altKey, bool shiftKey, @@ -40491,7 +40560,7 @@ class Platform { * browser. If false, using these types will generate a runtime * error. */ - static final supportsTypedData = JS('bool', '!!(window.ArrayBuffer)'); + static final bool supportsTypedData = JS('bool', '!!(window.ArrayBuffer)'); /** * Returns true if SIMD types in dart:typed_data types are supported @@ -40511,7 +40580,7 @@ class _WrappedEvent implements Event { final Event wrapped; /** The CSS selector involved with event delegation. */ - String _selector; + String? _selector; _WrappedEvent(this.wrapped); @@ -40521,7 +40590,7 @@ class _WrappedEvent implements Event { bool get composed => wrapped.composed; - EventTarget get currentTarget => wrapped.currentTarget; + EventTarget? get currentTarget => wrapped.currentTarget; bool get defaultPrevented => wrapped.defaultPrevented; @@ -40529,13 +40598,13 @@ class _WrappedEvent implements Event { bool get isTrusted => wrapped.isTrusted; - EventTarget get target => wrapped.target; + EventTarget? get target => wrapped.target; - double get timeStamp => wrapped.timeStamp; + double get timeStamp => wrapped.timeStamp as double; String get type => wrapped.type; - void _initEvent(String type, [bool bubbles, bool cancelable]) { + void _initEvent(String type, [bool? bubbles, bool? cancelable]) { throw new UnsupportedError('Cannot initialize this Event.'); } @@ -40563,13 +40632,12 @@ class _WrappedEvent implements Event { throw new UnsupportedError('Cannot call matchingTarget if this Event did' ' not arise as a result of event delegation.'); } - Element currentTarget = this.currentTarget; - Element target = this.target; - var matchedTarget; + Element? currentTarget = this.currentTarget as Element?; + Element? target = this.target as Element?; do { - if (target.matches(_selector)) return target; + if (target!.matches(_selector!)) return target; target = target.parent; - } while (target != null && target != currentTarget.parent); + } while (target != null && target != currentTarget!.parent); throw new StateError('No selector matched for populating matchedTarget.'); } @@ -40583,7 +40651,7 @@ class _WrappedEvent implements Event { * from W3C. */ // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#extensions-to-event - List get path => wrapped.path; + List get path => wrapped.path as List; dynamic get _get_currentTarget => wrapped._get_currentTarget; @@ -40593,14 +40661,15 @@ class _WrappedEvent implements Event { // 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. -void Function(T) _wrapZone(void Function(T) callback) { +void Function(T)? _wrapZone(void Function(T)? callback) { // For performance reasons avoid wrapping if we are in the root zone. if (Zone.current == Zone.root) return callback; if (callback == null) return null; return Zone.current.bindUnaryCallbackGuarded(callback); } -void Function(T1, T2) _wrapBinaryZone(void Function(T1, T2) callback) { +void Function(T1, T2)? _wrapBinaryZone( + void Function(T1, T2)? callback) { // For performance reasons avoid wrapping if we are in the root zone. if (Zone.current == Zone.root) return callback; if (callback == null) return null; @@ -40624,7 +40693,7 @@ void Function(T1, T2) _wrapBinaryZone(void Function(T1, T2) callback) { * For details about CSS selector syntax, see the * [CSS selector specification](http://www.w3.org/TR/css3-selectors/). */ -Element querySelector(String selectors) => document.querySelector(selectors); +Element? querySelector(String selectors) => document.querySelector(selectors); /** * Finds all descendant elements of this document that match the specified @@ -40672,7 +40741,7 @@ abstract class NodeValidator { * * If a uriPolicy is not specified then the default uriPolicy will be used. */ - factory NodeValidator({UriPolicy uriPolicy}) => + factory NodeValidator({UriPolicy? uriPolicy}) => new _Html5NodeValidator(uriPolicy: uriPolicy); factory NodeValidator.throws(NodeValidator base) => @@ -40816,12 +40885,12 @@ class _ValidatingTreeSanitizer implements NodeTreeSanitizer { _ValidatingTreeSanitizer(this.validator) {} void sanitizeTree(Node node) { - void walk(Node node, Node parent) { + void walk(Node node, Node? parent) { sanitizeNode(node, parent); var child = node.lastChild; while (null != child) { - Node nextChild; + Node? nextChild; try { // Child may be removed during the walk, and we may not even be able // to get its previousNode. But it's also possible that previousNode @@ -40852,7 +40921,7 @@ class _ValidatingTreeSanitizer implements NodeTreeSanitizer { } /// Aggressively try to remove node. - void _removeNode(Node node, Node parent) { + void _removeNode(Node node, Node? parent) { // If we have the parent, it's presumably already passed more sanitization // or is the fragment, so ask it to remove the child. And if that fails // try to set the outer html. @@ -40865,7 +40934,7 @@ class _ValidatingTreeSanitizer implements NodeTreeSanitizer { } /// Sanitize the element, assuming we can't trust anything about it. - void _sanitizeUntrustedElement(/* Element */ element, Node parent) { + void _sanitizeUntrustedElement(/* Element */ element, Node? parent) { // If the _hasCorruptedAttributes does not successfully return false, // then we consider it corrupted and remove. // TODO(alanknight): This is a workaround because on Firefox @@ -40914,8 +40983,8 @@ class _ValidatingTreeSanitizer implements NodeTreeSanitizer { /// Having done basic sanity checking on the element, and computed the /// important attributes we want to check, remove it if it's not valid /// or not allowed, either as a whole or particular attributes. - void _sanitizeElement(Element element, Node parent, bool corrupted, - String text, String tag, Map attrs, String isAttr) { + void _sanitizeElement(Element element, Node? parent, bool corrupted, + String text, String tag, Map attrs, String? isAttr) { if (false != corrupted) { _removeNode(element, parent); window.console @@ -40957,7 +41026,7 @@ class _ValidatingTreeSanitizer implements NodeTreeSanitizer { } /// Sanitize the node and its children recursively. - void sanitizeNode(Node node, Node parent) { + void sanitizeNode(Node node, Node? parent) { switch (node.nodeType) { case Node.ELEMENT_NODE: _sanitizeUntrustedElement(node, parent); diff --git a/sdk/lib/html/dartium/nativewrappers.dart b/sdk/lib/html/dartium/nativewrappers.dart index db807989900..b6d2dc4bb91 100644 --- a/sdk/lib/html/dartium/nativewrappers.dart +++ b/sdk/lib/html/dartium/nativewrappers.dart @@ -2,8 +2,6 @@ // 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.6 - library nativewrappers; class NativeFieldWrapperClass1 {} diff --git a/sdk/lib/html/html_common/conversions.dart b/sdk/lib/html/html_common/conversions.dart index cbe2cd64da9..0b5459f3406 100644 --- a/sdk/lib/html/html_common/conversions.dart +++ b/sdk/lib/html/html_common/conversions.dart @@ -2,8 +2,6 @@ // 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.6 - // Conversions for IDBKey. // // Per http://www.w3.org/TR/IndexedDB/#key-construct @@ -257,7 +255,7 @@ abstract class _AcceptStructuredClone { if (isJavaScriptArray(e)) { var l = JS('returns:List;creates:;', '#', e); var slot = findSlot(l); - var copy = JS('returns:List|Null;creates:;', '#', readSlot(slot)); + var copy = JS('returns:List|Null;creates:;', '#', readSlot(slot)); if (copy != null) return copy; int length = l.length; diff --git a/sdk/lib/html/html_common/conversions_dart2js.dart b/sdk/lib/html/html_common/conversions_dart2js.dart index 028707f269a..c1fb0be3da9 100644 --- a/sdk/lib/html/html_common/conversions_dart2js.dart +++ b/sdk/lib/html/html_common/conversions_dart2js.dart @@ -1,13 +1,12 @@ -// @dart = 2.6 - part of html_common; /// Converts a JavaScript object with properties into a Dart Map. /// Not suitable for nested objects. -Map convertNativeToDart_Dictionary(object) { +Map? convertNativeToDart_Dictionary(object) { if (object == null) return null; var dict = {}; - var keys = JS('JSExtendableArray', 'Object.getOwnPropertyNames(#)', object); + var keys = JS( + 'JSExtendableArray', 'Object.getOwnPropertyNames(#)', object); for (final key in keys) { dict[key] = JS('var', '#[#]', object, key); } @@ -15,7 +14,7 @@ Map convertNativeToDart_Dictionary(object) { } /// Converts a flat Dart map into a JavaScript object with properties. -convertDartToNative_Dictionary(Map dict, [void postCreate(Object f)]) { +convertDartToNative_Dictionary(Map? dict, [void postCreate(Object? f)?]) { if (dict == null) return null; var object = JS('var', '{}'); if (postCreate != null) { @@ -38,7 +37,7 @@ List convertDartToNative_StringArray(List input) { } DateTime convertNativeToDart_DateTime(date) { - var millisSinceEpoch = JS('int', '#.getTime()', date); + int millisSinceEpoch = JS('int', '#.getTime()', date); return new DateTime.fromMillisecondsSinceEpoch(millisSinceEpoch, isUtc: true); } diff --git a/sdk/lib/html/html_common/css_class_set.dart b/sdk/lib/html/html_common/css_class_set.dart index 814829bd20d..ff15a4d3aff 100644 --- a/sdk/lib/html/html_common/css_class_set.dart +++ b/sdk/lib/html/html_common/css_class_set.dart @@ -2,8 +2,6 @@ // 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.6 - part of html_common; abstract class CssClassSetImpl extends SetBase implements CssClassSet { @@ -25,7 +23,7 @@ abstract class CssClassSetImpl extends SetBase implements CssClassSet { * If [shouldAdd] is true, then we always add that [value] to the element. If * [shouldAdd] is false then we always remove [value] from the element. */ - bool toggle(String value, [bool shouldAdd]) { + bool toggle(String value, [bool? shouldAdd]) { _validateToken(value); Set s = readClasses(); bool result = false; @@ -91,14 +89,14 @@ abstract class CssClassSetImpl extends SetBase implements CssClassSet { * This is the Dart equivalent of jQuery's * [hasClass](http://api.jquery.com/hasClass/). */ - bool contains(Object value) { + bool contains(Object? value) { if (value is! String) return false; _validateToken(value); return readClasses().contains(value); } /** Lookup from the Set interface. Not interesting for a String set. */ - String lookup(Object value) => contains(value) ? value : null; + String? lookup(Object? value) => contains(value) ? value as String : null; /** * Add the class [value] to element. @@ -120,9 +118,9 @@ abstract class CssClassSetImpl extends SetBase implements CssClassSet { * This is the Dart equivalent of jQuery's * [removeClass](http://api.jquery.com/removeClass/). */ - bool remove(Object value) { - _validateToken(value); + bool remove(Object? value) { if (value is! String) return false; + _validateToken(value); Set s = readClasses(); bool result = s.remove(value); writeClasses(s); @@ -146,7 +144,7 @@ abstract class CssClassSetImpl extends SetBase implements CssClassSet { * This is the Dart equivalent of jQuery's * [removeClass](http://api.jquery.com/removeClass/). */ - void removeAll(Iterable iterable) { + void removeAll(Iterable iterable) { modify((s) => s.removeAll(iterable)); } @@ -160,11 +158,11 @@ abstract class CssClassSetImpl extends SetBase implements CssClassSet { * element. If [shouldAdd] is false then we always remove all the classes in * [iterable] from the element. */ - void toggleAll(Iterable iterable, [bool shouldAdd]) { + void toggleAll(Iterable iterable, [bool? shouldAdd]) { iterable.forEach((e) => toggle(e, shouldAdd)); } - void retainAll(Iterable iterable) { + void retainAll(Iterable iterable) { modify((s) => s.retainAll(iterable)); } @@ -176,15 +174,15 @@ abstract class CssClassSetImpl extends SetBase implements CssClassSet { modify((s) => s.retainWhere(test)); } - bool containsAll(Iterable collection) => + bool containsAll(Iterable collection) => readClasses().containsAll(collection); - Set intersection(Set other) => + Set intersection(Set other) => readClasses().intersection(other); Set union(Set other) => readClasses().union(other); - Set difference(Set other) => readClasses().difference(other); + Set difference(Set other) => readClasses().difference(other); String get first => readClasses().first; String get last => readClasses().last; @@ -198,11 +196,11 @@ abstract class CssClassSetImpl extends SetBase implements CssClassSet { Iterable skip(int n) => readClasses().skip(n); Iterable skipWhile(bool test(String value)) => readClasses().skipWhile(test); - String firstWhere(bool test(String value), {String orElse()}) => + String firstWhere(bool test(String value), {String orElse()?}) => readClasses().firstWhere(test, orElse: orElse); - String lastWhere(bool test(String value), {String orElse()}) => + String lastWhere(bool test(String value), {String orElse()?}) => readClasses().lastWhere(test, orElse: orElse); - String singleWhere(bool test(String value), {String orElse()}) => + String singleWhere(bool test(String value), {String orElse()?}) => readClasses().singleWhere(test, orElse: orElse); String elementAt(int index) => readClasses().elementAt(index); diff --git a/sdk/lib/html/html_common/device.dart b/sdk/lib/html/html_common/device.dart index d4d9ed5d75c..57c37e61e59 100644 --- a/sdk/lib/html/html_common/device.dart +++ b/sdk/lib/html/html_common/device.dart @@ -2,21 +2,12 @@ // 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.6 - part of html_common; /** * Utils for device detection. */ class Device { - static bool _isOpera; - static bool _isIE; - static bool _isFirefox; - static bool _isWebKit; - static String _cachedCssPrefix; - static String _cachedPropertyPrefix; - /** * Gets the browser's user agent. Using this function allows tests to inject * the user agent. @@ -27,78 +18,33 @@ class Device { /** * Determines if the current device is running Opera. */ - static bool get isOpera { - if (_isOpera == null) { - _isOpera = userAgent.contains("Opera", 0); - } - return _isOpera; - } + static final bool isOpera = userAgent.contains("Opera", 0); /** * Determines if the current device is running Internet Explorer. */ - static bool get isIE { - if (_isIE == null) { - _isIE = !isOpera && userAgent.contains("Trident/", 0); - } - return _isIE; - } + static final bool isIE = !isOpera && userAgent.contains("Trident/", 0); /** * Determines if the current device is running Firefox. */ - static bool get isFirefox { - if (_isFirefox == null) { - _isFirefox = userAgent.contains("Firefox", 0); - } - return _isFirefox; - } + static final bool isFirefox = userAgent.contains("Firefox", 0); /** * Determines if the current device is running WebKit. */ - static bool get isWebKit { - if (_isWebKit == null) { - _isWebKit = !isOpera && userAgent.contains("WebKit", 0); - } - return _isWebKit; - } + static final bool isWebKit = !isOpera && userAgent.contains("WebKit", 0); /** * Gets the CSS property prefix for the current platform. */ - static String get cssPrefix { - String prefix = _cachedCssPrefix; - if (prefix != null) return prefix; - if (isFirefox) { - prefix = '-moz-'; - } else if (isIE) { - prefix = '-ms-'; - } else if (isOpera) { - prefix = '-o-'; - } else { - prefix = '-webkit-'; - } - return _cachedCssPrefix = prefix; - } + static final String cssPrefix = '-${propertyPrefix}-'; /** * Prefix as used for JS property names. */ - static String get propertyPrefix { - String prefix = _cachedPropertyPrefix; - if (prefix != null) return prefix; - if (isFirefox) { - prefix = 'moz'; - } else if (isIE) { - prefix = 'ms'; - } else if (isOpera) { - prefix = 'o'; - } else { - prefix = 'webkit'; - } - return _cachedPropertyPrefix = prefix; - } + static final String propertyPrefix = + isFirefox ? 'moz' : (isIE ? 'ms' : (isOpera ? 'o' : 'webkit')); /** * Checks to see if the event class is supported by the current platform. diff --git a/sdk/lib/html/html_common/filtered_element_list.dart b/sdk/lib/html/html_common/filtered_element_list.dart index 35e01cb07fc..8bedca41202 100644 --- a/sdk/lib/html/html_common/filtered_element_list.dart +++ b/sdk/lib/html/html_common/filtered_element_list.dart @@ -2,8 +2,6 @@ // 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.6 - part of html_common; /** @@ -64,7 +62,7 @@ class FilteredElementList extends ListBase implements NodeListWrapper { } } - bool contains(Object needle) { + bool contains(Object? needle) { if (needle is! Element) return false; Element element = needle; return element.parentNode == _node; @@ -72,7 +70,7 @@ class FilteredElementList extends ListBase implements NodeListWrapper { Iterable get reversed => _filtered.reversed; - void sort([int compare(Element a, Element b)]) { + void sort([int compare(Element a, Element b)?]) { throw new UnsupportedError('Cannot sort filtered list'); } @@ -81,7 +79,7 @@ class FilteredElementList extends ListBase implements NodeListWrapper { throw new UnsupportedError('Cannot setRange on filtered list'); } - void fillRange(int start, int end, [Element fillValue]) { + void fillRange(int start, int end, [Element? fillValue]) { throw new UnsupportedError('Cannot fillRange on filtered list'); } @@ -113,7 +111,7 @@ class FilteredElementList extends ListBase implements NodeListWrapper { add(value); } else { var element = _iterable.elementAt(index); - element.parentNode.insertBefore(value, element); + element.parentNode!.insertBefore(value, element); } } @@ -122,7 +120,7 @@ class FilteredElementList extends ListBase implements NodeListWrapper { addAll(iterable); } else { var element = _iterable.elementAt(index); - element.parentNode.insertAllBefore(iterable, element); + element.parentNode!.insertAllBefore(iterable, element); } } @@ -132,7 +130,7 @@ class FilteredElementList extends ListBase implements NodeListWrapper { return result; } - bool remove(Object element) { + bool remove(Object? element) { if (element is! Element) return false; if (contains(element)) { (element as Element).remove(); // Placate the type checker diff --git a/sdk/lib/html/html_common/html_common.dart b/sdk/lib/html/html_common/html_common.dart index aab2cefdedb..1fb9d526f05 100644 --- a/sdk/lib/html/html_common/html_common.dart +++ b/sdk/lib/html/html_common/html_common.dart @@ -1,8 +1,6 @@ // 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.6 - library html_common; import 'dart:async'; diff --git a/sdk/lib/html/html_common/html_common_dart2js.dart b/sdk/lib/html/html_common/html_common_dart2js.dart index da4e21009fa..3df2ccfd614 100644 --- a/sdk/lib/html/html_common/html_common_dart2js.dart +++ b/sdk/lib/html/html_common/html_common_dart2js.dart @@ -2,8 +2,6 @@ // 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.6 - library html_common; import 'dart:async'; diff --git a/sdk/lib/html/html_common/lists.dart b/sdk/lib/html/html_common/lists.dart index 83d65b71e24..c7abc41cb00 100644 --- a/sdk/lib/html/html_common/lists.dart +++ b/sdk/lib/html/html_common/lists.dart @@ -2,8 +2,6 @@ // 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.6 - part of html_common; class Lists { diff --git a/sdk/lib/html/html_common/metadata.dart b/sdk/lib/html/html_common/metadata.dart index 991d99fdf3d..8e2f616c8dc 100644 --- a/sdk/lib/html/html_common/metadata.dart +++ b/sdk/lib/html/html_common/metadata.dart @@ -2,8 +2,6 @@ // 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.6 - library metadata; /** @@ -25,7 +23,7 @@ class SupportedBrowser { /// The minimum version of the browser that supports the feature, or null /// if supported on all versions. - final String minimumVersion; + final String? minimumVersion; const SupportedBrowser(this.browserName, [this.minimumVersion]); } diff --git a/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart b/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart index 08bc19b06c4..4cb159b9a53 100644 --- a/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart +++ b/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart @@ -1,5 +1,3 @@ -// @dart = 2.6 - /** * A client-side key-value store with support for indexes. * @@ -233,7 +231,7 @@ class Cursor extends Interceptor { } @JSName('continue') - void next([Object key]) { + void next([Object? key]) { if (key == null) { JS('void', '#.continue()', this); } else { @@ -250,15 +248,15 @@ class Cursor extends Interceptor { @_annotation_Creates_IDBKey @_annotation_Returns_IDBKey - Object get key native; + Object? get key native; @_annotation_Creates_IDBKey @_annotation_Returns_IDBKey - Object get primaryKey native; + Object? get primaryKey native; @Creates('Null') @Returns('ObjectStore|Index|Null') - Object get source native; + Object? get source native; void advance(int count) native; @@ -307,7 +305,7 @@ class CursorWithValue extends Cursor { @Unstable() @Native("IDBDatabase") class Database extends EventTarget { - ObjectStore createObjectStore(String name, {keyPath, bool autoIncrement}) { + ObjectStore createObjectStore(String name, {keyPath, bool? autoIncrement}) { var options = {}; if (keyPath != null) { options['keyPath'] = keyPath; @@ -404,7 +402,7 @@ class Database extends EventTarget { String get name native; - @Returns('DomStringList|Null') + @Returns('DomStringList') @Creates('DomStringList') List get objectStoreNames native; @@ -414,7 +412,7 @@ class Database extends EventTarget { void close() native; - ObjectStore _createObjectStore(String name, [Map options]) { + ObjectStore _createObjectStore(String name, [Map? options]) { if (options != null) { var options_1 = convertDartToNative_Dictionary(options); return _createObjectStore_1(name, options_1); @@ -471,9 +469,9 @@ class IdbFactory extends Interceptor { } Future open(String name, - {int version, - void onUpgradeNeeded(VersionChangeEvent event), - void onBlocked(Event event)}) { + {int? version, + void onUpgradeNeeded(VersionChangeEvent event)?, + void onBlocked(Event event)?}) { if ((version == null) != (onUpgradeNeeded == null)) { return new Future.error(new ArgumentError( 'version and onUpgradeNeeded must be specified together')); @@ -498,7 +496,7 @@ class IdbFactory extends Interceptor { } } - Future deleteDatabase(String name, {void onBlocked(Event e)}) { + Future deleteDatabase(String name, {void onBlocked(Event e)?}) { try { var request = _deleteDatabase(name); @@ -540,7 +538,7 @@ class IdbFactory extends Interceptor { @Returns('Request') @Creates('Request') @Creates('Database') - OpenDBRequest _open(String name, [int version]) native; + OpenDBRequest _open(String name, [int? version]) native; } /** @@ -602,7 +600,7 @@ class Index extends Interceptor { * * [ObjectStore.openCursor] */ Stream openCursor( - {key, KeyRange range, String direction, bool autoAdvance}) { + {key, KeyRange? range, String? direction, bool? autoAdvance}) { var key_OR_range = null; if (key != null) { if (range != null) { @@ -630,7 +628,7 @@ class Index extends Interceptor { * * [ObjectStore.openCursor] */ Stream openKeyCursor( - {key, KeyRange range, String direction, bool autoAdvance}) { + {key, KeyRange? range, String? direction, bool? autoAdvance}) { var key_OR_range = null; if (key != null) { if (range != null) { @@ -656,7 +654,7 @@ class Index extends Interceptor { } @annotation_Creates_SerializedScriptValue - Object get keyPath native; + Object? get keyPath native; bool get multiEntry native; @@ -669,7 +667,7 @@ class Index extends Interceptor { bool get unique native; @JSName('count') - Request _count(Object key) native; + Request _count(Object? key) native; @JSName('get') @Returns('Request') @@ -677,9 +675,9 @@ class Index extends Interceptor { @annotation_Creates_SerializedScriptValue Request _get(Object key) native; - Request getAll(Object query, [int count]) native; + Request getAll(Object? query, [int? count]) native; - Request getAllKeys(Object query, [int count]) native; + Request getAllKeys(Object? query, [int? count]) native; @JSName('getKey') @Returns('Request') @@ -692,13 +690,13 @@ class Index extends Interceptor { @Returns('Request') @Creates('Request') @Creates('Cursor') - Request _openCursor(Object range, [String direction]) native; + Request _openCursor(Object? range, [String? direction]) native; @JSName('openKeyCursor') @Returns('Request') @Creates('Request') @Creates('Cursor') - Request _openKeyCursor(Object range, [String direction]) native; + Request _openKeyCursor(Object? range, [String? direction]) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -727,29 +725,29 @@ class KeyRange extends Interceptor { } @annotation_Creates_SerializedScriptValue - Object get lower native; + Object? get lower native; bool get lowerOpen native; @annotation_Creates_SerializedScriptValue - Object get upper native; + Object? get upper native; bool get upperOpen native; @JSName('bound') static KeyRange bound_(Object lower, Object upper, - [bool lowerOpen, bool upperOpen]) native; + [bool? lowerOpen, bool? upperOpen]) native; bool includes(Object key) native; @JSName('lowerBound') - static KeyRange lowerBound_(Object bound, [bool open]) native; + static KeyRange lowerBound_(Object bound, [bool? open]) native; @JSName('only') static KeyRange only_(Object value) native; @JSName('upperBound') - static KeyRange upperBound_(Object bound, [bool open]) native; + static KeyRange upperBound_(Object bound, [bool? open]) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -843,7 +841,7 @@ class ObjectStore extends Interceptor { * the current transaction. */ Stream openCursor( - {key, KeyRange range, String direction, bool autoAdvance}) { + {key, KeyRange? range, String? direction, bool? autoAdvance}) { var key_OR_range = null; if (key != null) { if (range != null) { @@ -864,7 +862,7 @@ class ObjectStore extends Interceptor { return _cursorStreamFromResult(request, autoAdvance); } - Index createIndex(String name, keyPath, {bool unique, bool multiEntry}) { + Index createIndex(String name, keyPath, {bool? unique, bool? multiEntry}) { var options = {}; if (unique != null) { options['unique'] = unique; @@ -883,12 +881,12 @@ class ObjectStore extends Interceptor { bool get autoIncrement native; - @Returns('DomStringList|Null') + @Returns('DomStringList') @Creates('DomStringList') List get indexNames native; @annotation_Creates_SerializedScriptValue - Object get keyPath native; + Object? get keyPath native; String get name native; @@ -924,9 +922,9 @@ class ObjectStore extends Interceptor { Request _clear() native; @JSName('count') - Request _count(Object key) native; + Request _count(Object? key) native; - Index _createIndex(String name, Object keyPath, [Map options]) { + Index _createIndex(String name, Object keyPath, [Map? options]) { if (options != null) { var options_1 = convertDartToNative_Dictionary(options); return _createIndex_1(name, keyPath, options_1); @@ -950,9 +948,9 @@ class ObjectStore extends Interceptor { @annotation_Creates_SerializedScriptValue Request _get(Object key) native; - Request getAll(Object query, [int count]) native; + Request getAll(Object? query, [int? count]) native; - Request getAllKeys(Object query, [int count]) native; + Request getAllKeys(Object? query, [int? count]) native; Request getKey(Object key) native; @@ -962,9 +960,9 @@ class ObjectStore extends Interceptor { @Returns('Request') @Creates('Request') @Creates('Cursor') - Request _openCursor(Object range, [String direction]) native; + Request _openCursor(Object? range, [String? direction]) native; - Request openKeyCursor(Object range, [String direction]) native; + Request openKeyCursor(Object? range, [String? direction]) native; @Returns('Request') @Creates('Request') @@ -994,7 +992,7 @@ class ObjectStore extends Interceptor { * Helper for iterating over cursors in a request. */ static Stream _cursorStreamFromResult( - Request request, bool autoAdvance) { + Request request, bool? autoAdvance) { // TODO: need to guarantee that the controller provides the values // immediately as waiting until the next tick will cause the transaction to // close. @@ -1004,7 +1002,7 @@ class ObjectStore extends Interceptor { request.onError.listen(controller.addError); request.onSuccess.listen((e) { - T cursor = request.result as dynamic; + T? cursor = request.result as dynamic; if (cursor == null) { controller.close(); } else { @@ -1028,11 +1026,11 @@ class Observation extends Interceptor { throw new UnsupportedError("Not supported"); } - Object get key native; + Object? get key native; String get type native; - Object get value native; + Object? get value native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -1076,7 +1074,7 @@ class ObserverChanges extends Interceptor { Database get database native; - Object get records native; + Object? get records native; Transaction get transaction native; } @@ -1157,7 +1155,7 @@ class Request extends EventTarget { dynamic get _get_result native; @Creates('Null') - Object get source native; + Object? get source native; Transaction get transaction native; @@ -1240,7 +1238,7 @@ class Transaction extends EventTarget { String get mode native; - @Returns('DomStringList|Null') + @Returns('DomStringList') @Creates('DomStringList') List get objectStoreNames native; @@ -1269,7 +1267,7 @@ class VersionChangeEvent extends Event { throw new UnsupportedError("Not supported"); } - factory VersionChangeEvent(String type, [Map eventInitDict]) { + factory VersionChangeEvent(String type, [Map? eventInitDict]) { if (eventInitDict != null) { var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict); return VersionChangeEvent._create_1(type, eventInitDict_1); @@ -1290,7 +1288,7 @@ class VersionChangeEvent extends Event { @Creates('int|String|Null') @Returns('int|String|Null') - int get newVersion native; + int? get newVersion native; @Creates('int|String|Null') @Returns('int|String|Null') diff --git a/sdk/lib/internal/async_cast.dart b/sdk/lib/internal/async_cast.dart index aa3e375d027..306ada8bf5b 100644 --- a/sdk/lib/internal/async_cast.dart +++ b/sdk/lib/internal/async_cast.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart._internal; // Casting wrappers for asynchronous classes. @@ -13,8 +11,8 @@ class CastStream extends Stream { CastStream(this._source); bool get isBroadcast => _source.isBroadcast; - StreamSubscription listen(void onData(T data), - {Function onError, void onDone(), bool cancelOnError}) { + StreamSubscription listen(void Function(T data)? onData, + {Function? onError, void Function()? onDone, bool? cancelOnError}) { return new CastStreamSubscription( _source.listen(null, onDone: onDone, cancelOnError: cancelOnError)) ..onData(onData) @@ -30,12 +28,11 @@ class CastStreamSubscription implements StreamSubscription { /// Zone where listen was called. final Zone _zone = Zone.current; - /// User's data handler. May be null. - void Function(T) _handleData; + /// User's data handler. + void Function(T)? _handleData; /// Copy of _source's handleError so we can report errors in onData. - /// May be null. - Function _handleError; + Function? _handleError; CastStreamSubscription(this._source) { _source.onData(_onData); @@ -43,25 +40,28 @@ class CastStreamSubscription implements StreamSubscription { Future cancel() => _source.cancel(); - void onData(void handleData(T data)) { + void onData(void Function(T data)? handleData) { _handleData = handleData == null ? null : _zone.registerUnaryCallback(handleData); } - void onError(Function handleError) { + void onError(Function? handleError) { _source.onError(handleError); if (handleError == null) { _handleError = null; - } else if (handleError is Function(Null, Null)) { + } else if (handleError is void Function(Object, StackTrace)) { _handleError = _zone .registerBinaryCallback(handleError); - } else { + } else if (handleError is void Function(Object)) { _handleError = _zone.registerUnaryCallback(handleError); + } else { + throw ArgumentError("handleError callback must take either an Object " + "(the error), or both an Object (the error) and a StackTrace."); } } - void onDone(void handleDone()) { + void onDone(void handleDone()?) { _source.onDone(handleDone); } @@ -71,19 +71,21 @@ class CastStreamSubscription implements StreamSubscription { try { targetData = data as T; } catch (error, stack) { - if (_handleError == null) { + var handleError = _handleError; + if (handleError == null) { _zone.handleUncaughtError(error, stack); - } else if (_handleError is Function(Null, Null)) { - _zone.runBinaryGuarded(_handleError, error, stack); + } else if (handleError is void Function(Object, StackTrace)) { + _zone.runBinaryGuarded(handleError, error, stack); } else { - _zone.runUnaryGuarded(_handleError, error); + _zone.runUnaryGuarded( + handleError as void Function(Object), error); } return; } - _zone.runUnaryGuarded(_handleData, targetData); + _zone.runUnaryGuarded(_handleData!, targetData); } - void pause([Future resumeSignal]) { + void pause([Future? resumeSignal]) { _source.pause(resumeSignal); } @@ -93,7 +95,7 @@ class CastStreamSubscription implements StreamSubscription { bool get isPaused => _source.isPaused; - Future asFuture([E futureValue]) => _source.asFuture(futureValue); + Future asFuture([E? futureValue]) => _source.asFuture(futureValue); } class CastStreamTransformer diff --git a/sdk/lib/internal/cast.dart b/sdk/lib/internal/cast.dart index f019c955a67..d99b68710a1 100644 --- a/sdk/lib/internal/cast.dart +++ b/sdk/lib/internal/cast.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart._internal; // Casting wrappers for collection classes. @@ -46,11 +44,11 @@ abstract class _CastIterableBase extends Iterable { T get last => _source.last as T; T get single => _source.single as T; - bool contains(Object other) => _source.contains(other); + bool contains(Object? other) => _source.contains(other); // Might be implemented by testing backwards from the end, // so use the _source's implementation. - T lastWhere(bool test(T element), {T orElse()}) => + T lastWhere(bool test(T element), {T Function()? orElse}) => _source.lastWhere((S element) => test(element as T), orElse: (orElse == null) ? null : () => orElse() as S) as T; @@ -116,12 +114,12 @@ abstract class _CastListBase extends _CastIterableBase _source.addAll(new CastIterable(values)); } - void sort([int compare(T v1, T v2)]) { + void sort([int Function(T v1, T v2)? compare]) { _source.sort( compare == null ? null : (S v1, S v2) => compare(v1 as T, v2 as T)); } - void shuffle([Random random]) { + void shuffle([Random? random]) { _source.shuffle(random); } @@ -137,7 +135,7 @@ abstract class _CastListBase extends _CastIterableBase _source.setAll(index, new CastIterable(elements)); } - bool remove(Object value) => _source.remove(value); + bool remove(Object? value) => _source.remove(value); T removeAt(int index) => _source.removeAt(index) as T; @@ -162,7 +160,7 @@ abstract class _CastListBase extends _CastIterableBase _source.removeRange(start, end); } - void fillRange(int start, int end, [T fillValue]) { + void fillRange(int start, int end, [T? fillValue]) { _source.fillRange(start, end, fillValue as S); } @@ -184,7 +182,7 @@ class CastSet extends _CastIterableBase implements Set { /// Creates a new empty set of the same *kind* as [_source], /// but with `` as type argument. /// Used by [toSet] and [union]. - final Set Function() _emptySet; + final Set Function()? _emptySet; CastSet(this._source, this._emptySet); @@ -197,13 +195,13 @@ class CastSet extends _CastIterableBase implements Set { _source.addAll(new CastIterable(elements)); } - bool remove(Object object) => _source.remove(object); + bool remove(Object? object) => _source.remove(object); - void removeAll(Iterable objects) { + void removeAll(Iterable objects) { _source.removeAll(objects); } - void retainAll(Iterable objects) { + void retainAll(Iterable objects) { _source.retainAll(objects); } @@ -215,20 +213,21 @@ class CastSet extends _CastIterableBase implements Set { _source.retainWhere((S element) => test(element as T)); } - bool containsAll(Iterable objects) => _source.containsAll(objects); + bool containsAll(Iterable objects) => _source.containsAll(objects); - Set intersection(Set other) { + Set intersection(Set other) { if (_emptySet != null) return _conditionalAdd(other, true); return new CastSet(_source.intersection(other), null); } - Set difference(Set other) { + Set difference(Set other) { if (_emptySet != null) return _conditionalAdd(other, false); return new CastSet(_source.difference(other), null); } - Set _conditionalAdd(Set other, bool otherContains) { - Set result = (_emptySet == null) ? new Set() : _emptySet(); + Set _conditionalAdd(Set other, bool otherContains) { + var emptySet = _emptySet; + Set result = (emptySet == null) ? new Set() : emptySet(); for (var element in _source) { T castElement = element as T; if (otherContains == other.contains(castElement)) result.add(castElement); @@ -243,14 +242,15 @@ class CastSet extends _CastIterableBase implements Set { } Set _clone() { - Set result = (_emptySet == null) ? new Set() : _emptySet(); + var emptySet = _emptySet; + Set result = (emptySet == null) ? new Set() : emptySet(); result.addAll(this); return result; } Set toSet() => _clone(); - T lookup(Object key) => _source.lookup(key) as T; + T lookup(Object? key) => _source.lookup(key) as T; } class CastMap extends MapBase { @@ -260,24 +260,24 @@ class CastMap extends MapBase { Map cast() => new CastMap(_source); - bool containsValue(Object value) => _source.containsValue(value); + bool containsValue(Object? value) => _source.containsValue(value); - bool containsKey(Object key) => _source.containsKey(key); + bool containsKey(Object? key) => _source.containsKey(key); - V operator [](Object key) => _source[key] as V; + V? operator [](Object? key) => _source[key] as V?; void operator []=(K key, V value) { _source[key as SK] = value as SV; } - V putIfAbsent(K key, V ifAbsent()) => _source.putIfAbsent( - key as SK, (ifAbsent == null) ? null : () => ifAbsent() as SV) as V; + V putIfAbsent(K key, V Function() ifAbsent) => + _source.putIfAbsent(key as SK, () => ifAbsent() as SV) as V; void addAll(Map other) { _source.addAll(new CastMap(other)); } - V remove(Object key) => _source.remove(key) as V; + V remove(Object? key) => _source.remove(key) as V; void clear() { _source.clear(); @@ -299,7 +299,7 @@ class CastMap extends MapBase { bool get isNotEmpty => _source.isNotEmpty; - V update(K key, V update(V value), {V ifAbsent()}) { + V update(K key, V update(V value), {V Function()? ifAbsent}) { return _source.update(key as SK, (SV value) => update(value as V) as SV, ifAbsent: (ifAbsent == null) ? null : () => ifAbsent() as SV) as V; } @@ -344,7 +344,7 @@ class CastQueue extends _CastIterableBase implements Queue { _source.addLast(value as S); } - bool remove(Object other) => _source.remove(other); + bool remove(Object? other) => _source.remove(other); void addAll(Iterable elements) { _source.addAll(new CastIterable(elements)); } diff --git a/sdk/lib/internal/errors.dart b/sdk/lib/internal/errors.dart index f88b4138607..9010622b8f3 100644 --- a/sdk/lib/internal/errors.dart +++ b/sdk/lib/internal/errors.dart @@ -2,13 +2,11 @@ // 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.6 - part of dart._internal; class LateInitializationErrorImpl extends Error implements LateInitializationError { - final String _message; + final String? _message; LateInitializationErrorImpl([this._message]); diff --git a/sdk/lib/internal/internal.dart b/sdk/lib/internal/internal.dart index d044b034b37..dad3b05cc14 100644 --- a/sdk/lib/internal/internal.dart +++ b/sdk/lib/internal/internal.dart @@ -2,8 +2,6 @@ // 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.6 - library dart._internal; import 'dart:collection'; @@ -18,7 +16,7 @@ import 'dart:async' Zone; import 'dart:convert' show Converter; import 'dart:core' hide Symbol; -import 'dart:core' as core; +import 'dart:core' as core show Symbol; import 'dart:math' show Random; import 'dart:typed_data' show Uint8List; @@ -32,6 +30,10 @@ part 'print.dart'; part 'sort.dart'; part 'symbol.dart'; +// Returns true iff `null as T` will succeed based on the +// execution mode. +external bool typeAcceptsNull(); + // Powers of 10 up to 10^22 are representable as doubles. // Powers of 10 above that are only approximate due to lack of precission. // Used by double-parsing. @@ -167,7 +169,7 @@ int parseHexByte(String source, int index) { /// /// See this issue for more context: /// https://github.com/dart-lang/sdk/issues/31371 -external Object extractTypeArguments(T instance, Function extract); +external Object? extractTypeArguments(T instance, Function extract); /// Annotation class marking the version where SDK API was added. /// @@ -207,6 +209,49 @@ class Since { const Since(this.version); } +/// A null-check function for function parameters in Null Safety enabled code. +/// +/// Because Dart does not have full null safety +/// until all legacy code has been removed from a program, +/// a non-nullable parameter can still end up with a `null` value. +/// This function can be used to guard those functions against null arguments. +/// It throws a [TypeError] because we are really seeing the failure to +/// assign `null` to a non-nullable type. +/// +/// See http://dartbug.com/40614 for context. +T checkNotNullable(T value, String name) { + if ((value as dynamic) == null) { + throw NotNullableError(name); + } + return value; +} + +/// A [TypeError] thrown by [checkNotNullable]. +class NotNullableError extends Error implements TypeError { + final String _name; + NotNullableError(this._name); + String toString() => + "Null is not a valid value for the parameter '$_name' of type '$T'"; +} + +/// A function that returns the value or default value (if invoked with `null` +/// value) for non-nullable function parameters in Null safety enabled code. +/// +/// Because Dart does not have full null safety +/// until all legacy code has been removed from a program, +/// a non-nullable parameter can still end up with a `null` value. +/// This function can be used to get a default value for a parameter +/// when a `null` value is passed in for a non-nullable parameter. +/// +/// TODO(40810) - Remove uses of this function when Dart has full null safety. +T valueOfNonNullableParamWithDefault(T value, T defaultVal) { + if ((value as dynamic) == null) { + return defaultVal; + } else { + return value; + } +} + /** * HTTP status codes. Exported in dart:io and dart:html. */ diff --git a/sdk/lib/internal/iterable.dart b/sdk/lib/internal/iterable.dart index 8f28b5f270f..2817132c23f 100644 --- a/sdk/lib/internal/iterable.dart +++ b/sdk/lib/internal/iterable.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart._internal; /** @@ -63,7 +61,7 @@ abstract class ListIterable extends EfficientLengthIterable { return elementAt(0); } - bool contains(Object element) { + bool contains(Object? element) { int length = this.length; for (int i = 0; i < length; i++) { if (elementAt(i) == element) return true; @@ -96,7 +94,7 @@ abstract class ListIterable extends EfficientLengthIterable { return false; } - E firstWhere(bool test(E element), {E orElse()}) { + E firstWhere(bool test(E element), {E Function()? orElse}) { int length = this.length; for (int i = 0; i < length; i++) { E element = elementAt(i); @@ -109,7 +107,7 @@ abstract class ListIterable extends EfficientLengthIterable { throw IterableElementError.noElement(); } - E lastWhere(bool test(E element), {E orElse()}) { + E lastWhere(bool test(E element), {E Function()? orElse}) { int length = this.length; for (int i = length - 1; i >= 0; i--) { E element = elementAt(i); @@ -122,9 +120,9 @@ abstract class ListIterable extends EfficientLengthIterable { throw IterableElementError.noElement(); } - E singleWhere(bool test(E element), {E orElse()}) { + E singleWhere(bool test(E element), {E Function()? orElse}) { int length = this.length; - E match = null; + late E match; bool matchFound = false; for (int i = 0; i < length; i++) { E element = elementAt(i); @@ -210,18 +208,7 @@ abstract class ListIterable extends EfficientLengthIterable { Iterable takeWhile(bool test(E element)) => super.takeWhile(test); - List toList({bool growable: true}) { - List result; - if (growable) { - result = []..length = length; - } else { - result = new List(length); - } - for (int i = 0; i < length; i++) { - result[i] = elementAt(i); - } - return result; - } + List toList({bool growable: true}) => List.of(this, growable: growable); Set toSet() { Set result = new Set(); @@ -236,22 +223,24 @@ class SubListIterable extends ListIterable { final Iterable _iterable; // Has efficient length and elementAt. final int _start; /** If null, represents the length of the iterable. */ - final int _endOrLength; + final int? _endOrLength; SubListIterable(this._iterable, this._start, this._endOrLength) { RangeError.checkNotNegative(_start, "start"); - if (_endOrLength != null) { - RangeError.checkNotNegative(_endOrLength, "end"); - if (_start > _endOrLength) { - throw new RangeError.range(_start, 0, _endOrLength, "start"); + int? endOrLength = _endOrLength; + if (endOrLength != null) { + RangeError.checkNotNegative(endOrLength, "end"); + if (_start > endOrLength) { + throw new RangeError.range(_start, 0, endOrLength, "start"); } } } int get _endIndex { int length = _iterable.length; - if (_endOrLength == null || _endOrLength > length) return length; - return _endOrLength; + int? endOrLength = _endOrLength; + if (endOrLength == null || endOrLength > length) return length; + return endOrLength; } int get _startIndex { @@ -263,10 +252,11 @@ class SubListIterable extends ListIterable { int get length { int length = _iterable.length; if (_start >= length) return 0; - if (_endOrLength == null || _endOrLength >= length) { + int? endOrLength = _endOrLength; + if (endOrLength == null || endOrLength >= length) { return length - _start; } - return _endOrLength - _start; + return endOrLength - _start; } E elementAt(int index) { @@ -280,7 +270,8 @@ class SubListIterable extends ListIterable { Iterable skip(int count) { RangeError.checkNotNegative(count, "count"); int newStart = _start + count; - if (_endOrLength != null && newStart >= _endOrLength) { + int? endOrLength = _endOrLength; + if (endOrLength != null && newStart >= endOrLength) { return new EmptyIterable(); } return new SubListIterable(_iterable, newStart, _endOrLength); @@ -288,11 +279,12 @@ class SubListIterable extends ListIterable { Iterable take(int count) { RangeError.checkNotNegative(count, "count"); - if (_endOrLength == null) { + int? endOrLength = _endOrLength; + if (endOrLength == null) { return new SubListIterable(_iterable, _start, _start + count); } else { int newEnd = _start + count; - if (_endOrLength < newEnd) return this; + if (endOrLength < newEnd) return this; return new SubListIterable(_iterable, _start, newEnd); } } @@ -300,12 +292,14 @@ class SubListIterable extends ListIterable { List toList({bool growable: true}) { int start = _start; int end = _iterable.length; - if (_endOrLength != null && _endOrLength < end) end = _endOrLength; + int? endOrLength = _endOrLength; + if (endOrLength != null && endOrLength < end) end = endOrLength; int length = end - start; - if (length < 0) length = 0; + if (length <= 0) return List.empty(growable: growable); + List result = - growable ? (new List()..length = length) : new List(length); - for (int i = 0; i < length; i++) { + List.filled(length, _iterable.elementAt(start), growable: growable); + for (int i = 1; i < length; i++) { result[i] = _iterable.elementAt(start + i); if (_iterable.length < end) throw new ConcurrentModificationError(this); } @@ -324,14 +318,17 @@ class ListIterator implements Iterator { final Iterable _iterable; final int _length; int _index; - E _current; + E? _current; ListIterator(Iterable iterable) : _iterable = iterable, _length = iterable.length, _index = 0; - E get current => _current; + E get current { + final cur = _current; + return (cur != null) ? cur : cur as E; + } @pragma("vm:prefer-inline") bool moveNext() { @@ -384,7 +381,7 @@ class EfficientLengthMappedIterable extends MappedIterable } class MappedIterator extends Iterator { - T _current; + T? _current; final Iterator _iterator; final _Transformation _f; @@ -399,7 +396,10 @@ class MappedIterator extends Iterator { return false; } - T get current => _current; + T get current { + final cur = _current; + return (cur != null) ? cur : cur as T; + } } /** @@ -466,16 +466,19 @@ class ExpandIterator implements Iterator { // Initialize _currentExpansion to an empty iterable. A null value // marks the end of iteration, and we don't want to call _f before // the first moveNext call. - Iterator _currentExpansion = const EmptyIterator(); - T _current; + Iterator? _currentExpansion = const EmptyIterator(); + T? _current; ExpandIterator(this._iterator, this._f); - T get current => _current; + T get current { + final cur = _current; + return (cur != null) ? cur : cur as T; + } bool moveNext() { if (_currentExpansion == null) return false; - while (!_currentExpansion.moveNext()) { + while (!_currentExpansion!.moveNext()) { _current = null; if (_iterator.moveNext()) { // If _f throws, this ends iteration. Otherwise _currentExpansion and @@ -486,7 +489,7 @@ class ExpandIterator implements Iterator { return false; } } - _current = _currentExpansion.current; + _current = _currentExpansion!.current; return true; } } @@ -541,7 +544,11 @@ class TakeIterator extends Iterator { } E get current { - if (_remaining < 0) return null; + // Before NNBD, this returned null when iteration was complete. In order to + // avoid a hard breaking change, we return "null as E" in that case so that + // if strong checking is not enabled or E is nullable, the existing + // behavior is preserved. + if (_remaining < 0) return null as E; return _iterator.current; } } @@ -574,7 +581,7 @@ class TakeWhileIterator extends Iterator { } E get current { - if (_isFinished) return null; + if (_isFinished) return null as E; return _iterator.current; } } @@ -682,7 +689,7 @@ class SkipWhileIterator extends Iterator { class EmptyIterable extends EfficientLengthIterable { const EmptyIterable(); - Iterator get iterator => const EmptyIterator(); + Iterator get iterator => const EmptyIterator(); void forEach(void action(E element)) {} @@ -706,23 +713,23 @@ class EmptyIterable extends EfficientLengthIterable { throw new RangeError.range(index, 0, 0, "index"); } - bool contains(Object element) => false; + bool contains(Object? element) => false; bool every(bool test(E element)) => true; bool any(bool test(E element)) => false; - E firstWhere(bool test(E element), {E orElse()}) { + E firstWhere(bool test(E element), {E Function()? orElse}) { if (orElse != null) return orElse(); throw IterableElementError.noElement(); } - E lastWhere(bool test(E element), {E orElse()}) { + E lastWhere(bool test(E element), {E Function()? orElse}) { if (orElse != null) return orElse(); throw IterableElementError.noElement(); } - E singleWhere(bool test(E element), {E orElse()}) { + E singleWhere(bool test(E element), {E Function()? orElse}) { if (orElse != null) return orElse(); throw IterableElementError.noElement(); } @@ -755,7 +762,7 @@ class EmptyIterable extends EfficientLengthIterable { Iterable takeWhile(bool test(E element)) => this; - List toList({bool growable: true}) => growable ? [] : new List(0); + List toList({bool growable: true}) => List.empty(growable: growable); Set toSet() => new Set(); } @@ -764,7 +771,9 @@ class EmptyIterable extends EfficientLengthIterable { class EmptyIterator implements Iterator { const EmptyIterator(); bool moveNext() => false; - E get current => null; + E get current { + throw IterableElementError.noElement(); + } } class FollowedByIterable extends Iterable { @@ -787,7 +796,7 @@ class FollowedByIterable extends Iterable { bool get isNotEmpty => _first.isNotEmpty || _second.isNotEmpty; // May be more efficient if either iterable is a Set. - bool contains(Object value) => + bool contains(Object? value) => _first.contains(value) || _second.contains(value); E get first { @@ -816,20 +825,6 @@ class EfficientLengthFollowedByIterable extends FollowedByIterable EfficientLengthIterable first, EfficientLengthIterable second) : super(first, second); - Iterable skip(int count) { - int firstLength = _first.length; - if (count >= firstLength) return _second.skip(count - firstLength); - return new EfficientLengthFollowedByIterable( - _first.skip(count), _second); - } - - Iterable take(int count) { - int firstLength = _first.length; - if (count <= firstLength) return _first.take(count); - return new EfficientLengthFollowedByIterable( - _first, _second.take(count - firstLength)); - } - E elementAt(int index) { int firstLength = _first.length; if (index < firstLength) return _first.elementAt(index); @@ -849,7 +844,7 @@ class EfficientLengthFollowedByIterable extends FollowedByIterable class FollowedByIterator implements Iterator { Iterator _currentIterator; - Iterable _nextIterable; + Iterable? _nextIterable; FollowedByIterator(Iterable first, this._nextIterable) : _currentIterator = first.iterator; @@ -857,7 +852,7 @@ class FollowedByIterator implements Iterator { bool moveNext() { if (_currentIterator.moveNext()) return true; if (_nextIterable != null) { - _currentIterator = _nextIterable.iterator; + _currentIterator = _nextIterable!.iterator; _nextIterable = null; return _currentIterator.moveNext(); } @@ -868,13 +863,13 @@ class FollowedByIterator implements Iterator { } class WhereTypeIterable extends Iterable { - final Iterable _source; + final Iterable _source; WhereTypeIterable(this._source); Iterator get iterator => new WhereTypeIterator(_source.iterator); } class WhereTypeIterator implements Iterator { - final Iterator _source; + final Iterator _source; WhereTypeIterator(this._source); bool moveNext() { while (_source.moveNext()) { @@ -883,7 +878,7 @@ class WhereTypeIterator implements Iterator { return false; } - T get current => _source.current; + T get current => _source.current as T; } /** diff --git a/sdk/lib/internal/linked_list.dart b/sdk/lib/internal/linked_list.dart index 1ad58893296..b5e5275782c 100644 --- a/sdk/lib/internal/linked_list.dart +++ b/sdk/lib/internal/linked_list.dart @@ -2,14 +2,16 @@ // 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.6 - part of dart._internal; /// A rudimentary linked list. class LinkedList> extends IterableBase { - T first; - T last; + T get first => _first as T; + T? _first; + + T get last => _last as T; + T? _last; + int length = 0; bool get isEmpty => length == 0; @@ -19,15 +21,15 @@ class LinkedList> extends IterableBase { */ void add(T newLast) { assert(newLast._next == null && newLast._previous == null); - if (last != null) { - assert(last._next == null); - last._next = newLast; + if (_last != null) { + assert(_last!._next == null); + _last!._next = newLast; } else { - first = newLast; + _first = newLast; } - newLast._previous = last; - last = newLast; - last._list = this; + newLast._previous = _last; + _last = newLast; + _last!._list = this; length++; } @@ -35,15 +37,15 @@ class LinkedList> extends IterableBase { * Adds [newFirst] to the beginning of this linked list. */ void addFirst(T newFirst) { - if (first != null) { - assert(first._previous == null); - first._previous = newFirst; + if (_first != null) { + assert(_first!._previous == null); + _first!._previous = newFirst; } else { - last = newFirst; + _last = newFirst; } - newFirst._next = first; - first = newFirst; - first._list = this; + newFirst._next = _first; + _first = newFirst; + _first!._list = this; length++; } @@ -58,16 +60,16 @@ class LinkedList> extends IterableBase { if (node._list != this) return; length--; if (node._previous == null) { - assert(identical(node, first)); - first = node._next; + assert(identical(node, _first)); + _first = node._next; } else { - node._previous._next = node._next; + node._previous!._next = node._next; } if (node._next == null) { - assert(identical(node, last)); - last = node._previous; + assert(identical(node, _last)); + _last = node._previous; } else { - node._next._previous = node._previous; + node._next!._previous = node._previous; } node._next = node._previous = null; node._list = null; @@ -77,9 +79,9 @@ class LinkedList> extends IterableBase { } class LinkedListEntry> { - T _next; - T _previous; - LinkedList _list; + T? _next; + T? _previous; + LinkedList? _list; /** * Unlinks the element from its linked list. @@ -89,15 +91,18 @@ class LinkedListEntry> { * is currently in. */ void unlink() { - if (_list == null) return; - _list.remove(this); + _list?.remove(this as T); } } class _LinkedListIterator> implements Iterator { /// The current element of the iterator. - // This field is writeable, but should only read by users of this class. - T current; + T? _current; + + T get current { + final cur = _current; + return (cur != null) ? cur : cur as T; + } /// The list the iterator iterates over. /// @@ -106,23 +111,24 @@ class _LinkedListIterator> implements Iterator { /// /// Set to [null] as soon as [moveNext] was invoked (indicating that the /// iterator has to work with [current] from now on. - LinkedList _list; + LinkedList? _list; - _LinkedListIterator(this._list) { - if (_list.length == 0) _list = null; + _LinkedListIterator(LinkedList list) : _list = list { + if (list.length == 0) _list = null; } bool moveNext() { // current is null if the iterator hasn't started iterating, or if the // iteration is finished. In the first case, the [_list] field is not null. - if (current == null) { - if (_list == null) return false; - assert(_list.length > 0); - current = _list.first; + if (_current == null) { + var list = _list; + if (list == null) return false; + assert(list.length > 0); + _current = list.first; _list = null; return true; } - current = current._next; - return current != null; + _current = _current!._next; + return _current != null; } } diff --git a/sdk/lib/internal/list.dart b/sdk/lib/internal/list.dart index 3bf14a965b8..0a8b6a92147 100644 --- a/sdk/lib/internal/list.dart +++ b/sdk/lib/internal/list.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart._internal; /** @@ -39,7 +37,7 @@ abstract class FixedLengthListMixin { } /** This operation is not supported by a fixed length list. */ - bool remove(Object element) { + bool remove(Object? element) { throw new UnsupportedError("Cannot remove from a fixed-length list"); } @@ -132,7 +130,7 @@ abstract class UnmodifiableListMixin implements List { } /** This operation is not supported by an unmodifiable list. */ - bool remove(Object element) { + bool remove(Object? element) { throw new UnsupportedError("Cannot remove from an unmodifiable list"); } @@ -147,12 +145,12 @@ abstract class UnmodifiableListMixin implements List { } /** This operation is not supported by an unmodifiable list. */ - void sort([Comparator compare]) { + void sort([Comparator? compare]) { throw new UnsupportedError("Cannot modify an unmodifiable list"); } /** This operation is not supported by an unmodifiable list. */ - void shuffle([Random random]) { + void shuffle([Random? random]) { throw new UnsupportedError("Cannot modify an unmodifiable list"); } @@ -187,7 +185,7 @@ abstract class UnmodifiableListMixin implements List { } /** This operation is not supported by an unmodifiable list. */ - void fillRange(int start, int end, [E fillValue]) { + void fillRange(int start, int end, [E? fillValue]) { throw new UnsupportedError("Cannot modify an unmodifiable list"); } } @@ -227,7 +225,7 @@ class ListMapView extends UnmodifiableMapBase { ListMapView(this._values); - E operator [](Object key) => containsKey(key) ? _values[key] : null; + E? operator [](Object? key) => containsKey(key) ? _values[key as int] : null; int get length => _values.length; Iterable get values => new SubListIterable(_values, 0, null); @@ -235,8 +233,8 @@ class ListMapView extends UnmodifiableMapBase { bool get isEmpty => _values.isEmpty; bool get isNotEmpty => _values.isNotEmpty; - bool containsValue(Object value) => _values.contains(value); - bool containsKey(Object key) => key is int && key >= 0 && key < length; + bool containsValue(Object? value) => _values.contains(value); + bool containsKey(Object? key) => key is int && key >= 0 && key < length; void forEach(void f(int key, E value)) { int length = _values.length; @@ -304,7 +302,7 @@ abstract class NonGrowableListError { * Converts a growable list to a fixed length list with the same elements. * * For internal use only. - * Only works on growable lists as created by `[]` or `new List()`. + * Only works on growable lists like the one created by `[]`. * May throw on any other list. * * The operation is efficient. It doesn't copy the elements, but converts diff --git a/sdk/lib/internal/patch.dart b/sdk/lib/internal/patch.dart index b6aeea89f26..3fc973317ae 100644 --- a/sdk/lib/internal/patch.dart +++ b/sdk/lib/internal/patch.dart @@ -2,8 +2,6 @@ // 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.6 - part of "dart:_internal"; class _Patch { diff --git a/sdk/lib/internal/print.dart b/sdk/lib/internal/print.dart index 466a41479ad..20285031965 100644 --- a/sdk/lib/internal/print.dart +++ b/sdk/lib/internal/print.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart._internal; /** @@ -14,6 +12,6 @@ part of dart._internal; * * This decouples the core library from the async library. */ -void Function(String) printToZone = null; +void Function(String)? printToZone = null; external void printToConsole(String line); diff --git a/sdk/lib/internal/sort.dart b/sdk/lib/internal/sort.dart index a4489f366e3..d6cca2e3e54 100644 --- a/sdk/lib/internal/sort.dart +++ b/sdk/lib/internal/sort.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart._internal; /** diff --git a/sdk/lib/internal/symbol.dart b/sdk/lib/internal/symbol.dart index 7fba4af819f..bf484937f62 100644 --- a/sdk/lib/internal/symbol.dart +++ b/sdk/lib/internal/symbol.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart._internal; /** @@ -111,7 +109,7 @@ class Symbol implements core.Symbol { // This is called by dart2js. Symbol.validated(String name) : this._name = validatePublicSymbol(name); - bool operator ==(other) => other is Symbol && _name == other._name; + bool operator ==(Object other) => other is Symbol && _name == other._name; external int get hashCode; diff --git a/sdk/lib/io/bytes_builder.dart b/sdk/lib/io/bytes_builder.dart index b35dfcae2bf..6f13693a031 100644 --- a/sdk/lib/io/bytes_builder.dart +++ b/sdk/lib/io/bytes_builder.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.io; /** diff --git a/sdk/lib/io/common.dart b/sdk/lib/io/common.dart index 58f5f70bd5e..9688d8de438 100644 --- a/sdk/lib/io/common.dart +++ b/sdk/lib/io/common.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.io; // Constants used when working with native ports. @@ -56,8 +54,8 @@ class OSError implements Exception { /** Constant used to indicate that no OS error code is available. */ static const int noErrorCode = -1; - /// Error message supplied by the operating system. This may be `null` or - /// empty if no message is associated with the error. + /// Error message supplied by the operating system. This will be empty if no + /// message is associated with the error. final String message; /// Error code supplied by the operating system. diff --git a/sdk/lib/io/data_transformer.dart b/sdk/lib/io/data_transformer.dart index cdcaa199a86..4346a1ab2b6 100644 --- a/sdk/lib/io/data_transformer.dart +++ b/sdk/lib/io/data_transformer.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.io; /** @@ -155,7 +153,7 @@ class ZLibCodec extends Codec, List> { * be predicted with good accuracy; the data can then be compressed better * than with the default empty dictionary. */ - final List dictionary; + final List? dictionary; ZLibCodec( {this.level: ZLibOption.defaultLevel, @@ -266,7 +264,7 @@ class GZipCodec extends Codec, List> { * be predicted with good accuracy; the data can then be compressed better * than with the default empty dictionary. */ - final List dictionary; + final List? dictionary; /** * When true, deflate generates raw data with no zlib header or trailer, and @@ -373,7 +371,7 @@ class ZLibEncoder extends Converter, List> { * be predicted with good accuracy; the data can then be compressed better * than with the default empty dictionary. */ - final List dictionary; + final List? dictionary; /** * When true, deflate generates raw data with no zlib header or trailer, and @@ -442,7 +440,7 @@ class ZLibDecoder extends Converter, List> { * be predicted with good accuracy; the data can then be compressed better * than with the default empty dictionary. */ - final List dictionary; + final List? dictionary; /** * When true, deflate generates raw data with no zlib header or trailer, and @@ -496,7 +494,7 @@ abstract class RawZLibFilter { int windowBits: ZLibOption.defaultWindowBits, int memLevel: ZLibOption.defaultMemLevel, int strategy: ZLibOption.strategyDefault, - List dictionary, + List? dictionary, bool raw: false, }) { return _makeZLibDeflateFilter( @@ -509,7 +507,7 @@ abstract class RawZLibFilter { */ factory RawZLibFilter.inflateFilter({ int windowBits: ZLibOption.defaultWindowBits, - List dictionary, + List? dictionary, bool raw: false, }) { return _makeZLibInflateFilter(windowBits, dictionary, raw); @@ -529,7 +527,7 @@ abstract class RawZLibFilter { * The last call to [processed] should have [end] set to [:true:]. This will * make sure an 'end' packet is written on the stream. */ - List processed({bool flush: true, bool end: false}); + List? processed({bool flush: true, bool end: false}); external static RawZLibFilter _makeZLibDeflateFilter( bool gzip, @@ -537,11 +535,11 @@ abstract class RawZLibFilter { int windowBits, int memLevel, int strategy, - List dictionary, + List? dictionary, bool raw); external static RawZLibFilter _makeZLibInflateFilter( - int windowBits, List dictionary, bool raw); + int windowBits, List? dictionary, bool raw); } class _BufferSink extends ByteConversionSink { @@ -572,7 +570,7 @@ class _ZLibEncoderSink extends _FilterSink { int windowBits, int memLevel, int strategy, - List dictionary, + List? dictionary, bool raw) : super( sink, @@ -582,7 +580,7 @@ class _ZLibEncoderSink extends _FilterSink { class _ZLibDecoderSink extends _FilterSink { _ZLibDecoderSink._( - ByteConversionSink sink, int windowBits, List dictionary, bool raw) + ByteConversionSink sink, int windowBits, List? dictionary, bool raw) : super(sink, RawZLibFilter._makeZLibInflateFilter(windowBits, dictionary, raw)); } @@ -600,8 +598,9 @@ class _FilterSink extends ByteConversionSink { } void addSlice(List data, int start, int end, bool isLast) { + // TODO(40614): Remove once non-nullability is sound. + ArgumentError.checkNotNull(end, "end"); if (_closed) return; - if (end == null) throw new ArgumentError.notNull("end"); RangeError.checkValidRange(start, end, data.length); try { _empty = false; @@ -609,8 +608,10 @@ class _FilterSink extends ByteConversionSink { _ensureFastAndSerializableByteData(data, start, end); _filter.process(bufferAndStart.buffer, bufferAndStart.start, end - (start - bufferAndStart.start)); - List out; - while ((out = _filter.processed(flush: false)) != null) { + List? out; + while (true) { + final out = _filter.processed(flush: false); + if (out == null) break; _sink.add(out); } } catch (e) { @@ -627,8 +628,9 @@ class _FilterSink extends ByteConversionSink { // message would not have a GZip frame (if compressed with GZip). if (_empty) _filter.process(const [], 0, 0); try { - List out; - while ((out = _filter.processed(end: true)) != null) { + while (true) { + final out = _filter.processed(end: true); + if (out == null) break; _sink.add(out); } } catch (e) { diff --git a/sdk/lib/io/directory.dart b/sdk/lib/io/directory.dart index 44b83999b23..90e21591d32 100644 --- a/sdk/lib/io/directory.dart +++ b/sdk/lib/io/directory.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.io; /** @@ -131,7 +129,7 @@ abstract class Directory implements FileSystemEntity { */ @pragma("vm:entry-point") factory Directory(String path) { - final IOOverrides overrides = IOOverrides.current; + final IOOverrides? overrides = IOOverrides.current; if (overrides == null) { return new _Directory(path); } @@ -156,7 +154,7 @@ abstract class Directory implements FileSystemEntity { * directory. */ static Directory get current { - final IOOverrides overrides = IOOverrides.current; + final IOOverrides? overrides = IOOverrides.current; if (overrides == null) { return _Directory.current; } @@ -191,7 +189,7 @@ abstract class Directory implements FileSystemEntity { * are working with the file system, can lead to unexpected results. */ static void set current(path) { - final IOOverrides overrides = IOOverrides.current; + final IOOverrides? overrides = IOOverrides.current; if (overrides == null) { _Directory.current = path; return; @@ -232,7 +230,7 @@ abstract class Directory implements FileSystemEntity { * and may be set by an environment variable. */ static Directory get systemTemp { - final IOOverrides overrides = IOOverrides.current; + final IOOverrides? overrides = IOOverrides.current; if (overrides == null) { return _Directory.systemTemp; } @@ -248,7 +246,7 @@ abstract class Directory implements FileSystemEntity { * Returns a [:Future:] that completes with the newly * created temporary directory. */ - Future createTemp([String prefix]); + Future createTemp([String? prefix]); /** * Synchronously creates a temporary directory in this directory. @@ -258,7 +256,7 @@ abstract class Directory implements FileSystemEntity { * * Returns the newly created temporary directory. */ - Directory createTempSync([String prefix]); + Directory createTempSync([String? prefix]); Future resolveSymbolicLinks(); diff --git a/sdk/lib/io/directory_impl.dart b/sdk/lib/io/directory_impl.dart index bcd63b24ef6..9ca5b6cd21c 100644 --- a/sdk/lib/io/directory_impl.dart +++ b/sdk/lib/io/directory_impl.dart @@ -2,27 +2,20 @@ // 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.6 - part of dart.io; class _Directory extends FileSystemEntity implements Directory { - String _path; - Uint8List _rawPath; + final String _path; + final Uint8List _rawPath; - _Directory(String path) { - ArgumentError.checkNotNull(path, 'path'); - _path = path; - _rawPath = FileSystemEntity._toUtf8Array(_path); - } + _Directory(String path) + : _path = _checkNotNull(path, "path"), + _rawPath = FileSystemEntity._toUtf8Array(path); - _Directory.fromRawPath(Uint8List rawPath) { - if (rawPath == null) { - throw new ArgumentError('rawPath cannot be null'); - } - _rawPath = FileSystemEntity._toNullTerminatedUtf8Array(rawPath); - _path = FileSystemEntity._toStringFromUtf8Array(rawPath); - } + _Directory.fromRawPath(Uint8List rawPath) + : _rawPath = FileSystemEntity._toNullTerminatedUtf8Array( + _checkNotNull(rawPath, "rawPath")), + _path = FileSystemEntity._toStringFromUtf8Array(rawPath); String get path => _path; @@ -53,7 +46,7 @@ class _Directory extends FileSystemEntity implements Directory { } static void set current(path) { - Uint8List _rawPath; + late Uint8List _rawPath; if (path is _Directory) { // For our internal Directory implementation, go ahead and use the raw // path. @@ -144,7 +137,7 @@ class _Directory extends FileSystemEntity implements Directory { static Directory get systemTemp => new Directory(_systemTemp(_Namespace._namespace)); - Future createTemp([String prefix]) { + Future createTemp([String? prefix]) { prefix ??= ''; if (path == '') { throw new ArgumentError("Directory.createTemp called with an empty path. " @@ -168,7 +161,7 @@ class _Directory extends FileSystemEntity implements Directory { }); } - Directory createTempSync([String prefix]) { + Directory createTempSync([String? prefix]) { prefix ??= ''; if (path == '') { throw new ArgumentError("Directory.createTemp called with an empty path. " @@ -220,9 +213,8 @@ class _Directory extends FileSystemEntity implements Directory { } Directory renameSync(String newPath) { - if (newPath is! String) { - throw new ArgumentError(); - } + // TODO(40614): Remove once non-nullability is sound. + ArgumentError.checkNotNull(newPath, "newPath"); var result = _rename(_Namespace._namespace, _rawPath, newPath); if (result is OSError) { throw new FileSystemException("Rename failed", path, result); @@ -244,9 +236,9 @@ class _Directory extends FileSystemEntity implements Directory { List listSync( {bool recursive: false, bool followLinks: true}) { - if (recursive is! bool || followLinks is! bool) { - throw new ArgumentError(); - } + // TODO(40614): Remove once non-nullability is sound. + ArgumentError.checkNotNull(recursive, "recursive"); + ArgumentError.checkNotNull(followLinks, "followLinks"); var result = []; _fillWithDirectoryListing( _Namespace._namespace, @@ -278,12 +270,18 @@ class _Directory extends FileSystemEntity implements Directory { return new Exception("Unknown error"); } } + + // TODO(40614): Remove once non-nullability is sound. + static T _checkNotNull(T t, String name) { + ArgumentError.checkNotNull(t, name); + return t; + } } abstract class _AsyncDirectoryListerOps { external factory _AsyncDirectoryListerOps(int pointer); - int getPointer(); + int? getPointer(); } class _AsyncDirectoryLister { @@ -302,16 +300,18 @@ class _AsyncDirectoryLister { final bool recursive; final bool followLinks; - StreamController controller; + final controller = new StreamController(sync: true); bool canceled = false; bool nextRunning = false; bool closed = false; - _AsyncDirectoryListerOps _ops; + _AsyncDirectoryListerOps? _ops; Completer closeCompleter = new Completer(); _AsyncDirectoryLister(this.rawPath, this.recursive, this.followLinks) { - controller = new StreamController( - onListen: onListen, onResume: onResume, onCancel: onCancel, sync: true); + controller + ..onListen = onListen + ..onResume = onResume + ..onCancel = onCancel; } // WARNING: @@ -319,8 +319,8 @@ class _AsyncDirectoryLister { // object that implements the async directory lister operations. It should // only be called to pass the pointer to the IO Service, which will decrement // the reference count when it is finished with it. - int _pointer() { - return (_ops == null) ? null : _ops.getPointer(); + int? _pointer() { + return _ops?.getPointer(); } Stream get stream => controller.stream; diff --git a/sdk/lib/io/embedder_config.dart b/sdk/lib/io/embedder_config.dart index 179c06abb30..cbc94f7243b 100644 --- a/sdk/lib/io/embedder_config.dart +++ b/sdk/lib/io/embedder_config.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.io; /// Embedder-specific, fine-grained dart:io configuration. diff --git a/sdk/lib/io/eventhandler.dart b/sdk/lib/io/eventhandler.dart index 6a3467fd17c..cfad3101f78 100644 --- a/sdk/lib/io/eventhandler.dart +++ b/sdk/lib/io/eventhandler.dart @@ -2,10 +2,8 @@ // 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.6 - part of dart.io; class _EventHandler { - external static void _sendData(Object sender, SendPort sendPort, int data); + external static void _sendData(Object? sender, SendPort sendPort, int data); } diff --git a/sdk/lib/io/file.dart b/sdk/lib/io/file.dart index 7100de71fd5..234220a0410 100644 --- a/sdk/lib/io/file.dart +++ b/sdk/lib/io/file.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.io; /** @@ -252,7 +250,7 @@ abstract class File implements FileSystemEntity { */ @pragma("vm:entry-point") factory File(String path) { - final IOOverrides overrides = IOOverrides.current; + final IOOverrides? overrides = IOOverrides.current; if (overrides == null) { return new _File(path); } @@ -485,7 +483,7 @@ abstract class File implements FileSystemEntity { * must be read to completion or the subscription on the stream must * be cancelled. */ - Stream> openRead([int start, int end]); + Stream> openRead([int? start, int? end]); /** * Creates a new independent [IOSink] for the file. The @@ -703,7 +701,7 @@ abstract class RandomAccessFile { * * Returns a `Future` that completes with the number of bytes read. */ - Future readInto(List buffer, [int start = 0, int end]); + Future readInto(List buffer, [int start = 0, int? end]); /** * Synchronously reads into an existing [List] from the file and returns @@ -716,7 +714,7 @@ abstract class RandomAccessFile { * * Throws a [FileSystemException] if the operation fails. */ - int readIntoSync(List buffer, [int start = 0, int end]); + int readIntoSync(List buffer, [int start = 0, int? end]); /** * Writes a single byte to the file. Returns a @@ -741,7 +739,7 @@ abstract class RandomAccessFile { * [RandomAccessFile] when the write completes. */ Future writeFrom(List buffer, - [int start = 0, int end]); + [int start = 0, int? end]); /** * Synchronously writes from a [List] to the file. It will read the @@ -751,7 +749,7 @@ abstract class RandomAccessFile { * * Throws a [FileSystemException] if the operation fails. */ - void writeFromSync(List buffer, [int start = 0, int end]); + void writeFromSync(List buffer, [int start = 0, int? end]); /** * Writes a string to the file using the given [Encoding]. Returns a @@ -973,13 +971,13 @@ class FileSystemException implements IOException { * The file system path on which the error occurred. Can be `null` * if the exception does not relate directly to a file system path. */ - final String path; + final String? path; /** * The underlying OS error. Can be `null` if the exception is not * raised due to an OS error. */ - final OSError osError; + final OSError? osError; /** * Creates a new FileSystemException with an optional error message diff --git a/sdk/lib/io/file_impl.dart b/sdk/lib/io/file_impl.dart index f0a1275d8c2..ee34b7d665c 100644 --- a/sdk/lib/io/file_impl.dart +++ b/sdk/lib/io/file_impl.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.io; // Read the file in blocks of size 64k. @@ -11,13 +9,13 @@ const int _blockSize = 64 * 1024; class _FileStream extends Stream> { // Stream controller. - StreamController _controller; + late StreamController _controller; // Information about the underlying file. - String _path; - RandomAccessFile _openedFile; + String? _path; + late RandomAccessFile _openedFile; int _position; - int _end; + int? _end; final Completer _closeCompleter = new Completer(); // Has the stream been paused or unsubscribed? @@ -29,20 +27,12 @@ class _FileStream extends Stream> { bool _atEnd = false; - _FileStream(this._path, this._position, this._end) { - _position ??= 0; - } + _FileStream(this._path, int? position, this._end) : _position = position ?? 0; _FileStream.forStdin() : _position = 0; - StreamSubscription listen(void onData(Uint8List event), - {Function onError, void onDone(), bool cancelOnError}) { - _setupController(); - return _controller.stream.listen(onData, - onError: onError, onDone: onDone, cancelOnError: cancelOnError); - } - - void _setupController() { + StreamSubscription listen(void onData(Uint8List event)?, + {Function? onError, void onDone()?, bool? cancelOnError}) { _controller = new StreamController( sync: true, onListen: _start, @@ -51,6 +41,8 @@ class _FileStream extends Stream> { _unsubscribed = true; return _closeFile(); }); + return _controller.stream.listen(onData, + onError: onError, onDone: onDone, cancelOnError: cancelOnError); } Future _closeFile() { @@ -77,12 +69,13 @@ class _FileStream extends Stream> { } _readInProgress = true; int readBytes = _blockSize; - if (_end != null) { - readBytes = min(readBytes, _end - _position); + final end = _end; + if (end != null) { + readBytes = min(readBytes, end - _position); if (readBytes < 0) { _readInProgress = false; if (!_unsubscribed) { - _controller.addError(new RangeError("Bad end position: $_end")); + _controller.addError(new RangeError("Bad end position: $end")); _closeFile(); _unsubscribed = true; } @@ -147,8 +140,9 @@ class _FileStream extends Stream> { _closeCompleter.complete(); } - if (_path != null) { - new File(_path) + final path = _path; + if (path != null) { + new File(path) .open(mode: FileMode.read) .then(onOpenFile, onError: openFailed); } else { @@ -162,22 +156,21 @@ class _FileStream extends Stream> { } class _FileStreamConsumer extends StreamConsumer> { - File _file; + File? _file; Future _openFuture; - _FileStreamConsumer(this._file, FileMode mode) { - _openFuture = _file.open(mode: mode); - } + _FileStreamConsumer(File file, FileMode mode) + : _file = file, + _openFuture = file.open(mode: mode); - _FileStreamConsumer.fromStdio(int fd) { - _openFuture = new Future.value(_File._openStdioSync(fd)); - } + _FileStreamConsumer.fromStdio(int fd) + : _openFuture = new Future.value(_File._openStdioSync(fd)); - Future addStream(Stream> stream) { - Completer completer = new Completer.sync(); + Future addStream(Stream> stream) { + Completer completer = new Completer.sync(); _openFuture.then((openedFile) { - var _subscription; - void error(e, [StackTrace stackTrace]) { + late StreamSubscription> _subscription; + void error(e, StackTrace stackTrace) { _subscription.cancel(); openedFile.close(); completer.completeError(e, stackTrace); @@ -199,26 +192,23 @@ class _FileStreamConsumer extends StreamConsumer> { return completer.future; } - Future close() => + Future close() => _openFuture.then((openedFile) => openedFile.close()).then((_) => _file); } // Class for encapsulating the native implementation of files. class _File extends FileSystemEntity implements File { - String _path; - Uint8List _rawPath; + final String _path; + final Uint8List _rawPath; - _File(String path) { - ArgumentError.checkNotNull(path, 'path'); - _path = path; - _rawPath = FileSystemEntity._toUtf8Array(path); - } + _File(String path) + : _path = _checkNotNull(path, "path"), + _rawPath = FileSystemEntity._toUtf8Array(path); - _File.fromRawPath(Uint8List rawPath) { - ArgumentError.checkNotNull(rawPath, 'rawPath'); - _rawPath = FileSystemEntity._toNullTerminatedUtf8Array(rawPath); - _path = FileSystemEntity._toStringFromUtf8Array(rawPath); - } + _File.fromRawPath(Uint8List rawPath) + : _rawPath = FileSystemEntity._toNullTerminatedUtf8Array( + _checkNotNull(rawPath, "rawPath")), + _path = FileSystemEntity._toStringFromUtf8Array(rawPath); String get path => _path; @@ -500,7 +490,7 @@ class _File extends FileSystemEntity implements File { return new _RandomAccessFile(id, ""); } - Stream> openRead([int start, int end]) { + Stream> openRead([int? start, int? end]) { return new _FileStream(path, start, end); } @@ -645,6 +635,12 @@ class _File extends FileSystemEntity implements File { throw new FileSystemException(msg, path, result); } } + + // TODO(40614): Remove once non-nullability is sound. + static T _checkNotNull(T t, String name) { + ArgumentError.checkNotNull(t, name); + return t; + } } abstract class _RandomAccessFileOps { @@ -654,9 +650,9 @@ abstract class _RandomAccessFileOps { int close(); readByte(); read(int bytes); - readInto(List buffer, int start, int end); + readInto(List buffer, int start, int? end); writeByte(int value); - writeFrom(List buffer, int start, int end); + writeFrom(List buffer, int start, int? end); position(); setPosition(int position); truncate(int length); @@ -671,13 +667,12 @@ class _RandomAccessFile implements RandomAccessFile { final String path; bool _asyncDispatched = false; - SendPort _fileService; - _FileResourceInfo _resourceInfo; + late _FileResourceInfo _resourceInfo; _RandomAccessFileOps _ops; - _RandomAccessFile(int pointer, this.path) { - _ops = new _RandomAccessFileOps(pointer); + _RandomAccessFile(int pointer, this.path) + : _ops = new _RandomAccessFileOps(pointer) { _resourceInfo = new _FileResourceInfo(this); _maybeConnectHandler(); } @@ -744,7 +739,8 @@ class _RandomAccessFile implements RandomAccessFile { } Future read(int bytes) { - ArgumentError.checkNotNull(bytes, 'bytes'); + // TODO(40614): Remove once non-nullability is sound. + ArgumentError.checkNotNull(bytes, "bytes"); return _dispatch(_IOService.fileRead, [null, bytes]).then((response) { if (_isErrorResponse(response)) { throw _exceptionFromResponse(response, "read failed", path); @@ -756,8 +752,9 @@ class _RandomAccessFile implements RandomAccessFile { } Uint8List readSync(int bytes) { + // TODO(40614): Remove once non-nullability is sound. + ArgumentError.checkNotNull(bytes, "bytes"); _checkAvailable(); - ArgumentError.checkNotNull(bytes, 'bytes'); var result = _ops.read(bytes); if (result is OSError) { throw new FileSystemException("readSync failed", path, result); @@ -766,12 +763,9 @@ class _RandomAccessFile implements RandomAccessFile { return result; } - Future readInto(List buffer, [int start = 0, int end]) { - if ((buffer is! List) || - ((start != null) && (start is! int)) || - ((end != null) && (end is! int))) { - throw new ArgumentError(); - } + Future readInto(List buffer, [int start = 0, int? end]) { + // TODO(40614): Remove once non-nullability is sound. + ArgumentError.checkNotNull(buffer, "buffer"); end = RangeError.checkValidRange(start, end, buffer.length); if (end == start) { return new Future.value(0); @@ -789,13 +783,10 @@ class _RandomAccessFile implements RandomAccessFile { }); } - int readIntoSync(List buffer, [int start = 0, int end]) { + int readIntoSync(List buffer, [int start = 0, int? end]) { + // TODO(40614): Remove once non-nullability is sound. + ArgumentError.checkNotNull(buffer, "buffer"); _checkAvailable(); - if ((buffer is! List) || - ((start != null) && (start is! int)) || - ((end != null) && (end is! int))) { - throw new ArgumentError(); - } end = RangeError.checkValidRange(start, end, buffer.length); if (end == start) { return 0; @@ -809,7 +800,8 @@ class _RandomAccessFile implements RandomAccessFile { } Future writeByte(int value) { - ArgumentError.checkNotNull(value, 'value'); + // TODO(40614): Remove once non-nullability is sound. + ArgumentError.checkNotNull(value, "value"); return _dispatch(_IOService.fileWriteByte, [null, value]).then((response) { if (_isErrorResponse(response)) { throw _exceptionFromResponse(response, "writeByte failed", path); @@ -821,7 +813,8 @@ class _RandomAccessFile implements RandomAccessFile { int writeByteSync(int value) { _checkAvailable(); - ArgumentError.checkNotNull(value, 'value'); + // TODO(40614): Remove once non-nullability is sound. + ArgumentError.checkNotNull(value, "value"); var result = _ops.writeByte(value); if (result is OSError) { throw new FileSystemException("writeByte failed", path, result); @@ -831,12 +824,10 @@ class _RandomAccessFile implements RandomAccessFile { } Future writeFrom(List buffer, - [int start = 0, int end]) { - if ((buffer is! List) || - ((start != null) && (start is! int)) || - ((end != null) && (end is! int))) { - throw new ArgumentError("Invalid arguments to writeFrom"); - } + [int start = 0, int? end]) { + // TODO(40614): Remove once non-nullability is sound. + ArgumentError.checkNotNull(buffer, "buffer"); + ArgumentError.checkNotNull(start, "start"); end = RangeError.checkValidRange(start, end, buffer.length); if (end == start) { return new Future.value(this); @@ -848,7 +839,7 @@ class _RandomAccessFile implements RandomAccessFile { return new Future.error(e); } - List request = new List(4); + List request = new List.filled(4, null); request[0] = null; request[1] = result.buffer; request[2] = result.start; @@ -857,18 +848,16 @@ class _RandomAccessFile implements RandomAccessFile { if (_isErrorResponse(response)) { throw _exceptionFromResponse(response, "writeFrom failed", path); } - _resourceInfo.addWrite(end - (start - result.start)); + _resourceInfo.addWrite(end! - (start - result.start)); return this; }); } - void writeFromSync(List buffer, [int start = 0, int end]) { + void writeFromSync(List buffer, [int start = 0, int? end]) { _checkAvailable(); - if ((buffer is! List) || - ((start != null) && (start is! int)) || - ((end != null) && (end is! int))) { - throw new ArgumentError("Invalid arguments to writeFromSync"); - } + // TODO(40614): Remove once non-nullability is sound. + ArgumentError.checkNotNull(buffer, "buffer"); + ArgumentError.checkNotNull(start, "start"); end = RangeError.checkValidRange(start, end, buffer.length); if (end == start) { return; @@ -885,13 +874,15 @@ class _RandomAccessFile implements RandomAccessFile { Future writeString(String string, {Encoding encoding: utf8}) { - ArgumentError.checkNotNull(encoding, 'encoding'); + // TODO(40614): Remove once non-nullability is sound. + ArgumentError.checkNotNull(encoding, "encoding"); var data = encoding.encode(string); return writeFrom(data, 0, data.length); } void writeStringSync(String string, {Encoding encoding: utf8}) { - ArgumentError.checkNotNull(encoding, 'encoding'); + // TODO(40614): Remove once non-nullability is sound. + ArgumentError.checkNotNull(encoding, "encoding"); var data = encoding.encode(string); writeFromSync(data, 0, data.length); } @@ -994,9 +985,10 @@ class _RandomAccessFile implements RandomAccessFile { Future lock( [FileLock mode = FileLock.exclusive, int start = 0, int end = -1]) { - if ((mode is! FileLock) || (start is! int) || (end is! int)) { - throw new ArgumentError(); - } + // TODO(40614): Remove once non-nullability is sound. + ArgumentError.checkNotNull(mode, "mode"); + ArgumentError.checkNotNull(start, "start"); + ArgumentError.checkNotNull(end, "end"); if ((start < 0) || (end < -1) || ((end != -1) && (start >= end))) { throw new ArgumentError(); } @@ -1011,9 +1003,9 @@ class _RandomAccessFile implements RandomAccessFile { } Future unlock([int start = 0, int end = -1]) { - if ((start is! int) || (end is! int)) { - throw new ArgumentError(); - } + // TODO(40614): Remove once non-nullability is sound. + ArgumentError.checkNotNull(start, "start"); + ArgumentError.checkNotNull(end, "end"); if (start == end) { throw new ArgumentError(); } @@ -1029,9 +1021,10 @@ class _RandomAccessFile implements RandomAccessFile { void lockSync( [FileLock mode = FileLock.exclusive, int start = 0, int end = -1]) { _checkAvailable(); - if ((mode is! FileLock) || (start is! int) || (end is! int)) { - throw new ArgumentError(); - } + // TODO(40614): Remove once non-nullability is sound. + ArgumentError.checkNotNull(mode, "mode"); + ArgumentError.checkNotNull(start, "start"); + ArgumentError.checkNotNull(end, "end"); if ((start < 0) || (end < -1) || ((end != -1) && (start >= end))) { throw new ArgumentError(); } @@ -1044,9 +1037,9 @@ class _RandomAccessFile implements RandomAccessFile { void unlockSync([int start = 0, int end = -1]) { _checkAvailable(); - if ((start is! int) || (end is! int)) { - throw new ArgumentError(); - } + // TODO(40614): Remove once non-nullability is sound. + ArgumentError.checkNotNull(start, "start"); + ArgumentError.checkNotNull(end, "end"); if (start == end) { throw new ArgumentError(); } diff --git a/sdk/lib/io/file_system_entity.dart b/sdk/lib/io/file_system_entity.dart index 3f45ca585fd..0741583267b 100644 --- a/sdk/lib/io/file_system_entity.dart +++ b/sdk/lib/io/file_system_entity.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.io; /** @@ -117,7 +115,7 @@ class FileStat { * [FileSystemEntityType.notFound] and the other fields invalid. */ static FileStat statSync(String path) { - final IOOverrides overrides = IOOverrides.current; + final IOOverrides? overrides = IOOverrides.current; if (overrides == null) { return _statSyncInternal(path); } @@ -147,7 +145,7 @@ class FileStat { * Returns a [Future] which completes with the same results as [statSync]. */ static Future stat(String path) { - final IOOverrides overrides = IOOverrides.current; + final IOOverrides? overrides = IOOverrides.current; if (overrides == null) { return _stat(path); } @@ -249,8 +247,8 @@ FileStat: type $type * files and directories. */ abstract class FileSystemEntity { - String _path; - Uint8List _rawPath; + String get _path; + Uint8List get _rawPath; String get path; @@ -496,7 +494,7 @@ abstract class FileSystemEntity { {int events: FileSystemEvent.all, bool recursive: false}) { // FIXME(bkonyi): find a way to do this using the raw path. final String trimmedPath = _trimTrailingPathSeparators(path); - final IOOverrides overrides = IOOverrides.current; + final IOOverrides? overrides = IOOverrides.current; if (overrides == null) { return _FileSystemWatcher._watch(trimmedPath, events, recursive); } @@ -532,7 +530,7 @@ abstract class FileSystemEntity { * to an object that does not exist. */ static Future identical(String path1, String path2) { - IOOverrides overrides = IOOverrides.current; + IOOverrides? overrides = IOOverrides.current; if (overrides == null) { return _identical(path1, path2); } @@ -614,7 +612,7 @@ abstract class FileSystemEntity { * exist. */ static bool identicalSync(String path1, String path2) { - IOOverrides overrides = IOOverrides.current; + IOOverrides? overrides = IOOverrides.current; if (overrides == null) { return _identicalSync(path1, path2); } @@ -627,7 +625,7 @@ abstract class FileSystemEntity { * OS X 10.6 and below is not supported. */ static bool get isWatchSupported { - final IOOverrides overrides = IOOverrides.current; + final IOOverrides? overrides = IOOverrides.current; if (overrides == null) { return _FileSystemWatcher.isSupported; } @@ -637,12 +635,9 @@ abstract class FileSystemEntity { // The native methods which determine type of the FileSystemEntity require // that the buffer provided is null terminated. static Uint8List _toUtf8Array(String s) => - _toNullTerminatedUtf8Array(utf8.encode(s)); + _toNullTerminatedUtf8Array(utf8.encoder.convert(s)); static Uint8List _toNullTerminatedUtf8Array(Uint8List l) { - if (l == null) { - return null; - } if (l.isNotEmpty && l.last != 0) { final tmp = new Uint8List(l.length + 1); tmp.setRange(0, l.length, l); @@ -653,9 +648,6 @@ abstract class FileSystemEntity { } static String _toStringFromUtf8Array(Uint8List l) { - if (l == null) { - return ''; - } Uint8List nonNullTerminated = l; if (l.last == 0) { nonNullTerminated = @@ -793,7 +785,7 @@ abstract class FileSystemEntity { static FileSystemEntityType _getTypeSync( Uint8List rawPath, bool followLinks) { - IOOverrides overrides = IOOverrides.current; + IOOverrides? overrides = IOOverrides.current; if (overrides == null) { return _getTypeSyncHelper(rawPath, followLinks); } @@ -815,7 +807,7 @@ abstract class FileSystemEntity { static Future _getType( Uint8List rawPath, bool followLinks) { - IOOverrides overrides = IOOverrides.current; + IOOverrides? overrides = IOOverrides.current; if (overrides == null) { return _getTypeRequest(rawPath, followLinks); } @@ -823,7 +815,7 @@ abstract class FileSystemEntity { utf8.decode(rawPath, allowMalformed: true), followLinks); } - static _throwIfError(Object result, String msg, [String path]) { + static _throwIfError(Object result, String msg, [String? path]) { if (result is OSError) { throw new FileSystemException(msg, path, result); } else if (result is ArgumentError) { @@ -833,8 +825,8 @@ abstract class FileSystemEntity { // TODO(bkonyi): find a way to do this with raw paths. static String _trimTrailingPathSeparators(String path) { - // Don't handle argument errors here. - if (path == null) return path; + // TODO(40614): Remove once non-nullability is sound. + ArgumentError.checkNotNull(path, "path"); if (Platform.isWindows) { while (path.length > 1 && (path.endsWith(Platform.pathSeparator) || path.endsWith('/'))) { @@ -850,8 +842,6 @@ abstract class FileSystemEntity { // TODO(bkonyi): find a way to do this with raw paths. static String _ensureTrailingPathSeparators(String path) { - // Don't handle argument errors here. - if (path == null) return path; if (path.isEmpty) path = '.'; if (Platform.isWindows) { while (!path.endsWith(Platform.pathSeparator) && !path.endsWith('/')) { @@ -980,7 +970,7 @@ class FileSystemMoveEvent extends FileSystemEvent { * If the underlying implementation is able to identify the destination of * the moved file, [destination] will be set. Otherwise, it will be `null`. */ - final String destination; + final String? destination; FileSystemMoveEvent._(path, isDirectory, this.destination) : super._(FileSystemEvent.move, path, isDirectory); @@ -994,7 +984,7 @@ class FileSystemMoveEvent extends FileSystemEvent { } } -class _FileSystemWatcher { +abstract class _FileSystemWatcher { external static Stream _watch( String path, int events, bool recursive); external static bool get isSupported; diff --git a/sdk/lib/io/io.dart b/sdk/lib/io/io.dart index e9fc2778a3a..27cd6a3b801 100644 --- a/sdk/lib/io/io.dart +++ b/sdk/lib/io/io.dart @@ -2,8 +2,6 @@ // 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.6 - /** * File, socket, HTTP, and other I/O support for non-web applications. * diff --git a/sdk/lib/io/io_resource_info.dart b/sdk/lib/io/io_resource_info.dart index a81da1177aa..b916dd800bd 100644 --- a/sdk/lib/io/io_resource_info.dart +++ b/sdk/lib/io/io_resource_info.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.io; abstract class _IOResourceInfo { @@ -125,10 +123,9 @@ class _FileResourceInfo extends _ReadWriteResourceInfo { } static Future getFileInfoMapByID(function, params) { - assert(params.containsKey('id')); - var id = int.parse(params['id']); + var id = int.parse(params['id']!); var result = - openFiles.containsKey(id) ? openFiles[id].getFileInfoMap() : {}; + openFiles.containsKey(id) ? openFiles[id]!.getFileInfoMap() : {}; var jsonValue = json.encode(result); return new Future.value(new ServiceExtensionResponse.result(jsonValue)); } @@ -192,9 +189,9 @@ class _ProcessResourceInfo extends _IOResourceInfo { static Future getProcessInfoMapById( String function, Map params) { - var id = int.parse(params['id']); + var id = int.parse(params['id']!); var result = startedProcesses.containsKey(id) - ? startedProcesses[id].fullValueMap + ? startedProcesses[id]!.fullValueMap : {}; var jsonValue = json.encode(result); return new Future.value(new ServiceExtensionResponse.result(jsonValue)); @@ -257,10 +254,9 @@ class _SocketResourceInfo extends _ReadWriteResourceInfo { static Future getSocketInfoMapByID( String function, Map params) { - assert(params.containsKey('id')); - var id = int.parse(params['id']); + var id = int.parse(params['id']!); var result = - openSockets.containsKey(id) ? openSockets[id].getSocketInfoMap() : {}; + openSockets.containsKey(id) ? openSockets[id]!.getSocketInfoMap() : {}; var jsonValue = json.encode(result); return new Future.value(new ServiceExtensionResponse.result(jsonValue)); } diff --git a/sdk/lib/io/io_service.dart b/sdk/lib/io/io_service.dart index 92d3e846b7f..7af382c9807 100644 --- a/sdk/lib/io/io_service.dart +++ b/sdk/lib/io/io_service.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.io; class _IOService { diff --git a/sdk/lib/io/io_sink.dart b/sdk/lib/io/io_sink.dart index 96a68a9a17b..622656adfc1 100644 --- a/sdk/lib/io/io_sink.dart +++ b/sdk/lib/io/io_sink.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.io; /** @@ -33,7 +31,7 @@ abstract class IOSink implements StreamSink>, StringSink { * The [Encoding] used when writing strings. Depending on the * underlying consumer this property might be mutable. */ - Encoding encoding; + late Encoding encoding; /** * Adds byte [data] to the target consumer, ignoring [encoding]. @@ -58,13 +56,13 @@ abstract class IOSink implements StreamSink>, StringSink { * This operation is non-blocking. See [flush] or [done] for how to get any * errors generated by this call. */ - void write(Object obj); + void write(Object? obj); /** * Iterates over the given [objects] and [write]s them in sequence. * * If [separator] is provided, a `write` with the `separator` is performed - * between any two elements of objects`. + * between any two elements of objects. * * This operation is non-blocking. See [flush] or [done] for how to get any * errors generated by this call. @@ -78,7 +76,7 @@ abstract class IOSink implements StreamSink>, StringSink { * This operation is non-blocking. See [flush] or [done] for how to get any * errors generated by this call. */ - void writeln([Object obj = ""]); + void writeln([Object? obj = ""]); /** * Writes the character of [charCode]. @@ -99,7 +97,7 @@ abstract class IOSink implements StreamSink>, StringSink { * This operation is non-blocking. See [flush] or [done] for how to get any * errors generated by this call. */ - void addError(error, [StackTrace stackTrace]); + void addError(error, [StackTrace? stackTrace]); /** * Adds all elements of the given [stream] to `this`. @@ -143,8 +141,8 @@ abstract class IOSink implements StreamSink>, StringSink { class _StreamSinkImpl implements StreamSink { final StreamConsumer _target; final Completer _doneCompleter = new Completer(); - StreamController _controllerInstance; - Completer _controllerCompleter; + StreamController? _controllerInstance; + Completer? _controllerCompleter; bool _isClosed = false; bool _isBound = false; bool _hasError = false; @@ -158,7 +156,7 @@ class _StreamSinkImpl implements StreamSink { _controller.add(data); } - void addError(error, [StackTrace stackTrace]) { + void addError(error, [StackTrace? stackTrace]) { if (_isClosed) { throw StateError("StreamSink is closed"); } @@ -174,7 +172,7 @@ class _StreamSinkImpl implements StreamSink { _isBound = true; var future = _controllerCompleter == null ? _target.addStream(stream) - : _controllerCompleter.future.then((_) => _target.addStream(stream)); + : _controllerCompleter!.future.then((_) => _target.addStream(stream)); _controllerInstance?.close(); // Wait for any pending events in [_controller] to be dispatched before @@ -192,8 +190,8 @@ class _StreamSinkImpl implements StreamSink { // Adding an empty stream-controller will return a future that will complete // when all data is done. _isBound = true; - var future = _controllerCompleter.future; - _controllerInstance.close(); + var future = _controllerCompleter!.future; + _controllerInstance!.close(); return future.whenComplete(() { _isBound = false; }); @@ -206,7 +204,7 @@ class _StreamSinkImpl implements StreamSink { if (!_isClosed) { _isClosed = true; if (_controllerInstance != null) { - _controllerInstance.close(); + _controllerInstance!.close(); } else { _closeTarget(); } @@ -226,7 +224,7 @@ class _StreamSinkImpl implements StreamSink { } } - void _completeDoneError(error, StackTrace stackTrace) { + void _completeDoneError(error, StackTrace? stackTrace) { if (!_doneCompleter.isCompleted) { _hasError = true; _doneCompleter.completeError(error, stackTrace); @@ -246,7 +244,7 @@ class _StreamSinkImpl implements StreamSink { _target.addStream(_controller.stream).then((_) { if (_isBound) { // A new stream takes over - forward values to that stream. - _controllerCompleter.complete(this); + _controllerCompleter!.complete(this); _controllerCompleter = null; _controllerInstance = null; } else { @@ -256,7 +254,7 @@ class _StreamSinkImpl implements StreamSink { }, onError: (error, stackTrace) { if (_isBound) { // A new stream takes over - forward errors to that stream. - _controllerCompleter.completeError(error, stackTrace); + _controllerCompleter!.completeError(error, stackTrace); _controllerCompleter = null; _controllerInstance = null; } else { @@ -266,7 +264,7 @@ class _StreamSinkImpl implements StreamSink { } }); } - return _controllerInstance; + return _controllerInstance!; } } @@ -285,7 +283,7 @@ class _IOSinkImpl extends _StreamSinkImpl> implements IOSink { _encoding = value; } - void write(Object obj) { + void write(Object? obj) { String string = '$obj'; if (string.isEmpty) return; add(_encoding.encode(string)); @@ -307,7 +305,7 @@ class _IOSinkImpl extends _StreamSinkImpl> implements IOSink { } } - void writeln([Object object = ""]) { + void writeln([Object? object = ""]) { write(object); write("\n"); } diff --git a/sdk/lib/io/link.dart b/sdk/lib/io/link.dart index b2105070412..3f2896fc21b 100644 --- a/sdk/lib/io/link.dart +++ b/sdk/lib/io/link.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.io; /** @@ -17,7 +15,7 @@ abstract class Link implements FileSystemEntity { */ @pragma("vm:entry-point") factory Link(String path) { - final IOOverrides overrides = IOOverrides.current; + final IOOverrides? overrides = IOOverrides.current; if (overrides == null) { return new _Link(path); } @@ -155,19 +153,16 @@ abstract class Link implements FileSystemEntity { } class _Link extends FileSystemEntity implements Link { - String _path; - Uint8List _rawPath; + final String _path; + final Uint8List _rawPath; - _Link(String path) { - ArgumentError.checkNotNull(path, 'path'); - _path = path; - _rawPath = FileSystemEntity._toUtf8Array(path); - } + _Link(String path) + : _path = path, + _rawPath = FileSystemEntity._toUtf8Array(path); - _Link.fromRawPath(Uint8List rawPath) { - _rawPath = FileSystemEntity._toNullTerminatedUtf8Array(rawPath); - _path = FileSystemEntity._toStringFromUtf8Array(rawPath); - } + _Link.fromRawPath(Uint8List rawPath) + : _rawPath = FileSystemEntity._toNullTerminatedUtf8Array(rawPath), + _path = FileSystemEntity._toStringFromUtf8Array(rawPath); String get path => _path; @@ -276,7 +271,7 @@ class _Link extends FileSystemEntity implements Link { return result; } - static throwIfError(Object result, String msg, [String path = ""]) { + static throwIfError(Object? result, String msg, [String path = ""]) { if (result is OSError) { throw new FileSystemException(msg, path, result); } diff --git a/sdk/lib/io/namespace_impl.dart b/sdk/lib/io/namespace_impl.dart index 763f4aa76df..88987b60ef2 100644 --- a/sdk/lib/io/namespace_impl.dart +++ b/sdk/lib/io/namespace_impl.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.io; // Each Isolate may run in a different "namespace", which provides the scope in diff --git a/sdk/lib/io/network_profiling.dart b/sdk/lib/io/network_profiling.dart index f23ed3703e6..5032d72a109 100644 --- a/sdk/lib/io/network_profiling.dart +++ b/sdk/lib/io/network_profiling.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.io; const int _versionMajor = 1; @@ -73,7 +71,7 @@ abstract class _NetworkProfiling { 'Method $method does not exist')); } return Future.value(ServiceExtensionResponse.result(responseJson)); - } catch (errorMessage) { + } on dynamic catch (errorMessage) { return Future.value(ServiceExtensionResponse.error( ServiceExtensionResponse.invalidParams, errorMessage)); } @@ -105,7 +103,7 @@ String _setHttpEnableTimelineLogging(Map parameters) { if (!parameters.containsKey(kEnable)) { throw _missingArgument(kEnable); } - final enable = parameters[kEnable].toLowerCase(); + final enable = parameters[kEnable]!.toLowerCase(); if (enable != 'true' && enable != 'false') { throw _invalidArgument(kEnable, enable); } @@ -139,8 +137,7 @@ abstract class _SocketProfile { // Skip socket that started before _enableSocketProfiling turned on. if (!_idToSocketStatistic.containsKey(id) && type != _SocketProfileType.startTime) return; - _idToSocketStatistic[id] ??= _SocketStatistic(id); - _SocketStatistic stats = _idToSocketStatistic[id]; + _SocketStatistic stats = _idToSocketStatistic[id] ??= _SocketStatistic(id); switch (type) { case _SocketProfileType.startTime: stats.startTime = Timeline.now; @@ -162,16 +159,12 @@ abstract class _SocketProfile { break; case _SocketProfileType.readBytes: if (object == null) return; - assert(object is int); - stats.readBytes ??= 0; - stats.readBytes += object; + stats.readBytes += object as int; stats.lastReadTime = Timeline.now; break; case _SocketProfileType.writeBytes: if (object == null) return; - assert(object is int); - stats.writeBytes ??= 0; - stats.writeBytes += object; + stats.writeBytes += object as int; stats.lastWriteTime = Timeline.now; break; default: @@ -192,7 +185,7 @@ abstract class _SocketProfile { // clear the storage if _idToSocketStatistic has been initialized. static String clear() { - _idToSocketStatistic?.clear(); + _idToSocketStatistic.clear(); return _success(); } } @@ -212,15 +205,15 @@ enum _SocketProfileType { /// Socket statistic class _SocketStatistic { final int id; - int startTime; - int endTime; - String address; - int port; - String socketType; + int? startTime; + int? endTime; + String? address; + int? port; + String? socketType; int readBytes = 0; int writeBytes = 0; - int lastWriteTime; - int lastReadTime; + int? lastWriteTime; + int? lastReadTime; _SocketStatistic(this.id); @@ -240,7 +233,7 @@ class _SocketStatistic { return map; } - void _setIfNotNull(Map json, String key, Object value) { + void _setIfNotNull(Map json, String key, Object? value) { if (value == null) return; json[key] = value; } diff --git a/sdk/lib/io/overrides.dart b/sdk/lib/io/overrides.dart index eecda8eb0be..4b7deaaa8d2 100644 --- a/sdk/lib/io/overrides.dart +++ b/sdk/lib/io/overrides.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.io; final _ioOverridesToken = new Object(); @@ -34,9 +32,9 @@ const _asyncRunZoned = runZoned; /// } /// ``` abstract class IOOverrides { - static IOOverrides _global; + static IOOverrides? _global; - static IOOverrides get current { + static IOOverrides? get current { return Zone.current[_ioOverridesToken] ?? _global; } @@ -45,7 +43,7 @@ abstract class IOOverrides { /// These are the [IOOverrides] that will be used in the root Zone, and in /// Zone's that do not set [IOOverrides] and whose ancestors up to the root /// Zone do not set [IOOverrides]. - static set global(IOOverrides overrides) { + static set global(IOOverrides? overrides) { _global = overrides; } @@ -56,42 +54,42 @@ abstract class IOOverrides { static R runZoned(R body(), { // Directory - Directory Function(String) createDirectory, - Directory Function() getCurrentDirectory, - void Function(String) setCurrentDirectory, - Directory Function() getSystemTempDirectory, + Directory Function(String)? createDirectory, + Directory Function()? getCurrentDirectory, + void Function(String)? setCurrentDirectory, + Directory Function()? getSystemTempDirectory, // File - File Function(String) createFile, + File Function(String)? createFile, // FileStat - Future Function(String) stat, - FileStat Function(String) statSync, + Future Function(String)? stat, + FileStat Function(String)? statSync, // FileSystemEntity - Future Function(String, String) fseIdentical, - bool Function(String, String) fseIdenticalSync, - Future Function(String, bool) fseGetType, - FileSystemEntityType Function(String, bool) fseGetTypeSync, + Future Function(String, String)? fseIdentical, + bool Function(String, String)? fseIdenticalSync, + Future Function(String, bool)? fseGetType, + FileSystemEntityType Function(String, bool)? fseGetTypeSync, // _FileSystemWatcher - Stream Function(String, int, bool) fsWatch, - bool Function() fsWatchIsSupported, + Stream Function(String, int, bool)? fsWatch, + bool Function()? fsWatchIsSupported, // Link - Link Function(String) createLink, + Link Function(String)? createLink, // Socket Future Function(dynamic, int, - {dynamic sourceAddress, Duration timeout}) + {dynamic sourceAddress, Duration? timeout})? socketConnect, Future> Function(dynamic, int, - {dynamic sourceAddress}) + {dynamic sourceAddress})? socketStartConnect, // ServerSocket Future Function(dynamic, int, - {int backlog, bool v6Only, bool shared}) + {int backlog, bool v6Only, bool shared})? serverSocketBind}) { IOOverrides overrides = new _IOOverridesScope( // Directory @@ -217,7 +215,8 @@ abstract class IOOverrides { /// When this override is installed, this function overrides the behavior of /// `FileSystemEntity.type`. Future fseGetType(String path, bool followLinks) { - return FileSystemEntity._getTypeRequest(utf8.encode(path), followLinks); + return FileSystemEntity._getTypeRequest( + utf8.encoder.convert(path), followLinks); } /// Returns the [FileSystemEntityType] for [path]. @@ -225,7 +224,8 @@ abstract class IOOverrides { /// When this override is installed, this function overrides the behavior of /// `FileSystemEntity.typeSync`. FileSystemEntityType fseGetTypeSync(String path, bool followLinks) { - return FileSystemEntity._getTypeSyncHelper(utf8.encode(path), followLinks); + return FileSystemEntity._getTypeSyncHelper( + utf8.encoder.convert(path), followLinks); } // _FileSystemWatcher @@ -259,7 +259,7 @@ abstract class IOOverrides { /// When this override is installed, this functions overrides the behavior of /// `Socket.connect(...)`. Future socketConnect(host, int port, - {sourceAddress, Duration timeout}) { + {sourceAddress, Duration? timeout}) { return Socket._connect(host, port, sourceAddress: sourceAddress, timeout: timeout); } @@ -289,43 +289,43 @@ abstract class IOOverrides { } class _IOOverridesScope extends IOOverrides { - final IOOverrides _previous = IOOverrides.current; + final IOOverrides? _previous = IOOverrides.current; // Directory - Directory Function(String) _createDirectory; - Directory Function() _getCurrentDirectory; - void Function(String) _setCurrentDirectory; - Directory Function() _getSystemTempDirectory; + Directory Function(String)? _createDirectory; + Directory Function()? _getCurrentDirectory; + void Function(String)? _setCurrentDirectory; + Directory Function()? _getSystemTempDirectory; // File - File Function(String) _createFile; + File Function(String)? _createFile; // FileStat - Future Function(String) _stat; - FileStat Function(String) _statSync; + Future Function(String)? _stat; + FileStat Function(String)? _statSync; // FileSystemEntity - Future Function(String, String) _fseIdentical; - bool Function(String, String) _fseIdenticalSync; - Future Function(String, bool) _fseGetType; - FileSystemEntityType Function(String, bool) _fseGetTypeSync; + Future Function(String, String)? _fseIdentical; + bool Function(String, String)? _fseIdenticalSync; + Future Function(String, bool)? _fseGetType; + FileSystemEntityType Function(String, bool)? _fseGetTypeSync; // _FileSystemWatcher - Stream Function(String, int, bool) _fsWatch; - bool Function() _fsWatchIsSupported; + Stream Function(String, int, bool)? _fsWatch; + bool Function()? _fsWatchIsSupported; // Link - Link Function(String) _createLink; + Link Function(String)? _createLink; // Socket Future Function(dynamic, int, - {dynamic sourceAddress, Duration timeout}) _socketConnect; - Future> Function(dynamic, int, {dynamic sourceAddress}) - _socketStartConnect; + {dynamic sourceAddress, Duration? timeout})? _socketConnect; + Future> Function(dynamic, int, + {dynamic sourceAddress})? _socketStartConnect; // ServerSocket Future Function(dynamic, int, - {int backlog, bool v6Only, bool shared}) _serverSocketBind; + {int backlog, bool v6Only, bool shared})? _serverSocketBind; _IOOverridesScope( // Directory @@ -365,120 +365,120 @@ class _IOOverridesScope extends IOOverrides { // Directory @override Directory createDirectory(String path) { - if (_createDirectory != null) return _createDirectory(path); - if (_previous != null) return _previous.createDirectory(path); + if (_createDirectory != null) return _createDirectory!(path); + if (_previous != null) return _previous!.createDirectory(path); return super.createDirectory(path); } @override Directory getCurrentDirectory() { - if (_getCurrentDirectory != null) return _getCurrentDirectory(); - if (_previous != null) return _previous.getCurrentDirectory(); + if (_getCurrentDirectory != null) return _getCurrentDirectory!(); + if (_previous != null) return _previous!.getCurrentDirectory(); return super.getCurrentDirectory(); } @override void setCurrentDirectory(String path) { if (_setCurrentDirectory != null) - _setCurrentDirectory(path); + _setCurrentDirectory!(path); else if (_previous != null) - _previous.setCurrentDirectory(path); + _previous!.setCurrentDirectory(path); else super.setCurrentDirectory(path); } @override Directory getSystemTempDirectory() { - if (_getSystemTempDirectory != null) return _getSystemTempDirectory(); - if (_previous != null) return _previous.getSystemTempDirectory(); + if (_getSystemTempDirectory != null) return _getSystemTempDirectory!(); + if (_previous != null) return _previous!.getSystemTempDirectory(); return super.getSystemTempDirectory(); } // File @override File createFile(String path) { - if (_createFile != null) return _createFile(path); - if (_previous != null) return _previous.createFile(path); + if (_createFile != null) return _createFile!(path); + if (_previous != null) return _previous!.createFile(path); return super.createFile(path); } // FileStat @override Future stat(String path) { - if (_stat != null) return _stat(path); - if (_previous != null) return _previous.stat(path); + if (_stat != null) return _stat!(path); + if (_previous != null) return _previous!.stat(path); return super.stat(path); } @override FileStat statSync(String path) { - if (_stat != null) return _statSync(path); - if (_previous != null) return _previous.statSync(path); + if (_stat != null) return _statSync!(path); + if (_previous != null) return _previous!.statSync(path); return super.statSync(path); } // FileSystemEntity @override Future fseIdentical(String path1, String path2) { - if (_fseIdentical != null) return _fseIdentical(path1, path2); - if (_previous != null) return _previous.fseIdentical(path1, path2); + if (_fseIdentical != null) return _fseIdentical!(path1, path2); + if (_previous != null) return _previous!.fseIdentical(path1, path2); return super.fseIdentical(path1, path2); } @override bool fseIdenticalSync(String path1, String path2) { - if (_fseIdenticalSync != null) return _fseIdenticalSync(path1, path2); - if (_previous != null) return _previous.fseIdenticalSync(path1, path2); + if (_fseIdenticalSync != null) return _fseIdenticalSync!(path1, path2); + if (_previous != null) return _previous!.fseIdenticalSync(path1, path2); return super.fseIdenticalSync(path1, path2); } @override Future fseGetType(String path, bool followLinks) { - if (_fseGetType != null) return _fseGetType(path, followLinks); - if (_previous != null) return _previous.fseGetType(path, followLinks); + if (_fseGetType != null) return _fseGetType!(path, followLinks); + if (_previous != null) return _previous!.fseGetType(path, followLinks); return super.fseGetType(path, followLinks); } @override FileSystemEntityType fseGetTypeSync(String path, bool followLinks) { - if (_fseGetTypeSync != null) return _fseGetTypeSync(path, followLinks); - if (_previous != null) return _previous.fseGetTypeSync(path, followLinks); + if (_fseGetTypeSync != null) return _fseGetTypeSync!(path, followLinks); + if (_previous != null) return _previous!.fseGetTypeSync(path, followLinks); return super.fseGetTypeSync(path, followLinks); } // _FileSystemWatcher @override Stream fsWatch(String path, int events, bool recursive) { - if (_fsWatch != null) return _fsWatch(path, events, recursive); - if (_previous != null) return _previous.fsWatch(path, events, recursive); + if (_fsWatch != null) return _fsWatch!(path, events, recursive); + if (_previous != null) return _previous!.fsWatch(path, events, recursive); return super.fsWatch(path, events, recursive); } @override bool fsWatchIsSupported() { - if (_fsWatchIsSupported != null) return _fsWatchIsSupported(); - if (_previous != null) return _previous.fsWatchIsSupported(); + if (_fsWatchIsSupported != null) return _fsWatchIsSupported!(); + if (_previous != null) return _previous!.fsWatchIsSupported(); return super.fsWatchIsSupported(); } // Link @override Link createLink(String path) { - if (_createLink != null) return _createLink(path); - if (_previous != null) return _previous.createLink(path); + if (_createLink != null) return _createLink!(path); + if (_previous != null) return _previous!.createLink(path); return super.createLink(path); } // Socket @override Future socketConnect(host, int port, - {sourceAddress, Duration timeout}) { + {sourceAddress, Duration? timeout}) { if (_socketConnect != null) { - return _socketConnect(host, port, + return _socketConnect!(host, port, sourceAddress: sourceAddress, timeout: timeout); } if (_previous != null) { - return _previous.socketConnect(host, port, + return _previous!.socketConnect(host, port, sourceAddress: sourceAddress, timeout: timeout); } return super.socketConnect(host, port, @@ -489,11 +489,11 @@ class _IOOverridesScope extends IOOverrides { Future> socketStartConnect(host, int port, {sourceAddress}) { if (_socketStartConnect != null) { - return _socketStartConnect(host, port, sourceAddress: sourceAddress); + return _socketStartConnect!(host, port, sourceAddress: sourceAddress); } if (_previous != null) { - return _previous.socketStartConnect(host, port, - sourceAddress: sourceAddress); + return _previous! + .socketStartConnect(host, port, sourceAddress: sourceAddress); } return super.socketStartConnect(host, port, sourceAddress: sourceAddress); } @@ -503,11 +503,11 @@ class _IOOverridesScope extends IOOverrides { Future serverSocketBind(address, int port, {int backlog: 0, bool v6Only: false, bool shared: false}) { if (_serverSocketBind != null) { - return _serverSocketBind(address, port, + return _serverSocketBind!(address, port, backlog: backlog, v6Only: v6Only, shared: shared); } if (_previous != null) { - return _previous.serverSocketBind(address, port, + return _previous!.serverSocketBind(address, port, backlog: backlog, v6Only: v6Only, shared: shared); } return super.serverSocketBind(address, port, diff --git a/sdk/lib/io/platform.dart b/sdk/lib/io/platform.dart index 7fd53c8f9a8..412e25822fc 100644 --- a/sdk/lib/io/platform.dart +++ b/sdk/lib/io/platform.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.io; /** @@ -210,7 +208,7 @@ class Platform { * */ @Deprecated('packages/ directory resolution is not supported in Dart 2') - static String get packageRoot => null; // TODO(mfairhurst): remove this + static String? get packageRoot => null; // TODO(mfairhurst): remove this /** * The `--packages` flag passed to the executable used to run the script @@ -220,7 +218,7 @@ class Platform { * * Is `null` if there is no `--packages` flag. */ - static String get packageConfig => _Platform.packageConfig; + static String? get packageConfig => _Platform.packageConfig; /** * The version of the current Dart runtime. diff --git a/sdk/lib/io/platform_impl.dart b/sdk/lib/io/platform_impl.dart index 87056978f62..0251445a80e 100644 --- a/sdk/lib/io/platform_impl.dart +++ b/sdk/lib/io/platform_impl.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.io; class _Platform { @@ -32,21 +30,19 @@ class _Platform { */ external static _environment(); external static List _executableArguments(); - external static String _packageRoot(); // TODO(mfairhurst): remove this - external static String _packageConfig(); + external static String? _packageConfig(); external static String _version(); external static String _localeName(); external static Uri _script(); static String executable = _executable(); static String resolvedExecutable = _resolvedExecutable(); - static String packageRoot; // TODO(mfairhurst): remove this - static String packageConfig = _packageConfig(); + static String? packageConfig = _packageConfig(); @pragma("vm:entry-point") - static String Function() _localeClosure; + static String Function()? _localeClosure; static String localeName() { - final result = (_localeClosure == null) ? _localeName() : _localeClosure(); + final result = (_localeClosure == null) ? _localeName() : _localeClosure!(); if (result is OSError) { throw result; } @@ -55,14 +51,14 @@ class _Platform { // Cache the OS environment. This can be an OSError instance if // retrieving the environment failed. - static var /*OSError|Map*/ _environmentCache; + static var /*OSError?|Map?*/ _environmentCache; static int get numberOfProcessors => _numberOfProcessors(); static String get pathSeparator => _pathSeparator(); static String get operatingSystem => _operatingSystem(); static Uri get script => _script(); - static String _cachedOSVersion; + static String? _cachedOSVersion; static String get operatingSystemVersion { if (_cachedOSVersion == null) { var result = _operatingSystemVersion(); @@ -71,7 +67,7 @@ class _Platform { } _cachedOSVersion = result; } - return _cachedOSVersion; + return _cachedOSVersion!; } static String get localHostname { @@ -116,7 +112,7 @@ class _Platform { if (_environmentCache is OSError) { throw _environmentCache; } else { - return _environmentCache; + return _environmentCache!; } } @@ -128,10 +124,10 @@ class _Platform { class _CaseInsensitiveStringMap extends MapBase { final Map _map = new Map(); - bool containsKey(Object key) => + bool containsKey(Object? key) => key is String && _map.containsKey(key.toUpperCase()); - bool containsValue(Object value) => _map.containsValue(value); - V operator [](Object key) => key is String ? _map[key.toUpperCase()] : null; + bool containsValue(Object? value) => _map.containsValue(value); + V? operator [](Object? key) => key is String ? _map[key.toUpperCase()] : null; void operator []=(String key, V value) { _map[key.toUpperCase()] = value; } @@ -144,7 +140,8 @@ class _CaseInsensitiveStringMap extends MapBase { other.forEach((key, value) => this[key.toUpperCase()] = value); } - V remove(Object key) => key is String ? _map.remove(key.toUpperCase()) : null; + V? remove(Object? key) => + key is String ? _map.remove(key.toUpperCase()) : null; void clear() { _map.clear(); @@ -165,7 +162,7 @@ class _CaseInsensitiveStringMap extends MapBase { Map map(MapEntry transform(String key, V value)) => _map.map(transform); - V update(String key, V update(V value), {V ifAbsent()}) => + V update(String key, V update(V value), {V ifAbsent()?}) => _map.update(key.toUpperCase(), update, ifAbsent: ifAbsent); void updateAll(V update(String key, V value)) { diff --git a/sdk/lib/io/process.dart b/sdk/lib/io/process.dart index d9fad383943..e0d0b155bab 100644 --- a/sdk/lib/io/process.dart +++ b/sdk/lib/io/process.dart @@ -2,18 +2,16 @@ // 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.6 - part of dart.io; // TODO(ager): The only reason for this class is that we // cannot patch a top-level at this point. class _ProcessUtils { - external static void _exit(int status); + external static Never _exit(int status); external static void _setExitCode(int status); external static int _getExitCode(); external static void _sleep(int millis); - external static int _pid(Process process); + external static int _pid(Process? process); external static Stream _watchSignal(ProcessSignal signal); } @@ -51,7 +49,7 @@ class _ProcessUtils { * program to the surrounding environment. This will avoid any * cross-platform issues. */ -void exit(int code) { +Never exit(int code) { ArgumentError.checkNotNull(code, "code"); if (!_EmbedderConfig._mayExit) { throw new UnsupportedError( @@ -363,8 +361,8 @@ abstract class Process { */ external static Future start( String executable, List arguments, - {String workingDirectory, - Map environment, + {String? workingDirectory, + Map? environment, bool includeParentEnvironment: true, bool runInShell: false, ProcessStartMode mode: ProcessStartMode.normal}); @@ -412,12 +410,12 @@ abstract class Process { */ external static Future run( String executable, List arguments, - {String workingDirectory, - Map environment, + {String? workingDirectory, + Map? environment, bool includeParentEnvironment: true, bool runInShell: false, - Encoding stdoutEncoding: systemEncoding, - Encoding stderrEncoding: systemEncoding}); + Encoding? stdoutEncoding: systemEncoding, + Encoding? stderrEncoding: systemEncoding}); /** * Starts a process and runs it to completion. This is a synchronous @@ -430,12 +428,12 @@ abstract class Process { */ external static ProcessResult runSync( String executable, List arguments, - {String workingDirectory, - Map environment, + {String? workingDirectory, + Map? environment, bool includeParentEnvironment: true, bool runInShell: false, - Encoding stdoutEncoding: systemEncoding, - Encoding stderrEncoding: systemEncoding}); + Encoding? stdoutEncoding: systemEncoding, + Encoding? stderrEncoding: systemEncoding}); /** * Kills the process with id [pid]. @@ -695,8 +693,7 @@ class ProcessException implements IOException { const ProcessException(this.executable, this.arguments, [this.message = "", this.errorCode = 0]); String toString() { - var msg = (message == null) ? 'OS error code: $errorCode' : message; var args = arguments.join(' '); - return "ProcessException: $msg\n Command: $executable $args"; + return "ProcessException: $message\n Command: $executable $args"; } } diff --git a/sdk/lib/io/secure_server_socket.dart b/sdk/lib/io/secure_server_socket.dart index f21b4a27d7a..dbdcc28cef0 100644 --- a/sdk/lib/io/secure_server_socket.dart +++ b/sdk/lib/io/secure_server_socket.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.io; /** @@ -69,15 +67,14 @@ class SecureServerSocket extends Stream { * isolates this way. */ static Future bind( - address, int port, SecurityContext context, + address, int port, SecurityContext? context, {int backlog: 0, bool v6Only: false, bool requestClientCertificate: false, bool requireClientCertificate: false, - List supportedProtocols, + List? supportedProtocols, bool shared: false}) { - return RawSecureServerSocket - .bind(address, port, context, + return RawSecureServerSocket.bind(address, port, context, backlog: backlog, v6Only: v6Only, requestClientCertificate: requestClientCertificate, @@ -87,8 +84,8 @@ class SecureServerSocket extends Stream { .then((serverSocket) => new SecureServerSocket._(serverSocket)); } - StreamSubscription listen(void onData(SecureSocket socket), - {Function onError, void onDone(), bool cancelOnError}) { + StreamSubscription listen(void onData(SecureSocket socket)?, + {Function? onError, void onDone()?, bool? cancelOnError}) { return _socket.map((rawSocket) => new SecureSocket._(rawSocket)).listen( onData, onError: onError, @@ -125,12 +122,12 @@ class SecureServerSocket extends Stream { */ class RawSecureServerSocket extends Stream { final RawServerSocket _socket; - StreamController _controller; - StreamSubscription _subscription; - final SecurityContext _context; + late StreamController _controller; + StreamSubscription? _subscription; + final SecurityContext? _context; final bool requestClientCertificate; final bool requireClientCertificate; - final List supportedProtocols; + final List? supportedProtocols; bool _closed = false; RawSecureServerSocket._( @@ -198,15 +195,15 @@ class RawSecureServerSocket extends Stream { * multiple isolates this way. */ static Future bind( - address, int port, SecurityContext context, + address, int port, SecurityContext? context, {int backlog: 0, bool v6Only: false, bool requestClientCertificate: false, bool requireClientCertificate: false, - List supportedProtocols, + List? supportedProtocols, bool shared: false}) { - return RawServerSocket - .bind(address, port, backlog: backlog, v6Only: v6Only, shared: shared) + return RawServerSocket.bind(address, port, + backlog: backlog, v6Only: v6Only, shared: shared) .then((serverSocket) => new RawSecureServerSocket._( serverSocket, context, @@ -215,8 +212,8 @@ class RawSecureServerSocket extends Stream { supportedProtocols)); } - StreamSubscription listen(void onData(RawSecureSocket s), - {Function onError, void onDone(), bool cancelOnError}) { + StreamSubscription listen(void onData(RawSecureSocket s)?, + {Function? onError, void onDone()?, bool? cancelOnError}) { return _controller.stream.listen(onData, onError: onError, onDone: onDone, cancelOnError: cancelOnError); } @@ -249,11 +246,8 @@ class RawSecureServerSocket extends Stream { // Do nothing - connection is closed. return; } - _RawSecureSocket - .connect(connection.address, remotePort, + _RawSecureSocket.connect(connection.address, remotePort, true, connection, context: _context, - is_server: true, - socket: connection, requestClientCertificate: requestClientCertificate, requireClientCertificate: requireClientCertificate, supportedProtocols: supportedProtocols) @@ -272,9 +266,9 @@ class RawSecureServerSocket extends Stream { void _onPauseStateChange() { if (_controller.isPaused) { - _subscription.pause(); + _subscription!.pause(); } else { - _subscription.resume(); + _subscription!.resume(); } } diff --git a/sdk/lib/io/secure_socket.dart b/sdk/lib/io/secure_socket.dart index efec0b3a733..08e9bf704d6 100644 --- a/sdk/lib/io/secure_socket.dart +++ b/sdk/lib/io/secure_socket.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.io; /** @@ -44,10 +42,10 @@ abstract class SecureSocket implements Socket { */ static Future connect(host, int port, - {SecurityContext context, - bool onBadCertificate(X509Certificate certificate), - List supportedProtocols, - Duration timeout}) { + {SecurityContext? context, + bool onBadCertificate(X509Certificate certificate)?, + List? supportedProtocols, + Duration? timeout}) { return RawSecureSocket.connect(host, port, context: context, onBadCertificate: onBadCertificate, @@ -60,9 +58,9 @@ abstract class SecureSocket implements Socket { /// [ConnectionTask] that can be cancelled if the [SecureSocket] is no /// longer needed. static Future> startConnect(host, int port, - {SecurityContext context, - bool onBadCertificate(X509Certificate certificate), - List supportedProtocols}) { + {SecurityContext? context, + bool onBadCertificate(X509Certificate certificate)?, + List? supportedProtocols}) { return RawSecureSocket.startConnect(host, port, context: context, onBadCertificate: onBadCertificate, @@ -70,8 +68,7 @@ abstract class SecureSocket implements Socket { .then((rawState) { Future socket = rawState.socket.then((rawSocket) => new SecureSocket._(rawSocket)); - return new ConnectionTask._( - socket: socket, onCancel: rawState._onCancel); + return new ConnectionTask._(socket, rawState._onCancel); }); } @@ -110,13 +107,13 @@ abstract class SecureSocket implements Socket { */ static Future secure(Socket socket, {host, - SecurityContext context, - bool onBadCertificate(X509Certificate certificate), - @Since("2.6") List supportedProtocols}) { + SecurityContext? context, + bool onBadCertificate(X509Certificate certificate)?, + @Since("2.6") List? supportedProtocols}) { return ((socket as dynamic /*_Socket*/)._detachRaw() as Future) .then((detachedRaw) { return RawSecureSocket.secure(detachedRaw[0] as RawSocket, - subscription: detachedRaw[1] as StreamSubscription, + subscription: detachedRaw[1] as StreamSubscription?, host: host, context: context, onBadCertificate: onBadCertificate, @@ -146,15 +143,15 @@ abstract class SecureSocket implements Socket { * */ static Future secureServer( - Socket socket, SecurityContext context, - {List bufferedData, + Socket socket, SecurityContext? context, + {List? bufferedData, bool requestClientCertificate: false, bool requireClientCertificate: false, - List supportedProtocols}) { + List? supportedProtocols}) { return ((socket as dynamic /*_Socket*/)._detachRaw() as Future) .then((detachedRaw) { return RawSecureSocket.secureServer(detachedRaw[0] as RawSocket, context, - subscription: detachedRaw[1] as StreamSubscription, + subscription: detachedRaw[1] as StreamSubscription?, bufferedData: bufferedData, requestClientCertificate: requestClientCertificate, requireClientCertificate: requireClientCertificate, @@ -169,7 +166,7 @@ abstract class SecureSocket implements Socket { * client certificate was received. If it is the client end, * [peerCertificate] will return the server's certificate. */ - X509Certificate get peerCertificate; + X509Certificate? get peerCertificate; /** * The protocol which was selected during ALPN protocol negotiation. @@ -178,7 +175,7 @@ abstract class SecureSocket implements Socket { * specify a list of supported ALPN protocols or there was no common * protocol between client and server. */ - String get selectedProtocol; + String? get selectedProtocol; /** * Renegotiate an existing secure connection, renewing the session keys @@ -228,12 +225,11 @@ abstract class RawSecureSocket implements RawSocket { * can be obtained via [RawSecureSocket.selectedProtocol]. */ static Future connect(host, int port, - {SecurityContext context, - bool onBadCertificate(X509Certificate certificate), - List supportedProtocols, - Duration timeout}) { - _RawSecureSocket._verifyFields( - host, port, false, false, false, onBadCertificate); + {SecurityContext? context, + bool onBadCertificate(X509Certificate certificate)?, + List? supportedProtocols, + Duration? timeout}) { + _RawSecureSocket._verifyFields(host, port, false, false); return RawSocket.connect(host, port, timeout: timeout).then((socket) { return secure(socket, context: context, @@ -246,9 +242,9 @@ abstract class RawSecureSocket implements RawSocket { /// [ConnectionTask] that can be cancelled if the [RawSecureSocket] is no /// longer needed. static Future> startConnect(host, int port, - {SecurityContext context, - bool onBadCertificate(X509Certificate certificate), - List supportedProtocols}) { + {SecurityContext? context, + bool onBadCertificate(X509Certificate certificate)?, + List? supportedProtocols}) { return RawSocket.startConnect(host, port) .then((ConnectionTask rawState) { Future socket = rawState.socket.then((rawSocket) { @@ -257,8 +253,7 @@ abstract class RawSecureSocket implements RawSocket { onBadCertificate: onBadCertificate, supportedProtocols: supportedProtocols); }); - return new ConnectionTask._( - socket: socket, onCancel: rawState._onCancel); + return new ConnectionTask._(socket, rawState._onCancel); }); } @@ -296,17 +291,15 @@ abstract class RawSecureSocket implements RawSocket { * */ static Future secure(RawSocket socket, - {StreamSubscription subscription, + {StreamSubscription? subscription, host, - SecurityContext context, - bool onBadCertificate(X509Certificate certificate), - List supportedProtocols}) { + SecurityContext? context, + bool onBadCertificate(X509Certificate certificate)?, + List? supportedProtocols}) { socket.readEventsEnabled = false; socket.writeEventsEnabled = false; return _RawSecureSocket.connect( - host != null ? host : socket.address.host, socket.port, - is_server: false, - socket: socket, + host != null ? host : socket.address.host, socket.port, false, socket, subscription: subscription, context: context, onBadCertificate: onBadCertificate, @@ -337,18 +330,17 @@ abstract class RawSecureSocket implements RawSocket { * */ static Future secureServer( - RawSocket socket, SecurityContext context, - {StreamSubscription subscription, - List bufferedData, + RawSocket socket, SecurityContext? context, + {StreamSubscription? subscription, + List? bufferedData, bool requestClientCertificate: false, bool requireClientCertificate: false, - List supportedProtocols}) { + List? supportedProtocols}) { socket.readEventsEnabled = false; socket.writeEventsEnabled = false; - return _RawSecureSocket.connect(socket.address, socket.remotePort, + return _RawSecureSocket.connect( + socket.address, socket.remotePort, true, socket, context: context, - is_server: true, - socket: socket, subscription: subscription, bufferedData: bufferedData, requestClientCertificate: requestClientCertificate, @@ -375,7 +367,7 @@ abstract class RawSecureSocket implements RawSocket { * client certificate was received. If it is the client end, * [peerCertificate] will return the server's certificate. */ - X509Certificate get peerCertificate; + X509Certificate? get peerCertificate; /** * The protocol which was selected during protocol negotiation. @@ -384,7 +376,7 @@ abstract class RawSecureSocket implements RawSocket { * specify a list of supported ALPN protocols or there was no common * protocol between client and server. */ - String get selectedProtocol; + String? get selectedProtocol; } /** @@ -443,20 +435,19 @@ class _RawSecureSocket extends Stream static bool _isBufferEncrypted(int identifier) => identifier >= readEncryptedId; - RawSocket _socket; + final RawSocket _socket; final Completer<_RawSecureSocket> _handshakeComplete = new Completer<_RawSecureSocket>(); - StreamController _controller; - Stream _stream; - StreamSubscription _socketSubscription; - List _bufferedData; + final _controller = new StreamController(sync: true); + late final StreamSubscription _socketSubscription; + List? _bufferedData; int _bufferedDataIndex = 0; final InternetAddress address; - final bool is_server; - SecurityContext context; + final bool isServer; + final SecurityContext context; final bool requestClientCertificate; final bool requireClientCertificate; - final Function onBadCertificate; + final bool Function(X509Certificate certificate)? onBadCertificate; var _status = handshakeStatus; bool _writeEventsEnabled = true; @@ -474,22 +465,23 @@ class _RawSecureSocket extends Stream bool _filterPending = false; bool _filterActive = false; - _SecureFilter _secureFilter = new _SecureFilter._(); - String _selectedProtocol; + _SecureFilter? _secureFilter = new _SecureFilter._(); + String? _selectedProtocol; static Future<_RawSecureSocket> connect( - dynamic /*String|InternetAddress*/ host, int requestedPort, - {bool is_server, - SecurityContext context, + dynamic /*String|InternetAddress*/ host, + int requestedPort, + bool isServer, RawSocket socket, - StreamSubscription subscription, - List bufferedData, + {SecurityContext? context, + StreamSubscription? subscription, + List? bufferedData, bool requestClientCertificate: false, bool requireClientCertificate: false, - bool onBadCertificate(X509Certificate certificate), - List supportedProtocols}) { - _verifyFields(host, requestedPort, is_server, requestClientCertificate, - requireClientCertificate, onBadCertificate); + bool onBadCertificate(X509Certificate certificate)?, + List? supportedProtocols}) { + _verifyFields(host, requestedPort, requestClientCertificate, + requireClientCertificate); if (host is InternetAddress) host = host.host; InternetAddress address = socket.address; if (host != null) { @@ -498,8 +490,8 @@ class _RawSecureSocket extends Stream return new _RawSecureSocket( address, requestedPort, - is_server, - context, + isServer, + context ?? SecurityContext.defaultContext, socket, subscription, bufferedData, @@ -514,39 +506,38 @@ class _RawSecureSocket extends Stream _RawSecureSocket( this.address, int requestedPort, - this.is_server, + this.isServer, this.context, this._socket, - this._socketSubscription, + StreamSubscription? subscription, this._bufferedData, this.requestClientCertificate, this.requireClientCertificate, this.onBadCertificate, - List supportedProtocols) { - context ??= SecurityContext.defaultContext; - _controller = new StreamController( - sync: true, - onListen: _onSubscriptionStateChange, - onPause: _onPauseStateChange, - onResume: _onPauseStateChange, - onCancel: _onSubscriptionStateChange); - _stream = _controller.stream; + List? supportedProtocols) { + _controller + ..onListen = _onSubscriptionStateChange + ..onPause = _onPauseStateChange + ..onResume = _onPauseStateChange + ..onCancel = _onSubscriptionStateChange; // Throw an ArgumentError if any field is invalid. After this, all // errors will be reported through the future or the stream. - _secureFilter.init(); - _secureFilter + final secureFilter = _secureFilter!; + secureFilter.init(); + secureFilter .registerHandshakeCompleteCallback(_secureHandshakeCompleteHandler); if (onBadCertificate != null) { - _secureFilter.registerBadCertificateCallback(_onBadCertificateWrapper); + secureFilter.registerBadCertificateCallback(_onBadCertificateWrapper); } _socket.readEventsEnabled = true; _socket.writeEventsEnabled = false; - if (_socketSubscription == null) { + if (subscription == null) { // If a current subscription is provided use this otherwise // create a new one. _socketSubscription = _socket.listen(_eventDispatcher, onError: _reportError, onDone: _doneHandler); } else { + _socketSubscription = subscription; if (_socketSubscription.isPaused) { _socket.close(); throw new ArgumentError("Subscription passed to TLS upgrade is paused"); @@ -565,10 +556,10 @@ class _RawSecureSocket extends Stream try { var encodedProtocols = SecurityContext._protocolsToLengthEncoding(supportedProtocols); - _secureFilter.connect( + secureFilter.connect( address.host, context, - is_server, + isServer, requestClientCertificate || requireClientCertificate, requireClientCertificate, encodedProtocols); @@ -578,27 +569,24 @@ class _RawSecureSocket extends Stream } } - StreamSubscription listen(void onData(RawSocketEvent data), - {Function onError, void onDone(), bool cancelOnError}) { + StreamSubscription listen(void onData(RawSocketEvent data)?, + {Function? onError, void onDone()?, bool? cancelOnError}) { _sendWriteEvent(); - return _stream.listen(onData, + return _controller.stream.listen(onData, onError: onError, onDone: onDone, cancelOnError: cancelOnError); } - static void _verifyFields( - host, - int requestedPort, - bool is_server, - bool requestClientCertificate, - bool requireClientCertificate, - Function onBadCertificate) { + static void _verifyFields(host, int requestedPort, + bool requestClientCertificate, bool requireClientCertificate) { if (host is! String && host is! InternetAddress) { throw new ArgumentError("host is not a String or an InternetAddress"); } + // TODO(40614): Remove once non-nullability is sound. ArgumentError.checkNotNull(requestedPort, "requestedPort"); if (requestedPort < 0 || requestedPort > 65535) { throw ArgumentError("requestedPort is not in the range 0..65535"); } + // TODO(40614): Remove once non-nullability is sound. ArgumentError.checkNotNull( requestClientCertificate, "requestClientCertificate"); ArgumentError.checkNotNull( @@ -618,7 +606,7 @@ class _RawSecureSocket extends Stream int available() { return _status != connectedStatus ? 0 - : _secureFilter.buffers[readPlaintextId].length; + : _secureFilter!.buffers![readPlaintextId].length; } Future close() { @@ -626,22 +614,18 @@ class _RawSecureSocket extends Stream return _closeCompleter.future; } - void _completeCloseCompleter([RawSocket dummy]) { + void _completeCloseCompleter([RawSocket? dummy]) { if (!_closeCompleter.isCompleted) _closeCompleter.complete(this); } void _close() { _closedWrite = true; _closedRead = true; - if (_socket != null) { - _socket.close().then(_completeCloseCompleter); - } else { - _completeCloseCompleter(); - } + _socket.close().then(_completeCloseCompleter); _socketClosedWrite = true; _socketClosedRead = true; if (!_filterActive && _secureFilter != null) { - _secureFilter.destroy(); + _secureFilter!.destroy(); _secureFilter = null; } if (_socketSubscription != null) { @@ -690,8 +674,8 @@ class _RawSecureSocket extends Stream _scheduleReadEvent(); } - Uint8List read([int length]) { - if (length != null && (length is! int || length < 0)) { + Uint8List? read([int? length]) { + if (length != null && length < 0) { throw new ArgumentError( "Invalid length parameter in SecureSocket.read (length: $length)"); } @@ -701,18 +685,22 @@ class _RawSecureSocket extends Stream if (_status != connectedStatus) { return null; } - var result = _secureFilter.buffers[readPlaintextId].read(length); + var result = _secureFilter!.buffers![readPlaintextId].read(length); _scheduleFilter(); return result; } + static int _fixOffset(int? offset) => offset ?? 0; + // Write the data to the socket, and schedule the filter to encrypt it. - int write(List data, [int offset, int bytes]) { - if (bytes != null && (bytes is! int || bytes < 0)) { + int write(List data, [int offset = 0, int? bytes]) { + if (bytes != null && bytes < 0) { throw new ArgumentError( "Invalid bytes parameter in SecureSocket.read (bytes: $bytes)"); } - if (offset != null && (offset is! int || offset < 0)) { + // TODO(40614): Remove once non-nullability is sound. + offset = _fixOffset(offset); + if (offset < 0) { throw new ArgumentError( "Invalid offset parameter in SecureSocket.read (offset: $offset)"); } @@ -721,11 +709,10 @@ class _RawSecureSocket extends Stream return 0; } if (_status != connectedStatus) return 0; - offset ??= 0; bytes ??= data.length - offset; int written = - _secureFilter.buffers[writePlaintextId].write(data, offset, bytes); + _secureFilter!.buffers![writePlaintextId].write(data, offset, bytes); if (written > 0) { _filterStatus.writeEmpty = false; } @@ -733,29 +720,25 @@ class _RawSecureSocket extends Stream return written; } - X509Certificate get peerCertificate => _secureFilter.peerCertificate; + X509Certificate? get peerCertificate => _secureFilter!.peerCertificate; - String get selectedProtocol => _selectedProtocol; + String? get selectedProtocol => _selectedProtocol; bool _onBadCertificateWrapper(X509Certificate certificate) { if (onBadCertificate == null) return false; - var result = onBadCertificate(certificate); - if (result is bool) return result; - throw new HandshakeException( - "onBadCertificate callback returned non-boolean $result"); + return onBadCertificate!(certificate); } bool setOption(SocketOption option, bool enabled) { - if (_socket == null) return false; return _socket.setOption(option, enabled); } Uint8List getRawOption(RawSocketOption option) { - return _socket?.getRawOption(option); + return _socket.getRawOption(option); } void setRawOption(RawSocketOption option) { - _socket?.setRawOption(option); + _socket.setRawOption(option); } void _eventDispatcher(RawSocketEvent event) { @@ -788,7 +771,7 @@ class _RawSecureSocket extends Stream } } - void _reportError(e, [StackTrace stackTrace]) { + void _reportError(e, [StackTrace? stackTrace]) { if (_status == closedStatus) { return; } else if (_connectPending) { @@ -829,7 +812,7 @@ class _RawSecureSocket extends Stream void _secureHandshake() { try { - _secureFilter.handshake(); + _secureFilter!.handshake(); _filterStatus.writeEmpty = false; _readSocket(); _writeSocket(); @@ -847,7 +830,7 @@ class _RawSecureSocket extends Stream throw new HandshakeException( "Called renegotiate on a non-connected socket"); } - _secureFilter.renegotiate( + _secureFilter!.renegotiate( useSessionCache, requestClientCertificate, requireClientCertificate); _status = handshakeStatus; _filterStatus.writeEmpty = false; @@ -859,7 +842,7 @@ class _RawSecureSocket extends Stream if (_connectPending) { _connectPending = false; try { - _selectedProtocol = _secureFilter.selectedProtocol(); + _selectedProtocol = _secureFilter!.selectedProtocol(); // We don't want user code to run synchronously in this callback. Timer.run(() => _handshakeComplete.complete(this)); } catch (error, stack) { @@ -910,7 +893,7 @@ class _RawSecureSocket extends Stream _filterStatus = status; _filterActive = false; if (_status == closedStatus) { - _secureFilter.destroy(); + _secureFilter!.destroy(); _secureFilter = null; return; } @@ -924,7 +907,7 @@ class _RawSecureSocket extends Stream } if (_filterStatus.readEmpty && _socketClosedRead && !_closedRead) { if (_status == handshakeStatus) { - _secureFilter.handshake(); + _secureFilter!.handshake(); if (_status == handshakeStatus) { throw new HandshakeException( 'Connection terminated during handshake'); @@ -958,15 +941,16 @@ class _RawSecureSocket extends Stream } } - List _readSocketOrBufferedData(int bytes) { - if (_bufferedData != null) { - if (bytes > _bufferedData.length - _bufferedDataIndex) { - bytes = _bufferedData.length - _bufferedDataIndex; + List? _readSocketOrBufferedData(int bytes) { + final bufferedData = _bufferedData; + if (bufferedData != null) { + if (bytes > bufferedData.length - _bufferedDataIndex) { + bytes = bufferedData.length - _bufferedDataIndex; } var result = - _bufferedData.sublist(_bufferedDataIndex, _bufferedDataIndex + bytes); + bufferedData.sublist(_bufferedDataIndex, _bufferedDataIndex + bytes); _bufferedDataIndex += bytes; - if (_bufferedData.length == _bufferedDataIndex) { + if (bufferedData.length == _bufferedDataIndex) { _bufferedData = null; } return result; @@ -979,7 +963,7 @@ class _RawSecureSocket extends Stream void _readSocket() { if (_status == closedStatus) return; - var buffer = _secureFilter.buffers[readEncryptedId]; + var buffer = _secureFilter!.buffers![readEncryptedId]; if (buffer.writeFromSource(_readSocketOrBufferedData) > 0) { _filterStatus.readEmpty = false; } else { @@ -989,7 +973,7 @@ class _RawSecureSocket extends Stream void _writeSocket() { if (_socketClosedWrite) return; - var buffer = _secureFilter.buffers[writeEncryptedId]; + var buffer = _secureFilter!.buffers![writeEncryptedId]; if (buffer.readToSocket(_socket)) { // Returns true if blocked _socket.writeEventsEnabled = true; @@ -1002,7 +986,7 @@ class _RawSecureSocket extends Stream _readEventsEnabled && _pauseCount == 0 && _secureFilter != null && - !_secureFilter.buffers[readPlaintextId].isEmpty) { + !_secureFilter!.buffers![readPlaintextId].isEmpty) { _pendingReadEvent = true; Timer.run(_sendReadEvent); } @@ -1014,7 +998,7 @@ class _RawSecureSocket extends Stream _readEventsEnabled && _pauseCount == 0 && _secureFilter != null && - !_secureFilter.buffers[readPlaintextId].isEmpty) { + !_secureFilter!.buffers![readPlaintextId].isEmpty) { _controller.add(RawSocketEvent.read); _scheduleReadEvent(); } @@ -1026,7 +1010,7 @@ class _RawSecureSocket extends Stream _writeEventsEnabled && _pauseCount == 0 && _secureFilter != null && - _secureFilter.buffers[writePlaintextId].free > 0) { + _secureFilter!.buffers![writePlaintextId].free > 0) { _writeEventsEnabled = false; _controller.add(RawSocketEvent.write); } @@ -1034,10 +1018,10 @@ class _RawSecureSocket extends Stream Future<_FilterStatus> _pushAllFilterStages() { bool wasInHandshake = _status != connectedStatus; - List args = new List(2 + bufferCount * 2); - args[0] = _secureFilter._pointer(); + List args = new List.filled(2 + bufferCount * 2, null); + args[0] = _secureFilter!._pointer(); args[1] = wasInHandshake; - var bufs = _secureFilter.buffers; + var bufs = _secureFilter!.buffers!; for (var i = 0; i < bufferCount; ++i) { args[2 * i + 2] = bufs[i].start; args[2 * i + 3] = bufs[i].end; @@ -1123,7 +1107,7 @@ class _RawSecureSocket extends Stream class _ExternalBuffer { // This will be an ExternalByteArray, backed by C allocated data. @pragma("vm:entry-point", "set") - List data; + List? data; @pragma("vm:entry-point") int start; @@ -1131,11 +1115,12 @@ class _ExternalBuffer { @pragma("vm:entry-point") int end; - final size; + final int size; - _ExternalBuffer(this.size) { - start = end = size ~/ 2; - } + _ExternalBuffer(int size) + : size = size, + start = size ~/ 2, + end = size ~/ 2; void advanceStart(int bytes) { assert(start > end || start + bytes <= end); @@ -1171,7 +1156,7 @@ class _ExternalBuffer { return size - end; } - Uint8List read(int bytes) { + Uint8List? read(int? bytes) { if (bytes == null) { bytes = length; } else { @@ -1183,7 +1168,7 @@ class _ExternalBuffer { // Loop over zero, one, or two linear data ranges. while (bytesRead < bytes) { int toRead = min(bytes - bytesRead, linearLength); - result.setRange(bytesRead, bytesRead + toRead, data, start); + result.setRange(bytesRead, bytesRead + toRead, data!, start); advanceStart(toRead); bytesRead += toRead; } @@ -1198,7 +1183,7 @@ class _ExternalBuffer { int toWrite = min(bytes, linearFree); // Loop over zero, one, or two linear data ranges. while (toWrite > 0) { - data.setRange(end, end + toWrite, inputData, offset); + data!.setRange(end, end + toWrite, inputData, offset); advanceEnd(toWrite); offset += toWrite; written += toWrite; @@ -1207,7 +1192,7 @@ class _ExternalBuffer { return written; } - int writeFromSource(List getData(int requested)) { + int writeFromSource(List? getData(int requested)) { int written = 0; int toWrite = linearFree; // Loop over zero, one, or two linear data ranges. @@ -1216,7 +1201,7 @@ class _ExternalBuffer { var inputData = getData(toWrite); if (inputData == null || inputData.length == 0) break; var len = inputData.length; - data.setRange(end, end + len, inputData); + data!.setRange(end, end + len, inputData); advanceEnd(len); written += len; toWrite = linearFree; @@ -1229,7 +1214,7 @@ class _ExternalBuffer { while (true) { var toWrite = linearLength; if (toWrite == 0) return false; - int bytes = socket.write(data, start, toWrite); + int bytes = socket.write(data!, start, toWrite); advanceStart(bytes); if (bytes < toWrite) { // The socket has blocked while we have data to write. @@ -1245,18 +1230,18 @@ abstract class _SecureFilter { void connect( String hostName, SecurityContext context, - bool is_server, + bool isServer, bool requestClientCertificate, bool requireClientCertificate, Uint8List protocols); void destroy(); void handshake(); - String selectedProtocol(); + String? selectedProtocol(); void rehandshake(); void renegotiate(bool useSessionCache, bool requestClientCertificate, bool requireClientCertificate); void init(); - X509Certificate get peerCertificate; + X509Certificate? get peerCertificate; int processBuffer(int bufferIndex); void registerBadCertificateCallback(Function callback); void registerHandshakeCompleteCallback(Function handshakeCompleteHandler); @@ -1266,7 +1251,7 @@ abstract class _SecureFilter { // value is passed to the IO service through a call to dispatch(). int _pointer(); - List<_ExternalBuffer> get buffers; + List<_ExternalBuffer>? get buffers; } /** A secure networking exception caused by a failure in the @@ -1275,10 +1260,10 @@ abstract class _SecureFilter { class TlsException implements IOException { final String type; final String message; - final OSError osError; + final OSError? osError; @pragma("vm:entry-point") - const TlsException([String message = "", OSError osError]) + const TlsException([String message = "", OSError? osError]) : this._("TlsException", message, osError); const TlsException._(this.type, this.message, this.osError); @@ -1305,7 +1290,7 @@ class TlsException implements IOException { @pragma("vm:entry-point") class HandshakeException extends TlsException { @pragma("vm:entry-point") - const HandshakeException([String message = "", OSError osError]) + const HandshakeException([String message = "", OSError? osError]) : super._("HandshakeException", message, osError); } @@ -1316,6 +1301,6 @@ class HandshakeException extends TlsException { */ class CertificateException extends TlsException { @pragma("vm:entry-point") - const CertificateException([String message = "", OSError osError]) + const CertificateException([String message = "", OSError? osError]) : super._("CertificateException", message, osError); } diff --git a/sdk/lib/io/security_context.dart b/sdk/lib/io/security_context.dart index e98fd7891a7..e4fd5c6c019 100644 --- a/sdk/lib/io/security_context.dart +++ b/sdk/lib/io/security_context.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.io; /** @@ -69,7 +67,7 @@ abstract class SecurityContext { * data is used instead of two calls to [useCertificateChain] and * [usePrivateKey]. */ - void usePrivateKey(String file, {String password}); + void usePrivateKey(String file, {String? password}); /** * Sets the private key for a server certificate or client certificate. @@ -77,7 +75,7 @@ abstract class SecurityContext { * Like [usePrivateKey], but takes the contents of the file as a list * of bytes. */ - void usePrivateKeyBytes(List keyBytes, {String password}); + void usePrivateKeyBytes(List keyBytes, {String? password}); /** * Sets the set of trusted X509 certificates used by [SecureSocket] @@ -99,7 +97,7 @@ abstract class SecurityContext { * * $ openssl x509 -outform der -in cert.pem -out cert.der */ - void setTrustedCertificates(String file, {String password}); + void setTrustedCertificates(String file, {String? password}); /** * Sets the set of trusted X509 certificates used by [SecureSocket] @@ -107,7 +105,7 @@ abstract class SecurityContext { * * Like [setTrustedCertificates] but takes the contents of the file. */ - void setTrustedCertificatesBytes(List certBytes, {String password}); + void setTrustedCertificatesBytes(List certBytes, {String? password}); /** * Sets the chain of X509 certificates served by [SecureServerSocket] @@ -127,7 +125,7 @@ abstract class SecurityContext { * iOS note: As noted above, [usePrivateKey] does the job of both * that call and this one. On iOS, this call is a no-op. */ - void useCertificateChain(String file, {String password}); + void useCertificateChain(String file, {String? password}); /** * Sets the chain of X509 certificates served by [SecureServerSocket] @@ -135,7 +133,7 @@ abstract class SecurityContext { * * Like [useCertificateChain] but takes the contents of the file. */ - void useCertificateChainBytes(List chainBytes, {String password}); + void useCertificateChainBytes(List chainBytes, {String? password}); /** * Sets the list of authority names that a [SecureServerSocket] will advertise @@ -153,7 +151,7 @@ abstract class SecurityContext { * * iOS note: This call is not supported. */ - void setClientAuthorities(String file, {String password}); + void setClientAuthorities(String file, {String? password}); /** * Sets the list of authority names that a [SecureServerSocket] will advertise @@ -162,7 +160,7 @@ abstract class SecurityContext { * * Like [setClientAuthorities] but takes the contents of the file. */ - void setClientAuthoritiesBytes(List authCertBytes, {String password}); + void setClientAuthoritiesBytes(List authCertBytes, {String? password}); /** * Whether the platform supports ALPN. This always returns true and will be @@ -205,7 +203,7 @@ abstract class SecurityContext { /// `ProtocolNameList` length of 65535, this limit cannot be reached. Testing /// showed that more than ~ 2^14 bytes will fail to negotiate a protocol. /// We will be conservative and support only messages up to (1<<13)-1 bytes. - static Uint8List _protocolsToLengthEncoding(List protocols) { + static Uint8List _protocolsToLengthEncoding(List? protocols) { if (protocols == null || protocols.length == 0) { return new Uint8List(0); } diff --git a/sdk/lib/io/service_object.dart b/sdk/lib/io/service_object.dart index 6c0f882d7e8..e6b1851707a 100644 --- a/sdk/lib/io/service_object.dart +++ b/sdk/lib/io/service_object.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.io; int _nextServiceId = 1; diff --git a/sdk/lib/io/socket.dart b/sdk/lib/io/socket.dart index c030553d9cc..b5e814fc9b0 100644 --- a/sdk/lib/io/socket.dart +++ b/sdk/lib/io/socket.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.io; /** @@ -165,7 +163,7 @@ abstract class InternetAddress { * [InternetAddressType.unix] and [address] should be a string. */ external factory InternetAddress(String address, - {@Since("2.8") InternetAddressType type}); + {@Since("2.8") InternetAddressType? type}); /** * Creates a new [InternetAddress] from the provided raw address bytes. @@ -182,7 +180,7 @@ abstract class InternetAddress { * [InternetAddress.IPv6] respectively. */ external factory InternetAddress.fromRawAddress(Uint8List rawAddress, - {@Since("2.8") InternetAddressType type}); + {@Since("2.8") InternetAddressType? type}); /** * Perform a reverse DNS lookup on this [address] @@ -197,7 +195,7 @@ abstract class InternetAddress { /** * Lookup a host, returning a Future of a list of - * [InternetAddress]s. If [type] is [InternetAddressType.any], it + * [InternetAddress]s. If [type] is [InternetAddressType.ANY], it * will lookup both IP version 4 (IPv4) and IP version 6 (IPv6) * addresses. If [type] is either [InternetAddressType.IPv4] or * [InternetAddressType.IPv6] it will only lookup addresses of the @@ -218,9 +216,9 @@ abstract class InternetAddress { /// Attempts to parse [address] as a numeric address. /// - /// Returns `null` if [address] is not a numeric IPv4 (dotted-decimal + /// Returns `null` If [address] is not a numeric IPv4 (dotted-decimal /// notation) or IPv6 (hexadecimal representation) address. - external static InternetAddress tryParse(String address); + external static InternetAddress? tryParse(String address); } /** @@ -383,7 +381,7 @@ abstract class ServerSocket implements Stream { */ static Future bind(address, int port, {int backlog: 0, bool v6Only: false, bool shared: false}) { - final IOOverrides overrides = IOOverrides.current; + final IOOverrides? overrides = IOOverrides.current; if (overrides == null) { return ServerSocket._bind(address, port, backlog: backlog, v6Only: v6Only, shared: shared); @@ -394,7 +392,6 @@ abstract class ServerSocket implements Stream { external static Future _bind(address, int port, {int backlog: 0, bool v6Only: false, bool shared: false}); - /** * Returns the port used by this socket. */ @@ -471,18 +468,16 @@ enum _RawSocketOptions { IPPROTO_UDP, // 6 } -/// The [RawSocketOption] is used as a parameter to [Socket.setRawOption], -/// [RawSocket.setRawOption], and [RawDatagramSocket.setRawOption] to customize -/// the behaviour of the underlying socket. +/// The [RawSocketOption] is used as a parameter to [Socket.setRawOption] and +/// [RawSocket.setRawOption] to set customize the behaviour of the underlying +/// socket. /// -/// It allows for fine grained control of the socket options, and its values -/// will be passed to the underlying platform's implementation of `setsockopt` -/// and `getsockopt`. +/// It allows for fine grained control of the socket options, and its values will +/// be passed to the underlying platform's implementation of setsockopt and +/// getsockopt. @Since("2.2") class RawSocketOption { - /// Creates a [RawSocketOption] for `getRawOption` and `setRawOption`. - /// - /// All arguments are required and must not be null. + /// Creates a RawSocketOption for getRawOption andSetRawOption. /// /// The level and option arguments correspond to level and optname arguments /// on the get/setsockopt native calls. @@ -490,18 +485,15 @@ class RawSocketOption { /// The value argument and its length correspond to the optval and length /// arguments on the native call. /// - /// For a `getRawOption` call, the value parameter will be updated after a + /// For a [getRawOption] call, the value parameter will be updated after a /// successful call (although its length will not be changed). /// - /// For a `setRawOption` call, the value parameter will be used set the + /// For a [setRawOption] call, the value parameter will be used set the /// option. const RawSocketOption(this.level, this.option, this.value); /// Convenience constructor for creating an int based RawSocketOption. factory RawSocketOption.fromInt(int level, int option, int value) { - if (value == null) { - value = 0; - } final Uint8List list = Uint8List(4); final buffer = ByteData.view(list.buffer, list.offsetInBytes); buffer.setInt32(0, value, Endian.host); @@ -510,7 +502,7 @@ class RawSocketOption { /// Convenience constructor for creating a bool based RawSocketOption. factory RawSocketOption.fromBool(int level, int option, bool value) => - RawSocketOption.fromInt(level, option, value == true ? 1 : 0); + RawSocketOption.fromInt(level, option, value ? 1 : 0); /// The level for the option to set or get. /// @@ -606,11 +598,8 @@ class ConnectionTask { final Future socket; final void Function() _onCancel; - ConnectionTask._({Future socket, void Function() onCancel}) - : assert(socket != null), - assert(onCancel != null), - this.socket = socket, - this._onCancel = onCancel; + ConnectionTask._(Future this.socket, void Function() onCancel) + : _onCancel = onCancel; /// Cancels the connection attempt. /// @@ -635,7 +624,8 @@ abstract class RawSocket implements Stream { * Set or get, if the [RawSocket] should listen for [RawSocketEvent.read] * events. Default is [:true:]. */ - bool readEventsEnabled; + bool get readEventsEnabled; + void set readEventsEnabled(bool value); /** * Set or get, if the [RawSocket] should listen for [RawSocketEvent.write] @@ -643,7 +633,8 @@ abstract class RawSocket implements Stream { * This is a one-shot listener, and writeEventsEnabled must be set * to true again to receive another write event. */ - bool writeEventsEnabled; + bool get writeEventsEnabled; + void set writeEventsEnabled(bool value); /** * Creates a new socket connection to the host and port and returns a [Future] @@ -668,7 +659,7 @@ abstract class RawSocket implements Stream { * connection attempts to [host] are cancelled. */ external static Future connect(host, int port, - {sourceAddress, Duration timeout}); + {sourceAddress, Duration? timeout}); /// Like [connect], but returns a [Future] that completes with a /// [ConnectionTask] that can be cancelled if the [RawSocket] is no @@ -689,7 +680,7 @@ abstract class RawSocket implements Stream { * available for immediate reading. If no data is available [:null:] * is returned. */ - Uint8List read([int len]); + Uint8List? read([int? len]); /** * Writes up to [count] bytes of the buffer from [offset] buffer offset to @@ -700,7 +691,7 @@ abstract class RawSocket implements Stream { * The default value for [offset] is 0, and the default value for [count] is * [:buffer.length - offset:]. */ - int write(List buffer, [int offset, int count]); + int write(List buffer, [int offset = 0, int? count]); /** * Returns the port used by this socket. @@ -807,8 +798,8 @@ abstract class Socket implements Stream, IOSink { * connection attempts to [host] are cancelled. */ static Future connect(host, int port, - {sourceAddress, Duration timeout}) { - final IOOverrides overrides = IOOverrides.current; + {sourceAddress, Duration? timeout}) { + final IOOverrides? overrides = IOOverrides.current; if (overrides == null) { return Socket._connect(host, port, sourceAddress: sourceAddress, timeout: timeout); @@ -822,7 +813,7 @@ abstract class Socket implements Stream, IOSink { /// longer needed. static Future> startConnect(host, int port, {sourceAddress}) { - final IOOverrides overrides = IOOverrides.current; + final IOOverrides? overrides = IOOverrides.current; if (overrides == null) { return Socket._startConnect(host, port, sourceAddress: sourceAddress); } @@ -831,7 +822,7 @@ abstract class Socket implements Stream, IOSink { } external static Future _connect(host, int port, - {sourceAddress, Duration timeout}); + {sourceAddress, Duration? timeout}); external static Future> _startConnect(host, int port, {sourceAddress}); @@ -942,7 +933,8 @@ abstract class RawDatagramSocket extends Stream { * Set or get, if the [RawDatagramSocket] should listen for * [RawSocketEvent.read] events. Default is [:true:]. */ - bool readEventsEnabled; + bool get readEventsEnabled; + void set readEventsEnabled(bool value); /** * Set or get, if the [RawDatagramSocket] should listen for @@ -950,14 +942,16 @@ abstract class RawDatagramSocket extends Stream { * one-shot listener, and writeEventsEnabled must be set to true * again to receive another write event. */ - bool writeEventsEnabled; + bool get writeEventsEnabled; + void set writeEventsEnabled(bool value); /** * Set or get, whether multicast traffic is looped back to the host. * * By default multicast loopback is enabled. */ - bool multicastLoopback; + bool get multicastLoopback; + void set multicastLoopback(bool value); /** * Set or get, the maximum network hops for multicast packages @@ -968,7 +962,8 @@ abstract class RawDatagramSocket extends Stream { * By default this value is 1 causing multicast traffic to stay on * the local network. */ - int multicastHops; + int get multicastHops; + void set multicastHops(int value); /** * Set or get, the network interface used for outgoing multicast packages. @@ -980,7 +975,7 @@ abstract class RawDatagramSocket extends Stream { */ @Deprecated("This property is not implemented. Use getRawOption and " "setRawOption instead.") - NetworkInterface multicastInterface; + NetworkInterface? multicastInterface; /** * Set or get, whether IPv4 broadcast is enabled. @@ -991,7 +986,8 @@ abstract class RawDatagramSocket extends Stream { * For IPv6 there is no general broadcast mechanism. Use multicast * instead. */ - bool broadcastEnabled; + bool get broadcastEnabled; + void set broadcastEnabled(bool value); /** * Creates a new raw datagram socket binding it to an address and @@ -1029,7 +1025,7 @@ abstract class RawDatagramSocket extends Stream { * * The maximum length of the datagram that can be received is 65503 bytes. */ - Datagram receive(); + Datagram? receive(); /** * Join a multicast group. @@ -1037,7 +1033,7 @@ abstract class RawDatagramSocket extends Stream { * If an error occur when trying to join the multicast group an * exception is thrown. */ - void joinMulticast(InternetAddress group, [NetworkInterface interface]); + void joinMulticast(InternetAddress group, [NetworkInterface? interface]); /** * Leave a multicast group. @@ -1045,7 +1041,7 @@ abstract class RawDatagramSocket extends Stream { * If an error occur when trying to join the multicase group an * exception is thrown. */ - void leaveMulticast(InternetAddress group, [NetworkInterface interface]); + void leaveMulticast(InternetAddress group, [NetworkInterface? interface]); /** * Use [getRawOption] to get low level information about the [RawSocket]. See @@ -1068,9 +1064,9 @@ abstract class RawDatagramSocket extends Stream { class SocketException implements IOException { final String message; - final OSError osError; - final InternetAddress address; - final int port; + final OSError? osError; + final InternetAddress? address; + final int? port; const SocketException(this.message, {this.osError, this.address, this.port}); const SocketException.closed() @@ -1091,7 +1087,7 @@ class SocketException implements IOException { sb.write(": $osError"); } if (address != null) { - sb.write(", address = ${address.host}"); + sb.write(", address = ${address!.host}"); } if (port != null) { sb.write(", port = $port"); diff --git a/sdk/lib/io/stdio.dart b/sdk/lib/io/stdio.dart index 4dfc0afd1b4..a0034c6ccaa 100644 --- a/sdk/lib/io/stdio.dart +++ b/sdk/lib/io/stdio.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.io; // These match enum StdioHandleType in file.h @@ -19,8 +17,8 @@ class _StdStream extends Stream> { _StdStream(this._stream); - StreamSubscription> listen(void onData(List event), - {Function onError, void onDone(), bool cancelOnError}) { + StreamSubscription> listen(void onData(List event)?, + {Function? onError, void onDone()?, bool? cancelOnError}) { return _stream.listen(onData, onError: onError, onDone: onDone, cancelOnError: cancelOnError); } @@ -43,7 +41,7 @@ class Stdin extends _StdStream implements Stream> { * Blocks until a full line is available. * * Lines my be terminated by either `` or ``. On Windows in cases - * where the [stdioType] of stdin is [StdioType.terminal] the terminator may + * where the [stdioType] of stdin is [StdioType.termimal] the terminator may * also be a single ``. * * Input bytes are converted to a string by [encoding]. @@ -57,7 +55,7 @@ class Stdin extends _StdStream implements Stream> { * that data is returned without a line terminator. * Returns `null` if no bytes preceded the end of input. */ - String readLineSync( + String? readLineSync( {Encoding encoding: systemEncoding, bool retainNewlines: false}) { const CR = 13; const LF = 10; @@ -214,7 +212,7 @@ class Stdin extends _StdStream implements Stream> { */ class Stdout extends _StdSink implements IOSink { final int _fd; - IOSink _nonBlocking; + IOSink? _nonBlocking; Stdout._(IOSink sink, this._fd) : super(sink); @@ -272,14 +270,13 @@ class Stdout extends _StdSink implements IOSink { * Get a non-blocking `IOSink`. */ IOSink get nonBlocking { - _nonBlocking ??= new IOSink(new _FileStreamConsumer.fromStdio(_fd)); - return _nonBlocking; + return _nonBlocking ??= new IOSink(new _FileStreamConsumer.fromStdio(_fd)); } } class StdoutException implements IOException { final String message; - final OSError osError; + final OSError? osError; const StdoutException(this.message, [this.osError]); @@ -290,7 +287,7 @@ class StdoutException implements IOException { class StdinException implements IOException { final String message; - final OSError osError; + final OSError? osError; const StdinException(this.message, [this.osError]); @@ -337,15 +334,15 @@ class _StdSink implements IOSink { _sink.encoding = encoding; } - void write(object) { + void write(Object? object) { _sink.write(object); } - void writeln([object = ""]) { + void writeln([Object? object = ""]) { _sink.writeln(object); } - void writeAll(objects, [sep = ""]) { + void writeAll(Iterable objects, [String sep = ""]) { _sink.writeAll(objects, sep); } @@ -353,7 +350,7 @@ class _StdSink implements IOSink { _sink.add(data); } - void addError(error, [StackTrace stackTrace]) { + void addError(error, [StackTrace? stackTrace]) { _sink.addError(error, stackTrace); } @@ -388,9 +385,9 @@ class StdioType { String toString() => "StdioType: $name"; } -Stdin _stdin; -Stdout _stdout; -Stdout _stderr; +Stdin? _stdin; +Stdout? _stdout; +Stdout? _stderr; // These may be set to different values by the embedder by calling // _setStdioFDs when initializing dart:io. @@ -407,8 +404,7 @@ void _setStdioFDs(int stdin, int stdout, int stderr) { /// The standard input stream of data read by this program. Stdin get stdin { - _stdin ??= _StdIOUtils._getStdioInputStream(_stdinFD); - return _stdin; + return _stdin ??= _StdIOUtils._getStdioInputStream(_stdinFD); } /// The standard output stream of data written by this program. @@ -417,8 +413,7 @@ Stdin get stdin { /// result in an unhandled asynchronous error unless there is an error handler /// on `done`. Stdout get stdout { - _stdout ??= _StdIOUtils._getStdioOutputStream(_stdoutFD); - return _stdout; + return _stdout ??= _StdIOUtils._getStdioOutputStream(_stdoutFD); } /// The standard output stream of errors written by this program. @@ -427,8 +422,7 @@ Stdout get stdout { /// result in an unhandled asynchronous error unless there is an error handler /// on `done`. Stdout get stderr { - _stderr ??= _StdIOUtils._getStdioOutputStream(_stderrFD); - return _stderr; + return _stderr ??= _StdIOUtils._getStdioOutputStream(_stderrFD); } /// For a stream, returns whether it is attached to a file, pipe, terminal, or @@ -456,7 +450,7 @@ StdioType stdioType(object) { return StdioType.file; } if (object is Socket) { - int socketType = _StdIOUtils._socketType(object); + int? socketType = _StdIOUtils._socketType(object); if (socketType == null) return StdioType.other; switch (socketType) { case _stdioHandleTypeTerminal: @@ -484,6 +478,6 @@ class _StdIOUtils { external static Stdin _getStdioInputStream(int fd); /// Returns the socket type or `null` if [socket] is not a builtin socket. - external static int _socketType(Socket socket); + external static int? _socketType(Socket socket); external static _getStdioHandleType(int fd); } diff --git a/sdk/lib/io/string_transformer.dart b/sdk/lib/io/string_transformer.dart index c39993297bc..f31c41e79b0 100644 --- a/sdk/lib/io/string_transformer.dart +++ b/sdk/lib/io/string_transformer.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.io; /// The current system encoding. diff --git a/sdk/lib/io/sync_socket.dart b/sdk/lib/io/sync_socket.dart index 386dc2e6ab7..771edfdb1ca 100644 --- a/sdk/lib/io/sync_socket.dart +++ b/sdk/lib/io/sync_socket.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.io; /** @@ -54,7 +52,7 @@ abstract class RawSynchronousSocket { * otherwise up to [buffer.length]. If [end] == [start], no bytes are read. * Returns the number of bytes read. */ - int readIntoSync(List buffer, [int start = 0, int end]); + int readIntoSync(List buffer, [int start = 0, int? end]); /** * Reads up to [bytes] bytes from the socket. @@ -64,7 +62,7 @@ abstract class RawSynchronousSocket { * be read. Returns the list of bytes read, which could be less than the * value specified by [bytes]. */ - List readSync(int bytes); + List? readSync(int bytes); /** * Shutdown a socket in the provided direction. @@ -87,7 +85,7 @@ abstract class RawSynchronousSocket { * be written to the socket starting from index [start]. If [end] == [start], * nothing happens. */ - void writeFromSync(List buffer, [int start = 0, int end]); + void writeFromSync(List buffer, [int start = 0, int? end]); /** * The port used by this socket. diff --git a/sdk/lib/isolate/capability.dart b/sdk/lib/isolate/capability.dart index 4619192e93b..a51eec21061 100644 --- a/sdk/lib/isolate/capability.dart +++ b/sdk/lib/isolate/capability.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.isolate; /** diff --git a/sdk/lib/isolate/isolate.dart b/sdk/lib/isolate/isolate.dart index 22c40b6009d..881fd14c8fe 100644 --- a/sdk/lib/isolate/isolate.dart +++ b/sdk/lib/isolate/isolate.dart @@ -2,8 +2,6 @@ // 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.6 - /** * Concurrent programming using _isolates_: * independent workers that are similar to threads @@ -103,7 +101,7 @@ class Isolate { * If the isolate is spawned in a paused state, use this capability as * argument to the [resume] method in order to resume the paused isolate. */ - final Capability pauseCapability; + final Capability? pauseCapability; /** * Capability granting the ability to terminate the isolate. @@ -113,7 +111,7 @@ class Isolate { * capability of the isolate identified by [controlPort], * then calls to those methods will have no effect. */ - final Capability terminateCapability; + final Capability? terminateCapability; /** * The name of the [Isolate] displayed for debug purposes. @@ -128,7 +126,7 @@ class Isolate { * [IsolateMirror]. */ @Since("2.3") - external String get debugName; + external String? get debugName; /** * Create a new [Isolate] object with a restricted set of capabilities. @@ -180,7 +178,7 @@ class Isolate { * in Dart 2. */ @Deprecated('packages/ directory resolution is not supported in Dart 2.') - external static Future get packageRoot; + external static Future get packageRoot; /** * The package root of the current isolate, if any. @@ -189,7 +187,7 @@ class Isolate { * setup for package resolution, this getter returns `null`, otherwise it * returns the package config URI. */ - external static Future get packageConfig; + external static Future get packageConfig; /** * Maps a package: URI to a non-package Uri. @@ -198,7 +196,7 @@ class Isolate { * isolate, then this call returns `null`. Non-package: URIs are * returned unmodified. */ - external static Future resolvePackageUri(Uri packageUri); + external static Future resolvePackageUri(Uri packageUri); /** * Creates and spawns an isolate that shares the same code as the current @@ -250,11 +248,11 @@ class Isolate { */ external static Future spawn( void entryPoint(T message), T message, - {bool paused: false, - bool errorsAreFatal, - SendPort onExit, - SendPort onError, - @Since("2.3") String debugName}); + {bool paused = false, + bool errorsAreFatal = true, + SendPort? onExit, + SendPort? onError, + @Since("2.3") String? debugName}); /** * Creates and spawns an isolate that runs the code from the library with @@ -332,18 +330,18 @@ class Isolate { Uri uri, List args, var message, - {bool paused: false, - SendPort onExit, - SendPort onError, - bool errorsAreFatal, - bool checked, - Map environment, + {bool paused = false, + SendPort? onExit, + SendPort? onError, + bool errorsAreFatal = true, + bool? checked, + Map? environment, @Deprecated('The packages/ dir is not supported in Dart 2') - Uri packageRoot, - Uri packageConfig, - bool automaticPackageResolution: false, + Uri? packageRoot, + Uri? packageConfig, + bool automaticPackageResolution = false, @Since("2.3") - String debugName}); + String? debugName}); /** * Requests the isolate to pause. @@ -378,7 +376,7 @@ class Isolate { * of the isolate identified by [controlPort], * the pause request is ignored by the receiving isolate. */ - Capability pause([Capability resumeCapability]) { + Capability pause([Capability? resumeCapability]) { resumeCapability ??= new Capability(); _pause(resumeCapability); return resumeCapability; @@ -431,7 +429,7 @@ class Isolate { /* TODO(lrn): Can we do better? Can the system recognize this message and * send a reply if the receiving isolate is dead? */ - external void addOnExitListener(SendPort responsePort, {Object response}); + external void addOnExitListener(SendPort responsePort, {Object? response}); /** * Stops listening for exit messages from the isolate. @@ -498,7 +496,7 @@ class Isolate { * of the isolate identified by [controlPort], * the kill request is ignored by the receiving isolate. */ - external void kill({int priority: beforeNextEvent}); + external void kill({int priority = beforeNextEvent}); /** * Requests that the isolate send [response] on the [responsePort]. @@ -524,7 +522,7 @@ class Isolate { * are completed. */ external void ping(SendPort responsePort, - {Object response, int priority: immediate}); + {Object? response, int priority = immediate}); /** * Requests that uncaught errors of the isolate are sent back to [port]. @@ -579,27 +577,27 @@ class Isolate { * This stream is based on [addErrorListener] and [removeErrorListener]. */ Stream get errors { - StreamController controller; - RawReceivePort port; - void handleError(message) { - List listMessage = message; - String errorDescription = listMessage[0]; - String stackDescription = listMessage[1]; + StreamController controller = StreamController.broadcast(sync: true); + RawReceivePort? port; + void handleError(Object? message) { + var listMessage = message as List; + var errorDescription = listMessage[0] as String; + var stackDescription = listMessage[1] as String; var error = new RemoteError(errorDescription, stackDescription); controller.addError(error, error.stackTrace); } - controller = new StreamController.broadcast( - sync: true, - onListen: () { - port = new RawReceivePort(handleError); - this.addErrorListener(port.sendPort); - }, - onCancel: () { - this.removeErrorListener(port.sendPort); - port.close(); - port = null; - }); + controller.onListen = () { + RawReceivePort receivePort = new RawReceivePort(handleError); + port = receivePort; + this.addErrorListener(receivePort.sendPort); + }; + controller.onCancel = () { + var listenPort = port!; + port = null; + this.removeErrorListener(listenPort.sendPort); + listenPort.close(); + }; return controller.stream; } } @@ -632,7 +630,7 @@ abstract class SendPort implements Capability { * port can receive the message as soon as its isolate's event loop is ready * to deliver it, independently of what the sending isolate is doing. */ - void send(var message); + void send(Object? message); /** * Tests whether [other] is a [SendPort] pointing to the same @@ -662,7 +660,7 @@ abstract class SendPort implements Capability { * * A [ReceivePort] may have many [SendPort]s. */ -abstract class ReceivePort implements Stream { +abstract class ReceivePort implements Stream { /** * Opens a long-lived port for receiving messages. * @@ -692,8 +690,8 @@ abstract class ReceivePort implements Stream { * The [onDone] handler will be called when the stream closes. * The stream closes when [close] is called. */ - StreamSubscription listen(void onData(var message), - {Function onError, void onDone(), bool cancelOnError}); + StreamSubscription listen(void onData(var message)?, + {Function? onError, void onDone()?, bool? cancelOnError}); /** * Closes `this`. @@ -719,14 +717,14 @@ abstract class RawReceivePort { * can not be paused. The data-handler must be set before the first * event is received. */ - external factory RawReceivePort([Function handler]); + external factory RawReceivePort([Function? handler]); /** * Sets the handler that is invoked for every incoming message. * * The handler is invoked in the root-zone ([Zone.root]). */ - void set handler(Function newHandler); + void set handler(Function? newHandler); /** * Closes the port. diff --git a/sdk/lib/js/_js.dart b/sdk/lib/js/_js.dart index cddb791a705..aef7ef90a58 100644 --- a/sdk/lib/js/_js.dart +++ b/sdk/lib/js/_js.dart @@ -2,8 +2,6 @@ // 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.6 - /// Helper library used by `dart:js`. /// /// This library hides any logic that is specific to the web, and allows us to diff --git a/sdk/lib/js/_js_client.dart b/sdk/lib/js/_js_client.dart index b3070d607b1..de255409c8e 100644 --- a/sdk/lib/js/_js_client.dart +++ b/sdk/lib/js/_js_client.dart @@ -2,8 +2,6 @@ // 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.6 - import 'dart:html' show Blob, Event, ImageData, Node, Window, WorkerGlobalScope; import 'dart:indexed_db' show KeyRange; import 'dart:_js_helper' show patch; diff --git a/sdk/lib/js/_js_server.dart b/sdk/lib/js/_js_server.dart index 936c8bf0680..b941d77c899 100644 --- a/sdk/lib/js/_js_server.dart +++ b/sdk/lib/js/_js_server.dart @@ -2,8 +2,6 @@ // 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.6 - import 'dart:_js_helper' show patch; @patch diff --git a/sdk/lib/js/js.dart b/sdk/lib/js/js.dart index 139823d05b7..26a614129e7 100644 --- a/sdk/lib/js/js.dart +++ b/sdk/lib/js/js.dart @@ -2,8 +2,6 @@ // 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.6 - /// Low-level support for interoperating with JavaScript. /// /// You should usually use `package:js` instead of this library. For more @@ -98,7 +96,7 @@ external JsObject get context; class JsObject { /// Constructs a JavaScript object from its native [constructor] and returns /// a proxy to it. - external factory JsObject(JsFunction constructor, [List arguments]); + external factory JsObject(JsFunction constructor, [List? arguments]); /// Constructs a [JsObject] that proxies a native Dart object; _for expert use /// only_. @@ -107,9 +105,9 @@ class JsObject { /// properties attached to a browser host object, such as a Node or Blob, that /// is normally automatically converted into a native Dart object. /// - /// An exception will be thrown if [object] either is `null` or has the type + /// An exception will be thrown if [object] has the type /// `bool`, `num`, or `String`. - external factory JsObject.fromBrowserObject(object); + external factory JsObject.fromBrowserObject(Object object); /// Recursively converts a JSON-like collection of Dart objects to a /// collection of JavaScript objects and returns a [JsObject] proxy to it. @@ -118,34 +116,34 @@ class JsObject { /// converted. Maps and Iterables are copied to a new JavaScript object. /// Primitives and other transferable values are directly converted to their /// JavaScript type, and all other objects are proxied. - external factory JsObject.jsify(object); + external factory JsObject.jsify(Object object); /// Returns the value associated with [property] from the proxied JavaScript /// object. /// /// The type of [property] must be either [String] or [num]. - external dynamic operator [](property); + external dynamic operator [](Object property); // Sets the value associated with [property] on the proxied JavaScript // object. // // The type of [property] must be either [String] or [num]. - external void operator []=(property, value); + external void operator []=(Object property, Object? value); int get hashCode => 0; - external bool operator ==(other); + external bool operator ==(Object other); /// Returns `true` if the JavaScript object contains the specified property /// either directly or though its prototype chain. /// /// This is the equivalent of the `in` operator in JavaScript. - external bool hasProperty(property); + external bool hasProperty(Object property); /// Removes [property] from the JavaScript object. /// /// This is the equivalent of the `delete` operator in JavaScript. - external void deleteProperty(property); + external void deleteProperty(Object property); /// Returns `true` if the JavaScript object has [type] in its prototype chain. /// @@ -159,7 +157,7 @@ class JsObject { /// returns the result. /// /// The type of [method] must be either [String] or [num]. - external dynamic callMethod(method, [List args]); + external dynamic callMethod(Object method, [List? args]); } /// A proxy on a JavaScript Function object. @@ -184,9 +182,9 @@ class JsArray extends JsObject with ListMixin { // Methods required by ListMixin - external E operator [](dynamic index); + external E operator [](Object index); - external void operator []=(dynamic index, E value); + external void operator []=(Object index, E value); external int get length; @@ -209,7 +207,7 @@ class JsArray extends JsObject with ListMixin { external void setRange(int start, int end, Iterable iterable, [int skipCount = 0]); - external void sort([int compare(E a, E b)]); + external void sort([int compare(E a, E b)?]); } /// Returns a wrapper around function [f] that can be called from JavaScript diff --git a/sdk/lib/js_util/js_util.dart b/sdk/lib/js_util/js_util.dart index a299a303c2c..605f6d671e4 100644 --- a/sdk/lib/js_util/js_util.dart +++ b/sdk/lib/js_util/js_util.dart @@ -2,8 +2,6 @@ // 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.6 - /// Utility methods to manipulate `package:js` annotated JavaScript interop /// objects in cases where the name to call is not known at runtime. /// @@ -27,21 +25,21 @@ import 'dart:_js_helper' show convertDartClosureToJS; /// objects for JS interop. /// /// The argument must be a [Map] or [Iterable], the contents of which are also -/// deeply converted. Maps are converted into JavaScript Objects. Iterables are +/// deeply converted. Maps are converted into JavaScript objects. Iterables are /// converted into arrays. Strings, numbers, bools, and `@JS()` annotated /// objects are passed through unmodified. Dart objects are also passed through /// unmodified, but their members aren't usable from JavaScript. -jsify(object) { +dynamic jsify(Object object) { if ((object is! Map) && (object is! Iterable)) { throw ArgumentError("object must be a Map or Iterable"); } return _convertDataTree(object); } -_convertDataTree(data) { +Object _convertDataTree(Object data) { var _convertedObjects = HashMap.identity(); - _convert(o) { + Object? _convert(Object? o) { if (_convertedObjects.containsKey(o)) { return _convertedObjects[o]; } @@ -62,27 +60,30 @@ _convertDataTree(data) { } } - return _convert(data); + return _convert(data)!; } -newObject() => JS('=Object', '{}'); +dynamic newObject() => JS('=Object', '{}'); -bool hasProperty(o, name) => JS('bool', '# in #', name, o); +bool hasProperty(Object o, Object name) => JS('bool', '# in #', name, o); -getProperty(o, name) => JS('Object|Null', '#[#]', o, name); +dynamic getProperty(Object o, Object name) => + JS('Object|Null', '#[#]', o, name); -setProperty(o, name, value) => JS('', '#[#]=#', o, name, value); +dynamic setProperty(Object o, Object name, Object? value) => + JS('', '#[#]=#', o, name, value); -callMethod(o, String method, List args) => +dynamic callMethod(Object o, String method, List args) => JS('Object|Null', '#[#].apply(#, #)', o, method, o, args); /// Check whether [o] is an instance of [type]. /// /// The value in [type] is expected to be a JS-interop object that /// represents a valid JavaScript constructor function. -bool instanceof(o, Object type) => JS('bool', '# instanceof #', o, type); +bool instanceof(Object? o, Object type) => + JS('bool', '# instanceof #', o, type); -callConstructor(Object constr, List arguments) { +dynamic callConstructor(Object constr, List arguments) { if (arguments == null) { return JS('Object', 'new #()', constr); } @@ -151,7 +152,7 @@ callConstructor(Object constr, List arguments) { /// /// final three = await threeFuture; // == 3 /// ``` -Future promiseToFuture(jsPromise) { +Future promiseToFuture(Object jsPromise) { final completer = Completer(); final success = convertDartClosureToJS((r) => completer.complete(r), 1); diff --git a/sdk/lib/math/jenkins_smi_hash.dart b/sdk/lib/math/jenkins_smi_hash.dart index 7bab10be714..deca56cba0b 100644 --- a/sdk/lib/math/jenkins_smi_hash.dart +++ b/sdk/lib/math/jenkins_smi_hash.dart @@ -1,7 +1,6 @@ // Copyright (c) 2013, 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.6 part of dart.math; @@ -34,8 +33,8 @@ class _JenkinsSmiHash { return 0x1fffffff & (hash + ((0x00003fff & hash) << 15)); } - static int hash2(a, b) => finish(combine(combine(0, a), b)); + static int hash2(int a, int b) => finish(combine(combine(0, a), b)); - static int hash4(a, b, c, d) => + static int hash4(int a, int b, int c, int d) => finish(combine(combine(combine(combine(0, a), b), c), d)); } diff --git a/sdk/lib/math/math.dart b/sdk/lib/math/math.dart index 4e893f0647b..b33566976c1 100644 --- a/sdk/lib/math/math.dart +++ b/sdk/lib/math/math.dart @@ -2,8 +2,6 @@ // 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.6 - /// Mathematical constants and functions, plus a random number generator. /// /// To use this library in your code: diff --git a/sdk/lib/math/point.dart b/sdk/lib/math/point.dart index 4bebc0ff49b..4b0fed55724 100644 --- a/sdk/lib/math/point.dart +++ b/sdk/lib/math/point.dart @@ -1,7 +1,6 @@ // Copyright (c) 2013, 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.6 part of dart.math; @@ -16,14 +15,12 @@ class Point { String toString() => 'Point($x, $y)'; - /// A `Point` is only equal to another `Point` with the same coordinates. + /// Whether [other] is a point with the same coordinates as this point. /// - /// This point is equal to `other` if, and only if, - /// `other` is a `Point` with - /// [x] equal to `other.x` and [y] equal to `other.y`. - bool operator ==(dynamic other) => - // Cannot change parameter type to `Object` in case some class - // inherits the type and uses their argument dynamically. + /// Returns `true` if [other] is a [Point] with [x] and [y] + /// coordinates equal to the corresponding coordiantes of this point, + /// and `false` otherwise. + bool operator ==(Object other) => other is Point && x == other.x && y == other.y; int get hashCode => _JenkinsSmiHash.hash2(x.hashCode, y.hashCode); @@ -32,25 +29,25 @@ class Point { /// /// Returns the resulting "vector" as a Point. Point operator +(Point other) { - return Point(x + other.x, y + other.y); + return Point((x + other.x) as T, (y + other.y) as T); } /// Subtract [other] from `this`, as if both points were vectors. /// /// Returns the resulting "vector" as a Point. Point operator -(Point other) { - return Point(x - other.x, y - other.y); + return Point((x - other.x) as T, (y - other.y) as T); } /// Scale this point by [factor] as if it were a vector. /// /// *Important* *Note*: This function accepts a `num` as its argument only so - /// that you can scale Point objects by an `int` factor. Because the - /// star operator always returns the same type of Point that originally called - /// it, passing in a double [factor] on a `Point` _causes_ _a_ - /// _runtime_ _error_ in checked mode. + /// that you can scale `Point` objects by an `int` factor. Because the + /// `*` operator always returns the same type of `Point` as it is called on, + /// passing in a double [factor] on a `Point` _causes_ _a_ + /// _runtime_ _error_. Point operator *(num /*T|int*/ factor) { - return Point((x * factor), (y * factor)); + return Point((x * factor) as T, (y * factor) as T); } /// Get the straight line (Euclidean) distance between the origin (0, 0) and @@ -71,6 +68,6 @@ class Point { T squaredDistanceTo(Point other) { var dx = x - other.x; var dy = y - other.y; - return dx * dx + dy * dy; + return (dx * dx + dy * dy) as T; } } diff --git a/sdk/lib/math/random.dart b/sdk/lib/math/random.dart index 65c96bebe20..fd75e12b44f 100644 --- a/sdk/lib/math/random.dart +++ b/sdk/lib/math/random.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.math; /// A generator of random bool, int, or double values. @@ -11,14 +9,14 @@ part of dart.math; /// The default implementation supplies a stream of pseudo-random bits that are /// not suitable for cryptographic purposes. /// -/// Use the [Random.secure] constructor for cryptographic purposes. +/// Use the [Random.secure]() constructor for cryptographic purposes. abstract class Random { /// Creates a random number generator. /// /// The optional parameter [seed] is used to initialize the /// internal state of the generator. The implementation of the /// random stream can change between releases of the library. - external factory Random([int seed]); + external factory Random([int? seed]); /// Creates a cryptographically secure random number generator. /// diff --git a/sdk/lib/math/rectangle.dart b/sdk/lib/math/rectangle.dart index 51d90ef9fb1..2ee86c91d5c 100644 --- a/sdk/lib/math/rectangle.dart +++ b/sdk/lib/math/rectangle.dart @@ -1,7 +1,6 @@ // Copyright (c) 2013, 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.6 part of dart.math; @@ -33,18 +32,16 @@ abstract class _RectangleBase { T get height; /// The x-coordinate of the right edge. - T get right => left + width; + T get right => (left + width) as T; /// The y-coordinate of the bottom edge. - T get bottom => top + height; + T get bottom => (top + height) as T; String toString() { return 'Rectangle ($left, $top) $width x $height'; } - bool operator ==(dynamic other) => - // Can't change argument type to `Object` since subclasses inherit it - // and uses their argument dynamically. + bool operator ==(Object other) => other is Rectangle && left == other.left && top == other.top && @@ -61,7 +58,7 @@ abstract class _RectangleBase { /// /// Returns the intersection of this and `other`, or `null` if they don't /// intersect. - Rectangle intersection(Rectangle other) { + Rectangle? intersection(Rectangle other) { var x0 = max(left, other.left); var x1 = min(left + width, other.left + other.width); @@ -70,7 +67,7 @@ abstract class _RectangleBase { var y1 = min(top + height, other.top + other.height); if (y0 <= y1) { - return Rectangle(x0, y0, x1 - x0, y1 - y0); + return Rectangle(x0, y0, (x1 - x0) as T, (y1 - y0) as T); } } return null; @@ -92,7 +89,7 @@ abstract class _RectangleBase { var left = min(this.left, other.left); var top = min(this.top, other.top); - return Rectangle(left, top, right - left, bottom - top); + return Rectangle(left, top, (right - left) as T, (bottom - top) as T); } /// Tests whether `this` entirely contains [another]. @@ -112,10 +109,10 @@ abstract class _RectangleBase { } Point get topLeft => Point(this.left, this.top); - Point get topRight => Point(this.left + this.width, this.top); + Point get topRight => Point((this.left + this.width) as T, this.top); Point get bottomRight => - Point(this.left + this.width, this.top + this.height); - Point get bottomLeft => Point(this.left, this.top + this.height); + Point((this.left + this.width) as T, (this.top + this.height) as T); + Point get bottomLeft => Point(this.left, (this.top + this.height) as T); } /// A class for representing two-dimensional rectangles whose properties are @@ -139,8 +136,10 @@ class Rectangle extends _RectangleBase { /// If `width` and `height` are zero, the "rectangle" comprises only the /// single point `(left, top)`. const Rectangle(this.left, this.top, T width, T height) - : this.width = (width < 0) ? -width * 0 : width, // Inline _clampToZero. - this.height = (height < 0) ? -height * 0 : height; + : width = (width < 0) + ? (-width * 0) as dynamic + : width, // Inline _clampToZero. + height = (height < 0) ? (-height * 0) as dynamic : height; /// Create a rectangle spanned by the points [a] and [b]; /// @@ -154,9 +153,9 @@ class Rectangle extends _RectangleBase { /// Similar for the y-coordinates and the bottom edge. factory Rectangle.fromPoints(Point a, Point b) { T left = min(a.x, b.x); - T width = max(a.x, b.x) - left; + T width = (max(a.x, b.x) - left) as T; T top = min(a.y, b.y); - T height = max(a.y, b.y) - top; + T height = (max(a.y, b.y) - top) as T; return Rectangle(left, top, width, height); } } @@ -205,9 +204,9 @@ class MutableRectangle extends _RectangleBase /// Similar for the y-coordinates and the bottom edge. factory MutableRectangle.fromPoints(Point a, Point b) { T left = min(a.x, b.x); - T width = max(a.x, b.x) - left; + T width = (max(a.x, b.x) - left) as T; T top = min(a.y, b.y); - T height = max(a.y, b.y) - top; + T height = (max(a.y, b.y) - top) as T; return MutableRectangle(left, top, width, height); } @@ -245,5 +244,5 @@ class MutableRectangle extends _RectangleBase /// Returns `0` if value is int, `0.0` if value is double. T _clampToZero(T value) { assert(value < 0); - return -value * 0; + return (-value * 0) as T; } diff --git a/sdk/lib/mirrors/mirrors.dart b/sdk/lib/mirrors/mirrors.dart index 731a0a5fdb1..95a8aff18c0 100644 --- a/sdk/lib/mirrors/mirrors.dart +++ b/sdk/lib/mirrors/mirrors.dart @@ -2,8 +2,6 @@ // 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.6 - // For the purposes of the mirrors library, we adopt a naming // convention with respect to getters and setters. Specifically, for // some variable or field... @@ -139,7 +137,7 @@ abstract class MirrorSystem { * Using this method may result in larger output. If possible, use * the const constructor of [Symbol] or symbol literals. */ - external static Symbol getSymbol(String name, [LibraryMirror library]); + external static Symbol getSymbol(String name, [LibraryMirror? library]); } /** @@ -191,7 +189,7 @@ external ClassMirror reflectClass(Type key); * function can only be used to obtain type mirrors on types of the current * isolate. */ -external TypeMirror reflectType(Type key, [List typeArguments]); +external TypeMirror reflectType(Type key, [List? typeArguments]); /** * A [Mirror] reflects some Dart language entity. @@ -228,7 +226,7 @@ abstract class IsolateMirror implements Mirror { * 2. the isolate being reflected by this mirror is the same isolate being * reflected by [other]. */ - bool operator ==(other); + bool operator ==(Object other); /** * Loads the library at the given uri into this isolate. @@ -300,7 +298,7 @@ abstract class DeclarationMirror implements Mirror { * * For a parameter, local variable or local function the owner is the * immediately enclosing function. */ - DeclarationMirror get owner; + DeclarationMirror? get owner; /** * Whether this declaration is library private. @@ -352,7 +350,7 @@ abstract class DeclarationMirror implements Mirror { * * This operation is optional and may throw an [UnsupportedError]. */ - SourceLocation get location; + SourceLocation? get location; /** * A list of the metadata associated with this declaration. @@ -409,7 +407,7 @@ abstract class ObjectMirror implements Mirror { * method throws *e*. */ InstanceMirror invoke(Symbol memberName, List positionalArguments, - [Map namedArguments]); + [Map namedArguments = const {}]); /** * Invokes a getter and returns a mirror on the result. @@ -547,7 +545,7 @@ abstract class InstanceMirror implements ObjectMirror { * b. the remote objects reflected by this mirror and by [other] are * identical. */ - bool operator ==(other); + bool operator ==(Object other); } /** @@ -600,7 +598,7 @@ abstract class ClosureMirror implements InstanceMirror { * method throws *e*. */ InstanceMirror apply(List positionalArguments, - [Map namedArguments]); + [Map namedArguments = const {}]); } /** @@ -632,7 +630,7 @@ abstract class LibraryMirror implements DeclarationMirror, ObjectMirror { * 2. The library being reflected by this mirror and the library being * reflected by [other] are the same library in the same isolate. */ - bool operator ==(other); + bool operator ==(Object other); /** * Returns a list of the imports and exports in this library; @@ -658,17 +656,17 @@ abstract class LibraryDependencyMirror implements Mirror { /// Returns the library mirror of the library that is imported or exported, /// or null if the library is not loaded. - LibraryMirror get targetLibrary; + LibraryMirror? get targetLibrary; /// Returns the prefix if this is a prefixed import and `null` otherwise. - Symbol get prefix; + Symbol? get prefix; /// Returns the list of show/hide combinators on the import/export /// declaration. List get combinators; /// Returns the source location for this import/export declaration. - SourceLocation get location; + SourceLocation? get location; List get metadata; @@ -783,7 +781,7 @@ abstract class ClassMirror implements TypeMirror, ObjectMirror { * * If this type is [:Object:], the superclass will be null. */ - ClassMirror get superclass; + ClassMirror? get superclass; /** * A list of mirrors on the superinterfaces of the reflectee. @@ -877,7 +875,7 @@ abstract class ClassMirror implements TypeMirror, ObjectMirror { */ InstanceMirror newInstance( Symbol constructorName, List positionalArguments, - [Map namedArguments]); + [Map namedArguments = const {}]); /** * Whether this mirror is equal to [other]. @@ -890,7 +888,7 @@ abstract class ClassMirror implements TypeMirror, ObjectMirror { * Note that if the reflected class is an invocation of a generic class, 2. * implies that the reflected class and [other] have equal type arguments. */ - bool operator ==(other); + bool operator ==(Object other); /** * Returns whether the class denoted by the receiver is a subclass of the @@ -950,7 +948,7 @@ abstract class TypeVariableMirror extends TypeMirror { * 1. [other] is a mirror of the same kind, and * 2. [:simpleName == other.simpleName:] and [:owner == other.owner:]. */ - bool operator ==(other); + bool operator ==(Object other); } /** @@ -981,7 +979,7 @@ abstract class MethodMirror implements DeclarationMirror { /** * The source code for the reflectee, if available. Otherwise null. */ - String get source; + String? get source; /** * A list of mirrors on the parameters for the reflectee. @@ -1083,7 +1081,7 @@ abstract class MethodMirror implements DeclarationMirror { * 1. [other] is a mirror of the same kind, and * 2. [:simpleName == other.simpleName:] and [:owner == other.owner:]. */ - bool operator ==(other); + bool operator ==(Object other); } /** @@ -1129,7 +1127,7 @@ abstract class VariableMirror implements DeclarationMirror { * 1. [other] is a mirror of the same kind, and * 2. [:simpleName == other.simpleName:] and [:owner == other.owner:]. */ - bool operator ==(other); + bool operator ==(Object other); } /** @@ -1169,7 +1167,7 @@ abstract class ParameterMirror implements VariableMirror { * * Returns `null` for a required parameter. */ - InstanceMirror get defaultValue; + InstanceMirror? get defaultValue; } /** diff --git a/sdk/lib/svg/dart2js/svg_dart2js.dart b/sdk/lib/svg/dart2js/svg_dart2js.dart index c54ac08c685..ebb90155e14 100644 --- a/sdk/lib/svg/dart2js/svg_dart2js.dart +++ b/sdk/lib/svg/dart2js/svg_dart2js.dart @@ -1,5 +1,3 @@ -// @dart = 2.6 - /** * Scalable Vector Graphics: * Two-dimensional vector graphics with support for events and animation. @@ -32,7 +30,7 @@ class _SvgElementFactoryProvider { static SvgElement createSvgElement_tag(String tag) { final Element temp = document.createElementNS("http://www.w3.org/2000/svg", tag); - return temp; + return temp as SvgElement; } } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file @@ -47,7 +45,8 @@ class AElement extends GraphicsElement implements UriReference { throw new UnsupportedError("Not supported"); } - factory AElement() => _SvgElementFactoryProvider.createSvgElement_tag("a"); + factory AElement() => + _SvgElementFactoryProvider.createSvgElement_tag("a") as AElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -117,7 +116,8 @@ class AnimateElement extends AnimationElement { } factory AnimateElement() => - _SvgElementFactoryProvider.createSvgElement_tag("animate"); + _SvgElementFactoryProvider.createSvgElement_tag("animate") + as AnimateElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -146,7 +146,8 @@ class AnimateMotionElement extends AnimationElement { } factory AnimateMotionElement() => - _SvgElementFactoryProvider.createSvgElement_tag("animateMotion"); + _SvgElementFactoryProvider.createSvgElement_tag("animateMotion") + as AnimateMotionElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -175,7 +176,8 @@ class AnimateTransformElement extends AnimationElement { } factory AnimateTransformElement() => - _SvgElementFactoryProvider.createSvgElement_tag("animateTransform"); + _SvgElementFactoryProvider.createSvgElement_tag("animateTransform") + as AnimateTransformElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -403,7 +405,8 @@ class AnimationElement extends SvgElement implements Tests { } factory AnimationElement() => - _SvgElementFactoryProvider.createSvgElement_tag("animation"); + _SvgElementFactoryProvider.createSvgElement_tag("animation") + as AnimationElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -446,7 +449,8 @@ class CircleElement extends GeometryElement { } factory CircleElement() => - _SvgElementFactoryProvider.createSvgElement_tag("circle"); + _SvgElementFactoryProvider.createSvgElement_tag("circle") + as CircleElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -473,7 +477,8 @@ class ClipPathElement extends GraphicsElement { } factory ClipPathElement() => - _SvgElementFactoryProvider.createSvgElement_tag("clipPath"); + _SvgElementFactoryProvider.createSvgElement_tag("clipPath") + as ClipPathElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -496,7 +501,7 @@ class DefsElement extends GraphicsElement { } factory DefsElement() => - _SvgElementFactoryProvider.createSvgElement_tag("defs"); + _SvgElementFactoryProvider.createSvgElement_tag("defs") as DefsElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -517,7 +522,7 @@ class DescElement extends SvgElement { } factory DescElement() => - _SvgElementFactoryProvider.createSvgElement_tag("desc"); + _SvgElementFactoryProvider.createSvgElement_tag("desc") as DescElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -555,7 +560,8 @@ class EllipseElement extends GeometryElement { } factory EllipseElement() => - _SvgElementFactoryProvider.createSvgElement_tag("ellipse"); + _SvgElementFactoryProvider.createSvgElement_tag("ellipse") + as EllipseElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -589,7 +595,8 @@ class FEBlendElement extends SvgElement } factory FEBlendElement() => - _SvgElementFactoryProvider.createSvgElement_tag("feBlend"); + _SvgElementFactoryProvider.createSvgElement_tag("feBlend") + as FEBlendElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -650,7 +657,8 @@ class FEColorMatrixElement extends SvgElement } factory FEColorMatrixElement() => - _SvgElementFactoryProvider.createSvgElement_tag("feColorMatrix"); + _SvgElementFactoryProvider.createSvgElement_tag("feColorMatrix") + as FEColorMatrixElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -709,7 +717,8 @@ class FEComponentTransferElement extends SvgElement } factory FEComponentTransferElement() => - _SvgElementFactoryProvider.createSvgElement_tag("feComponentTransfer"); + _SvgElementFactoryProvider.createSvgElement_tag("feComponentTransfer") + as FEComponentTransferElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -813,7 +822,8 @@ class FEConvolveMatrixElement extends SvgElement } factory FEConvolveMatrixElement() => - _SvgElementFactoryProvider.createSvgElement_tag("feConvolveMatrix"); + _SvgElementFactoryProvider.createSvgElement_tag("feConvolveMatrix") + as FEConvolveMatrixElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -888,7 +898,8 @@ class FEDiffuseLightingElement extends SvgElement } factory FEDiffuseLightingElement() => - _SvgElementFactoryProvider.createSvgElement_tag("feDiffuseLighting"); + _SvgElementFactoryProvider.createSvgElement_tag("feDiffuseLighting") + as FEDiffuseLightingElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -941,7 +952,8 @@ class FEDisplacementMapElement extends SvgElement } factory FEDisplacementMapElement() => - _SvgElementFactoryProvider.createSvgElement_tag("feDisplacementMap"); + _SvgElementFactoryProvider.createSvgElement_tag("feDisplacementMap") + as FEDisplacementMapElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -1003,7 +1015,8 @@ class FEDistantLightElement extends SvgElement { } factory FEDistantLightElement() => - _SvgElementFactoryProvider.createSvgElement_tag("feDistantLight"); + _SvgElementFactoryProvider.createSvgElement_tag("feDistantLight") + as FEDistantLightElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -1038,7 +1051,8 @@ class FEFloodElement extends SvgElement } factory FEFloodElement() => - _SvgElementFactoryProvider.createSvgElement_tag("feFlood"); + _SvgElementFactoryProvider.createSvgElement_tag("feFlood") + as FEFloodElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -1080,7 +1094,8 @@ class FEFuncAElement extends _SVGComponentTransferFunctionElement { } factory FEFuncAElement() => - _SvgElementFactoryProvider.createSvgElement_tag("feFuncA"); + _SvgElementFactoryProvider.createSvgElement_tag("feFuncA") + as FEFuncAElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -1110,7 +1125,8 @@ class FEFuncBElement extends _SVGComponentTransferFunctionElement { } factory FEFuncBElement() => - _SvgElementFactoryProvider.createSvgElement_tag("feFuncB"); + _SvgElementFactoryProvider.createSvgElement_tag("feFuncB") + as FEFuncBElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -1140,7 +1156,8 @@ class FEFuncGElement extends _SVGComponentTransferFunctionElement { } factory FEFuncGElement() => - _SvgElementFactoryProvider.createSvgElement_tag("feFuncG"); + _SvgElementFactoryProvider.createSvgElement_tag("feFuncG") + as FEFuncGElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -1170,7 +1187,8 @@ class FEFuncRElement extends _SVGComponentTransferFunctionElement { } factory FEFuncRElement() => - _SvgElementFactoryProvider.createSvgElement_tag("feFuncR"); + _SvgElementFactoryProvider.createSvgElement_tag("feFuncR") + as FEFuncRElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -1201,7 +1219,8 @@ class FEGaussianBlurElement extends SvgElement } factory FEGaussianBlurElement() => - _SvgElementFactoryProvider.createSvgElement_tag("feGaussianBlur"); + _SvgElementFactoryProvider.createSvgElement_tag("feGaussianBlur") + as FEGaussianBlurElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -1252,7 +1271,8 @@ class FEImageElement extends SvgElement } factory FEImageElement() => - _SvgElementFactoryProvider.createSvgElement_tag("feImage"); + _SvgElementFactoryProvider.createSvgElement_tag("feImage") + as FEImageElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -1301,7 +1321,8 @@ class FEMergeElement extends SvgElement } factory FEMergeElement() => - _SvgElementFactoryProvider.createSvgElement_tag("feMerge"); + _SvgElementFactoryProvider.createSvgElement_tag("feMerge") + as FEMergeElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -1343,7 +1364,8 @@ class FEMergeNodeElement extends SvgElement { } factory FEMergeNodeElement() => - _SvgElementFactoryProvider.createSvgElement_tag("feMergeNode"); + _SvgElementFactoryProvider.createSvgElement_tag("feMergeNode") + as FEMergeNodeElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -1425,7 +1447,8 @@ class FEOffsetElement extends SvgElement } factory FEOffsetElement() => - _SvgElementFactoryProvider.createSvgElement_tag("feOffset"); + _SvgElementFactoryProvider.createSvgElement_tag("feOffset") + as FEOffsetElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -1473,7 +1496,8 @@ class FEPointLightElement extends SvgElement { } factory FEPointLightElement() => - _SvgElementFactoryProvider.createSvgElement_tag("fePointLight"); + _SvgElementFactoryProvider.createSvgElement_tag("fePointLight") + as FEPointLightElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -1510,7 +1534,8 @@ class FESpecularLightingElement extends SvgElement } factory FESpecularLightingElement() => - _SvgElementFactoryProvider.createSvgElement_tag("feSpecularLighting"); + _SvgElementFactoryProvider.createSvgElement_tag("feSpecularLighting") + as FESpecularLightingElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -1564,7 +1589,8 @@ class FESpotLightElement extends SvgElement { } factory FESpotLightElement() => - _SvgElementFactoryProvider.createSvgElement_tag("feSpotLight"); + _SvgElementFactoryProvider.createSvgElement_tag("feSpotLight") + as FESpotLightElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -1611,7 +1637,8 @@ class FETileElement extends SvgElement } factory FETileElement() => - _SvgElementFactoryProvider.createSvgElement_tag("feTile"); + _SvgElementFactoryProvider.createSvgElement_tag("feTile") + as FETileElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -1656,7 +1683,8 @@ class FETurbulenceElement extends SvgElement } factory FETurbulenceElement() => - _SvgElementFactoryProvider.createSvgElement_tag("feTurbulence"); + _SvgElementFactoryProvider.createSvgElement_tag("feTurbulence") + as FETurbulenceElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -1722,7 +1750,8 @@ class FilterElement extends SvgElement implements UriReference { } factory FilterElement() => - _SvgElementFactoryProvider.createSvgElement_tag("filter"); + _SvgElementFactoryProvider.createSvgElement_tag("filter") + as FilterElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -1803,7 +1832,8 @@ class ForeignObjectElement extends GraphicsElement { } factory ForeignObjectElement() => - _SvgElementFactoryProvider.createSvgElement_tag("foreignObject"); + _SvgElementFactoryProvider.createSvgElement_tag("foreignObject") + as ForeignObjectElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -1836,7 +1866,8 @@ class GElement extends GraphicsElement { throw new UnsupportedError("Not supported"); } - factory GElement() => _SvgElementFactoryProvider.createSvgElement_tag("g"); + factory GElement() => + _SvgElementFactoryProvider.createSvgElement_tag("g") as GElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -1921,7 +1952,7 @@ class ImageElement extends GraphicsElement implements UriReference { } factory ImageElement() => - _SvgElementFactoryProvider.createSvgElement_tag("image"); + _SvgElementFactoryProvider.createSvgElement_tag("image") as ImageElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -2091,7 +2122,7 @@ class LineElement extends GeometryElement { } factory LineElement() => - _SvgElementFactoryProvider.createSvgElement_tag("line"); + _SvgElementFactoryProvider.createSvgElement_tag("line") as LineElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -2120,7 +2151,8 @@ class LinearGradientElement extends _GradientElement { } factory LinearGradientElement() => - _SvgElementFactoryProvider.createSvgElement_tag("linearGradient"); + _SvgElementFactoryProvider.createSvgElement_tag("linearGradient") + as LinearGradientElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -2149,7 +2181,8 @@ class MarkerElement extends SvgElement implements FitToViewBox { } factory MarkerElement() => - _SvgElementFactoryProvider.createSvgElement_tag("marker"); + _SvgElementFactoryProvider.createSvgElement_tag("marker") + as MarkerElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -2206,7 +2239,7 @@ class MaskElement extends SvgElement implements Tests { } factory MaskElement() => - _SvgElementFactoryProvider.createSvgElement_tag("mask"); + _SvgElementFactoryProvider.createSvgElement_tag("mask") as MaskElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -2414,7 +2447,7 @@ class PathElement extends GeometryElement { } factory PathElement() => - _SvgElementFactoryProvider.createSvgElement_tag("path"); + _SvgElementFactoryProvider.createSvgElement_tag("path") as PathElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -2436,7 +2469,8 @@ class PatternElement extends SvgElement } factory PatternElement() => - _SvgElementFactoryProvider.createSvgElement_tag("pattern"); + _SvgElementFactoryProvider.createSvgElement_tag("pattern") + as PatternElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -2541,7 +2575,8 @@ class PolygonElement extends GeometryElement { } factory PolygonElement() => - _SvgElementFactoryProvider.createSvgElement_tag("polygon"); + _SvgElementFactoryProvider.createSvgElement_tag("polygon") + as PolygonElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -2566,7 +2601,8 @@ class PolylineElement extends GeometryElement { } factory PolylineElement() => - _SvgElementFactoryProvider.createSvgElement_tag("polyline"); + _SvgElementFactoryProvider.createSvgElement_tag("polyline") + as PolylineElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -2639,7 +2675,8 @@ class RadialGradientElement extends _GradientElement { } factory RadialGradientElement() => - _SvgElementFactoryProvider.createSvgElement_tag("radialGradient"); + _SvgElementFactoryProvider.createSvgElement_tag("radialGradient") + as RadialGradientElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -2700,7 +2737,7 @@ class RectElement extends GeometryElement { } factory RectElement() => - _SvgElementFactoryProvider.createSvgElement_tag("rect"); + _SvgElementFactoryProvider.createSvgElement_tag("rect") as RectElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -2733,7 +2770,8 @@ class ScriptElement extends SvgElement implements UriReference { } factory ScriptElement() => - _SvgElementFactoryProvider.createSvgElement_tag("script"); + _SvgElementFactoryProvider.createSvgElement_tag("script") + as ScriptElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -2765,7 +2803,7 @@ class SetElement extends AnimationElement { } factory SetElement() => - _SvgElementFactoryProvider.createSvgElement_tag("set"); + _SvgElementFactoryProvider.createSvgElement_tag("set") as SetElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -2791,7 +2829,7 @@ class StopElement extends SvgElement { } factory StopElement() => - _SvgElementFactoryProvider.createSvgElement_tag("stop"); + _SvgElementFactoryProvider.createSvgElement_tag("stop") as StopElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -2891,7 +2929,7 @@ class StyleElement extends SvgElement { } factory StyleElement() => - _SvgElementFactoryProvider.createSvgElement_tag("style"); + _SvgElementFactoryProvider.createSvgElement_tag("style") as StyleElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -2907,7 +2945,7 @@ class StyleElement extends SvgElement { set media(String value) native; - StyleSheet get sheet native; + StyleSheet? get sheet native; // Use implementation from Element. // String get title native; @@ -2956,16 +2994,16 @@ class SvgElement extends Element implements GlobalEventHandlers, NoncedElement { static final _START_TAG_REGEXP = new RegExp('<(\\w+)'); factory SvgElement.tag(String tag) => - document.createElementNS("http://www.w3.org/2000/svg", tag); + document.createElementNS("http://www.w3.org/2000/svg", tag) as SvgElement; factory SvgElement.svg(String svg, - {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) { + {NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) { if (validator == null && treeSanitizer == null) { validator = new NodeValidatorBuilder.common()..allowSvg(); } final match = _START_TAG_REGEXP.firstMatch(svg); var parentElement; - if (match != null && match.group(1).toLowerCase() == 'svg') { + if (match != null && match.group(1)!.toLowerCase() == 'svg') { parentElement = document.body; } else { parentElement = new SvgSvgElement(); @@ -2987,24 +3025,24 @@ class SvgElement extends Element implements GlobalEventHandlers, NoncedElement { String get outerHtml { final container = new DivElement(); - final SvgElement cloned = this.clone(true); + final SvgElement cloned = this.clone(true) as SvgElement; container.children.add(cloned); return container.innerHtml; } String get innerHtml { final container = new DivElement(); - final SvgElement cloned = this.clone(true); + final SvgElement cloned = this.clone(true) as SvgElement; container.children.addAll(cloned.children); return container.innerHtml; } - set innerHtml(String value) { + set innerHtml(String? value) { this.setInnerHtml(value); } - DocumentFragment createFragment(String svg, - {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) { + DocumentFragment createFragment(String? svg, + {NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) { if (treeSanitizer == null) { if (validator == null) { validator = new NodeValidatorBuilder.common()..allowSvg(); @@ -3015,13 +3053,13 @@ class SvgElement extends Element implements GlobalEventHandlers, NoncedElement { // We create a fragment which will parse in the HTML parser var html = '$svg'; var fragment = - document.body.createFragment(html, treeSanitizer: treeSanitizer); + document.body!.createFragment(html, treeSanitizer: treeSanitizer); var svgFragment = new DocumentFragment(); // The root is the element, need to pull out the contents. var root = fragment.nodes.single; while (root.firstChild != null) { - svgFragment.append(root.firstChild); + svgFragment.append(root.firstChild!); } return svgFragment; } @@ -3033,7 +3071,7 @@ class SvgElement extends Element implements GlobalEventHandlers, NoncedElement { } void insertAdjacentHtml(String where, String text, - {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) { + {NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) { throw new UnsupportedError("Cannot invoke insertAdjacentHtml on SVG."); } @@ -3248,7 +3286,7 @@ class SvgElement extends Element implements GlobalEventHandlers, NoncedElement { AnimatedString get _svgClassName native; @JSName('ownerSVGElement') - SvgSvgElement get ownerSvgElement native; + SvgSvgElement? get ownerSvgElement native; // Use implementation from Element. // CssStyleDeclaration get style native; @@ -3258,7 +3296,7 @@ class SvgElement extends Element implements GlobalEventHandlers, NoncedElement { // int get tabIndex native; // void set tabIndex(int value) native; - SvgElement get viewportElement native; + SvgElement? get viewportElement native; void blur() native; @@ -3266,9 +3304,9 @@ class SvgElement extends Element implements GlobalEventHandlers, NoncedElement { // From NoncedElement - String get nonce native; + String? get nonce native; - set nonce(String value) native; + set nonce(String? value) native; ElementStream get onAbort => abortEvent.forElement(this); @@ -3406,7 +3444,7 @@ class SvgSvgElement extends GraphicsElement final el = new SvgElement.tag("svg"); // The SVG spec requires the version attribute to match the spec version el.attributes['version'] = "1.1"; - return el; + return el as SvgSvgElement; } // To suppress missing implicit constructor warnings. @@ -3472,13 +3510,14 @@ class SvgSvgElement extends GraphicsElement Element getElementById(String elementId) native; - @Returns('NodeList|Null') + @Returns('NodeList') @Creates('NodeList') - List getEnclosureList(Rect rect, SvgElement referenceElement) native; + List getEnclosureList(Rect rect, SvgElement? referenceElement) native; - @Returns('NodeList|Null') + @Returns('NodeList') @Creates('NodeList') - List getIntersectionList(Rect rect, SvgElement referenceElement) native; + List getIntersectionList(Rect rect, SvgElement? referenceElement) + native; void pauseAnimations() native; @@ -3517,7 +3556,8 @@ class SwitchElement extends GraphicsElement { } factory SwitchElement() => - _SvgElementFactoryProvider.createSvgElement_tag("switch"); + _SvgElementFactoryProvider.createSvgElement_tag("switch") + as SwitchElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -3538,7 +3578,8 @@ class SymbolElement extends SvgElement implements FitToViewBox { } factory SymbolElement() => - _SvgElementFactoryProvider.createSvgElement_tag("symbol"); + _SvgElementFactoryProvider.createSvgElement_tag("symbol") + as SymbolElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -3565,7 +3606,7 @@ class TSpanElement extends TextPositioningElement { } factory TSpanElement() => - _SvgElementFactoryProvider.createSvgElement_tag("tspan"); + _SvgElementFactoryProvider.createSvgElement_tag("tspan") as TSpanElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -3647,7 +3688,7 @@ class TextElement extends TextPositioningElement { } factory TextElement() => - _SvgElementFactoryProvider.createSvgElement_tag("text"); + _SvgElementFactoryProvider.createSvgElement_tag("text") as TextElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -3736,7 +3777,7 @@ class TitleElement extends SvgElement { } factory TitleElement() => - _SvgElementFactoryProvider.createSvgElement_tag("title"); + _SvgElementFactoryProvider.createSvgElement_tag("title") as TitleElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -3855,7 +3896,7 @@ class TransformList extends Interceptor void clear() native; - Transform consolidate() native; + Transform? consolidate() native; @JSName('createSVGTransformFromMatrix') Transform createSvgTransformFromMatrix(Matrix matrix) native; @@ -3914,7 +3955,7 @@ class UseElement extends GraphicsElement implements UriReference { } factory UseElement() => - _SvgElementFactoryProvider.createSvgElement_tag("use"); + _SvgElementFactoryProvider.createSvgElement_tag("use") as UseElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -3947,7 +3988,7 @@ class ViewElement extends SvgElement implements FitToViewBox, ZoomAndPan { } factory ViewElement() => - _SvgElementFactoryProvider.createSvgElement_tag("view"); + _SvgElementFactoryProvider.createSvgElement_tag("view") as ViewElement; /** * Constructor instantiated by the DOM when a custom element has been created. * @@ -4076,7 +4117,8 @@ abstract class _SVGMPathElement extends SvgElement implements UriReference { } factory _SVGMPathElement() => - _SvgElementFactoryProvider.createSvgElement_tag("mpath"); + _SvgElementFactoryProvider.createSvgElement_tag("mpath") + as _SVGMPathElement; /** * Constructor instantiated by the DOM when a custom element has been created. * diff --git a/sdk/lib/typed_data/typed_data.dart b/sdk/lib/typed_data/typed_data.dart index e1d8f7e6d80..8852ab89545 100644 --- a/sdk/lib/typed_data/typed_data.dart +++ b/sdk/lib/typed_data/typed_data.dart @@ -2,8 +2,6 @@ // 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.6 - /// Lists that efficiently handle fixed sized data /// (for example, unsigned 8 byte integers) and SIMD numeric types. /// @@ -46,7 +44,7 @@ abstract class ByteBuffer { * * `length` must not be negative, and * * `offsetInBytes + length` must not be greater than [lengthInBytes]. */ - Uint8List asUint8List([int offsetInBytes = 0, int length]); + Uint8List asUint8List([int offsetInBytes = 0, int? length]); /** * Creates a [Int8List] _view_ of a region of this byte buffer. @@ -64,7 +62,7 @@ abstract class ByteBuffer { * * `length` must not be negative, and * * `offsetInBytes + length` must not be greater than [lengthInBytes]. */ - Int8List asInt8List([int offsetInBytes = 0, int length]); + Int8List asInt8List([int offsetInBytes = 0, int? length]); /** * Creates a [Uint8ClampedList] _view_ of a region of this byte buffer. @@ -82,7 +80,7 @@ abstract class ByteBuffer { * * `length` must not be negative, and * * `offsetInBytes + length` must not be greater than [lengthInBytes]. */ - Uint8ClampedList asUint8ClampedList([int offsetInBytes = 0, int length]); + Uint8ClampedList asUint8ClampedList([int offsetInBytes = 0, int? length]); /** * Creates a [Uint16List] _view_ of a region of this byte buffer. @@ -105,7 +103,7 @@ abstract class ByteBuffer { * * `length` must not be negative, and * * `offsetInBytes + length * 2` must not be greater than [lengthInBytes]. */ - Uint16List asUint16List([int offsetInBytes = 0, int length]); + Uint16List asUint16List([int offsetInBytes = 0, int? length]); /** * Creates a [Int16List] _view_ of a region of this byte buffer. @@ -128,7 +126,7 @@ abstract class ByteBuffer { * * `length` must not be negative, and * * `offsetInBytes + length * 2` must not be greater than [lengthInBytes]. */ - Int16List asInt16List([int offsetInBytes = 0, int length]); + Int16List asInt16List([int offsetInBytes = 0, int? length]); /** * Creates a [Uint32List] _view_ of a region of this byte buffer. @@ -152,7 +150,7 @@ abstract class ByteBuffer { * * `length` must not be negative, and * * `offsetInBytes + length * 4` must not be greater than [lengthInBytes]. */ - Uint32List asUint32List([int offsetInBytes = 0, int length]); + Uint32List asUint32List([int offsetInBytes = 0, int? length]); /** * Creates a [Int32List] _view_ of a region of this byte buffer. @@ -176,7 +174,7 @@ abstract class ByteBuffer { * * `length` must not be negative, and * * `offsetInBytes + length * 4` must not be greater than [lengthInBytes]. */ - Int32List asInt32List([int offsetInBytes = 0, int length]); + Int32List asInt32List([int offsetInBytes = 0, int? length]); /** * Creates a [Uint64List] _view_ of a region of this byte buffer. @@ -200,7 +198,7 @@ abstract class ByteBuffer { * * `length` must not be negative, and * * `offsetInBytes + length * 8` must not be greater than [lengthInBytes]. */ - Uint64List asUint64List([int offsetInBytes = 0, int length]); + Uint64List asUint64List([int offsetInBytes = 0, int? length]); /** * Creates a [Int64List] _view_ of a region of this byte buffer. @@ -224,7 +222,7 @@ abstract class ByteBuffer { * * `length` must not be negative, and * * `offsetInBytes + length * 8` must not be greater than [lengthInBytes]. */ - Int64List asInt64List([int offsetInBytes = 0, int length]); + Int64List asInt64List([int offsetInBytes = 0, int? length]); /** * Creates a [Int32x4List] _view_ of a region of this byte buffer. @@ -248,7 +246,7 @@ abstract class ByteBuffer { * * `length` must not be negative, and * * `offsetInBytes + length * 16` must not be greater than [lengthInBytes]. */ - Int32x4List asInt32x4List([int offsetInBytes = 0, int length]); + Int32x4List asInt32x4List([int offsetInBytes = 0, int? length]); /** * Creates a [Float32List] _view_ of a region of this byte buffer. @@ -272,7 +270,7 @@ abstract class ByteBuffer { * * `length` must not be negative, and * * `offsetInBytes + length * 4` must not be greater than [lengthInBytes]. */ - Float32List asFloat32List([int offsetInBytes = 0, int length]); + Float32List asFloat32List([int offsetInBytes = 0, int? length]); /** * Creates a [Float64List] _view_ of a region of this byte buffer. @@ -296,7 +294,7 @@ abstract class ByteBuffer { * * `length` must not be negative, and * * `offsetInBytes + length * 8` must not be greater than [lengthInBytes]. */ - Float64List asFloat64List([int offsetInBytes = 0, int length]); + Float64List asFloat64List([int offsetInBytes = 0, int? length]); /** * Creates a [Float32x4List] _view_ of a region of this byte buffer. @@ -320,7 +318,7 @@ abstract class ByteBuffer { * * `length` must not be negative, and * * `offsetInBytes + length * 16` must not be greater than [lengthInBytes]. */ - Float32x4List asFloat32x4List([int offsetInBytes = 0, int length]); + Float32x4List asFloat32x4List([int offsetInBytes = 0, int? length]); /** * Creates a [Float64x2List] _view_ of a region of this byte buffer. @@ -344,7 +342,7 @@ abstract class ByteBuffer { * * `length` must not be negative, and * * `offsetInBytes + length * 16` must not be greater than [lengthInBytes]. */ - Float64x2List asFloat64x2List([int offsetInBytes = 0, int length]); + Float64x2List asFloat64x2List([int offsetInBytes = 0, int? length]); /** * Creates a [ByteData] _view_ of a region of this byte buffer. @@ -362,7 +360,7 @@ abstract class ByteBuffer { * * `length` must not be negative, and * * `offsetInBytes + length` must not be greater than [lengthInBytes]. */ - ByteData asByteData([int offsetInBytes = 0, int length]); + ByteData asByteData([int offsetInBytes = 0, int? length]); } /** @@ -442,15 +440,28 @@ class Endian { * with ordinary [List] implementations. * `ByteData` can save space, by eliminating the need for object headers, * and time, by eliminating the need for data copies. + * + * If data comes in as bytes, they can be converted to `ByteData` by + * sharing the same buffer. + * ```dart + * Uint8List bytes = ...; + * var blob = ByteData.sublistView(bytes); + * if (blob.getUint32(0, Endian.little) == 0x04034b50) { // Zip file marker + * ... + * } + * + * ``` + * * Finally, `ByteData` may be used to intentionally reinterpret the bytes * representing one arithmetic type as another. * For example this code fragment determine what 32-bit signed integer * is represented by the bytes of a 32-bit floating point number * (both stored as big endian): - * - * var bdata = new ByteData(8); - * bdata.setFloat32(0, 3.04); - * int huh = bdata.getInt32(0); // 0x40428f5c + * ```dart + * var bdata = new ByteData(8); + * bdata.setFloat32(0, 3.04); + * int huh = bdata.getInt32(0); // 0x40428f5c + * ``` */ abstract class ByteData implements TypedData { /** @@ -483,16 +494,16 @@ abstract class ByteData implements TypedData { * ByteData.view(other.buffer, other.offsetInBytes, count) * ``` * Alternatively, use [ByteData.sublistView] - * which includes this computation. + * which includes this computation: * ```dart - * ByteData.sublistView(other, 0, count) + * ByteData.sublistView(other, 0, count); * ``` * (The third argument is an end index rather than a length, so if * you start from a position greater than zero, you need not * reduce the count correspondingly). */ factory ByteData.view(ByteBuffer buffer, - [int offsetInBytes = 0, int length]) { + [int offsetInBytes = 0, int? length]) { return buffer.asByteData(offsetInBytes, length); } @@ -515,10 +526,12 @@ abstract class ByteData implements TypedData { * If omitted, [start] defaults to zero and [end] to *elementCount*. */ @Since("2.8") - factory ByteData.sublistView(TypedData data, [int start = 0, int end]) { + factory ByteData.sublistView(TypedData data, [int start = 0, int? end]) { int elementSize = data.elementSizeInBytes; end = RangeError.checkValidRange( start, end, data.lengthInBytes ~/ elementSize); + if (end == null) + throw "unreachable"; // TODO(38725): Remove when promotion works. return data.buffer.asByteData( data.offsetInBytes + start * elementSize, (end - start) * elementSize); } @@ -827,16 +840,16 @@ abstract class Int8List implements List, _TypedIntList { * Int8List.view(other.buffer, other.offsetInBytes, count) * ``` * Alternatively, use [Int8List.sublistView] - * which includes this computation. + * which includes this computation: * ```dart - * Int8List.sublistView(other, 0, count) + * Int8List.sublistView(other, 0, count); * ``` * (The third argument is an end index rather than a length, so if * you start from a position greater than zero, you need not * reduce the count correspondingly). */ factory Int8List.view(ByteBuffer buffer, - [int offsetInBytes = 0, int length]) { + [int offsetInBytes = 0, int? length]) { return buffer.asInt8List(offsetInBytes, length); } @@ -859,10 +872,11 @@ abstract class Int8List implements List, _TypedIntList { * If omitted, [start] defaults to zero and [end] to *elementCount*. */ @Since("2.8") - factory Int8List.sublistView(TypedData data, [int start = 0, int end]) { + factory Int8List.sublistView(TypedData data, [int start = 0, int? end]) { int elementSize = data.elementSizeInBytes; end = RangeError.checkValidRange( start, end, data.lengthInBytes ~/ elementSize); + if (end == null) throw "unreachable"; // TODO(38725) return data.buffer.asInt8List( data.offsetInBytes + start * elementSize, (end - start) * elementSize); } @@ -890,7 +904,7 @@ abstract class Int8List implements List, _TypedIntList { * 0 ≤ `start` ≤ `end` ≤ `this.length` * If `end` is equal to `start`, then the returned list is empty. */ - Int8List sublist(int start, [int end]); + Int8List sublist(int start, [int? end]); static const int bytesPerElement = 1; } @@ -949,16 +963,16 @@ abstract class Uint8List implements List, _TypedIntList { * Uint8List.view(other.buffer, other.offsetInBytes, count) * ``` * Alternatively, use [Uint8List.sublistView] - * which includes this computation. + * which includes this computation: * ```dart - * Uint8List.sublistView(other, 0, count) + * Uint8List.sublistView(other, 0, count); * ``` * (The third argument is an end index rather than a length, so if * you start from a position greater than zero, you need not * reduce the count correspondingly). */ factory Uint8List.view(ByteBuffer buffer, - [int offsetInBytes = 0, int length]) { + [int offsetInBytes = 0, int? length]) { return buffer.asUint8List(offsetInBytes, length); } @@ -981,10 +995,11 @@ abstract class Uint8List implements List, _TypedIntList { * If omitted, [start] defaults to zero and [end] to *elementCount*. */ @Since("2.8") - factory Uint8List.sublistView(TypedData data, [int start = 0, int end]) { + factory Uint8List.sublistView(TypedData data, [int start = 0, int? end]) { int elementSize = data.elementSizeInBytes; end = RangeError.checkValidRange( start, end, data.lengthInBytes ~/ elementSize); + if (end == null) throw "unreachable"; // TODO(38725) return data.buffer.asUint8List( data.offsetInBytes + start * elementSize, (end - start) * elementSize); } @@ -1021,7 +1036,7 @@ abstract class Uint8List implements List, _TypedIntList { * 0 ≤ `start` ≤ `end` ≤ `this.length` * If `end` is equal to `start`, then the returned list is empty. */ - Uint8List sublist(int start, [int end]); + Uint8List sublist(int start, [int? end]); static const int bytesPerElement = 1; } @@ -1081,16 +1096,16 @@ abstract class Uint8ClampedList implements List, _TypedIntList { * Uint8ClampedList.view(other.buffer, other.offsetInBytes, count) * ``` * Alternatively, use [Uint8ClampedList.sublistView] - * which includes this computation. + * which includes this computation: * ```dart - * Uint8ClampedList.sublistView(other, 0, count) + * Uint8ClampedList.sublistView(other, 0, count); * ``` * (The third argument is an end index rather than a length, so if * you start from a position greater than zero, you need not * reduce the count correspondingly). */ factory Uint8ClampedList.view(ByteBuffer buffer, - [int offsetInBytes = 0, int length]) { + [int offsetInBytes = 0, int? length]) { return buffer.asUint8ClampedList(offsetInBytes, length); } @@ -1114,10 +1129,11 @@ abstract class Uint8ClampedList implements List, _TypedIntList { */ @Since("2.8") factory Uint8ClampedList.sublistView(TypedData data, - [int start = 0, int end]) { + [int start = 0, int? end]) { int elementSize = data.elementSizeInBytes; end = RangeError.checkValidRange( start, end, data.lengthInBytes ~/ elementSize); + if (end == null) throw "unreachable"; // TODO(38725) return data.buffer.asUint8ClampedList( data.offsetInBytes + start * elementSize, (end - start) * elementSize); } @@ -1145,7 +1161,7 @@ abstract class Uint8ClampedList implements List, _TypedIntList { * 0 ≤ `start` ≤ `end` ≤ `this.length` * If `end` is equal to `start`, then the returned list is empty. */ - Uint8ClampedList sublist(int start, [int end]); + Uint8ClampedList sublist(int start, [int? end]); static const int bytesPerElement = 1; } @@ -1209,16 +1225,16 @@ abstract class Int16List implements List, _TypedIntList { * Int16List.view(other.buffer, other.offsetInBytes, count) * ``` * Alternatively, use [Int16List.sublistView] - * which includes this computation. + * which includes this computation: * ```dart - * Int16List.sublistView(other, 0, count) + * Int16List.sublistView(other, 0, count); * ``` * (The third argument is an end index rather than a length, so if * you start from a position greater than zero, you need not * reduce the count correspondingly). */ factory Int16List.view(ByteBuffer buffer, - [int offsetInBytes = 0, int length]) { + [int offsetInBytes = 0, int? length]) { return buffer.asInt16List(offsetInBytes, length); } @@ -1244,10 +1260,11 @@ abstract class Int16List implements List, _TypedIntList { * multiples of two. */ @Since("2.8") - factory Int16List.sublistView(TypedData data, [int start = 0, int end]) { + factory Int16List.sublistView(TypedData data, [int start = 0, int? end]) { int elementSize = data.elementSizeInBytes; end = RangeError.checkValidRange( start, end, data.lengthInBytes ~/ elementSize); + if (end == null) throw "unreachable"; // TODO(38725) int byteLength = (end - start) * elementSize; if (byteLength % bytesPerElement != 0) { throw ArgumentError("The number of bytes to view must be a multiple of " + @@ -1280,7 +1297,7 @@ abstract class Int16List implements List, _TypedIntList { * 0 ≤ `start` ≤ `end` ≤ `this.length` * If `end` is equal to `start`, then the returned list is empty. */ - Int16List sublist(int start, [int end]); + Int16List sublist(int start, [int? end]); static const int bytesPerElement = 2; } @@ -1345,16 +1362,16 @@ abstract class Uint16List implements List, _TypedIntList { * Uint16List.view(other.buffer, other.offsetInBytes, count) * ``` * Alternatively, use [Uint16List.sublistView] - * which includes this computation. + * which includes this computation: * ```dart - * Uint16List.sublistView(other, 0, count) + * Uint16List.sublistView(other, 0, count); * ``` * (The third argument is an end index rather than a length, so if * you start from a position greater than zero, you need not * reduce the count correspondingly). */ factory Uint16List.view(ByteBuffer buffer, - [int offsetInBytes = 0, int length]) { + [int offsetInBytes = 0, int? length]) { return buffer.asUint16List(offsetInBytes, length); } @@ -1380,10 +1397,11 @@ abstract class Uint16List implements List, _TypedIntList { * multiples of two. */ @Since("2.8") - factory Uint16List.sublistView(TypedData data, [int start = 0, int end]) { + factory Uint16List.sublistView(TypedData data, [int start = 0, int? end]) { int elementSize = data.elementSizeInBytes; end = RangeError.checkValidRange( start, end, data.lengthInBytes ~/ elementSize); + if (end == null) throw "unreachable"; // TODO(38725) int byteLength = (end - start) * elementSize; if (byteLength % bytesPerElement != 0) { throw ArgumentError("The number of bytes to view must be a multiple of " + @@ -1416,7 +1434,7 @@ abstract class Uint16List implements List, _TypedIntList { * 0 ≤ `start` ≤ `end` ≤ `this.length` * If `end` is equal to `start`, then the returned list is empty. */ - Uint16List sublist(int start, [int end]); + Uint16List sublist(int start, [int? end]); static const int bytesPerElement = 2; } @@ -1480,16 +1498,16 @@ abstract class Int32List implements List, _TypedIntList { * Int32List.view(other.buffer, other.offsetInBytes, count) * ``` * Alternatively, use [Int32List.sublistView] - * which includes this computation. + * which includes this computation: * ```dart - * Int32List.sublistView(other, 0, count) + * Int32List.sublistView(other, 0, count); * ``` * (The third argument is an end index rather than a length, so if * you start from a position greater than zero, you need not * reduce the count correspondingly). */ factory Int32List.view(ByteBuffer buffer, - [int offsetInBytes = 0, int length]) { + [int offsetInBytes = 0, int? length]) { return buffer.asInt32List(offsetInBytes, length); } @@ -1515,10 +1533,11 @@ abstract class Int32List implements List, _TypedIntList { * multiples of four. */ @Since("2.8") - factory Int32List.sublistView(TypedData data, [int start = 0, int end]) { + factory Int32List.sublistView(TypedData data, [int start = 0, int? end]) { int elementSize = data.elementSizeInBytes; end = RangeError.checkValidRange( start, end, data.lengthInBytes ~/ elementSize); + if (end == null) throw "unreachable"; // TODO(38725) int byteLength = (end - start) * elementSize; if (byteLength % bytesPerElement != 0) { throw ArgumentError("The number of bytes to view must be a multiple of " + @@ -1551,7 +1570,7 @@ abstract class Int32List implements List, _TypedIntList { * 0 ≤ `start` ≤ `end` ≤ `this.length` * If `end` is equal to `start`, then the returned list is empty. */ - Int32List sublist(int start, [int end]); + Int32List sublist(int start, [int? end]); static const int bytesPerElement = 4; } @@ -1616,16 +1635,16 @@ abstract class Uint32List implements List, _TypedIntList { * Uint32List.view(other.buffer, other.offsetInBytes, count) * ``` * Alternatively, use [Uint32List.sublistView] - * which includes this computation. + * which includes this computation: * ```dart - * Uint32List.sublistView(other, 0, count) + * Uint32List.sublistView(other, 0, count); * ``` * (The third argument is an end index rather than a length, so if * you start from a position greater than zero, you need not * reduce the count correspondingly). */ factory Uint32List.view(ByteBuffer buffer, - [int offsetInBytes = 0, int length]) { + [int offsetInBytes = 0, int? length]) { return buffer.asUint32List(offsetInBytes, length); } @@ -1651,10 +1670,11 @@ abstract class Uint32List implements List, _TypedIntList { * multiples of four. */ @Since("2.8") - factory Uint32List.sublistView(TypedData data, [int start = 0, int end]) { + factory Uint32List.sublistView(TypedData data, [int start = 0, int? end]) { int elementSize = data.elementSizeInBytes; end = RangeError.checkValidRange( start, end, data.lengthInBytes ~/ elementSize); + if (end == null) throw "unreachable"; // TODO(38725) int byteLength = (end - start) * elementSize; if (byteLength % bytesPerElement != 0) { throw ArgumentError("The number of bytes to view must be a multiple of " + @@ -1687,7 +1707,7 @@ abstract class Uint32List implements List, _TypedIntList { * 0 ≤ `start` ≤ `end` ≤ `this.length` * If `end` is equal to `start`, then the returned list is empty. */ - Uint32List sublist(int start, [int end]); + Uint32List sublist(int start, [int? end]); static const int bytesPerElement = 4; } @@ -1751,16 +1771,16 @@ abstract class Int64List implements List, _TypedIntList { * Int64List.view(other.buffer, other.offsetInBytes, count) * ``` * Alternatively, use [Int64List.sublistView] - * which includes this computation. + * which includes this computation: * ```dart - * Int64List.sublistView(other, 0, count) + * Int64List.sublistView(other, 0, count); * ``` * (The third argument is an end index rather than a length, so if * you start from a position greater than zero, you need not * reduce the count correspondingly). */ factory Int64List.view(ByteBuffer buffer, - [int offsetInBytes = 0, int length]) { + [int offsetInBytes = 0, int? length]) { return buffer.asInt64List(offsetInBytes, length); } @@ -1786,10 +1806,11 @@ abstract class Int64List implements List, _TypedIntList { * multiples of eight. */ @Since("2.8") - factory Int64List.sublistView(TypedData data, [int start = 0, int end]) { + factory Int64List.sublistView(TypedData data, [int start = 0, int? end]) { int elementSize = data.elementSizeInBytes; end = RangeError.checkValidRange( start, end, data.lengthInBytes ~/ elementSize); + if (end == null) throw "unreachable"; // TODO(38725) int byteLength = (end - start) * elementSize; if (byteLength % bytesPerElement != 0) { throw ArgumentError("The number of bytes to view must be a multiple of " + @@ -1822,7 +1843,7 @@ abstract class Int64List implements List, _TypedIntList { * 0 ≤ `start` ≤ `end` ≤ `this.length` * If `end` is equal to `start`, then the returned list is empty. */ - Int64List sublist(int start, [int end]); + Int64List sublist(int start, [int? end]); static const int bytesPerElement = 8; } @@ -1887,16 +1908,16 @@ abstract class Uint64List implements List, _TypedIntList { * Uint64List.view(other.buffer, other.offsetInBytes, count) * ``` * Alternatively, use [Uint64List.sublistView] - * which includes this computation. + * which includes this computation: * ```dart - * Uint64List.sublistView(other, 0, count) + * Uint64List.sublistView(other, 0, count); * ``` * (The third argument is an end index rather than a length, so if * you start from a position greater than zero, you need not * reduce the count correspondingly). */ factory Uint64List.view(ByteBuffer buffer, - [int offsetInBytes = 0, int length]) { + [int offsetInBytes = 0, int? length]) { return buffer.asUint64List(offsetInBytes, length); } @@ -1922,10 +1943,11 @@ abstract class Uint64List implements List, _TypedIntList { * multiples of eight. */ @Since("2.8") - factory Uint64List.sublistView(TypedData data, [int start = 0, int end]) { + factory Uint64List.sublistView(TypedData data, [int start = 0, int? end]) { int elementSize = data.elementSizeInBytes; end = RangeError.checkValidRange( start, end, data.lengthInBytes ~/ elementSize); + if (end == null) throw "unreachable"; // TODO(38725) int byteLength = (end - start) * elementSize; if (byteLength % bytesPerElement != 0) { throw ArgumentError("The number of bytes to view must be a multiple of " + @@ -1958,7 +1980,7 @@ abstract class Uint64List implements List, _TypedIntList { * 0 ≤ `start` ≤ `end` ≤ `this.length` * If `end` is equal to `start`, then the returned list is empty. */ - Uint64List sublist(int start, [int end]); + Uint64List sublist(int start, [int? end]); static const int bytesPerElement = 8; } @@ -2023,16 +2045,16 @@ abstract class Float32List implements List, _TypedFloatList { * Float32List.view(other.buffer, other.offsetInBytes, count) * ``` * Alternatively, use [Float32List.sublistView] - * which includes this computation. + * which includes this computation: * ```dart - * Float32List.sublistView(other, 0, count) + * Float32List.sublistView(other, 0, count); * ``` * (The third argument is an end index rather than a length, so if * you start from a position greater than zero, you need not * reduce the count correspondingly). */ factory Float32List.view(ByteBuffer buffer, - [int offsetInBytes = 0, int length]) { + [int offsetInBytes = 0, int? length]) { return buffer.asFloat32List(offsetInBytes, length); } @@ -2058,10 +2080,11 @@ abstract class Float32List implements List, _TypedFloatList { * multiples of four. */ @Since("2.8") - factory Float32List.sublistView(TypedData data, [int start = 0, int end]) { + factory Float32List.sublistView(TypedData data, [int start = 0, int? end]) { int elementSize = data.elementSizeInBytes; end = RangeError.checkValidRange( start, end, data.lengthInBytes ~/ elementSize); + if (end == null) throw "unreachable"; // TODO(38725) int byteLength = (end - start) * elementSize; if (byteLength % bytesPerElement != 0) { throw ArgumentError("The number of bytes to view must be a multiple of " + @@ -2094,7 +2117,7 @@ abstract class Float32List implements List, _TypedFloatList { * 0 ≤ `start` ≤ `end` ≤ `this.length` * If `end` is equal to `start`, then the returned list is empty. */ - Float32List sublist(int start, [int end]); + Float32List sublist(int start, [int? end]); static const int bytesPerElement = 4; } @@ -2152,16 +2175,16 @@ abstract class Float64List implements List, _TypedFloatList { * Float64List.view(other.buffer, other.offsetInBytes, count) * ``` * Alternatively, use [Float64List.sublistView] - * which includes this computation. + * which includes this computation: * ```dart - * Float64List.sublistView(other, 0, count) + * Float64List.sublistView(other, 0, count); * ``` * (The third argument is an end index rather than a length, so if * you start from a position greater than zero, you need not * reduce the count correspondingly). */ factory Float64List.view(ByteBuffer buffer, - [int offsetInBytes = 0, int length]) { + [int offsetInBytes = 0, int? length]) { return buffer.asFloat64List(offsetInBytes, length); } @@ -2187,10 +2210,11 @@ abstract class Float64List implements List, _TypedFloatList { * multiples of eight. */ @Since("2.8") - factory Float64List.sublistView(TypedData data, [int start = 0, int end]) { + factory Float64List.sublistView(TypedData data, [int start = 0, int? end]) { int elementSize = data.elementSizeInBytes; end = RangeError.checkValidRange( start, end, data.lengthInBytes ~/ elementSize); + if (end == null) throw "unreachable"; // TODO(38725) int byteLength = (end - start) * elementSize; if (byteLength % bytesPerElement != 0) { throw ArgumentError("The number of bytes to view must be a multiple of " + @@ -2223,7 +2247,7 @@ abstract class Float64List implements List, _TypedFloatList { * 0 ≤ `start` ≤ `end` ≤ `this.length` * If `end` is equal to `start`, then the returned list is empty. */ - Float64List sublist(int start, [int end]); + Float64List sublist(int start, [int? end]); static const int bytesPerElement = 8; } @@ -2280,16 +2304,16 @@ abstract class Float32x4List implements List, TypedData { * Float32x4List.view(other.buffer, other.offsetInBytes, count) * ``` * Alternatively, use [Float32x4List.sublistView] - * which includes this computation. + * which includes this computation: * ```dart - * Float32x4List.sublistView(other, 0, count) + * Float32x4List.sublistView(other, 0, count); * ``` * (The third argument is an end index rather than a length, so if * you start from a position greater than zero, you need not * reduce the count correspondingly). */ factory Float32x4List.view(ByteBuffer buffer, - [int offsetInBytes = 0, int length]) { + [int offsetInBytes = 0, int? length]) { return buffer.asFloat32x4List(offsetInBytes, length); } @@ -2315,10 +2339,11 @@ abstract class Float32x4List implements List, TypedData { * multiples of sixteen. */ @Since("2.8") - factory Float32x4List.sublistView(TypedData data, [int start = 0, int end]) { + factory Float32x4List.sublistView(TypedData data, [int start = 0, int? end]) { int elementSize = data.elementSizeInBytes; end = RangeError.checkValidRange( start, end, data.lengthInBytes ~/ elementSize); + if (end == null) throw "unreachable"; // TODO(38725) int byteLength = (end - start) * elementSize; if (byteLength % bytesPerElement != 0) { throw ArgumentError("The number of bytes to view must be a multiple of " + @@ -2359,7 +2384,7 @@ abstract class Float32x4List implements List, TypedData { * 0 ≤ `start` ≤ `end` ≤ `this.length` * If `end` is equal to `start`, then the returned list is empty. */ - Float32x4List sublist(int start, [int end]); + Float32x4List sublist(int start, [int? end]); static const int bytesPerElement = 16; } @@ -2416,16 +2441,16 @@ abstract class Int32x4List implements List, TypedData { * Int32x4List.view(other.buffer, other.offsetInBytes, count) * ``` * Alternatively, use [Int32x4List.sublistView] - * which includes this computation. + * which includes this computation: * ```dart - * Int32x4List.sublistView(other, 0, count) + * Int32x4List.sublistView(other, 0, count); * ``` * (The third argument is an end index rather than a length, so if * you start from a position greater than zero, you need not * reduce the count correspondingly). */ factory Int32x4List.view(ByteBuffer buffer, - [int offsetInBytes = 0, int length]) { + [int offsetInBytes = 0, int? length]) { return buffer.asInt32x4List(offsetInBytes, length); } @@ -2451,10 +2476,11 @@ abstract class Int32x4List implements List, TypedData { * multiples of sixteen. */ @Since("2.8") - factory Int32x4List.sublistView(TypedData data, [int start = 0, int end]) { + factory Int32x4List.sublistView(TypedData data, [int start = 0, int? end]) { int elementSize = data.elementSizeInBytes; end = RangeError.checkValidRange( start, end, data.lengthInBytes ~/ elementSize); + if (end == null) throw "unreachable"; // TODO(38725) int byteLength = (end - start) * elementSize; if (byteLength % bytesPerElement != 0) { throw ArgumentError("The number of bytes to view must be a multiple of " + @@ -2495,7 +2521,7 @@ abstract class Int32x4List implements List, TypedData { * 0 ≤ `start` ≤ `end` ≤ `this.length` * If `end` is equal to `start`, then the returned list is empty. */ - Int32x4List sublist(int start, [int end]); + Int32x4List sublist(int start, [int? end]); static const int bytesPerElement = 16; } @@ -2560,16 +2586,16 @@ abstract class Float64x2List implements List, TypedData { * Float64x2List.view(other.buffer, other.offsetInBytes, count) * ``` * Alternatively, use [Float64x2List.sublistView] - * which includes this computation. + * which includes this computation: * ```dart - * Float64x2List.sublistView(other, 0, count) + * Float64x2List.sublistView(other, 0, count); * ``` * (The third argument is an end index rather than a length, so if * you start from a position greater than zero, you need not * reduce the count correspondingly). */ factory Float64x2List.view(ByteBuffer buffer, - [int offsetInBytes = 0, int length]) { + [int offsetInBytes = 0, int? length]) { return buffer.asFloat64x2List(offsetInBytes, length); } @@ -2595,10 +2621,11 @@ abstract class Float64x2List implements List, TypedData { * multiples of sixteen. */ @Since("2.8") - factory Float64x2List.sublistView(TypedData data, [int start = 0, int end]) { + factory Float64x2List.sublistView(TypedData data, [int start = 0, int? end]) { int elementSize = data.elementSizeInBytes; end = RangeError.checkValidRange( start, end, data.lengthInBytes ~/ elementSize); + if (end == null) throw "unreachable"; // TODO(38725) int byteLength = (end - start) * elementSize; if (byteLength % bytesPerElement != 0) { throw ArgumentError("The number of bytes to view must be a multiple of " + @@ -2631,7 +2658,7 @@ abstract class Float64x2List implements List, TypedData { * 0 ≤ `start` ≤ `end` ≤ `this.length` * If `end` is equal to `start`, then the returned list is empty. */ - Float64x2List sublist(int start, [int end]); + Float64x2List sublist(int start, [int? end]); static const int bytesPerElement = 16; } diff --git a/sdk/lib/typed_data/unmodifiable_typed_data.dart b/sdk/lib/typed_data/unmodifiable_typed_data.dart index 2b0fe5e914d..30bdf51d494 100644 --- a/sdk/lib/typed_data/unmodifiable_typed_data.dart +++ b/sdk/lib/typed_data/unmodifiable_typed_data.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart.typed_data; /** @@ -16,55 +14,55 @@ class UnmodifiableByteBufferView implements ByteBuffer { int get lengthInBytes => _data.lengthInBytes; - Uint8List asUint8List([int offsetInBytes = 0, int length]) => + Uint8List asUint8List([int offsetInBytes = 0, int? length]) => new UnmodifiableUint8ListView(_data.asUint8List(offsetInBytes, length)); - Int8List asInt8List([int offsetInBytes = 0, int length]) => + Int8List asInt8List([int offsetInBytes = 0, int? length]) => new UnmodifiableInt8ListView(_data.asInt8List(offsetInBytes, length)); - Uint8ClampedList asUint8ClampedList([int offsetInBytes = 0, int length]) => + Uint8ClampedList asUint8ClampedList([int offsetInBytes = 0, int? length]) => new UnmodifiableUint8ClampedListView( _data.asUint8ClampedList(offsetInBytes, length)); - Uint16List asUint16List([int offsetInBytes = 0, int length]) => + Uint16List asUint16List([int offsetInBytes = 0, int? length]) => new UnmodifiableUint16ListView(_data.asUint16List(offsetInBytes, length)); - Int16List asInt16List([int offsetInBytes = 0, int length]) => + Int16List asInt16List([int offsetInBytes = 0, int? length]) => new UnmodifiableInt16ListView(_data.asInt16List(offsetInBytes, length)); - Uint32List asUint32List([int offsetInBytes = 0, int length]) => + Uint32List asUint32List([int offsetInBytes = 0, int? length]) => new UnmodifiableUint32ListView(_data.asUint32List(offsetInBytes, length)); - Int32List asInt32List([int offsetInBytes = 0, int length]) => + Int32List asInt32List([int offsetInBytes = 0, int? length]) => new UnmodifiableInt32ListView(_data.asInt32List(offsetInBytes, length)); - Uint64List asUint64List([int offsetInBytes = 0, int length]) => + Uint64List asUint64List([int offsetInBytes = 0, int? length]) => new UnmodifiableUint64ListView(_data.asUint64List(offsetInBytes, length)); - Int64List asInt64List([int offsetInBytes = 0, int length]) => + Int64List asInt64List([int offsetInBytes = 0, int? length]) => new UnmodifiableInt64ListView(_data.asInt64List(offsetInBytes, length)); - Int32x4List asInt32x4List([int offsetInBytes = 0, int length]) => + Int32x4List asInt32x4List([int offsetInBytes = 0, int? length]) => new UnmodifiableInt32x4ListView( _data.asInt32x4List(offsetInBytes, length)); - Float32List asFloat32List([int offsetInBytes = 0, int length]) => + Float32List asFloat32List([int offsetInBytes = 0, int? length]) => new UnmodifiableFloat32ListView( _data.asFloat32List(offsetInBytes, length)); - Float64List asFloat64List([int offsetInBytes = 0, int length]) => + Float64List asFloat64List([int offsetInBytes = 0, int? length]) => new UnmodifiableFloat64ListView( _data.asFloat64List(offsetInBytes, length)); - Float32x4List asFloat32x4List([int offsetInBytes = 0, int length]) => + Float32x4List asFloat32x4List([int offsetInBytes = 0, int? length]) => new UnmodifiableFloat32x4ListView( _data.asFloat32x4List(offsetInBytes, length)); - Float64x2List asFloat64x2List([int offsetInBytes = 0, int length]) => + Float64x2List asFloat64x2List([int offsetInBytes = 0, int? length]) => new UnmodifiableFloat64x2ListView( _data.asFloat64x2List(offsetInBytes, length)); - ByteData asByteData([int offsetInBytes = 0, int length]) => + ByteData asByteData([int offsetInBytes = 0, int? length]) => new UnmodifiableByteDataView(_data.asByteData(offsetInBytes, length)); } @@ -165,9 +163,10 @@ abstract class _UnmodifiableListMixin, L _createList(int length); - L sublist(int start, [int end]) { - end = RangeError.checkValidRange(start, end, length); - int sublistLength = end - start; + L sublist(int start, [int? end]) { + // NNBD: Spurious error at `end`, `checkValidRange` is legacy. + int endIndex = RangeError.checkValidRange(start, end!, length); + int sublistLength = endIndex - start; L result = _createList(sublistLength); result.setRange(0, sublistLength, _list, start); return result; diff --git a/sdk/lib/vmservice/asset.dart b/sdk/lib/vmservice/asset.dart index 512a0c91576..a29984e0355 100644 --- a/sdk/lib/vmservice/asset.dart +++ b/sdk/lib/vmservice/asset.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart._vmservice; class Asset { @@ -13,8 +11,8 @@ class Asset { Asset(this.name, this.data); String get mimeType { - var extensionStart = name.lastIndexOf('.'); - var extension = name.substring(extensionStart + 1); + final extensionStart = name.lastIndexOf('.'); + final extension = name.substring(extensionStart + 1); switch (extension) { case 'html': return 'text/html; charset=UTF-8'; @@ -39,15 +37,15 @@ class Asset { } } - static Map request() { - Uint8List tarBytes = _requestAssets(); + static Map? request() { + Uint8List? tarBytes = _requestAssets(); if (tarBytes == null) { return null; } List assetList = _decodeAssets(tarBytes); Map assets = new HashMap(); for (int i = 0; i < assetList.length; i += 2) { - var a = new Asset(assetList[i], assetList[i + 1]); + final a = Asset(assetList[i], assetList[i + 1]); assets[a.name] = a; } return assets; @@ -56,9 +54,9 @@ class Asset { String toString() => '$name ($mimeType)'; } -List _decodeAssets(Uint8List data) native "VMService_DecodeAssets"; +List _decodeAssets(Uint8List data) native 'VMService_DecodeAssets'; -Map _assets; +Map? _assets; Map get assets { if (_assets == null) { try { @@ -67,5 +65,5 @@ Map get assets { print('Could not load Observatory assets: $e'); } } - return _assets; + return _assets!; } diff --git a/sdk/lib/vmservice/client.dart b/sdk/lib/vmservice/client.dart index 915a3d09d6e..65a72ba84a7 100644 --- a/sdk/lib/vmservice/client.dart +++ b/sdk/lib/vmservice/client.dart @@ -2,42 +2,39 @@ // 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.6 - part of dart._vmservice; -typedef void ClientServiceHandle(Message response); +typedef void ClientServiceHandle(Message? response); // A service client. abstract class Client { + final VMService service; + final bool sendEvents; + static int _idCounter = 0; final int _id = ++_idCounter; String get defaultClientName => 'client$_id'; String get name => _name; - set name(n) => _name = n ?? defaultClientName; - String _name; - - final VMService service; - final bool sendEvents; + set name(String? n) => _name = (n ?? defaultClientName); + late String _name; /// A set streamIds which describes the streams the client is connected to - final Set streams = new Set(); + final streams = {}; /// Services registered and their aliases /// key: service /// value: alias - final Map services = new Map(); + final services = {}; /// Callbacks registered for service invocations set to the client /// key: RPC id used for the request /// value: callback that should be invoked - final Map serviceHandles = - new Map(); + final serviceHandles = {}; - Client(this.service, {bool sendEvents: true}) : this.sendEvents = sendEvents { - name = defaultClientName; + Client(this.service, {this.sendEvents = true}) { + _name = defaultClientName; service._addClient(this); } @@ -45,33 +42,28 @@ abstract class Client { disconnect(); /// When implementing, call [close] when the network connection closes. - void close() { - service._removeClient(this); - } + void close() => service._removeClient(this); /// Call to process a request. Response will be posted with 'seq'. - void onRequest(Message message) { - // In JSON-RPC 2.0 messages with and id are Request and must be answered - // http://www.jsonrpc.org/specification#notification - service.routeRequest(service, message).then(post); - } + void onRequest(Message message) => + // In JSON-RPC 2.0 messages with and id are Request and must be answered + // http://www.jsonrpc.org/specification#notification + service.routeRequest(service, message).then(post); - void onResponse(Message message) { - service.routeResponse(message); - } + void onResponse(Message message) => service.routeResponse(message); /// Call to process a notification. Response will not be posted. - void onNotification(Message message) { - // In JSON-RPC 2.0 messages without an id are Notification - // and should not be answered - // http://www.jsonrpc.org/specification#notification - service.routeRequest(service, message); - } + void onNotification(Message message) => + // In JSON-RPC 2.0 messages without an id are Notification + // and should not be answered + // http://www.jsonrpc.org/specification#notification + service.routeRequest(service, message); - // Sends a result to the client. Implemented in subclasses. - void post(Response result); + // Sends a result to the client. Implemented in subclasses. + // + // Null can be passed as response to a JSON-RPC notification to close the + // connection. + void post(Response? result); - dynamic toJson() { - return {}; - } + Map toJson() => {}; } diff --git a/sdk/lib/vmservice/constants.dart b/sdk/lib/vmservice/constants.dart index fa4b719f263..914576bc4d8 100644 --- a/sdk/lib/vmservice/constants.dart +++ b/sdk/lib/vmservice/constants.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart._vmservice; // These must be kept in sync with runtime/vm/service.cc. diff --git a/sdk/lib/vmservice/devfs.dart b/sdk/lib/vmservice/devfs.dart index 283006c4e5f..3463d6c33ca 100644 --- a/sdk/lib/vmservice/devfs.dart +++ b/sdk/lib/vmservice/devfs.dart @@ -2,24 +2,19 @@ // 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.6 - part of dart._vmservice; -String _encodeDevFSDisabledError(Message message) { - return encodeRpcError(message, kFeatureDisabled, - details: "DevFS is not supported by this Dart implementation"); -} +String _encodeDevFSDisabledError(Message message) => + encodeRpcError(message, kFeatureDisabled, + details: 'DevFS is not supported by this Dart implementation'); -String _encodeFileSystemAlreadyExistsError(Message message, String fsName) { - return encodeRpcError(message, kFileSystemAlreadyExists, - details: "${message.method}: file system '${fsName}' already exists"); -} +String _encodeFileSystemAlreadyExistsError(Message message, String fsName) => + encodeRpcError(message, kFileSystemAlreadyExists, + details: "${message.method}: file system '${fsName}' already exists"); -String _encodeFileSystemDoesNotExistError(Message message, String fsName) { - return encodeRpcError(message, kFileSystemDoesNotExist, - details: "${message.method}: file system '${fsName}' does not exist"); -} +String _encodeFileSystemDoesNotExistError(Message message, String fsName) => + encodeRpcError(message, kFileSystemDoesNotExist, + details: "${message.method}: file system '${fsName}' does not exist"); class _FileSystem { _FileSystem(this.name, this.uri); @@ -27,7 +22,7 @@ class _FileSystem { final String name; final Uri uri; - Uri resolvePath(String path) { + Uri? resolvePath(String path) { if (path.startsWith('/')) { path = path.substring(1); } @@ -36,23 +31,25 @@ class _FileSystem { } Uri pathUri; try { - pathUri = new Uri.file(path); - } on FormatException catch (e) { + pathUri = Uri.file(path); + // ignore: unused_catch_clause + } on FormatException catch (_) { return null; } return resolve(pathUri); } - Uri resolve(Uri pathUri) { + Uri? resolve(Uri pathUri) { try { // Make sure that this pathUri can be converted to a file path. pathUri.toFilePath(); - } on UnsupportedError catch (e) { + // ignore: unused_catch_clause + } on UnsupportedError catch (_) { return null; } - Uri resolvedUri = uri.resolveUri(pathUri); + final resolvedUri = uri.resolveUri(pathUri); if (!resolvedUri.toString().startsWith(uri.toString())) { // Resolved uri must be within the filesystem's base uri. return null; @@ -60,21 +57,19 @@ class _FileSystem { return resolvedUri; } - Map toMap() { - return { - 'type': 'FileSystem', - 'name': name, - 'uri': uri.toString(), - }; - } + Map toMap() => { + 'type': 'FileSystem', + 'name': name, + 'uri': uri.toString(), + }; } class DevFS { DevFS(); - Map _fsMap = {}; + final _fsMap = {}; - final Set _rpcNames = new Set.from([ + final _rpcNames = { '_listDevFS', '_createDevFS', '_deleteDevFS', @@ -82,27 +77,25 @@ class DevFS { '_writeDevFSFile', '_writeDevFSFiles', '_listDevFSFiles', - ]); + }; void cleanup() { - var deleteDir = VMServiceEmbedderHooks.deleteDir; + final deleteDir = VMServiceEmbedderHooks.deleteDir; if (deleteDir == null) { return; } - var deletions = []; - for (var fs in _fsMap.values) { - deletions.add(deleteDir(fs.uri)); - } + final deletions = [ + for (final fs in _fsMap.values) deleteDir(fs.uri), + ]; Future.wait(deletions); _fsMap.clear(); } - bool shouldHandleMessage(Message message) { - return _rpcNames.contains(message.method); - } + bool shouldHandleMessage(Message message) => + _rpcNames.contains(message.method); Future handleMessage(Message message) async { - switch (message.method) { + switch (message.method!) { case '_listDevFS': return _listDevFS(message); case '_createDevFS': @@ -124,10 +117,10 @@ class DevFS { } Future handlePutStream( - Object fsName, Object path, Uri fsUri, Stream> bytes) async { + Object? fsName, Object? path, Uri? fsUri, Stream> bytes) async { // A dummy Message for error message construction. - Message message = new Message.forMethod('_writeDevFSFile'); - var writeStreamFile = VMServiceEmbedderHooks.writeStreamFile; + final message = Message.forMethod('_writeDevFSFile'); + final writeStreamFile = VMServiceEmbedderHooks.writeStreamFile; if (writeStreamFile == null) { return _encodeDevFSDisabledError(message); } @@ -141,7 +134,7 @@ class DevFS { if (fs == null) { return _encodeFileSystemDoesNotExistError(message, fsName); } - Uri uri = fsUri; + Uri? uri = fsUri; if (uri == null) { if (path == null) { return encodeMissingParamError(message, 'path'); @@ -164,47 +157,47 @@ class DevFS { } Future _listDevFS(Message message) async { - var result = {}; + final result = {}; result['type'] = 'FileSystemList'; result['fsNames'] = _fsMap.keys.toList(); return encodeResult(message, result); } Future _createDevFS(Message message) async { - var createTempDir = VMServiceEmbedderHooks.createTempDir; + final createTempDir = VMServiceEmbedderHooks.createTempDir; if (createTempDir == null) { return _encodeDevFSDisabledError(message); } - var fsName = message.params['fsName']; + final fsName = message.params['fsName']; if (fsName == null) { return encodeMissingParamError(message, 'fsName'); } if (fsName is! String) { return encodeInvalidParamError(message, 'fsName'); } - var fs = _fsMap[fsName]; + _FileSystem? fs = _fsMap[fsName]; if (fs != null) { return _encodeFileSystemAlreadyExistsError(message, fsName); } - var tempDir = await createTempDir(fsName); - fs = new _FileSystem(fsName, tempDir); + final tempDir = await createTempDir(fsName); + fs = _FileSystem(fsName, tempDir); _fsMap[fsName] = fs; return encodeResult(message, fs.toMap()); } Future _deleteDevFS(Message message) async { - var deleteDir = VMServiceEmbedderHooks.deleteDir; + final deleteDir = VMServiceEmbedderHooks.deleteDir; if (deleteDir == null) { return _encodeDevFSDisabledError(message); } - var fsName = message.params['fsName']; + final fsName = message.params['fsName']; if (fsName == null) { return encodeMissingParamError(message, 'fsName'); } if (fsName is! String) { return encodeInvalidParamError(message, 'fsName'); } - var fs = _fsMap.remove(fsName); + final fs = _fsMap.remove(fsName); if (fs == null) { return _encodeFileSystemDoesNotExistError(message, fsName); } @@ -213,29 +206,29 @@ class DevFS { } Future _readDevFSFile(Message message) async { - var readFile = VMServiceEmbedderHooks.readFile; + final readFile = VMServiceEmbedderHooks.readFile; if (readFile == null) { return _encodeDevFSDisabledError(message); } - var fsName = message.params['fsName']; + final fsName = message.params['fsName']; if (fsName == null) { return encodeMissingParamError(message, 'fsName'); } if (fsName is! String) { return encodeInvalidParamError(message, 'fsName'); } - var fs = _fsMap[fsName]; + final fs = _fsMap[fsName]; if (fs == null) { return _encodeFileSystemDoesNotExistError(message, fsName); } - Uri uri; + Uri? uri; if (message.params['uri'] != null) { try { - var uriParam = message.params['uri']; + final uriParam = message.params['uri']; if (uriParam is! String) { return encodeInvalidParamError(message, 'uri'); } - Uri parsedUri = Uri.parse(uriParam); + final parsedUri = Uri.parse(uriParam); uri = fs.resolve(parsedUri); if (uri == null) { return encodeInvalidParamError(message, 'uri'); @@ -244,7 +237,7 @@ class DevFS { return encodeInvalidParamError(message, 'uri'); } } else { - var path = message.params['path']; + final path = message.params['path']; if (path == null) { return encodeMissingParamError(message, 'path'); } @@ -257,39 +250,39 @@ class DevFS { } } try { - List bytes = await readFile(uri); - var result = {'type': 'FSFile', 'fileContents': base64.encode(bytes)}; + final bytes = await readFile(uri); + final result = {'type': 'FSFile', 'fileContents': base64.encode(bytes)}; return encodeResult(message, result); } catch (e) { return encodeRpcError(message, kFileDoesNotExist, - details: "_readDevFSFile: $e"); + details: '_readDevFSFile: $e'); } } Future _writeDevFSFile(Message message) async { - var writeFile = VMServiceEmbedderHooks.writeFile; + final writeFile = VMServiceEmbedderHooks.writeFile; if (writeFile == null) { return _encodeDevFSDisabledError(message); } - var fsName = message.params['fsName']; + final fsName = message.params['fsName']; if (fsName == null) { return encodeMissingParamError(message, 'fsName'); } if (fsName is! String) { return encodeInvalidParamError(message, 'fsName'); } - var fs = _fsMap[fsName]; + final fs = _fsMap[fsName]; if (fs == null) { return _encodeFileSystemDoesNotExistError(message, fsName); } - Uri uri; + Uri? uri; if (message.params['uri'] != null) { try { - var uriParam = message.params['uri']; + final uriParam = message.params['uri']; if (uriParam is! String) { return encodeInvalidParamError(message, 'uri'); } - Uri parsedUri = Uri.parse(uriParam); + final parsedUri = Uri.parse(uriParam); uri = fs.resolve(parsedUri); if (uri == null) { return encodeInvalidParamError(message, 'uri'); @@ -298,7 +291,7 @@ class DevFS { return encodeInvalidParamError(message, 'uri'); } } else { - var path = message.params['path']; + final path = message.params['path']; if (path == null) { return encodeMissingParamError(message, 'path'); } @@ -310,45 +303,45 @@ class DevFS { return encodeInvalidParamError(message, 'path'); } } - var fileContents = message.params['fileContents']; + final fileContents = message.params['fileContents']; if (fileContents == null) { return encodeMissingParamError(message, 'fileContents'); } if (fileContents is! String) { return encodeInvalidParamError(message, 'fileContents'); } - List decodedFileContents = base64.decode(fileContents); + final decodedFileContents = base64.decode(fileContents); await writeFile(uri, decodedFileContents); return encodeSuccess(message); } Future _writeDevFSFiles(Message message) async { - var writeFile = VMServiceEmbedderHooks.writeFile; + final writeFile = VMServiceEmbedderHooks.writeFile; if (writeFile == null) { return _encodeDevFSDisabledError(message); } - var fsName = message.params['fsName']; + final fsName = message.params['fsName']; if (fsName == null) { return encodeMissingParamError(message, 'fsName'); } if (fsName is! String) { return encodeInvalidParamError(message, 'fsName'); } - var fs = _fsMap[fsName]; + final fs = _fsMap[fsName]; if (fs == null) { return _encodeFileSystemDoesNotExistError(message, fsName); } - var files = message.params['files']; + final files = message.params['files']; if (files == null) { return encodeMissingParamError(message, 'files'); } if (files is! List) { return encodeInvalidParamError(message, 'files'); } - var uris = []; + final uris = []; for (int i = 0; i < files.length; i++) { - var fileInfo = files[i]; + final fileInfo = files[i]; if (fileInfo is! List || fileInfo.length != 2 || fileInfo[0] is! String || @@ -357,7 +350,7 @@ class DevFS { details: "${message.method}: invalid 'files' parameter " "at index ${i}: ${fileInfo}"); } - var uri = fs.resolvePath(fileInfo[0]); + final uri = fs.resolvePath(fileInfo[0]); if (uri == null) { return encodeRpcError(message, kInvalidParams, details: "${message.method}: invalid 'files' parameter " @@ -365,9 +358,9 @@ class DevFS { } uris.add(uri); } - var pendingWrites = []; + final pendingWrites = []; for (int i = 0; i < uris.length; i++) { - List decodedFileContents = base64.decode(files[i][1]); + final decodedFileContents = base64.decode(files[i][1]); pendingWrites.add(writeFile(uris[i], decodedFileContents)); } await Future.wait(pendingWrites); @@ -375,27 +368,27 @@ class DevFS { } Future _listDevFSFiles(Message message) async { - var listFiles = VMServiceEmbedderHooks.listFiles; + final listFiles = VMServiceEmbedderHooks.listFiles; if (listFiles == null) { return _encodeDevFSDisabledError(message); } - var fsName = message.params['fsName']; + final fsName = message.params['fsName']; if (fsName == null) { return encodeMissingParamError(message, 'fsName'); } if (fsName is! String) { return encodeInvalidParamError(message, 'fsName'); } - var fs = _fsMap[fsName]; + final fs = _fsMap[fsName]; if (fs == null) { return _encodeFileSystemDoesNotExistError(message, fsName); } - var fileList = await listFiles(fs.uri); + final fileList = await listFiles(fs.uri); // Remove any url-encoding in the filenames. for (int i = 0; i < fileList.length; i++) { fileList[i]['name'] = Uri.decodeFull(fileList[i]['name']); } - var result = {'type': 'FSFileList', 'files': fileList}; + final result = {'type': 'FSFileList', 'files': fileList}; return encodeResult(message, result); } } diff --git a/sdk/lib/vmservice/message.dart b/sdk/lib/vmservice/message.dart index 6f2abcbdc09..ee29fe3ec63 100644 --- a/sdk/lib/vmservice/message.dart +++ b/sdk/lib/vmservice/message.dart @@ -2,19 +2,17 @@ // 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.6 - part of dart._vmservice; enum MessageType { Request, Notification, Response } class Message { - final Completer _completer = new Completer.sync(); + final _completer = Completer.sync(); bool get completed => _completer.isCompleted; /// Future of response. Future get response => _completer.future; - Client client; + Client? client; // Is a notification message (no serial) final MessageType type; @@ -22,35 +20,35 @@ class Message { // Client-side identifier for this message. final serial; - final String method; + final String? method; - final Map params = new Map(); - final Map result = new Map(); - final Map error = new Map(); + final params = {}; + final result = {}; + final error = {}; - factory Message.fromJsonRpc(Client client, Map map) { + factory Message.fromJsonRpc(Client? client, Map map) { if (map.containsKey('id')) { final id = map['id']; if (id != null && id is! num && id is! String) { - throw new Exception('"id" must be a number, string, or null.'); + throw Exception("'id' must be a number, string, or null."); } if (map.containsKey('method')) { - return new Message._fromJsonRpcRequest(client, map); + return Message._fromJsonRpcRequest(client, map); } if (map.containsKey('result')) { - return new Message._fromJsonRpcResult(client, map); + return Message._fromJsonRpcResult(client, map); } if (map.containsKey('error')) { - return new Message._fromJsonRpcError(client, map); + return Message._fromJsonRpcError(client, map); } } else if (map.containsKey('method')) { - return new Message._fromJsonRpcNotification(client, map); + return Message._fromJsonRpcNotification(client, map); } - throw new Exception('Invalid message format'); + throw Exception('Invalid message format'); } // http://www.jsonrpc.org/specification#request_object - Message._fromJsonRpcRequest(Client client, Map map) + Message._fromJsonRpcRequest(Client? client, Map map) : client = client, type = MessageType.Request, serial = map['id'], @@ -61,7 +59,7 @@ class Message { } // http://www.jsonrpc.org/specification#notification - Message._fromJsonRpcNotification(Client client, Map map) + Message._fromJsonRpcNotification(Client? client, Map map) : client = client, type = MessageType.Notification, method = map['method'], @@ -72,7 +70,7 @@ class Message { } // http://www.jsonrpc.org/specification#response_object - Message._fromJsonRpcResult(Client client, Map map) + Message._fromJsonRpcResult(Client? client, Map map) : client = client, type = MessageType.Response, serial = map['id'], @@ -81,7 +79,7 @@ class Message { } // http://www.jsonrpc.org/specification#response_object - Message._fromJsonRpcError(Client client, Map map) + Message._fromJsonRpcError(Client? client, Map map) : client = client, type = MessageType.Response, serial = map['id'], @@ -90,10 +88,7 @@ class Message { } static String _methodNameFromUri(Uri uri) { - if (uri == null) { - return ''; - } - if (uri.pathSegments.length == 0) { + if (uri == null || uri.pathSegments.length == 0) { return ''; } return uri.pathSegments[0]; @@ -120,16 +115,12 @@ class Message { params['isolateId'] = isolate.serviceId; } - Uri toUri() { - return new Uri(path: method, queryParameters: params); - } + Uri toUri() => Uri(path: method!, queryParameters: params); - dynamic toJson() { - throw 'unsupported'; - } + dynamic toJson() => throw 'unsupported'; - dynamic forwardToJson([Map overloads]) { - Map json = {'jsonrpc': '2.0', 'id': serial}; + Map forwardToJson([Map? overloads]) { + final json = {'jsonrpc': '2.0', 'id': serial}; switch (type) { case MessageType.Request: case MessageType.Notification: @@ -157,10 +148,7 @@ class Message { // This has a side effect that boolean literal values like true become 'true' // and thus indistinguishable from the string literal 'true'. List _makeAllString(List list) { - if (list == null) { - return null; - } - var new_list = new List(list.length); + var new_list = List.filled(list.length, ""); for (var i = 0; i < list.length; i++) { new_list[i] = list[i].toString(); } @@ -168,14 +156,14 @@ class Message { } Future sendToIsolate(SendPort sendPort) { - final receivePort = new RawReceivePort(); + final receivePort = RawReceivePort(); receivePort.handler = (value) { receivePort.close(); _setResponseFromPort(value); }; - var keys = _makeAllString(params.keys.toList(growable: false)); - var values = _makeAllString(params.values.toList(growable: false)); - var request = new List(6) + final keys = _makeAllString(params.keys.toList(growable: false)); + final values = _makeAllString(params.values.toList(growable: false)); + final request = List.filled(6, null) ..[0] = 0 // Make room for OOB message type. ..[1] = receivePort.sendPort ..[2] = serial @@ -184,7 +172,7 @@ class Message { ..[5] = values; if (!sendIsolateServiceMessage(sendPort, request)) { receivePort.close(); - _completer.complete(new Response.internalError( + _completer.complete(Response.internalError( 'could not send message [${serial}] to isolate')); } return _completer.future; @@ -212,19 +200,18 @@ class Message { } Future sendToVM() { - final receivePort = new RawReceivePort(); + final receivePort = RawReceivePort(); receivePort.handler = (value) { receivePort.close(); _setResponseFromPort(value); }; var keys = params.keys.toList(growable: false); var values = params.values.toList(growable: false); - if (!_methodNeedsObjectParameters(method)) { + if (!_methodNeedsObjectParameters(method!)) { keys = _makeAllString(keys); values = _makeAllString(values); } - - final request = new List(6) + final request = List.filled(6, null) ..[0] = 0 // Make room for OOB message type. ..[1] = receivePort.sendPort ..[2] = serial @@ -232,7 +219,7 @@ class Message { ..[4] = keys ..[5] = values; - if (_methodNeedsObjectParameters(method)) { + if (_methodNeedsObjectParameters(method!)) { // We use a different method invocation path here. sendObjectRootServiceMessage(request); } else { @@ -251,19 +238,17 @@ class Message { _completer.complete(Response.from(response)); } - void setResponse(String response) { - _completer.complete(new Response(ResponsePayloadKind.String, response)); - } + void setResponse(String response) => + _completer.complete(Response(ResponsePayloadKind.String, response)); - void setErrorResponse(int code, String details) { - setResponse(encodeRpcError(this, code, details: '$method: $details')); - } + void setErrorResponse(int code, String details) => + setResponse(encodeRpcError(this, code, details: '$method: $details')); } bool sendIsolateServiceMessage(SendPort sp, List m) - native "VMService_SendIsolateServiceMessage"; + native 'VMService_SendIsolateServiceMessage'; -void sendRootServiceMessage(List m) native "VMService_SendRootServiceMessage"; +void sendRootServiceMessage(List m) native 'VMService_SendRootServiceMessage'; void sendObjectRootServiceMessage(List m) - native "VMService_SendObjectRootServiceMessage"; + native 'VMService_SendObjectRootServiceMessage'; diff --git a/sdk/lib/vmservice/message_router.dart b/sdk/lib/vmservice/message_router.dart index 90ed1841120..2ca8d4f72f7 100644 --- a/sdk/lib/vmservice/message_router.dart +++ b/sdk/lib/vmservice/message_router.dart @@ -2,12 +2,10 @@ // 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.6 - part of dart._vmservice; abstract class MessageRouter { - Future routeRequest(VMService service, Message message); + Future routeRequest(VMService service, Message message); void routeResponse(Message message); } @@ -35,6 +33,8 @@ class Response { case ResponsePayloadKind.Binary: case ResponsePayloadKind.Utf8String: return payload is Uint8List; + default: + return false; } }()); } @@ -44,14 +44,12 @@ class Response { Response.json(Object value) : this(ResponsePayloadKind.String, json.encode(value)); - factory Response.internalError(String message) { - return new Response.json({ - 'type': 'ServiceError', - 'id': '', - 'kind': 'InternalError', - 'message': message, - }); - } + factory Response.internalError(String message) => Response.json({ + 'type': 'ServiceError', + 'id': '', + 'kind': 'InternalError', + 'message': message, + }); /// Construct response from the response [value] which can be either: /// String: a string @@ -59,13 +57,12 @@ class Response { /// Utf8String: a single element list containing Uint8List factory Response.from(Object value) { if (value is String) { - return new Response(ResponsePayloadKind.String, value); + return Response(ResponsePayloadKind.String, value); } else if (value is Uint8List) { - return new Response(ResponsePayloadKind.Binary, value); + return Response(ResponsePayloadKind.Binary, value); } else if (value is List) { assert(value.length == 1); - return new Response( - ResponsePayloadKind.Utf8String, value[0] as Uint8List); + return Response(ResponsePayloadKind.Utf8String, value[0] as Uint8List); } else if (value is Response) { return value; } else { diff --git a/sdk/lib/vmservice/named_lookup.dart b/sdk/lib/vmservice/named_lookup.dart index 0b5c0444e97..d611c3d79fe 100644 --- a/sdk/lib/vmservice/named_lookup.dart +++ b/sdk/lib/vmservice/named_lookup.dart @@ -2,18 +2,16 @@ // 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.6 - part of dart._vmservice; /// Set like containes which automatically generated String ids for its items -class NamedLookup extends Object with IterableMixin { +class NamedLookup extends Object with IterableMixin { final IdGenerator _generator; - final Map _elements = new Map(); - final Map _ids = new Map(); + final _elements = {}; + final _ids = {}; NamedLookup({String prologue = ''}) - : _generator = new IdGenerator(prologue: prologue); + : _generator = IdGenerator(prologue: prologue); void add(E e) { final id = _generator.newId(); @@ -22,13 +20,13 @@ class NamedLookup extends Object with IterableMixin { } void remove(E e) { - final id = _ids.remove(e); + final id = _ids.remove(e)!; _elements.remove(id); _generator.release(id); } - E operator [](String id) => _elements[id]; - String keyOf(E e) => _ids[e]; + E operator [](String id) => _elements[id]!; + String keyOf(E e) => _ids[e]!; Iterator get iterator => _ids.keys.iterator; } @@ -38,10 +36,10 @@ class IdGenerator { /// Fixed initial part of the id final String prologue; // Ids in use - final Set _used = new Set(); + final _used = {}; /// Ids that has been released (use these before generate new ones) - final Set _free = new Set(); + final _free = {}; /// Next id to generate if no one can be recycled (first use _free); int _next = 0; diff --git a/sdk/lib/vmservice/running_isolate.dart b/sdk/lib/vmservice/running_isolate.dart index 8f21a66ba86..029c6aa010a 100644 --- a/sdk/lib/vmservice/running_isolate.dart +++ b/sdk/lib/vmservice/running_isolate.dart @@ -2,8 +2,6 @@ // 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.6 - part of dart._vmservice; class RunningIsolate implements MessageRouter { @@ -52,7 +50,7 @@ class RunningIsolate implements MessageRouter { } } - bool _shouldResume(VMService service, Client client, int pauseType) { + bool _shouldResume(VMService service, Client? client, int pauseType) { if (client != null) { // Mark the approval by the client. _resumeApprovalsByName.add(client.name); @@ -107,7 +105,7 @@ class RunningIsolate implements MessageRouter { var pauseType; try { pauseType = await _isolatePauseType(service, message.params['isolateId']); - } catch (errorResponse) { + } on Response catch (errorResponse) { return errorResponse; } if (pauseType == kInvalidPauseEvent || diff --git a/sdk/lib/vmservice/running_isolates.dart b/sdk/lib/vmservice/running_isolates.dart index 191a8d10f02..20ab8a25012 100644 --- a/sdk/lib/vmservice/running_isolates.dart +++ b/sdk/lib/vmservice/running_isolates.dart @@ -2,13 +2,11 @@ // 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.6 - part of dart._vmservice; class RunningIsolates implements MessageRouter { - final Map isolates = new Map(); - int _rootPortId; + final isolates = {}; + int? _rootPortId; RunningIsolates(); @@ -16,7 +14,7 @@ class RunningIsolates implements MessageRouter { if (_rootPortId == null) { _rootPortId = portId; } - var ri = new RunningIsolate(portId, sp, name); + var ri = RunningIsolate(portId, sp, name); isolates[portId] = ri; } @@ -29,7 +27,7 @@ class RunningIsolates implements MessageRouter { @override Future routeRequest(VMService service, Message message) { - String isolateParam = message.params['isolateId']; + String isolateParam = message.params['isolateId']!; int isolateId; if (!isolateParam.startsWith('isolates/')) { message.setErrorResponse( @@ -38,7 +36,7 @@ class RunningIsolates implements MessageRouter { } isolateParam = isolateParam.substring('isolates/'.length); if (isolateParam == 'root') { - isolateId = _rootPortId; + isolateId = _rootPortId!; } else { try { isolateId = int.parse(isolateParam); @@ -48,11 +46,11 @@ class RunningIsolates implements MessageRouter { return message.response; } } - var isolate = isolates[isolateId]; + final isolate = isolates[isolateId]; if (isolate == null) { // There is some chance that this isolate may have lived before, // so return a sentinel rather than an error. - var result = { + final result = { 'type': 'Sentinel', 'kind': 'Collected', 'valueAsString': '', @@ -62,7 +60,7 @@ class RunningIsolates implements MessageRouter { } if (message.method == 'evaluateInFrame' || message.method == 'evaluate') { - return new _Evaluator(message, isolate, service).run(); + return _Evaluator(message, isolate, service).run(); } else { return isolate.routeRequest(service, message); } @@ -77,11 +75,19 @@ class _Evaluator { _Evaluator(this._message, this._isolate, this._service); Future run() async { - Response buildScopeResponse = await _buildScope(); - Map responseJson = buildScopeResponse.decodeJson(); + if (_service.ddsUri != null) { + return Response.from(encodeRpcError( + _message, + kInternalError, + details: 'Fell through to VM Service expression evaluation when a DDS ' + 'instance was connected. Please file an issue on GitHub.', + )); + } + final buildScopeResponse = await _buildScope(); + final responseJson = buildScopeResponse.decodeJson(); if (responseJson.containsKey('error')) { - return new Response.from(encodeCompilationError( + return Response.from(encodeCompilationError( _message, responseJson['error']['data']['details'])); } @@ -89,9 +95,9 @@ class _Evaluator { try { kernelBase64 = await _compileExpression(responseJson['result']); } catch (e) { - return new Response.from(encodeCompilationError(_message, e.toString())); + return Response.from(encodeCompilationError(_message, e.toString())); } - return _evaluateCompiledExpression(kernelBase64); + return await _evaluateCompiledExpression(kernelBase64); } Message _message; @@ -99,9 +105,9 @@ class _Evaluator { VMService _service; Future _buildScope() { - Map params = _setupParams(); + final params = _setupParams(); params['isolateId'] = _message.params['isolateId']; - Map buildScopeParams = { + final buildScopeParams = { 'method': '_buildExpressionEvaluationScope', 'id': _message.serial, 'params': params, @@ -109,8 +115,8 @@ class _Evaluator { if (_message.params['scope'] != null) { buildScopeParams['params']['scope'] = _message.params['scope']; } - var buildScope = - new Message._fromJsonRpcRequest(_message.client, buildScopeParams); + final buildScope = + Message._fromJsonRpcRequest(_message.client!, buildScopeParams); // Decode the JSON and and insert it into the map. The map key // is the request Uri. @@ -119,42 +125,40 @@ class _Evaluator { Future _compileExpression( Map buildScopeResponseResult) { - Client externalClient = + Client? externalClient = _service._findFirstClientThatHandlesService('compileExpression'); - Map compileParams = { - 'isolateId': _message.params['isolateId'], - 'expression': _message.params['expression'], - 'definitions': buildScopeResponseResult['param_names'], - 'typeDefinitions': buildScopeResponseResult['type_params_names'], - 'libraryUri': buildScopeResponseResult['libraryUri'], - 'isStatic': buildScopeResponseResult['isStatic'], + final compileParams = { + 'isolateId': _message.params['isolateId']!, + 'expression': _message.params['expression']!, + 'definitions': buildScopeResponseResult['param_names']!, + 'typeDefinitions': buildScopeResponseResult['type_params_names']!, + 'libraryUri': buildScopeResponseResult['libraryUri']!, + 'isStatic': buildScopeResponseResult['isStatic']!, }; - dynamic klass = buildScopeResponseResult['klass']; + final klass = buildScopeResponseResult['klass']; if (klass != null) { compileParams['klass'] = klass; } if (externalClient != null) { - var compileExpression = new Message.forMethod('compileExpression'); + final compileExpression = Message.forMethod('compileExpression'); compileExpression.client = externalClient; compileExpression.params.addAll(compileParams); final id = _service._serviceRequests.newId(); final oldId = _message.serial; - final completer = new Completer(); - externalClient.serviceHandles[id] = (Message m) { + final completer = Completer(); + externalClient.serviceHandles[id] = (Message? m) { if (m != null) { completer.complete(json.encode(m.forwardToJson({'id': oldId}))); } else { completer.complete(encodeRpcError(_message, kServiceDisappeared)); } }; - externalClient.post(new Response.json(compileExpression + externalClient.post(Response.json(compileExpression .forwardToJson({'id': id, 'method': 'compileExpression'}))); - return completer.future - .then((String s) => jsonDecode(s)) - .then((dynamic json) { - Map jsonMap = json; + return completer.future.then((s) => jsonDecode(s)).then((json) { + final Map jsonMap = json; if (jsonMap.containsKey('error')) { throw jsonMap['error']; } @@ -162,18 +166,18 @@ class _Evaluator { }); } else { // fallback to compile using kernel service - Map compileExpressionParams = { + final compileExpressionParams = { 'method': '_compileExpression', 'id': _message.serial, 'params': compileParams, }; - var compileExpression = new Message._fromJsonRpcRequest( - _message.client, compileExpressionParams); + final compileExpression = Message._fromJsonRpcRequest( + _message.client!, compileExpressionParams); return _isolate .routeRequest(_service, compileExpression) - .then((Response response) => response.decodeJson()) - .then((dynamic json) { + .then((response) => response.decodeJson()) + .then((json) { if (json['result'] != null) { return json['result']['kernelBytes']; } @@ -184,11 +188,11 @@ class _Evaluator { Future _evaluateCompiledExpression(String kernelBase64) { if (kernelBase64.isNotEmpty) { - Map params = _setupParams(); + final params = _setupParams(); params['isolateId'] = _message.params['isolateId']; params['kernelBytes'] = kernelBase64; params['disableBreakpoints'] = _message.params['disableBreakpoints']; - Map runParams = { + final runParams = { 'method': '_evaluateCompiledExpression', 'id': _message.serial, 'params': params, @@ -196,8 +200,8 @@ class _Evaluator { if (_message.params['scope'] != null) { runParams['params']['scope'] = _message.params['scope']; } - var runExpression = - new Message._fromJsonRpcRequest(_message.client, runParams); + final runExpression = + Message._fromJsonRpcRequest(_message.client!, runParams); return _isolate.routeRequest(_service, runExpression); // _message } else { // empty kernel indicates dart1 mode diff --git a/sdk/lib/vmservice/vmservice.dart b/sdk/lib/vmservice/vmservice.dart index 0cd0eeb6ec7..23f555b27e5 100644 --- a/sdk/lib/vmservice/vmservice.dart +++ b/sdk/lib/vmservice/vmservice.dart @@ -2,8 +2,6 @@ // 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.6 - library dart._vmservice; import 'dart:async'; @@ -23,8 +21,8 @@ part 'message.dart'; part 'message_router.dart'; part 'named_lookup.dart'; -final RawReceivePort isolateControlPort = new RawReceivePort(); -final RawReceivePort scriptLoadPort = new RawReceivePort(); +final isolateControlPort = RawReceivePort(); +final scriptLoadPort = RawReceivePort(); abstract class IsolateEmbedderData { void cleanup(); @@ -32,8 +30,8 @@ abstract class IsolateEmbedderData { String _makeAuthToken() { final kTokenByteSize = 8; - Uint8List bytes = new Uint8List(kTokenByteSize); - Random random = new Random.secure(); + Uint8List bytes = Uint8List(kTokenByteSize); + Random random = Random.secure(); for (int i = 0; i < kTokenByteSize; i++) { bytes[i] = random.nextInt(256); } @@ -41,16 +39,15 @@ String _makeAuthToken() { } // The randomly generated auth token used to access the VM service. -final String serviceAuthToken = _makeAuthToken(); +final serviceAuthToken = _makeAuthToken(); // This is for use by the embedder. It is a map from the isolateId to // anything implementing IsolateEmbedderData. When an isolate goes away, // the cleanup method will be invoked after being removed from the map. -final Map isolateEmbedderData = - new Map(); +final isolateEmbedderData = {}; // These must be kept in sync with the declarations in vm/json_stream.h and -// pkg/dds/lib/src/stream_manager.dart. +// pkg/dds/lib/src/rpc_error_codes.dart. const kParseError = -32700; const kInvalidRequest = -32600; const kMethodNotFound = -32601; @@ -79,7 +76,7 @@ const kFileSystemAlreadyExists = 1001; const kFileSystemDoesNotExist = 1002; const kFileDoesNotExist = 1003; -var _errorMessages = { +final _errorMessages = { kInvalidParams: 'Invalid params', kInternalError: 'Internal error', kFeatureDisabled: 'Feature is disabled', @@ -95,8 +92,8 @@ var _errorMessages = { 'due to the current configuration', }; -String encodeRpcError(Message message, int code, {String details}) { - var response = { +String encodeRpcError(Message message, int code, {String? details}) { + final response = { 'jsonrpc': '2.0', 'id': message.serial, 'error': { @@ -105,43 +102,36 @@ String encodeRpcError(Message message, int code, {String details}) { }, }; if (details != null) { - response['error']['data'] = { + response['error']['data'] = { 'details': details, }; } return json.encode(response); } -String encodeMissingParamError(Message message, String param) { - return encodeRpcError(message, kInvalidParams, - details: "${message.method} expects the '${param}' parameter"); -} +String encodeMissingParamError(Message message, String param) => + encodeRpcError(message, kInvalidParams, + details: "${message.method} expects the '${param}' parameter"); String encodeInvalidParamError(Message message, String param) { - var value = message.params[param]; + final value = message.params[param]; return encodeRpcError(message, kInvalidParams, details: "${message.method}: invalid '${param}' parameter: ${value}"); } -String encodeCompilationError(Message message, String diagnostic) { - return encodeRpcError(message, kExpressionCompilationError, - details: diagnostic); -} +String encodeCompilationError(Message message, String diagnostic) => + encodeRpcError(message, kExpressionCompilationError, details: diagnostic); -String encodeResult(Message message, Map result) { - var response = { - 'jsonrpc': '2.0', - 'id': message.serial, - 'result': result, - }; - return json.encode(response); -} +String encodeResult(Message message, Map result) => json.encode({ + 'jsonrpc': '2.0', + 'id': message.serial, + 'result': result, + }); -String encodeSuccess(Message message) { - return encodeResult(message, {'type': 'Success'}); -} +String encodeSuccess(Message message) => + encodeResult(message, {'type': 'Success'}); -const shortDelay = const Duration(milliseconds: 10); +const shortDelay = Duration(milliseconds: 10); /// Called when the server should be started. typedef Future ServerStartCallback(); @@ -174,10 +164,10 @@ typedef Future>> ListFilesCallback(Uri path); typedef Future ServerInformamessage_routertionCallback(); /// Called when we need information about the server. -typedef Future ServerInformationCallback(); +typedef Uri? ServerInformationCallback(); /// Called when we want to [enable] or disable the web server. -typedef Future WebServerControlCallback(bool enable); +typedef Future WebServerControlCallback(bool enable); /// Called when we want to [enable] or disable new websocket connections to the /// server. @@ -185,18 +175,18 @@ typedef void WebServerAcceptNewWebSocketConnectionsCallback(bool enable); /// Hooks that are setup by the embedder. class VMServiceEmbedderHooks { - static ServerStartCallback serverStart; - static ServerStopCallback serverStop; - static CleanupCallback cleanup; - static CreateTempDirCallback createTempDir; - static DeleteDirCallback deleteDir; - static WriteFileCallback writeFile; - static WriteStreamFileCallback writeStreamFile; - static ReadFileCallback readFile; - static ListFilesCallback listFiles; - static ServerInformationCallback serverInformation; - static WebServerControlCallback webServerControl; - static WebServerAcceptNewWebSocketConnectionsCallback + static ServerStartCallback? serverStart; + static ServerStopCallback? serverStop; + static CleanupCallback? cleanup; + static CreateTempDirCallback? createTempDir; + static DeleteDirCallback? deleteDir; + static WriteFileCallback? writeFile; + static WriteStreamFileCallback? writeStreamFile; + static ReadFileCallback? readFile; + static ListFilesCallback? listFiles; + static ServerInformationCallback? serverInformation; + static WebServerControlCallback? webServerControl; + static WebServerAcceptNewWebSocketConnectionsCallback? acceptNewWebSocketConnections; } @@ -206,21 +196,20 @@ class _ClientResumePermissions { } class VMService extends MessageRouter { - static VMService _instance; + static VMService? _instance; static const serviceNamespace = 's'; /// Collection of currently connected clients. - final NamedLookup clients = - new NamedLookup(prologue: serviceNamespace); - final IdGenerator _serviceRequests = new IdGenerator(prologue: 'sr'); + final clients = NamedLookup(prologue: serviceNamespace); + final _serviceRequests = IdGenerator(prologue: 'sr'); /// Mapping of client names to all clients of that name and their resume /// permissions. final Map clientResumePermissions = {}; /// Collection of currently running isolates. - RunningIsolates runningIsolates = new RunningIsolates(); + final runningIsolates = RunningIsolates(); /// Flag to indicate VM service is exiting. bool isExiting = false; @@ -228,10 +217,10 @@ class VMService extends MessageRouter { /// A port used to receive events from the VM. final RawReceivePort eventPort; - final devfs = new DevFS(); + final devfs = DevFS(); - Uri get ddsUri => _ddsUri; - Uri _ddsUri; + Uri? get ddsUri => _ddsUri; + Uri? _ddsUri; Future _yieldControlToDDS(Message message) async { final acceptNewWebSocketConnections = @@ -294,7 +283,7 @@ class VMService extends MessageRouter { /// If any resume approvals were set for this client previously they will /// need to be reset after a name change. String _setClientName(Message message) { - final client = message.client; + final client = message.client!; if (!message.params.containsKey('name')) { return encodeRpcError(message, kInvalidParams, details: "setClientName: missing required parameter 'name'"); @@ -310,15 +299,16 @@ class VMService extends MessageRouter { void _setClientNameHelper(Client client, String name) { _clearClientName(client); - client.name = name.isEmpty ? client.defaultClientName : name; + name = name.isEmpty ? client.defaultClientName : name; + client.name = name; clientResumePermissions.putIfAbsent( client.name, () => _ClientResumePermissions()); - clientResumePermissions[client.name].clients.add(client); + clientResumePermissions[name]!.clients.add(client); } String _getClientName(Message message) => encodeResult(message, { 'type': 'ClientName', - 'name': message.client.name, + 'name': message.client!.name, }); String _requirePermissionToResume(Message message) { @@ -334,7 +324,7 @@ class VMService extends MessageRouter { return arg; } - final client = message.client; + final client = message.client!; int pauseTypeMask = 0; try { if (parsePermission('onPauseStart')) { @@ -346,25 +336,24 @@ class VMService extends MessageRouter { if (parsePermission('onPauseExit')) { pauseTypeMask |= RunningIsolate.kPauseOnExitMask; } - } catch (rpcError) { + } on dynamic catch (rpcError) { return rpcError; } - clientResumePermissions[client.name].permissionsMask = pauseTypeMask; + clientResumePermissions[client.name]!.permissionsMask = pauseTypeMask; return encodeSuccess(message); } void _addClient(Client client) { assert(client.streams.isEmpty); assert(client.services.isEmpty); - _setClientNameHelper(client, client.defaultClientName); clients.add(client); } void _removeClient(Client client) { final namespace = clients.keyOf(client); clients.remove(client); - for (var streamId in client.streams) { + for (final streamId in client.streams) { if (!_isAnyClientSubscribed(streamId)) { _vmCancelStream(streamId); } @@ -373,18 +362,18 @@ class VMService extends MessageRouter { // Clean up client approvals state. _clearClientName(client); - for (var service in client.services.keys) { + for (final service in client.services.keys) { _eventMessageHandler( 'Service', - new Response.json({ + Response.json({ 'jsonrpc': '2.0', 'method': 'streamNotify', 'params': { 'streamId': 'Service', 'event': { - "type": "Event", - "kind": "ServiceUnregistered", - 'timestamp': new DateTime.now().millisecondsSinceEpoch, + 'type': 'Event', + 'kind': 'ServiceUnregistered', + 'timestamp': DateTime.now().millisecondsSinceEpoch, 'service': service, 'method': namespace + '.' + service, } @@ -392,7 +381,7 @@ class VMService extends MessageRouter { })); } // Complete all requests as failed - for (var handle in client.serviceHandles.values) { + for (final handle in client.serviceHandles.values) { handle(null); } if (clients.isEmpty) { @@ -408,7 +397,7 @@ class VMService extends MessageRouter { } void _eventMessageHandler(String streamId, Response event) { - for (var client in clients) { + for (final client in clients) { if (client.sendEvents && client.streams.contains(streamId)) { client.post(event); } @@ -422,57 +411,56 @@ class VMService extends MessageRouter { break; case Constants.ISOLATE_SHUTDOWN_MESSAGE_ID: runningIsolates.isolateShutdown(portId, sp); - IsolateEmbedderData ied = isolateEmbedderData.remove(portId); - if (ied != null) { - ied.cleanup(); - } + isolateEmbedderData.remove(portId)?.cleanup(); break; } } - Future _serverMessageHandler(int code, SendPort sp, bool enable) async { + Future _serverMessageHandler(int code, SendPort sp, bool enable) async { switch (code) { case Constants.WEB_SERVER_CONTROL_MESSAGE_ID: - if (VMServiceEmbedderHooks.webServerControl == null) { + final webServerControl = VMServiceEmbedderHooks.webServerControl; + if (webServerControl == null) { sp.send(null); return; } - Uri uri = await VMServiceEmbedderHooks.webServerControl(enable); + final uri = await webServerControl(enable); sp.send(uri); break; case Constants.SERVER_INFO_MESSAGE_ID: - if (VMServiceEmbedderHooks.serverInformation == null) { + final serverInformation = VMServiceEmbedderHooks.serverInformation; + if (serverInformation == null) { sp.send(null); return; } - Uri uri = await VMServiceEmbedderHooks.serverInformation(); + final uri = await serverInformation(); sp.send(uri); break; } } - Future _handleNativeRpcCall(message, SendPort replyPort) async { - // Keep in sync with "runtime/vm/service_isolate.cc:InvokeServiceRpc". + Future _handleNativeRpcCall(message, SendPort replyPort) async { + // Keep in sync with 'runtime/vm/service_isolate.cc:InvokeServiceRpc'. Response response; try { - final Message rpc = new Message.fromJsonRpc( + final rpc = Message.fromJsonRpc( null, json.decode(utf8.decode(message as List))); if (rpc.type != MessageType.Request) { - response = new Response.internalError( + response = Response.internalError( 'The client sent a non-request json-rpc message.'); } else { - response = await routeRequest(this, rpc); + response = (await routeRequest(this, rpc))!; } } catch (exception) { - response = new Response.internalError( + response = Response.internalError( 'The rpc call resulted in exception: $exception.'); } - List bytes; + late List bytes; switch (response.kind) { case ResponsePayloadKind.String: bytes = utf8.encode(response.payload); - bytes = bytes is Uint8List ? bytes : new Uint8List.fromList(bytes); + bytes = bytes is Uint8List ? bytes : Uint8List.fromList(bytes); break; case ResponsePayloadKind.Binary: case ResponsePayloadKind.Utf8String: @@ -485,9 +473,10 @@ class VMService extends MessageRouter { Future _exit() async { isExiting = true; + final serverStop = VMServiceEmbedderHooks.serverStop; // Stop the server. - if (VMServiceEmbedderHooks.serverStop != null) { - await VMServiceEmbedderHooks.serverStop(); + if (serverStop != null) { + await serverStop(); } // Close receive ports. @@ -496,13 +485,14 @@ class VMService extends MessageRouter { // Create a copy of the set as a list because client.disconnect() will // alter the connected clients set. - var clientsList = clients.toList(); - for (var client in clientsList) { + final clientsList = clients.toList(); + for (final client in clientsList) { client.disconnect(); } devfs.cleanup(); - if (VMServiceEmbedderHooks.cleanup != null) { - await VMServiceEmbedderHooks.cleanup(); + final cleanup = VMServiceEmbedderHooks.cleanup; + if (cleanup != null) { + await cleanup(); } // Notify the VM that we have exited. @@ -513,7 +503,7 @@ class VMService extends MessageRouter { if (message is List) { if (message.length == 2) { // This is an event. - _eventMessageHandler(message[0], new Response.from(message[1])); + _eventMessageHandler(message[0], Response.from(message[1])); return; } if (message.length == 1) { @@ -550,15 +540,17 @@ class VMService extends MessageRouter { } factory VMService() { - if (VMService._instance == null) { - VMService._instance = new VMService._internal(); + VMService? instance = VMService._instance; + if (instance == null) { + instance = VMService._internal(); + VMService._instance = instance; _onStart(); } - return _instance; + return instance; } bool _isAnyClientSubscribed(String streamId) { - for (var client in clients) { + for (final client in clients) { if (client.streams.contains(streamId)) { return true; } @@ -566,7 +558,7 @@ class VMService extends MessageRouter { return false; } - Client _findFirstClientThatHandlesService(String service) { + Client? _findFirstClientThatHandlesService(String service) { if (clients != null) { for (Client c in clients) { if (c.services.containsKey(service)) { @@ -578,11 +570,11 @@ class VMService extends MessageRouter { } static const kServiceStream = 'Service'; - static const serviceStreams = const [kServiceStream]; + static const serviceStreams = [kServiceStream]; Future _streamListen(Message message) async { - var client = message.client; - var streamId = message.params['streamId']; + final client = message.client!; + final streamId = message.params['streamId']!; if (client.streams.contains(streamId)) { return encodeRpcError(message, kStreamAlreadySubscribed); @@ -612,8 +604,8 @@ class VMService extends MessageRouter { } Future _streamCancel(Message message) async { - var client = message.client; - var streamId = message.params['streamId']; + final client = message.client!; + final streamId = message.params['streamId']!; if (!client.streams.contains(streamId)) { return encodeRpcError(message, kStreamNotSubscribed); @@ -634,7 +626,7 @@ class VMService extends MessageRouter { static String _getMethod(String method) => method.split('.').last; Future _registerService(Message message) async { - final client = message.client; + final client = message.client!; final service = message.params['service']; final alias = message.params['alias']; @@ -651,7 +643,7 @@ class VMService extends MessageRouter { } client.services[service] = alias; - bool removed; + bool removed = false; try { // Do not send streaming events to the client which registers the service removed = client.streams.remove(kServiceStream); @@ -663,19 +655,19 @@ class VMService extends MessageRouter { return encodeSuccess(message); } - _sendServiceRegisteredEvent(Client client, String service, - {Client target}) async { + Future _sendServiceRegisteredEvent(Client client, String service, + {Client? target}) async { final namespace = clients.keyOf(client); final alias = client.services[service]; - final event = new Response.json({ + final event = Response.json({ 'jsonrpc': '2.0', 'method': 'streamNotify', 'params': { 'streamId': kServiceStream, 'event': { - "type": "Event", - "kind": "ServiceRegistered", - 'timestamp': new DateTime.now().millisecondsSinceEpoch, + 'type': 'Event', + 'kind': 'ServiceRegistered', + 'timestamp': DateTime.now().millisecondsSinceEpoch, 'service': service, 'method': namespace + '.' + service, 'alias': alias @@ -690,28 +682,28 @@ class VMService extends MessageRouter { } Future _handleService(Message message) async { - final namespace = _getNamespace(message.method); - final method = _getMethod(message.method); + final namespace = _getNamespace(message.method!); + final method = _getMethod(message.method!); final client = clients[namespace]; if (client != null) { if (client.services.containsKey(method)) { final id = _serviceRequests.newId(); final oldId = message.serial; - final completer = new Completer(); - client.serviceHandles[id] = (Message m) { + final completer = Completer(); + client.serviceHandles[id] = (Message? m) { if (m != null) { completer.complete(json.encode(m.forwardToJson({'id': oldId}))); } else { completer.complete(encodeRpcError(message, kServiceDisappeared)); } }; - client.post(new Response.json( - message.forwardToJson({'id': id, 'method': method}))); + client.post( + Response.json(message.forwardToJson({'id': id, 'method': method}))); return completer.future; } } return encodeRpcError(message, kMethodNotFound, - details: "Unknown service: ${message.method}"); + details: 'Unknown service: ${message.method}'); } Future _getSupportedProtocols(Message message) async { @@ -733,14 +725,14 @@ class VMService extends MessageRouter { return encodeResult(message, protocols); } - Future routeRequest(VMService _, Message message) async { + Future routeRequest(VMService _, Message message) async { final response = await _routeRequestImpl(message); if (response == null) { // We should only have a null response for Notifications. assert(message.type == MessageType.Notification); return null; } - return new Response.from(response); + return Response.from(response); } Future _routeRequestImpl(Message message) async { @@ -775,7 +767,7 @@ class VMService extends MessageRouter { if (devfs.shouldHandleMessage(message)) { return await devfs.handleMessage(message); } - if (_hasNamespace(message.method)) { + if (_hasNamespace(message.method!)) { return await _handleService(message); } if (message.params['isolateId'] != null) { @@ -789,42 +781,41 @@ class VMService extends MessageRouter { } void routeResponse(message) { - final client = message.client; + final client = message.client!; if (client.serviceHandles.containsKey(message.serial)) { - client.serviceHandles.remove(message.serial)(message); + client.serviceHandles.remove(message.serial)!(message); _serviceRequests.release(message.serial); } } } -@pragma("vm:entry-point", - const bool.fromEnvironment("dart.vm.product") ? false : "call") +@pragma('vm:entry-point', + const bool.fromEnvironment('dart.vm.product') ? false : 'call') RawReceivePort boot() { // Return the port we expect isolate control messages on. return isolateControlPort; } -@pragma("vm:entry-point", !const bool.fromEnvironment("dart.vm.product")) -void _registerIsolate(int port_id, SendPort sp, String name) { - var service = new VMService(); - service.runningIsolates.isolateStartup(port_id, sp, name); -} +@pragma('vm:entry-point', !const bool.fromEnvironment('dart.vm.product')) +// ignore: unused_element +void _registerIsolate(int port_id, SendPort sp, String name) => + VMService().runningIsolates.isolateStartup(port_id, sp, name); /// Notify the VM that the service is running. -void _onStart() native "VMService_OnStart"; +void _onStart() native 'VMService_OnStart'; /// Notify the VM that the service is no longer running. -void _onExit() native "VMService_OnExit"; +void _onExit() native 'VMService_OnExit'; /// Notify the VM that the server's address has changed. -void onServerAddressChange(String address) - native "VMService_OnServerAddressChange"; +void onServerAddressChange(String? address) + native 'VMService_OnServerAddressChange'; /// Subscribe to a service stream. -bool _vmListenStream(String streamId) native "VMService_ListenStream"; +bool _vmListenStream(String streamId) native 'VMService_ListenStream'; /// Cancel a subscription to a service stream. -void _vmCancelStream(String streamId) native "VMService_CancelStream"; +void _vmCancelStream(String streamId) native 'VMService_CancelStream'; /// Get the bytes to the tar archive. -Uint8List _requestAssets() native "VMService_RequestAssets"; +Uint8List _requestAssets() native 'VMService_RequestAssets'; diff --git a/sdk/lib/vmservice_libraries.json b/sdk/lib/vmservice_libraries.json index af43f4829fa..0ef7b8d92b5 100644 --- a/sdk/lib/vmservice_libraries.json +++ b/sdk/lib/vmservice_libraries.json @@ -1,12 +1,14 @@ { + "comment:0": "NOTE: THIS FILE IS GENERATED. DO NOT EDIT.", + "comment:1": "Instead modify 'sdk/lib/vmservice_libraries.yaml' and follow the instructions therein.", "vm": { "libraries": { - "vmservice_io": { - "uri": "_internal/vm/bin/vmservice_io.dart" - }, "_vmservice": { "uri": "vmservice/vmservice.dart" + }, + "vmservice_io": { + "uri": "_internal/vm/bin/vmservice_io.dart" } } } -} +} \ No newline at end of file diff --git a/sdk/lib/wasm/wasm.dart b/sdk/lib/wasm/wasm.dart index 3495b019aaa..768445e3376 100644 --- a/sdk/lib/wasm/wasm.dart +++ b/sdk/lib/wasm/wasm.dart @@ -2,8 +2,6 @@ // 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.6 - /// {@category VM} /// {@nodoc} library dart.wasm; @@ -57,7 +55,7 @@ abstract class WasmImports { abstract class WasmMemory { // Create a new memory with the given number of initial pages, and optional // maximum number of pages. - external factory WasmMemory(int initialPages, [int maxPages]); + external factory WasmMemory(int initialPages, [int? maxPages]); // The WASM spec defines the page size as 64KiB. static const int kPageSizeInBytes = 64 * 1024; @@ -83,7 +81,7 @@ abstract class WasmInstance { // Find an exported function with the given signature. WasmFunction lookupFunction(String name); - // Returns this instances's memory. + // Returns this instance's memory. WasmMemory get memory; } diff --git a/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart b/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart index eea4e5515e6..146e158e7bd 100644 --- a/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart +++ b/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart @@ -1,5 +1,3 @@ -// @dart = 2.6 - /** * High-fidelity audio programming in the browser. * @@ -40,7 +38,7 @@ class AnalyserNode extends AudioNode { throw new UnsupportedError("Not supported"); } - factory AnalyserNode(BaseAudioContext context, [Map options]) { + factory AnalyserNode(BaseAudioContext context, [Map? options]) { if (options != null) { var options_1 = convertDartToNative_Dictionary(options); return AnalyserNode._create_1(context, options_1); @@ -105,10 +103,10 @@ class AudioBuffer extends Interceptor { num get sampleRate native; void copyFromChannel(Float32List destination, int channelNumber, - [int startInChannel]) native; + [int? startInChannel]) native; void copyToChannel(Float32List source, int channelNumber, - [int startInChannel]) native; + [int? startInChannel]) native; Float32List getChannelData(int channelIndex) native; } @@ -125,7 +123,7 @@ class AudioBufferSourceNode extends AudioScheduledSourceNode { throw new UnsupportedError("Not supported"); } - factory AudioBufferSourceNode(BaseAudioContext context, [Map options]) { + factory AudioBufferSourceNode(BaseAudioContext context, [Map? options]) { if (options != null) { var options_1 = convertDartToNative_Dictionary(options); return AudioBufferSourceNode._create_1(context, options_1); @@ -140,9 +138,9 @@ class AudioBufferSourceNode extends AudioScheduledSourceNode { static AudioBufferSourceNode _create_2(context) => JS('AudioBufferSourceNode', 'new AudioBufferSourceNode(#)', context); - AudioBuffer get buffer native; + AudioBuffer? get buffer native; - set buffer(AudioBuffer value) native; + set buffer(AudioBuffer? value) native; AudioParam get detune native; @@ -160,7 +158,7 @@ class AudioBufferSourceNode extends AudioScheduledSourceNode { AudioParam get playbackRate native; - void start([num when, num grainOffset, num grainDuration]) native; + void start([num? when, num? grainOffset, num? grainDuration]) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -184,7 +182,7 @@ class AudioContext extends BaseAudioContext { Future close() => promiseToFuture(JS("", "#.close()", this)); Map getOutputTimestamp() { - return convertNativeToDart_Dictionary(_getOutputTimestamp_1()); + return convertNativeToDart_Dictionary(_getOutputTimestamp_1())!; } @JSName('getOutputTimestamp') @@ -204,7 +202,9 @@ class AudioContext extends BaseAudioContext { } ScriptProcessorNode createScriptProcessor( - [int bufferSize, int numberOfInputChannels, int numberOfOutputChannels]) { + [int? bufferSize, + int? numberOfInputChannels, + int? numberOfOutputChannels]) { var function = JS( '=Object', '#.createScriptProcessor || ' @@ -226,13 +226,13 @@ class AudioContext extends BaseAudioContext { } @JSName('decodeAudioData') - Future _decodeAudioData(ByteBuffer audioData, - [DecodeSuccessCallback successCallback, - DecodeErrorCallback errorCallback]) native; + Future _decodeAudioData(ByteBuffer audioData, + [DecodeSuccessCallback? successCallback, + DecodeErrorCallback? errorCallback]) native; Future decodeAudioData(ByteBuffer audioData, - [DecodeSuccessCallback successCallback, - DecodeErrorCallback errorCallback]) { + [DecodeSuccessCallback? successCallback, + DecodeErrorCallback? errorCallback]) { if (successCallback != null && errorCallback != null) { return _decodeAudioData(audioData, successCallback, errorCallback); } @@ -326,9 +326,9 @@ class AudioNode extends EventTarget { int get numberOfOutputs native; @JSName('connect') - AudioNode _connect(destination, [int output, int input]) native; + AudioNode _connect(destination, [int? output, int? input]) native; - void disconnect([destination_OR_output, int output, int input]) native; + void disconnect([destination_OR_output, int? output, int? input]) native; void connectNode(AudioNode destination, [int output = 0, int input = 0]) { _connect(destination, output, input); @@ -385,7 +385,7 @@ class AudioParamMap extends Interceptor with MapMixin { throw new UnsupportedError("Not supported"); } - Map _getItem(String key) => + Map? _getItem(String key) => convertNativeToDart_Dictionary(JS('', '#.get(#)', this, key)); void addAll(Map other) { @@ -396,7 +396,7 @@ class AudioParamMap extends Interceptor with MapMixin { bool containsKey(dynamic key) => _getItem(key) != null; - Map operator [](dynamic key) => _getItem(key); + Map? operator [](dynamic key) => _getItem(key); void forEach(void f(String key, dynamic value)) { var entries = JS('', '#.entries()', this); @@ -484,9 +484,9 @@ class AudioScheduledSourceNode extends AudioNode { const EventStreamProvider('ended'); @JSName('start') - void start2([num when]) native; + void start2([num? when]) native; - void stop([num when]) native; + void stop([num? when]) native; Stream get onEnded => endedEvent.forTarget(this); } @@ -513,7 +513,7 @@ class AudioTrack extends Interceptor { String get language native; - SourceBuffer get sourceBuffer native; + SourceBuffer? get sourceBuffer native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -533,7 +533,7 @@ class AudioTrackList extends EventTarget { AudioTrack __getter__(int index) native; - AudioTrack getTrackById(String id) native; + AudioTrack? getTrackById(String id) native; Stream get onChange => changeEvent.forTarget(this); } @@ -566,7 +566,7 @@ class AudioWorkletNode extends AudioNode { } factory AudioWorkletNode(BaseAudioContext context, String name, - [Map options]) { + [Map? options]) { if (options != null) { var options_1 = convertDartToNative_Dictionary(options); return AudioWorkletNode._create_1(context, name, options_1); @@ -625,15 +625,15 @@ class BaseAudioContext extends EventTarget { AudioBufferSourceNode createBufferSource() native; - ChannelMergerNode createChannelMerger([int numberOfInputs]) native; + ChannelMergerNode createChannelMerger([int? numberOfInputs]) native; - ChannelSplitterNode createChannelSplitter([int numberOfOutputs]) native; + ChannelSplitterNode createChannelSplitter([int? numberOfOutputs]) native; ConstantSourceNode createConstantSource() native; ConvolverNode createConvolver() native; - DelayNode createDelay([num maxDelayTime]) native; + DelayNode createDelay([num? maxDelayTime]) native; DynamicsCompressorNode createDynamicsCompressor() native; @@ -656,7 +656,7 @@ class BaseAudioContext extends EventTarget { PannerNode createPanner() native; PeriodicWave createPeriodicWave(List real, List imag, - [Map options]) { + [Map? options]) { if (options != null) { var options_1 = convertDartToNative_Dictionary(options); return _createPeriodicWave_1(real, imag, options_1); @@ -671,17 +671,17 @@ class BaseAudioContext extends EventTarget { PeriodicWave _createPeriodicWave_2(List real, List imag) native; ScriptProcessorNode createScriptProcessor( - [int bufferSize, - int numberOfInputChannels, - int numberOfOutputChannels]) native; + [int? bufferSize, + int? numberOfInputChannels, + int? numberOfOutputChannels]) native; StereoPannerNode createStereoPanner() native; WaveShaperNode createWaveShaper() native; Future decodeAudioData(ByteBuffer audioData, - [DecodeSuccessCallback successCallback, - DecodeErrorCallback errorCallback]) => + [DecodeSuccessCallback? successCallback, + DecodeErrorCallback? errorCallback]) => promiseToFuture(JS("", "#.decodeAudioData(#, #, #)", this, audioData, successCallback, errorCallback)); @@ -698,7 +698,7 @@ class BiquadFilterNode extends AudioNode { throw new UnsupportedError("Not supported"); } - factory BiquadFilterNode(BaseAudioContext context, [Map options]) { + factory BiquadFilterNode(BaseAudioContext context, [Map? options]) { if (options != null) { var options_1 = convertDartToNative_Dictionary(options); return BiquadFilterNode._create_1(context, options_1); @@ -736,7 +736,7 @@ class ChannelMergerNode extends AudioNode { throw new UnsupportedError("Not supported"); } - factory ChannelMergerNode(BaseAudioContext context, [Map options]) { + factory ChannelMergerNode(BaseAudioContext context, [Map? options]) { if (options != null) { var options_1 = convertDartToNative_Dictionary(options); return ChannelMergerNode._create_1(context, options_1); @@ -759,7 +759,7 @@ class ChannelSplitterNode extends AudioNode { throw new UnsupportedError("Not supported"); } - factory ChannelSplitterNode(BaseAudioContext context, [Map options]) { + factory ChannelSplitterNode(BaseAudioContext context, [Map? options]) { if (options != null) { var options_1 = convertDartToNative_Dictionary(options); return ChannelSplitterNode._create_1(context, options_1); @@ -782,7 +782,7 @@ class ConstantSourceNode extends AudioScheduledSourceNode { throw new UnsupportedError("Not supported"); } - factory ConstantSourceNode(BaseAudioContext context, [Map options]) { + factory ConstantSourceNode(BaseAudioContext context, [Map? options]) { if (options != null) { var options_1 = convertDartToNative_Dictionary(options); return ConstantSourceNode._create_1(context, options_1); @@ -807,7 +807,7 @@ class ConvolverNode extends AudioNode { throw new UnsupportedError("Not supported"); } - factory ConvolverNode(BaseAudioContext context, [Map options]) { + factory ConvolverNode(BaseAudioContext context, [Map? options]) { if (options != null) { var options_1 = convertDartToNative_Dictionary(options); return ConvolverNode._create_1(context, options_1); @@ -819,9 +819,9 @@ class ConvolverNode extends AudioNode { static ConvolverNode _create_2(context) => JS('ConvolverNode', 'new ConvolverNode(#)', context); - AudioBuffer get buffer native; + AudioBuffer? get buffer native; - set buffer(AudioBuffer value) native; + set buffer(AudioBuffer? value) native; bool get normalize native; @@ -838,7 +838,7 @@ class DelayNode extends AudioNode { throw new UnsupportedError("Not supported"); } - factory DelayNode(BaseAudioContext context, [Map options]) { + factory DelayNode(BaseAudioContext context, [Map? options]) { if (options != null) { var options_1 = convertDartToNative_Dictionary(options); return DelayNode._create_1(context, options_1); @@ -863,7 +863,7 @@ class DynamicsCompressorNode extends AudioNode { throw new UnsupportedError("Not supported"); } - factory DynamicsCompressorNode(BaseAudioContext context, [Map options]) { + factory DynamicsCompressorNode(BaseAudioContext context, [Map? options]) { if (options != null) { var options_1 = convertDartToNative_Dictionary(options); return DynamicsCompressorNode._create_1(context, options_1); @@ -901,7 +901,7 @@ class GainNode extends AudioNode { throw new UnsupportedError("Not supported"); } - factory GainNode(BaseAudioContext context, [Map options]) { + factory GainNode(BaseAudioContext context, [Map? options]) { if (options != null) { var options_1 = convertDartToNative_Dictionary(options); return GainNode._create_1(context, options_1); @@ -971,7 +971,7 @@ class MediaStreamAudioDestinationNode extends AudioNode { } factory MediaStreamAudioDestinationNode(BaseAudioContext context, - [Map options]) { + [Map? options]) { if (options != null) { var options_1 = convertDartToNative_Dictionary(options); return MediaStreamAudioDestinationNode._create_1(context, options_1); @@ -1048,7 +1048,7 @@ class OfflineAudioContext extends BaseAudioContext { } factory OfflineAudioContext(numberOfChannels_OR_options, - [int numberOfFrames, num sampleRate]) { + [int? numberOfFrames, num? sampleRate]) { if ((sampleRate is num) && (numberOfFrames is int) && (numberOfChannels_OR_options is int)) { @@ -1093,7 +1093,7 @@ class OscillatorNode extends AudioScheduledSourceNode { throw new UnsupportedError("Not supported"); } - factory OscillatorNode(BaseAudioContext context, [Map options]) { + factory OscillatorNode(BaseAudioContext context, [Map? options]) { if (options != null) { var options_1 = convertDartToNative_Dictionary(options); return OscillatorNode._create_1(context, options_1); @@ -1126,7 +1126,7 @@ class PannerNode extends AudioNode { throw new UnsupportedError("Not supported"); } - factory PannerNode(BaseAudioContext context, [Map options]) { + factory PannerNode(BaseAudioContext context, [Map? options]) { if (options != null) { var options_1 = convertDartToNative_Dictionary(options); return PannerNode._create_1(context, options_1); @@ -1197,7 +1197,7 @@ class PeriodicWave extends Interceptor { throw new UnsupportedError("Not supported"); } - factory PeriodicWave(BaseAudioContext context, [Map options]) { + factory PeriodicWave(BaseAudioContext context, [Map? options]) { if (options != null) { var options_1 = convertDartToNative_Dictionary(options); return PeriodicWave._create_1(context, options_1); @@ -1255,7 +1255,7 @@ class StereoPannerNode extends AudioNode { throw new UnsupportedError("Not supported"); } - factory StereoPannerNode(BaseAudioContext context, [Map options]) { + factory StereoPannerNode(BaseAudioContext context, [Map? options]) { if (options != null) { var options_1 = convertDartToNative_Dictionary(options); return StereoPannerNode._create_1(context, options_1); @@ -1280,7 +1280,7 @@ class WaveShaperNode extends AudioNode { throw new UnsupportedError("Not supported"); } - factory WaveShaperNode(BaseAudioContext context, [Map options]) { + factory WaveShaperNode(BaseAudioContext context, [Map? options]) { if (options != null) { var options_1 = convertDartToNative_Dictionary(options); return WaveShaperNode._create_1(context, options_1); @@ -1292,9 +1292,9 @@ class WaveShaperNode extends AudioNode { static WaveShaperNode _create_2(context) => JS('WaveShaperNode', 'new WaveShaperNode(#)', context); - Float32List get curve native; + Float32List? get curve native; - set curve(Float32List value) native; + set curve(Float32List? value) native; String get oversample native; diff --git a/sdk/lib/web_gl/dart2js/web_gl_dart2js.dart b/sdk/lib/web_gl/dart2js/web_gl_dart2js.dart index 22d252cee3f..53671dfac15 100644 --- a/sdk/lib/web_gl/dart2js/web_gl_dart2js.dart +++ b/sdk/lib/web_gl/dart2js/web_gl_dart2js.dart @@ -1,5 +1,3 @@ -// @dart = 2.6 - /** * 3D programming in the browser. * @@ -302,7 +300,7 @@ class ContextEvent extends Event { throw new UnsupportedError("Not supported"); } - factory ContextEvent(String type, [Map eventInit]) { + factory ContextEvent(String type, [Map? eventInit]) { if (eventInit != null) { var eventInit_1 = convertDartToNative_Dictionary(eventInit); return ContextEvent._create_1(type, eventInit_1); @@ -342,7 +340,7 @@ class DebugShaders extends Interceptor { throw new UnsupportedError("Not supported"); } - String getTranslatedShaderSource(Shader shader) native; + String? getTranslatedShaderSource(Shader shader) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -459,19 +457,19 @@ class ExtDisjointTimerQuery extends Interceptor { TimerQueryExt createQueryExt() native; @JSName('deleteQueryEXT') - void deleteQueryExt(TimerQueryExt query) native; + void deleteQueryExt(TimerQueryExt? query) native; @JSName('endQueryEXT') void endQueryExt(int target) native; @JSName('getQueryEXT') - Object getQueryExt(int target, int pname) native; + Object? getQueryExt(int target, int pname) native; @JSName('getQueryObjectEXT') - Object getQueryObjectExt(TimerQueryExt query, int pname) native; + Object? getQueryObjectExt(TimerQueryExt query, int pname) native; @JSName('isQueryEXT') - bool isQueryExt(TimerQueryExt query) native; + bool isQueryExt(TimerQueryExt? query) native; @JSName('queryCounterEXT') void queryCounterExt(TimerQueryExt query, int target) native; @@ -559,7 +557,7 @@ class GetBufferSubDataAsync extends Interceptor { } Future getBufferSubDataAsync(int target, int srcByteOffset, TypedData dstData, - [int dstOffset, int length]) => + [int? dstOffset, int? length]) => promiseToFuture(JS("", "#.getBufferSubDataAsync(#, #, #, #, #)", this, target, srcByteOffset, dstData, dstOffset, length)); } @@ -662,16 +660,16 @@ class OesVertexArrayObject extends Interceptor { static const int VERTEX_ARRAY_BINDING_OES = 0x85B5; @JSName('bindVertexArrayOES') - void bindVertexArray(VertexArrayObjectOes arrayObject) native; + void bindVertexArray(VertexArrayObjectOes? arrayObject) native; @JSName('createVertexArrayOES') VertexArrayObjectOes createVertexArray() native; @JSName('deleteVertexArrayOES') - void deleteVertexArray(VertexArrayObjectOes arrayObject) native; + void deleteVertexArray(VertexArrayObjectOes? arrayObject) native; @JSName('isVertexArrayOES') - bool isVertexArray(VertexArrayObjectOes arrayObject) native; + bool isVertexArray(VertexArrayObjectOes? arrayObject) native; } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -739,13 +737,13 @@ class RenderingContext extends Interceptor implements CanvasRenderingContext { void bindAttribLocation(Program program, int index, String name) native; - void bindBuffer(int target, Buffer buffer) native; + void bindBuffer(int target, Buffer? buffer) native; - void bindFramebuffer(int target, Framebuffer framebuffer) native; + void bindFramebuffer(int target, Framebuffer? framebuffer) native; - void bindRenderbuffer(int target, Renderbuffer renderbuffer) native; + void bindRenderbuffer(int target, Renderbuffer? renderbuffer) native; - void bindTexture(int target, Texture texture) native; + void bindTexture(int target, Texture? texture) native; void blendColor(num red, num green, num blue, num alpha) native; @@ -804,17 +802,17 @@ class RenderingContext extends Interceptor implements CanvasRenderingContext { void cullFace(int mode) native; - void deleteBuffer(Buffer buffer) native; + void deleteBuffer(Buffer? buffer) native; - void deleteFramebuffer(Framebuffer framebuffer) native; + void deleteFramebuffer(Framebuffer? framebuffer) native; - void deleteProgram(Program program) native; + void deleteProgram(Program? program) native; - void deleteRenderbuffer(Renderbuffer renderbuffer) native; + void deleteRenderbuffer(Renderbuffer? renderbuffer) native; - void deleteShader(Shader shader) native; + void deleteShader(Shader? shader) native; - void deleteTexture(Texture texture) native; + void deleteTexture(Texture? texture) native; void depthFunc(int func) native; @@ -841,10 +839,10 @@ class RenderingContext extends Interceptor implements CanvasRenderingContext { void flush() native; void framebufferRenderbuffer(int target, int attachment, - int renderbuffertarget, Renderbuffer renderbuffer) native; + int renderbuffertarget, Renderbuffer? renderbuffer) native; void framebufferTexture2D(int target, int attachment, int textarget, - Texture texture, int level) native; + Texture? texture, int level) native; void frontFace(int mode) native; @@ -854,16 +852,16 @@ class RenderingContext extends Interceptor implements CanvasRenderingContext { ActiveInfo getActiveUniform(Program program, int index) native; - List getAttachedShaders(Program program) native; + List? getAttachedShaders(Program program) native; int getAttribLocation(Program program, String name) native; @Creates('int|Null') @Returns('int|Null') - Object getBufferParameter(int target, int pname) native; + Object? getBufferParameter(int target, int pname) native; @Creates('ContextAttributes|Null') - Map getContextAttributes() { + Map? getContextAttributes() { return convertNativeToDart_Dictionary(_getContextAttributes_1()); } @@ -873,77 +871,77 @@ class RenderingContext extends Interceptor implements CanvasRenderingContext { int getError() native; - Object getExtension(String name) native; + Object? getExtension(String name) native; @Creates('int|Renderbuffer|Texture|Null') @Returns('int|Renderbuffer|Texture|Null') - Object getFramebufferAttachmentParameter( + Object? getFramebufferAttachmentParameter( int target, int attachment, int pname) native; @Creates( 'Null|num|String|bool|JSExtendableArray|NativeFloat32List|NativeInt32List|NativeUint32List|Framebuffer|Renderbuffer|Texture') @Returns( 'Null|num|String|bool|JSExtendableArray|NativeFloat32List|NativeInt32List|NativeUint32List|Framebuffer|Renderbuffer|Texture') - Object getParameter(int pname) native; + Object? getParameter(int pname) native; - String getProgramInfoLog(Program program) native; + String? getProgramInfoLog(Program program) native; @Creates('int|bool|Null') @Returns('int|bool|Null') - Object getProgramParameter(Program program, int pname) native; + Object? getProgramParameter(Program program, int pname) native; @Creates('int|Null') @Returns('int|Null') - Object getRenderbufferParameter(int target, int pname) native; + Object? getRenderbufferParameter(int target, int pname) native; - String getShaderInfoLog(Shader shader) native; + String? getShaderInfoLog(Shader shader) native; @Creates('int|bool|Null') @Returns('int|bool|Null') - Object getShaderParameter(Shader shader, int pname) native; + Object? getShaderParameter(Shader shader, int pname) native; ShaderPrecisionFormat getShaderPrecisionFormat( int shadertype, int precisiontype) native; - String getShaderSource(Shader shader) native; + String? getShaderSource(Shader shader) native; - List getSupportedExtensions() native; + List? getSupportedExtensions() native; @Creates('int|Null') @Returns('int|Null') - Object getTexParameter(int target, int pname) native; + Object? getTexParameter(int target, int pname) native; @Creates( 'Null|num|String|bool|JSExtendableArray|NativeFloat32List|NativeInt32List|NativeUint32List') @Returns( 'Null|num|String|bool|JSExtendableArray|NativeFloat32List|NativeInt32List|NativeUint32List') - Object getUniform(Program program, UniformLocation location) native; + Object? getUniform(Program program, UniformLocation location) native; UniformLocation getUniformLocation(Program program, String name) native; @Creates('Null|num|bool|NativeFloat32List|Buffer') @Returns('Null|num|bool|NativeFloat32List|Buffer') - Object getVertexAttrib(int index, int pname) native; + Object? getVertexAttrib(int index, int pname) native; int getVertexAttribOffset(int index, int pname) native; void hint(int target, int mode) native; - bool isBuffer(Buffer buffer) native; + bool isBuffer(Buffer? buffer) native; bool isContextLost() native; bool isEnabled(int cap) native; - bool isFramebuffer(Framebuffer framebuffer) native; + bool isFramebuffer(Framebuffer? framebuffer) native; - bool isProgram(Program program) native; + bool isProgram(Program? program) native; - bool isRenderbuffer(Renderbuffer renderbuffer) native; + bool isRenderbuffer(Renderbuffer? renderbuffer) native; - bool isShader(Shader shader) native; + bool isShader(Shader? shader) native; - bool isTexture(Texture texture) native; + bool isTexture(Texture? texture) native; void lineWidth(num width) native; @@ -955,7 +953,7 @@ class RenderingContext extends Interceptor implements CanvasRenderingContext { @JSName('readPixels') void _readPixels(int x, int y, int width, int height, int format, int type, - TypedData pixels) native; + TypedData? pixels) native; void renderbufferStorage( int target, int internalformat, int width, int height) native; @@ -985,9 +983,9 @@ class RenderingContext extends Interceptor implements CanvasRenderingContext { int format_OR_width, int height_OR_type, bitmap_OR_border_OR_canvas_OR_image_OR_pixels_OR_video, - [int format, - int type, - TypedData pixels]) { + [int? format, + int? type, + TypedData? pixels]) { if (type != null && format != null && (bitmap_OR_border_OR_canvas_OR_image_OR_pixels_OR_video is int)) { @@ -1074,7 +1072,7 @@ class RenderingContext extends Interceptor implements CanvasRenderingContext { @JSName('texImage2D') void _texImage2D_1(target, level, internalformat, width, height, int border, - format, type, TypedData pixels) native; + format, type, TypedData? pixels) native; @JSName('texImage2D') void _texImage2D_2(target, level, internalformat, format, type, pixels) native; @@ -1103,8 +1101,8 @@ class RenderingContext extends Interceptor implements CanvasRenderingContext { int format_OR_width, int height_OR_type, bitmap_OR_canvas_OR_format_OR_image_OR_pixels_OR_video, - [int type, - TypedData pixels]) { + [int? type, + TypedData? pixels]) { if (type != null && (bitmap_OR_canvas_OR_format_OR_image_OR_pixels_OR_video is int)) { _texSubImage2D_1( @@ -1189,7 +1187,7 @@ class RenderingContext extends Interceptor implements CanvasRenderingContext { @JSName('texSubImage2D') void _texSubImage2D_1(target, level, xoffset, yoffset, width, height, - int format, type, TypedData pixels) native; + int format, type, TypedData? pixels) native; @JSName('texSubImage2D') void _texSubImage2D_2(target, level, xoffset, yoffset, format, type, pixels) native; @@ -1206,45 +1204,48 @@ class RenderingContext extends Interceptor implements CanvasRenderingContext { void _texSubImage2D_6( target, level, xoffset, yoffset, format, type, ImageBitmap bitmap) native; - void uniform1f(UniformLocation location, num x) native; + void uniform1f(UniformLocation? location, num x) native; - void uniform1fv(UniformLocation location, v) native; + void uniform1fv(UniformLocation? location, v) native; - void uniform1i(UniformLocation location, int x) native; + void uniform1i(UniformLocation? location, int x) native; - void uniform1iv(UniformLocation location, v) native; + void uniform1iv(UniformLocation? location, v) native; - void uniform2f(UniformLocation location, num x, num y) native; + void uniform2f(UniformLocation? location, num x, num y) native; - void uniform2fv(UniformLocation location, v) native; + void uniform2fv(UniformLocation? location, v) native; - void uniform2i(UniformLocation location, int x, int y) native; + void uniform2i(UniformLocation? location, int x, int y) native; - void uniform2iv(UniformLocation location, v) native; + void uniform2iv(UniformLocation? location, v) native; - void uniform3f(UniformLocation location, num x, num y, num z) native; + void uniform3f(UniformLocation? location, num x, num y, num z) native; - void uniform3fv(UniformLocation location, v) native; + void uniform3fv(UniformLocation? location, v) native; - void uniform3i(UniformLocation location, int x, int y, int z) native; + void uniform3i(UniformLocation? location, int x, int y, int z) native; - void uniform3iv(UniformLocation location, v) native; + void uniform3iv(UniformLocation? location, v) native; - void uniform4f(UniformLocation location, num x, num y, num z, num w) native; + void uniform4f(UniformLocation? location, num x, num y, num z, num w) native; - void uniform4fv(UniformLocation location, v) native; + void uniform4fv(UniformLocation? location, v) native; - void uniform4i(UniformLocation location, int x, int y, int z, int w) native; + void uniform4i(UniformLocation? location, int x, int y, int z, int w) native; - void uniform4iv(UniformLocation location, v) native; + void uniform4iv(UniformLocation? location, v) native; - void uniformMatrix2fv(UniformLocation location, bool transpose, array) native; + void uniformMatrix2fv(UniformLocation? location, bool transpose, array) + native; - void uniformMatrix3fv(UniformLocation location, bool transpose, array) native; + void uniformMatrix3fv(UniformLocation? location, bool transpose, array) + native; - void uniformMatrix4fv(UniformLocation location, bool transpose, array) native; + void uniformMatrix4fv(UniformLocation? location, bool transpose, array) + native; - void useProgram(Program program) native; + void useProgram(Program? program) native; void validateProgram(Program program) native; @@ -1270,7 +1271,7 @@ class RenderingContext extends Interceptor implements CanvasRenderingContext { void viewport(int x, int y, int width, int height) native; void readPixels(int x, int y, int width, int height, int format, int type, - TypedData pixels) { + TypedData? pixels) { _readPixels(x, y, width, height, format, type, pixels); } @@ -1370,36 +1371,38 @@ class RenderingContext2 extends Interceptor void beginTransformFeedback(int primitiveMode) native; - void bindBufferBase(int target, int index, Buffer buffer) native; + void bindBufferBase(int target, int index, Buffer? buffer) native; void bindBufferRange( - int target, int index, Buffer buffer, int offset, int size) native; + int target, int index, Buffer? buffer, int offset, int size) native; - void bindSampler(int unit, Sampler sampler) native; + void bindSampler(int unit, Sampler? sampler) native; - void bindTransformFeedback(int target, TransformFeedback feedback) native; + void bindTransformFeedback(int target, TransformFeedback? feedback) native; - void bindVertexArray(VertexArrayObject vertexArray) native; + void bindVertexArray(VertexArrayObject? vertexArray) native; void blitFramebuffer(int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, int mask, int filter) native; @JSName('bufferData') void bufferData2(int target, TypedData srcData, int usage, int srcOffset, - [int length]) native; + [int? length]) native; @JSName('bufferSubData') void bufferSubData2( int target, int dstByteOffset, TypedData srcData, int srcOffset, - [int length]) native; + [int? length]) native; void clearBufferfi(int buffer, int drawbuffer, num depth, int stencil) native; - void clearBufferfv(int buffer, int drawbuffer, value, [int srcOffset]) native; + void clearBufferfv(int buffer, int drawbuffer, value, [int? srcOffset]) + native; - void clearBufferiv(int buffer, int drawbuffer, value, [int srcOffset]) native; + void clearBufferiv(int buffer, int drawbuffer, value, [int? srcOffset]) + native; - void clearBufferuiv(int buffer, int drawbuffer, value, [int srcOffset]) + void clearBufferuiv(int buffer, int drawbuffer, value, [int? srcOffset]) native; int clientWaitSync(Sync sync, int flags, int timeout) native; @@ -1407,7 +1410,7 @@ class RenderingContext2 extends Interceptor @JSName('compressedTexImage2D') void compressedTexImage2D2(int target, int level, int internalformat, int width, int height, int border, TypedData data, int srcOffset, - [int srcLengthOverride]) native; + [int? srcLengthOverride]) native; @JSName('compressedTexImage2D') void compressedTexImage2D3(int target, int level, int internalformat, @@ -1415,7 +1418,7 @@ class RenderingContext2 extends Interceptor void compressedTexImage3D(int target, int level, int internalformat, int width, int height, int depth, int border, TypedData data, - [int srcOffset, int srcLengthOverride]) native; + [int? srcOffset, int? srcLengthOverride]) native; @JSName('compressedTexImage3D') void compressedTexImage3D2( @@ -1432,7 +1435,7 @@ class RenderingContext2 extends Interceptor @JSName('compressedTexSubImage2D') void compressedTexSubImage2D2(int target, int level, int xoffset, int yoffset, int width, int height, int format, TypedData data, int srcOffset, - [int srcLengthOverride]) native; + [int? srcLengthOverride]) native; @JSName('compressedTexSubImage2D') void compressedTexSubImage2D3(int target, int level, int xoffset, int yoffset, @@ -1440,7 +1443,7 @@ class RenderingContext2 extends Interceptor void compressedTexSubImage3D(int target, int level, int xoffset, int yoffset, int zoffset, int width, int height, int depth, int format, TypedData data, - [int srcOffset, int srcLengthOverride]) native; + [int? srcOffset, int? srcLengthOverride]) native; @JSName('compressedTexSubImage3D') void compressedTexSubImage3D2( @@ -1462,23 +1465,23 @@ class RenderingContext2 extends Interceptor void copyTexSubImage3D(int target, int level, int xoffset, int yoffset, int zoffset, int x, int y, int width, int height) native; - Query createQuery() native; + Query? createQuery() native; - Sampler createSampler() native; + Sampler? createSampler() native; - TransformFeedback createTransformFeedback() native; + TransformFeedback? createTransformFeedback() native; - VertexArrayObject createVertexArray() native; + VertexArrayObject? createVertexArray() native; - void deleteQuery(Query query) native; + void deleteQuery(Query? query) native; - void deleteSampler(Sampler sampler) native; + void deleteSampler(Sampler? sampler) native; - void deleteSync(Sync sync) native; + void deleteSync(Sync? sync) native; - void deleteTransformFeedback(TransformFeedback feedback) native; + void deleteTransformFeedback(TransformFeedback? feedback) native; - void deleteVertexArray(VertexArrayObject vertexArray) native; + void deleteVertexArray(VertexArrayObject? vertexArray) native; void drawArraysInstanced(int mode, int first, int count, int instanceCount) native; @@ -1495,64 +1498,64 @@ class RenderingContext2 extends Interceptor void endTransformFeedback() native; - Sync fenceSync(int condition, int flags) native; + Sync? fenceSync(int condition, int flags) native; - void framebufferTextureLayer( - int target, int attachment, Texture texture, int level, int layer) native; + void framebufferTextureLayer(int target, int attachment, Texture? texture, + int level, int layer) native; - String getActiveUniformBlockName(Program program, int uniformBlockIndex) + String? getActiveUniformBlockName(Program program, int uniformBlockIndex) native; - Object getActiveUniformBlockParameter( + Object? getActiveUniformBlockParameter( Program program, int uniformBlockIndex, int pname) native; - Object getActiveUniforms(Program program, List uniformIndices, int pname) - native; + Object? getActiveUniforms( + Program program, List uniformIndices, int pname) native; void getBufferSubData(int target, int srcByteOffset, TypedData dstData, - [int dstOffset, int length]) native; + [int? dstOffset, int? length]) native; int getFragDataLocation(Program program, String name) native; - Object getIndexedParameter(int target, int index) native; + Object? getIndexedParameter(int target, int index) native; - Object getInternalformatParameter(int target, int internalformat, int pname) + Object? getInternalformatParameter(int target, int internalformat, int pname) native; - Object getQuery(int target, int pname) native; + Object? getQuery(int target, int pname) native; - Object getQueryParameter(Query query, int pname) native; + Object? getQueryParameter(Query query, int pname) native; - Object getSamplerParameter(Sampler sampler, int pname) native; + Object? getSamplerParameter(Sampler sampler, int pname) native; - Object getSyncParameter(Sync sync, int pname) native; + Object? getSyncParameter(Sync sync, int pname) native; - ActiveInfo getTransformFeedbackVarying(Program program, int index) native; + ActiveInfo? getTransformFeedbackVarying(Program program, int index) native; int getUniformBlockIndex(Program program, String uniformBlockName) native; - List getUniformIndices(Program program, List uniformNames) { + List? getUniformIndices(Program program, List uniformNames) { List uniformNames_1 = convertDartToNative_StringArray(uniformNames); return _getUniformIndices_1(program, uniformNames_1); } @JSName('getUniformIndices') - List _getUniformIndices_1(Program program, List uniformNames) native; + List? _getUniformIndices_1(Program program, List uniformNames) native; void invalidateFramebuffer(int target, List attachments) native; void invalidateSubFramebuffer(int target, List attachments, int x, int y, int width, int height) native; - bool isQuery(Query query) native; + bool isQuery(Query? query) native; - bool isSampler(Sampler sampler) native; + bool isSampler(Sampler? sampler) native; - bool isSync(Sync sync) native; + bool isSync(Sync? sync) native; - bool isTransformFeedback(TransformFeedback feedback) native; + bool isTransformFeedback(TransformFeedback? feedback) native; - bool isVertexArray(VertexArrayObject vertexArray) native; + bool isVertexArray(VertexArrayObject? vertexArray) native; void pauseTransformFeedback() native; @@ -1561,7 +1564,7 @@ class RenderingContext2 extends Interceptor @JSName('readPixels') void readPixels2(int x, int y, int width, int height, int format, int type, dstData_OR_offset, - [int offset]) native; + [int? offset]) native; void renderbufferStorageMultisample(int target, int samples, int internalformat, int width, int height) native; @@ -1582,7 +1585,7 @@ class RenderingContext2 extends Interceptor int format, int type, bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_srcData_OR_video, - [int srcOffset]) { + [int? srcOffset]) { if ((bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_srcData_OR_video is int) && srcOffset == null) { @@ -1719,7 +1722,7 @@ class RenderingContext2 extends Interceptor int format, int type, bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video, - [int srcOffset]) { + [int? srcOffset]) { if ((bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video is int) && srcOffset == null) { @@ -1867,7 +1870,7 @@ class RenderingContext2 extends Interceptor border, format, type, ImageBitmap bitmap) native; @JSName('texImage3D') void _texImage3D_7(target, level, internalformat, width, height, depth, - border, format, type, TypedData pixels) native; + border, format, type, TypedData? pixels) native; @JSName('texImage3D') void _texImage3D_8(target, level, internalformat, width, height, depth, border, format, type, TypedData pixels, srcOffset) native; @@ -1888,7 +1891,7 @@ class RenderingContext2 extends Interceptor int format, int type, bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_srcData_OR_video, - [int srcOffset]) { + [int? srcOffset]) { if ((bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_srcData_OR_video is int) && srcOffset == null) { @@ -2026,7 +2029,7 @@ class RenderingContext2 extends Interceptor int format, int type, bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video, - [int srcOffset]) { + [int? srcOffset]) { if ((bitmap_OR_canvas_OR_data_OR_image_OR_offset_OR_pixels_OR_video is int) && srcOffset == null) { @@ -2196,93 +2199,93 @@ class RenderingContext2 extends Interceptor native; @JSName('uniform1fv') - void uniform1fv2(UniformLocation location, v, int srcOffset, [int srcLength]) - native; + void uniform1fv2(UniformLocation? location, v, int srcOffset, + [int? srcLength]) native; @JSName('uniform1iv') - void uniform1iv2(UniformLocation location, v, int srcOffset, [int srcLength]) - native; + void uniform1iv2(UniformLocation? location, v, int srcOffset, + [int? srcLength]) native; - void uniform1ui(UniformLocation location, int v0) native; + void uniform1ui(UniformLocation? location, int v0) native; - void uniform1uiv(UniformLocation location, v, [int srcOffset, int srcLength]) - native; + void uniform1uiv(UniformLocation? location, v, + [int? srcOffset, int? srcLength]) native; @JSName('uniform2fv') - void uniform2fv2(UniformLocation location, v, int srcOffset, [int srcLength]) - native; + void uniform2fv2(UniformLocation? location, v, int srcOffset, + [int? srcLength]) native; @JSName('uniform2iv') - void uniform2iv2(UniformLocation location, v, int srcOffset, [int srcLength]) - native; + void uniform2iv2(UniformLocation? location, v, int srcOffset, + [int? srcLength]) native; - void uniform2ui(UniformLocation location, int v0, int v1) native; + void uniform2ui(UniformLocation? location, int v0, int v1) native; - void uniform2uiv(UniformLocation location, v, [int srcOffset, int srcLength]) - native; + void uniform2uiv(UniformLocation? location, v, + [int? srcOffset, int? srcLength]) native; @JSName('uniform3fv') - void uniform3fv2(UniformLocation location, v, int srcOffset, [int srcLength]) - native; + void uniform3fv2(UniformLocation? location, v, int srcOffset, + [int? srcLength]) native; @JSName('uniform3iv') - void uniform3iv2(UniformLocation location, v, int srcOffset, [int srcLength]) - native; + void uniform3iv2(UniformLocation? location, v, int srcOffset, + [int? srcLength]) native; - void uniform3ui(UniformLocation location, int v0, int v1, int v2) native; + void uniform3ui(UniformLocation? location, int v0, int v1, int v2) native; - void uniform3uiv(UniformLocation location, v, [int srcOffset, int srcLength]) - native; + void uniform3uiv(UniformLocation? location, v, + [int? srcOffset, int? srcLength]) native; @JSName('uniform4fv') - void uniform4fv2(UniformLocation location, v, int srcOffset, [int srcLength]) - native; + void uniform4fv2(UniformLocation? location, v, int srcOffset, + [int? srcLength]) native; @JSName('uniform4iv') - void uniform4iv2(UniformLocation location, v, int srcOffset, [int srcLength]) + void uniform4iv2(UniformLocation? location, v, int srcOffset, + [int? srcLength]) native; + + void uniform4ui(UniformLocation? location, int v0, int v1, int v2, int v3) native; - void uniform4ui(UniformLocation location, int v0, int v1, int v2, int v3) - native; - - void uniform4uiv(UniformLocation location, v, [int srcOffset, int srcLength]) - native; + void uniform4uiv(UniformLocation? location, v, + [int? srcOffset, int? srcLength]) native; void uniformBlockBinding( Program program, int uniformBlockIndex, int uniformBlockBinding) native; @JSName('uniformMatrix2fv') void uniformMatrix2fv2( - UniformLocation location, bool transpose, array, int srcOffset, - [int srcLength]) native; + UniformLocation? location, bool transpose, array, int srcOffset, + [int? srcLength]) native; - void uniformMatrix2x3fv(UniformLocation location, bool transpose, value, - [int srcOffset, int srcLength]) native; + void uniformMatrix2x3fv(UniformLocation? location, bool transpose, value, + [int? srcOffset, int? srcLength]) native; - void uniformMatrix2x4fv(UniformLocation location, bool transpose, value, - [int srcOffset, int srcLength]) native; + void uniformMatrix2x4fv(UniformLocation? location, bool transpose, value, + [int? srcOffset, int? srcLength]) native; @JSName('uniformMatrix3fv') void uniformMatrix3fv2( - UniformLocation location, bool transpose, array, int srcOffset, - [int srcLength]) native; + UniformLocation? location, bool transpose, array, int srcOffset, + [int? srcLength]) native; - void uniformMatrix3x2fv(UniformLocation location, bool transpose, value, - [int srcOffset, int srcLength]) native; + void uniformMatrix3x2fv(UniformLocation? location, bool transpose, value, + [int? srcOffset, int? srcLength]) native; - void uniformMatrix3x4fv(UniformLocation location, bool transpose, value, - [int srcOffset, int srcLength]) native; + void uniformMatrix3x4fv(UniformLocation? location, bool transpose, value, + [int? srcOffset, int? srcLength]) native; @JSName('uniformMatrix4fv') void uniformMatrix4fv2( - UniformLocation location, bool transpose, array, int srcOffset, - [int srcLength]) native; + UniformLocation? location, bool transpose, array, int srcOffset, + [int? srcLength]) native; - void uniformMatrix4x2fv(UniformLocation location, bool transpose, value, - [int srcOffset, int srcLength]) native; + void uniformMatrix4x2fv(UniformLocation? location, bool transpose, value, + [int? srcOffset, int? srcLength]) native; - void uniformMatrix4x3fv(UniformLocation location, bool transpose, value, - [int srcOffset, int srcLength]) native; + void uniformMatrix4x3fv(UniformLocation? location, bool transpose, value, + [int? srcOffset, int? srcLength]) native; void vertexAttribDivisor(int index, int divisor) native; @@ -2311,13 +2314,13 @@ class RenderingContext2 extends Interceptor void bindAttribLocation(Program program, int index, String name) native; - void bindBuffer(int target, Buffer buffer) native; + void bindBuffer(int target, Buffer? buffer) native; - void bindFramebuffer(int target, Framebuffer framebuffer) native; + void bindFramebuffer(int target, Framebuffer? framebuffer) native; - void bindRenderbuffer(int target, Renderbuffer renderbuffer) native; + void bindRenderbuffer(int target, Renderbuffer? renderbuffer) native; - void bindTexture(int target, Texture texture) native; + void bindTexture(int target, Texture? texture) native; void blendColor(num red, num green, num blue, num alpha) native; @@ -2376,17 +2379,17 @@ class RenderingContext2 extends Interceptor void cullFace(int mode) native; - void deleteBuffer(Buffer buffer) native; + void deleteBuffer(Buffer? buffer) native; - void deleteFramebuffer(Framebuffer framebuffer) native; + void deleteFramebuffer(Framebuffer? framebuffer) native; - void deleteProgram(Program program) native; + void deleteProgram(Program? program) native; - void deleteRenderbuffer(Renderbuffer renderbuffer) native; + void deleteRenderbuffer(Renderbuffer? renderbuffer) native; - void deleteShader(Shader shader) native; + void deleteShader(Shader? shader) native; - void deleteTexture(Texture texture) native; + void deleteTexture(Texture? texture) native; void depthFunc(int func) native; @@ -2413,10 +2416,10 @@ class RenderingContext2 extends Interceptor void flush() native; void framebufferRenderbuffer(int target, int attachment, - int renderbuffertarget, Renderbuffer renderbuffer) native; + int renderbuffertarget, Renderbuffer? renderbuffer) native; void framebufferTexture2D(int target, int attachment, int textarget, - Texture texture, int level) native; + Texture? texture, int level) native; void frontFace(int mode) native; @@ -2426,13 +2429,13 @@ class RenderingContext2 extends Interceptor ActiveInfo getActiveUniform(Program program, int index) native; - List getAttachedShaders(Program program) native; + List? getAttachedShaders(Program program) native; int getAttribLocation(Program program, String name) native; - Object getBufferParameter(int target, int pname) native; + Object? getBufferParameter(int target, int pname) native; - Map getContextAttributes() { + Map? getContextAttributes() { return convertNativeToDart_Dictionary(_getContextAttributes_1()); } @@ -2441,57 +2444,57 @@ class RenderingContext2 extends Interceptor int getError() native; - Object getExtension(String name) native; + Object? getExtension(String name) native; - Object getFramebufferAttachmentParameter( + Object? getFramebufferAttachmentParameter( int target, int attachment, int pname) native; - Object getParameter(int pname) native; + Object? getParameter(int pname) native; - String getProgramInfoLog(Program program) native; + String? getProgramInfoLog(Program program) native; - Object getProgramParameter(Program program, int pname) native; + Object? getProgramParameter(Program program, int pname) native; - Object getRenderbufferParameter(int target, int pname) native; + Object? getRenderbufferParameter(int target, int pname) native; - String getShaderInfoLog(Shader shader) native; + String? getShaderInfoLog(Shader shader) native; - Object getShaderParameter(Shader shader, int pname) native; + Object? getShaderParameter(Shader shader, int pname) native; ShaderPrecisionFormat getShaderPrecisionFormat( int shadertype, int precisiontype) native; - String getShaderSource(Shader shader) native; + String? getShaderSource(Shader shader) native; - List getSupportedExtensions() native; + List? getSupportedExtensions() native; - Object getTexParameter(int target, int pname) native; + Object? getTexParameter(int target, int pname) native; - Object getUniform(Program program, UniformLocation location) native; + Object? getUniform(Program program, UniformLocation location) native; UniformLocation getUniformLocation(Program program, String name) native; - Object getVertexAttrib(int index, int pname) native; + Object? getVertexAttrib(int index, int pname) native; int getVertexAttribOffset(int index, int pname) native; void hint(int target, int mode) native; - bool isBuffer(Buffer buffer) native; + bool isBuffer(Buffer? buffer) native; bool isContextLost() native; bool isEnabled(int cap) native; - bool isFramebuffer(Framebuffer framebuffer) native; + bool isFramebuffer(Framebuffer? framebuffer) native; - bool isProgram(Program program) native; + bool isProgram(Program? program) native; - bool isRenderbuffer(Renderbuffer renderbuffer) native; + bool isRenderbuffer(Renderbuffer? renderbuffer) native; - bool isShader(Shader shader) native; + bool isShader(Shader? shader) native; - bool isTexture(Texture texture) native; + bool isTexture(Texture? texture) native; void lineWidth(num width) native; @@ -2503,7 +2506,7 @@ class RenderingContext2 extends Interceptor @JSName('readPixels') void _readPixels(int x, int y, int width, int height, int format, int type, - TypedData pixels) native; + TypedData? pixels) native; void renderbufferStorage( int target, int internalformat, int width, int height) native; @@ -2533,9 +2536,9 @@ class RenderingContext2 extends Interceptor int format_OR_width, int height_OR_type, bitmap_OR_border_OR_canvas_OR_image_OR_pixels_OR_video, - [int format, - int type, - TypedData pixels]) { + [int? format, + int? type, + TypedData? pixels]) { if (type != null && format != null && (bitmap_OR_border_OR_canvas_OR_image_OR_pixels_OR_video is int)) { @@ -2622,7 +2625,7 @@ class RenderingContext2 extends Interceptor @JSName('texImage2D') void _texImage2D_1(target, level, internalformat, width, height, int border, - format, type, TypedData pixels) native; + format, type, TypedData? pixels) native; @JSName('texImage2D') void _texImage2D_2(target, level, internalformat, format, type, pixels) native; @@ -2651,8 +2654,8 @@ class RenderingContext2 extends Interceptor int format_OR_width, int height_OR_type, bitmap_OR_canvas_OR_format_OR_image_OR_pixels_OR_video, - [int type, - TypedData pixels]) { + [int? type, + TypedData? pixels]) { if (type != null && (bitmap_OR_canvas_OR_format_OR_image_OR_pixels_OR_video is int)) { _texSubImage2D_1( @@ -2737,7 +2740,7 @@ class RenderingContext2 extends Interceptor @JSName('texSubImage2D') void _texSubImage2D_1(target, level, xoffset, yoffset, width, height, - int format, type, TypedData pixels) native; + int format, type, TypedData? pixels) native; @JSName('texSubImage2D') void _texSubImage2D_2(target, level, xoffset, yoffset, format, type, pixels) native; @@ -2754,45 +2757,48 @@ class RenderingContext2 extends Interceptor void _texSubImage2D_6( target, level, xoffset, yoffset, format, type, ImageBitmap bitmap) native; - void uniform1f(UniformLocation location, num x) native; + void uniform1f(UniformLocation? location, num x) native; - void uniform1fv(UniformLocation location, v) native; + void uniform1fv(UniformLocation? location, v) native; - void uniform1i(UniformLocation location, int x) native; + void uniform1i(UniformLocation? location, int x) native; - void uniform1iv(UniformLocation location, v) native; + void uniform1iv(UniformLocation? location, v) native; - void uniform2f(UniformLocation location, num x, num y) native; + void uniform2f(UniformLocation? location, num x, num y) native; - void uniform2fv(UniformLocation location, v) native; + void uniform2fv(UniformLocation? location, v) native; - void uniform2i(UniformLocation location, int x, int y) native; + void uniform2i(UniformLocation? location, int x, int y) native; - void uniform2iv(UniformLocation location, v) native; + void uniform2iv(UniformLocation? location, v) native; - void uniform3f(UniformLocation location, num x, num y, num z) native; + void uniform3f(UniformLocation? location, num x, num y, num z) native; - void uniform3fv(UniformLocation location, v) native; + void uniform3fv(UniformLocation? location, v) native; - void uniform3i(UniformLocation location, int x, int y, int z) native; + void uniform3i(UniformLocation? location, int x, int y, int z) native; - void uniform3iv(UniformLocation location, v) native; + void uniform3iv(UniformLocation? location, v) native; - void uniform4f(UniformLocation location, num x, num y, num z, num w) native; + void uniform4f(UniformLocation? location, num x, num y, num z, num w) native; - void uniform4fv(UniformLocation location, v) native; + void uniform4fv(UniformLocation? location, v) native; - void uniform4i(UniformLocation location, int x, int y, int z, int w) native; + void uniform4i(UniformLocation? location, int x, int y, int z, int w) native; - void uniform4iv(UniformLocation location, v) native; + void uniform4iv(UniformLocation? location, v) native; - void uniformMatrix2fv(UniformLocation location, bool transpose, array) native; + void uniformMatrix2fv(UniformLocation? location, bool transpose, array) + native; - void uniformMatrix3fv(UniformLocation location, bool transpose, array) native; + void uniformMatrix3fv(UniformLocation? location, bool transpose, array) + native; - void uniformMatrix4fv(UniformLocation location, bool transpose, array) native; + void uniformMatrix4fv(UniformLocation? location, bool transpose, array) + native; - void useProgram(Program program) native; + void useProgram(Program? program) native; void validateProgram(Program program) native; diff --git a/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart b/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart index 96107715628..f97b55eec2a 100644 --- a/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart +++ b/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart @@ -1,5 +1,3 @@ -// @dart = 2.6 - /** * An API for storing data in the browser that can be queried with SQL. * @@ -99,9 +97,9 @@ class SqlDatabase extends Interceptor { * * [Database.changeVersion](http://www.w3.org/TR/webdatabase/#dom-database-changeversion) from W3C. */ void _changeVersion(String oldVersion, String newVersion, - [SqlTransactionCallback callback, - SqlTransactionErrorCallback errorCallback, - VoidCallback successCallback]) native; + [SqlTransactionCallback? callback, + SqlTransactionErrorCallback? errorCallback, + VoidCallback? successCallback]) native; @JSName('changeVersion') /** @@ -130,8 +128,8 @@ class SqlDatabase extends Interceptor { @JSName('readTransaction') void _readTransaction(SqlTransactionCallback callback, - [SqlTransactionErrorCallback errorCallback, - VoidCallback successCallback]) native; + [SqlTransactionErrorCallback? errorCallback, + VoidCallback? successCallback]) native; @JSName('readTransaction') Future readTransaction() { @@ -145,8 +143,8 @@ class SqlDatabase extends Interceptor { } void transaction(SqlTransactionCallback callback, - [SqlTransactionErrorCallback errorCallback, - VoidCallback successCallback]) native; + [SqlTransactionErrorCallback? errorCallback, + VoidCallback? successCallback]) native; @JSName('transaction') Future transaction_future() { @@ -226,7 +224,7 @@ class SqlResultSetRowList extends Interceptor Map operator [](int index) { if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length)) throw new RangeError.index(index, this); - return this.item(index); + return this.item(index)!; } void operator []=(int index, Map value) { @@ -266,7 +264,7 @@ class SqlResultSetRowList extends Interceptor Map elementAt(int index) => this[index]; // -- end List mixins. - Map item(int index) { + Map? item(int index) { return convertNativeToDart_Dictionary(_item_1(index)); } @@ -290,12 +288,12 @@ class SqlTransaction extends Interceptor { @JSName('executeSql') void _executeSql(String sqlStatement, - [List arguments, - SqlStatementCallback callback, - SqlStatementErrorCallback errorCallback]) native; + [List? arguments, + SqlStatementCallback? callback, + SqlStatementErrorCallback? errorCallback]) native; @JSName('executeSql') - Future executeSql(String sqlStatement, [List arguments]) { + Future executeSql(String sqlStatement, [List? arguments]) { var completer = new Completer(); _executeSql(sqlStatement, arguments, (transaction, resultSet) { applyExtension('SQLResultSet', resultSet); diff --git a/sdk_args.gni b/sdk_args.gni index eb4017ed098..94e6b7a8eed 100644 --- a/sdk_args.gni +++ b/sdk_args.gni @@ -5,12 +5,6 @@ _dart_root = get_path_info(".", "abspath") declare_args() { - # Whether to build a Legacy SDK using Legacy core libraries. - # TODO(38701): Remove dont_use_nnbd once the NNBD SDK is stable/performant - # and there is no need to build a legacy version of the SDK for comparison - # purposes. - dont_use_nnbd = false - # Absolute path to the .git folder. # # This is used in rules that need to refer to `.git/logs/HEAD` to include diff --git a/sdk_nnbd/BUILD.gn b/sdk_nnbd/BUILD.gn deleted file mode 100644 index 5354079d5f6..00000000000 --- a/sdk_nnbd/BUILD.gn +++ /dev/null @@ -1,958 +0,0 @@ -# Copyright (c) 2017, 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. - -# This GN file contains build rules for assembling the Dart SDK. There are -# two possible variants: the "Full" SDK, and the "Platform" SDK. If you want -# to make a new subset of the Full SDK, make it the same way we make -# the Platform SDK. -# -# Warning: -# If you need to copy something into dart-sdk/lib/foo in addition to the stuff -# copied there by :copy_libraries, then you must depend on ":copy_libraries", -# or ":copy_libraries" may delete/overwrite your addition, and the build will -# fail. - -import("../build/dart/copy_tree.gni") -import("../runtime/runtime_args.gni") -import("../sdk_args.gni") - -declare_args() { - # Build a SDK with less stuff. It excludes dart2js, ddc, and web libraries. - dart_platform_sdk = true - - # Whether to include dart2native in the "create_sdk" target. - include_dart2native = false - - # Path to stripped dart binaries relative to build output directory. - dart_stripped_binary = "dart" - dart_precompiled_runtime_stripped_binary = "dart_precompiled_runtime" - gen_snapshot_stripped_binary = "gen_snapshot" -} - -# The directory layout of the SDK is as follows: -# -# ..dart-sdk/ -# ....bin/ -# ......dart or dart.exe (executable) -# ......dart.lib (import library for VM native extensions on Windows) -# ......dartaotruntime or dartaotruntime.exe (executable) -# ......dartdoc -# ......dartfmt -# ......dart2native (if `include_dart2native` and not on ia32) -# ......dart2js -# ......dartanalyzer -# ......dartdevc -# ......utils/gen_snapshot or utils/gen_snapshot.exe (if `include_dart2native` and not on ia32) -# ......pub -# ......snapshots/ -# ........analysis_server.dart.snapshot -# ........dart2js.dart.snapshot -# ........dartanalyzer.dart.snapshot -# ........dartdev.dart.snapshot -# ........dartdoc.dart.snapshot -# ........dartfmt.dart.snapshot -# ........dartdevc.dart.snapshot -# ........gen_kernel.dart.snapshot (if `include_dart2native` and not on ia32) -# ........dart2native.dart.snapshot (if `include_dart2native` and not on ia32) -# ........kernel_worker.dart.snapshot -# ........pub.dart.snapshot -# ........frontend_server.dart.snapshot -# ......resources/ -# ........dartdoc/ -# ...........packages -# ..........resources/ -# ..........templates/ -# ......model/ -# ........lexeme/ -# ..........idx2word.json -# ..........model.tflite -# ..........word2idx.json -# ....include/ -# ......dart_api.h -# ......dart_native_api.h -# ......dart_tools_api.h -# ....lib/ -# ......libraries.json -# ......_internal/ -# ........strong.sum -# ........dart2js_platform.dill -# ........dart2js_server_platform.dill -# ........dart2js_platform_strong.dill -# ........dart2js_server_platform_strong.dill -# ........vm_platform_strong.dill -# ........dev_compiler/ -# ......async/ -# ......collection/ -# ......convert/ -# ......core/ -# ......html/ -# ......_http/ -# ......internal/ -# ......io/ -# ......isolate/ -# ......js/ -# ......js_util/ -# ......math/ -# ......mirrors/ -# ......typed_data/ -# ......wasm/ -# ......api_readme.md - -# Scripts that go under bin/ -_platform_sdk_scripts = [ - "dartanalyzer", - "dartfmt", - "pub", -] - -_full_sdk_scripts = [ - "dart2js", - "dartanalyzer", - "dartdevc", - "dartfmt", - "pub", -] - -# Scripts not ending in _sdk that go under bin/ -_scripts = [ "dartdoc" ] - -# Snapshots that go under bin/snapshots -_platform_sdk_snapshots = [ - [ - "dartanalyzer", - "../utils/dartanalyzer:generate_dartanalyzer_snapshot", - ], - [ - "dartdev", - "../utils/dartdev:generate_dartdev_snapshot", - ], - [ - "dartdoc", - "../utils/dartdoc", - ], - [ - "dartfmt", - "../utils/dartfmt", - ], - [ - "pub", - "../utils/pub", - ], -] -if (include_dart2native && dart_target_arch != "ia32") { - _platform_sdk_snapshots += [ [ - "dart2native", - "../utils/dart2native:generate_dart2native_snapshot", - ] ] -} -if (create_kernel_service_snapshot) { - _platform_sdk_snapshots += [ [ - "kernel-service", - "../utils/kernel-service:kernel-service_snapshot", - ] ] -} -if (dart_target_arch != "arm") { - _platform_sdk_snapshots += [ [ - "analysis_server", - "../utils/analysis_server", - ] ] -} - -_full_sdk_snapshots = [ - [ - "dart2js", - "../utils/compiler:dart2js", - ], - [ - "dartanalyzer", - "../utils/dartanalyzer:generate_dartanalyzer_snapshot", - ], - [ - "dartdev", - "../utils/dartdev:generate_dartdev_snapshot", - ], - [ - "dartdevc", - "../utils/dartdevc", - ], - [ - "dartdoc", - "../utils/dartdoc", - ], - [ - "dartfmt", - "../utils/dartfmt", - ], - [ - "kernel_worker", - "../utils/bazel:kernel_worker", - ], - [ - "pub", - "../utils/pub", - ], - [ - "frontend_server", - "../utils/kernel-service:frontend_server", - ], -] -if (include_dart2native && dart_target_arch != "ia32") { - _full_sdk_snapshots += [ [ - "dart2native", - "../utils/dart2native:generate_dart2native_snapshot", - ] ] -} -if (create_kernel_service_snapshot) { - _full_sdk_snapshots += [ [ - "kernel-service", - "../utils/kernel-service:kernel-service_snapshot", - ] ] -} -if (dart_target_arch != "arm") { - _full_sdk_snapshots += [ [ - "analysis_server", - "../utils/analysis_server", - ] ] -} - -# Libraries that go under lib/ -_full_sdk_libraries = [ - "_internal", - "async", - "cli", - "collection", - "convert", - "core", - "developer", - "ffi", - "html", - "_http", - "indexed_db", - "internal", - "io", - "isolate", - "js", - "js_util", - "math", - "mirrors", - "svg", - "typed_data", - "wasm", - "web_audio", - "web_gl", - "web_sql", -] - -# Apps running on the platform SDK shouldn't be using Dart4Web libraries, but -# the analyzer and dartdoc expect all the library sources to be present. -# -# _platform_sdk_libraries = [ -# "_internal", -# "async", -# "cli", -# "collection", -# "convert", -# "core", -# "developer", -# "html", -# "_http", -# "internal", -# "io", -# "isolate", -# "math", -# "mirrors", -# "typed_data", -# ] -_platform_sdk_libraries = _full_sdk_libraries - -# From here down to the copy_trees() invocation, we collect all the information -# about trees that need to be copied in the list of scopes, copy_tree_specs. -copy_tree_specs = [] - -# This rule copies dartdoc templates to -# bin/resources/dartdoc/templates -copy_tree_specs += [ - { - target = "copy_dartdoc_templates" - visibility = [ ":copy_dartdoc_files" ] - source = "../third_party/pkg/dartdoc/lib/templates" - dest = "$root_out_dir/dart-sdk/bin/resources/dartdoc/templates" - ignore_patterns = "{}" - }, -] - -# This rule copies dartdoc resources to -# bin/resources/dartdoc/resources -copy_tree_specs += [ - { - target = "copy_dartdoc_resources" - visibility = [ ":copy_dartdoc_files" ] - source = "../third_party/pkg/dartdoc/lib/resources" - dest = "$root_out_dir/dart-sdk/bin/resources/dartdoc/resources" - ignore_patterns = "{}" - }, -] - -# This loop generates rules to copy libraries to lib/ -foreach(library, _full_sdk_libraries) { - copy_tree_specs += [ - { - target = "copy_${library}_library" - visibility = [ - ":copy_platform_sdk_libraries", - ":copy_full_sdk_libraries", - ] - source = "lib/$library" - dest = "$root_out_dir/dart-sdk/lib/$library" - ignore_patterns = "*.svn,doc,*.py,*.gypi,*.sh,.gitignore" - }, - ] -} - -if (is_win) { - copy_tree_specs += [ - { - target = "copy_7zip" - visibility = [ ":create_common_sdk" ] - deps = [ ":copy_libraries" ] - source = "../third_party/7zip" - dest = "$root_out_dir/dart-sdk/lib/_internal/pub/asset/7zip" - ignore_patterns = ".svn" - }, - ] -} - -if (target_cpu == "x64") { - copy_tree_specs += [ - { - target = "copy_language_model" - visibility = [ ":create_common_sdk" ] - deps = [ ":copy_libraries" ] - source = "../pkg/analysis_server/language_model" - dest = "$root_out_dir/dart-sdk/bin/model" - ignore_patterns = "{}" - }, - ] - if (is_linux || is_android) { - copy_tree_specs += [ - { - target = "copy_libtensorflowlite_c" - visibility = [ ":create_common_sdk" ] - deps = [ ":copy_libraries" ] - source = "../third_party/pkg/tflite_native/lib/src/blobs" - dest = "$root_out_dir/dart-sdk/bin/snapshots" - ignore_patterns = "*.dll,*mac64.so" - }, - ] - } - if (is_mac) { - copy_tree_specs += [ - { - target = "copy_libtensorflowlite_c" - visibility = [ ":create_common_sdk" ] - deps = [ ":copy_libraries" ] - source = "../third_party/pkg/tflite_native/lib/src/blobs" - dest = "$root_out_dir/dart-sdk/bin/snapshots" - ignore_patterns = "*.dll,*linux64.so" - }, - ] - } - if (is_win) { - copy_tree_specs += [ - { - target = "copy_libtensorflowlite_c" - visibility = [ ":create_common_sdk" ] - deps = [ ":copy_libraries" ] - source = "../third_party/pkg/tflite_native/lib/src/blobs" - dest = "$root_out_dir/dart-sdk/bin/snapshots" - ignore_patterns = "*.so" - }, - ] - } -} - -# This generates targets for everything in copy_tree_specs. The targets have the -# same name as the "target" fields in the scopes of copy_tree_specs. -copy_trees("copy_trees") { - sources = copy_tree_specs -} - -# Copies the Dart VM binary into bin/ -if (target_os != current_os && target_os == "fuchsia") { - # In the Fuchsia build, this has to use a symlink for two reasons. - # First, it makes the lookup of shared libraries relative to $ORIGIN - # (Linux) or @loader_path (macOS) find the libraries where they are, - # since those lookups use the directory of the symlink target rather - # than of the link itself (as they would for a copy or hard link). - # Second, when the dart binary is built as a "variant" (e.g. with a - # sanitizer), then $root_out_dir/dart is itself a symlink to the real - # binary in the selected variant toolchain's $root_out_dir and since - # the "copy" tool is actually a hard link rather than a copy, it will - # make a link to the symlink rather than the symlink's target, and the - # relative symlink interpreted from a different containing directory - # will not find the actual binary. - action("copy_dart") { - visibility = [ ":create_common_sdk" ] - dart_label = "../runtime/bin:dart" - deps = [ dart_label ] - dart_out = get_label_info(dart_label, "root_out_dir") - sources = [ "$dart_out/$dart_stripped_binary" ] - outputs = [ "$root_out_dir/dart-sdk/bin/$dart_stripped_binary" ] - script = "/bin/ln" - args = [ - "-snf", - rebase_path(sources[0], get_path_info(outputs[0], "dir")), - rebase_path(outputs[0]), - ] - } -} else { - copy("copy_dart") { - visibility = [ ":create_common_sdk" ] - deps = [ "../runtime/bin:dart" ] - dart_out = get_label_info("../runtime/bin:dart", "root_out_dir") - if (is_win) { - sources = [ "$dart_out/dart.exe" ] - } else { - sources = [ "$dart_out/$dart_stripped_binary" ] - } - if (is_win) { - sources += [ "$dart_out/dart.lib" ] - } - outputs = [ "$root_out_dir/dart-sdk/bin/{{source_file_part}}" ] - } -} - -copy("copy_dartaotruntime") { - deps = [ "../runtime/bin:dart_precompiled_runtime" ] - dartaotruntime_out = - get_label_info("../runtime/bin:dart_precompiled_runtime", "root_out_dir") - if (is_win) { - sources = [ "$dartaotruntime_out/dart_precompiled_runtime.exe" ] - outputs = [ "$root_out_dir/dart-sdk/bin/dartaotruntime.exe" ] - } else { - sources = - [ "$dartaotruntime_out/$dart_precompiled_runtime_stripped_binary" ] - outputs = [ "$root_out_dir/dart-sdk/bin/dartaotruntime" ] - } -} - -copy("copy_gen_snapshot") { - deps = [ "../runtime/bin:gen_snapshot" ] - gen_snapshot_out = - get_label_info("../runtime/bin:gen_snapshot", "root_out_dir") - if (is_win) { - sources = [ "$gen_snapshot_out/gen_snapshot.exe" ] - } else { - sources = [ "$gen_snapshot_out/$gen_snapshot_stripped_binary" ] - } - outputs = [ "$root_out_dir/dart-sdk/bin/utils/{{source_file_part}}" ] -} - -copy("copy_dart2native") { - deps = [ - ":copy_dartaotruntime", - ":copy_gen_kernel_snapshot", - ":copy_gen_snapshot", - ] - ext = "" - if (is_win) { - ext = ".bat" - } - sources = [ "bin/dart2native$ext" ] - outputs = [ "$root_out_dir/dart-sdk/bin/{{source_file_part}}" ] -} - -copy("copy_gen_kernel_snapshot") { - deps = [ "../utils/gen_kernel" ] - sources = [ "$root_gen_dir/gen_kernel.dart.snapshot" ] - outputs = [ "$root_out_dir/dart-sdk/bin/snapshots/{{source_file_part}}" ] -} - -# A template for copying the things in _platform_sdk_scripts and -# _full_sdk_scripts into bin/ -template("copy_sdk_script") { - assert(defined(invoker.name), "copy_sdk_script must define 'name'") - name = invoker.name - ext = "" - if (is_win) { - ext = ".bat" - } - copy(target_name) { - visibility = [ - ":copy_platform_sdk_scripts", - ":copy_full_sdk_scripts", - ] - sources = [ "bin/${name}_sdk$ext" ] - outputs = [ "$root_out_dir/dart-sdk/bin/$name$ext" ] - } -} - -foreach(sdk_script, _full_sdk_scripts) { - copy_sdk_script("copy_${sdk_script}_script") { - name = sdk_script - } -} - -foreach(script, _scripts) { - copy("copy_${script}_script") { - visibility = [ - ":copy_platform_sdk_scripts", - ":copy_full_sdk_scripts", - ] - ext = "" - if (is_win) { - ext = ".bat" - } - sources = [ "bin/$script$ext" ] - outputs = [ "$root_out_dir/dart-sdk/bin/{{source_file_part}}" ] - } -} - -# This is the main target for copying scripts in _platform_sdk_scripts to bin/ -group("copy_platform_sdk_scripts") { - visibility = [ ":_create_platform_sdk" ] - public_deps = [] - foreach(sdk_script, _platform_sdk_scripts) { - public_deps += [ ":copy_${sdk_script}_script" ] - } - foreach(script, _scripts) { - public_deps += [ ":copy_${script}_script" ] - } -} - -# This is the main target for copying scripts in _full_sdk_scripts to bin/ -group("copy_full_sdk_scripts") { - visibility = [ ":create_full_sdk" ] - public_deps = [] - foreach(sdk_script, _full_sdk_scripts) { - public_deps += [ ":copy_${sdk_script}_script" ] - } - foreach(script, _scripts) { - public_deps += [ ":copy_${script}_script" ] - } -} - -# This loop generates "copy" targets that put snapshots into bin/snapshots -foreach(snapshot, _full_sdk_snapshots) { - root = root_gen_dir - - # The frontend_server is output to root_out_dir so that it doesn't conflict - # with the flutter snapshot by the same name under root_gen_dir. - if (snapshot[0] == "frontend_server") { - root = root_out_dir - } - copy("copy_${snapshot[0]}_snapshot") { - visibility = [ - ":copy_platform_sdk_snapshots", - ":copy_full_sdk_snapshots", - ] - deps = [ snapshot[1] ] - sources = [ "$root/${snapshot[0]}.dart.snapshot" ] - outputs = [ "$root_out_dir/dart-sdk/bin/snapshots/{{source_file_part}}" ] - } -} - -# This is the main rule for copying snapshots from _platform_sdk_snapshots to -# bin/snapshots -group("copy_platform_sdk_snapshots") { - visibility = [ ":_create_platform_sdk" ] - public_deps = [] - foreach(snapshot, _platform_sdk_snapshots) { - public_deps += [ ":copy_${snapshot[0]}_snapshot" ] - } -} - -# This is the main rule for copying snapshots from _full_sdk_snapshots to -# bin/snapshots -group("copy_full_sdk_snapshots") { - visibility = [ ":create_full_sdk" ] - public_deps = [] - foreach(snapshot, _full_sdk_snapshots) { - public_deps += [ ":copy_${snapshot[0]}_snapshot" ] - } -} - -# This rule writes the .packages file for dartdoc resources. -write_file("$root_out_dir/dart-sdk/bin/resources/dartdoc/.packages", - "dartdoc:.") - -# This is the main rule for copying the files that dartdoc needs. -group("copy_dartdoc_files") { - visibility = [ ":create_common_sdk" ] - public_deps = [ - ":copy_dartdoc_resources", - ":copy_dartdoc_templates", - ] -} - -# This rule copies analyzer summaries to lib/_internal -copy("copy_analysis_summaries") { - visibility = [ ":create_common_sdk" ] - deps = [ - ":copy_libraries", - "../utils/dartanalyzer:generate_summary_strong", - ] - sources = [ "$root_gen_dir/strong.sum" ] - outputs = [ "$root_out_dir/dart-sdk/lib/_internal/{{source_file_part}}" ] -} - -# This rule copies dill files to lib/_internal. -copy("copy_vm_dill_files") { - visibility = [ ":create_common_sdk" ] - deps = [ - ":copy_libraries", - "../runtime/vm:kernel_platform_files", - ] - sources = [ "$root_out_dir/vm_platform_strong.dill" ] - outputs = [ "$root_out_dir/dart-sdk/lib/_internal/{{source_file_part}}" ] -} - -copy("copy_abi_dill_files") { - visibility = [ ":create_sdk_with_abi_versions" ] - sources = [ "../tools/abiversions" ] - outputs = [ "$root_out_dir/dart-sdk/lib/_internal/abiversions" ] -} - -copy("copy_dart2js_dill_files") { - visibility = [ ":create_full_sdk" ] - deps = [ - ":copy_libraries", - "../utils/compiler:compile_dart2js_nnbd_strong_platform", - "../utils/compiler:compile_dart2js_platform", - "../utils/compiler:compile_dart2js_server_nnbd_strong_platform", - "../utils/compiler:compile_dart2js_server_platform", - ] - sources = [ - "$root_out_dir/dart2js_nnbd_strong_platform.dill", - "$root_out_dir/dart2js_platform.dill", - "$root_out_dir/dart2js_server_nnbd_strong_platform.dill", - "$root_out_dir/dart2js_server_platform.dill", - ] - outputs = [ "$root_out_dir/dart-sdk/lib/_internal/{{source_file_part}}" ] -} - -# Copies DDC's SDK outline .dill to lib/_internal -copy("copy_dev_compiler_outline") { - visibility = [ ":copy_dev_compiler_sdk" ] - deps = [ - ":copy_libraries", - "../utils/dartdevc:dartdevc_platform", - ] - sources = [ "$root_out_dir/ddc_outline.dill" ] - - # TODO(nshahan) Fix the name here to be consistent and merge with below. - outputs = [ "$root_out_dir/dart-sdk/lib/_internal/ddc_sdk.dill" ] -} - -# Copies DDC's SDK outline .dill with sound null safety to lib/_internal -copy("copy_dev_compiler_outline_sound") { - visibility = [ "../utils/dartdevc:dartdevc_test" ] - deps = [ - ":copy_libraries", - "../utils/dartdevc:dartdevc_platform_sound", - ] - sources = [ "$root_out_dir/ddc_outline_sound.dill" ] - outputs = [ "$root_out_dir/dart-sdk/lib/_internal/{{source_file_part}}" ] -} - -# This rule copies DDK's JS SDK and require.js to lib/dev_compiler/kernel/amd. -copy("copy_dev_compiler_js_amd_kernel") { - visibility = [ ":copy_dev_compiler_js" ] - deps = [ "../utils/dartdevc:dartdevc_kernel_sdk" ] - gen_dir = - get_label_info("../utils/dartdevc:dartdevc_kernel_sdk", "target_gen_dir") - sources = [ - "$gen_dir/kernel/amd/dart_sdk.js", - "$gen_dir/kernel/amd/dart_sdk.js.map", - "../third_party/requirejs/require.js", - ] - outputs = [ - "$root_out_dir/dart-sdk/lib/dev_compiler/kernel/amd/{{source_file_part}}", - ] -} - -# This rule copies DDK's JS SDK to lib/dev_compiler/kernel/common. -copy("copy_dev_compiler_js_common_kernel") { - visibility = [ ":copy_dev_compiler_js" ] - deps = [ "../utils/dartdevc:dartdevc_kernel_sdk" ] - gen_dir = - get_label_info("../utils/dartdevc:dartdevc_kernel_sdk", "target_gen_dir") - sources = [ - "$gen_dir/kernel/common/dart_sdk.js", - "$gen_dir/kernel/common/dart_sdk.js.map", - "../pkg/dev_compiler/lib/js/common/run.js", - ] - outputs = [ "$root_out_dir/dart-sdk/lib/dev_compiler/kernel/common/{{source_file_part}}" ] -} - -# This rule copies DDK's JS SDK to lib/dev_compiler/kernel/es6. -copy("copy_dev_compiler_js_es6_kernel") { - visibility = [ ":copy_dev_compiler_js" ] - deps = [ "../utils/dartdevc:dartdevc_kernel_sdk" ] - gen_dir = - get_label_info("../utils/dartdevc:dartdevc_kernel_sdk", "target_gen_dir") - sources = [ - "$gen_dir/kernel/es6/dart_sdk.js", - "$gen_dir/kernel/es6/dart_sdk.js.map", - ] - outputs = [ - "$root_out_dir/dart-sdk/lib/dev_compiler/kernel/es6/{{source_file_part}}", - ] -} - -# Copies all of the JS artifacts needed by DDC. -group("copy_dev_compiler_js") { - visibility = [ - ":copy_dev_compiler_sdk", - ":copy_dev_compiler_tools", - ] - public_deps = [ - ":copy_dev_compiler_js_amd_kernel", - ":copy_dev_compiler_js_common_kernel", - ":copy_dev_compiler_js_es6_kernel", - ] -} - -# This rule copies tools to go along with ddc. -copy("copy_dev_compiler_tools") { - visibility = [ ":copy_dev_compiler_sdk" ] - deps = [ - ":copy_dev_compiler_js", - "../utils/dartdevc:stack_trace_mapper", - ] - dart_out = - get_label_info("../utils/dartdevc:stack_trace_mapper", "root_out_dir") - sources = [ "$dart_out/dev_compiler/build/web/dart_stack_trace_mapper.js" ] - outputs = - [ "$root_out_dir/dart-sdk/lib/dev_compiler/web/{{source_file_part}}" ] -} - -# This is the main rule for copying ddc's dependencies to lib/ -group("copy_dev_compiler_sdk") { - visibility = [ ":create_full_sdk" ] - public_deps = [ - ":copy_dev_compiler_js", - ":copy_dev_compiler_outline", - ":copy_dev_compiler_tools", - ] -} - -# This rule copies header files to include/ -copy("copy_headers") { - visibility = [ ":create_common_sdk" ] - sources = [ - "../runtime/include/dart_api.h", - "../runtime/include/dart_native_api.h", - "../runtime/include/dart_tools_api.h", - ] - outputs = [ "$root_out_dir/dart-sdk/include/{{source_file_part}}" ] -} - -# This rule copies libraries.json files to lib/ -copy("copy_libraries_specification") { - visibility = [ ":create_common_sdk" ] - sources = [ "lib/libraries.json" ] - deps = [ ":copy_libraries" ] - outputs = [ "$root_out_dir/dart-sdk/lib/{{source_file_part}}" ] -} - -# This is the main rule to copy libraries in _platform_sdk_libraries to lib/ -group("copy_platform_sdk_libraries") { - visibility = [ - ":_create_platform_sdk", - ":copy_libraries", - ] - public_deps = [] - foreach(library, _platform_sdk_libraries) { - public_deps += [ ":copy_${library}_library" ] - } -} - -# This is the main rule to copy libraries in _full_sdk_libraries to lib/ -group("copy_full_sdk_libraries") { - visibility = [ - ":create_full_sdk", - ":copy_libraries", - ] - public_deps = [] - foreach(library, _full_sdk_libraries) { - public_deps += [ ":copy_${library}_library" ] - } -} - -group("copy_libraries") { - if (dart_platform_sdk) { - public_deps = [ ":copy_platform_sdk_libraries" ] - } else { - public_deps = [ ":copy_full_sdk_libraries" ] - } -} - -# This rule writes the version file. -action("write_version_file") { - visibility = [ ":create_common_sdk" ] - inputs = [ - "../tools/VERSION", - "$default_git_folder/logs/HEAD", - ] - output = "$root_out_dir/dart-sdk/version" - outputs = [ output ] - script = "../tools/write_version_file.py" - args = [ - "--output", - rebase_path(output), - ] -} - -# This rule writes the revision file. -action("write_revision_file") { - visibility = [ ":create_common_sdk" ] - inputs = [ "$default_git_folder/logs/HEAD" ] - output = "$root_out_dir/dart-sdk/revision" - outputs = [ output ] - script = "../tools/write_revision_file.py" - args = [ - "--output", - rebase_path(output), - ] -} - -# Copy libraries.dart to lib/_internal/libraries.dart for backwards -# compatibility. -# -# TODO(sigmund): stop copying libraries.dart. Old versions (<=0.25.1-alpha.4) -# of the analyzer package do not support the new location of this file. We -# should be able to remove the old file once we release a newer version of -# analyzer and popular frameworks have migrated to use it. -copy("copy_libraries_dart") { - visibility = [ ":create_common_sdk" ] - deps = [ ":copy_libraries" ] - sources = [ "lib/_internal/sdk_library_metadata/lib/libraries.dart" ] - outputs = [ "$root_out_dir/dart-sdk/lib/_internal/{{source_file_part}}" ] -} - -# This rule copies the README file. -copy("copy_readme") { - visibility = [ ":create_common_sdk" ] - sources = [ "../README.dart-sdk" ] - outputs = [ "$root_out_dir/dart-sdk/README" ] -} - -# This rule copies the LICENSE file. -copy("copy_license") { - visibility = [ ":create_common_sdk" ] - sources = [ "../LICENSE" ] - outputs = [ "$root_out_dir/dart-sdk/LICENSE" ] -} - -# This rule generates a custom dartdoc_options.yaml file. -action("write_dartdoc_options") { - visibility = [ ":create_common_sdk" ] - inputs = [ "$default_git_folder/logs/HEAD" ] - output = "$root_out_dir/dart-sdk/dartdoc_options.yaml" - outputs = [ output ] - script = "../tools/write_dartdoc_options_file.py" - args = [ - "--output", - rebase_path(output), - ] -} - -# This rule copies the API readme file to lib/ -copy("copy_api_readme") { - visibility = [ ":create_common_sdk" ] - sources = [ "api_readme.md" ] - outputs = [ "$root_out_dir/dart-sdk/lib/api_readme.md" ] -} - -# Parts common to both platform and full SDKs. -group("create_common_sdk") { - visibility = [ - ":create_sdk", - ":create_platform_sdk", - ] - public_deps = [ - ":copy_analysis_summaries", - ":copy_api_readme", - ":copy_dart", - ":copy_dartdoc_files", - ":copy_headers", - ":copy_libraries_dart", - ":copy_libraries_specification", - ":copy_license", - ":copy_readme", - ":copy_vm_dill_files", - ":write_dartdoc_options", - ":write_revision_file", - ":write_version_file", - ] - - # We do not support AOT on ia32 and should therefore not add the - # dart2native script (since there is no AOT compiler/runtime available) - if (include_dart2native && dart_target_arch != "ia32") { - public_deps += [ ":copy_dart2native" ] - } - - if (is_win) { - public_deps += [ ":copy_7zip" ] - } - if (target_cpu == "x64") { - public_deps += [ - ":copy_language_model", - ":copy_libtensorflowlite_c", - ] - } -} - -# Parts specific to the platform SDK. -group("_create_platform_sdk") { - visibility = [ - ":create_sdk", - ":create_platform_sdk", - ] - public_deps = [ - ":copy_platform_sdk_libraries", - ":copy_platform_sdk_scripts", - ":copy_platform_sdk_snapshots", - ] -} - -# Parts specific to the full SDK. -group("create_full_sdk") { - visibility = [ ":create_sdk" ] - - public_deps = [ - ":copy_dart2js_dill_files", - ":copy_dev_compiler_sdk", - ":copy_full_sdk_libraries", - ":copy_full_sdk_scripts", - ":copy_full_sdk_snapshots", - ] -} - -# Build a SDK with less stuff. It excludes dart2js, ddc, and web libraries. -group("create_platform_sdk") { - public_deps = [ - ":_create_platform_sdk", - ":create_common_sdk", - ] -} - -# The main target to depend on from ../BUILD.gn -group("create_sdk") { - public_deps = [ ":create_common_sdk" ] - if (dart_platform_sdk) { - public_deps += [ ":_create_platform_sdk" ] - } else { - public_deps += [ ":create_full_sdk" ] - } -} - -# Same as create_sdk, but with abi version files. -group("create_sdk_with_abi_versions") { - public_deps = [ - ":copy_abi_dill_files", - ":create_sdk", - ] -} diff --git a/sdk_nnbd/api_readme.md b/sdk_nnbd/api_readme.md deleted file mode 100644 index 60f763b5804..00000000000 --- a/sdk_nnbd/api_readme.md +++ /dev/null @@ -1,31 +0,0 @@ -Welcome to the [Dart](https://dart.dev/) API reference documentation, covering -the [Dart core libraries](https://dart.dev/guides/libraries). These include: - - * [dart:core](dart-core/dart-core-library.html): Core functionality such as - strings, numbers, collections, errors, dates, and URIs. - * [dart:html](dart-html/dart-html-library.html): DOM manipulation for web apps - (available only to web apps). - * [dart:io](dart-io/dart-io-library.html): I/O for non-web apps. - -Except for `dart:core`, you must import a library before you can use it. Here's -an example of importing `dart:async` and `dart:math`: - -```dart -import 'dart:async'; -import 'dart:math'; -``` - -You can find more libraries using the [pub.dev site](https://pub.dev). - -The main site for learning and using Dart is -[dart.dev](https://dart.dev). Check out these pages: - - * [Platforms](https://dart.dev/platforms) - * [Language tour](https://dart.dev/guides/language/language-tour) - * [Library tour](https://dart.dev/guides/libraries/library-tour) - * [Sample code](https://dart.dev/samples) - -This API reference is automatically generated from source code in the [Dart -SDK project](https://github.com/dart-lang/sdk). -If you'd like to give feedback or edit this documentation, see -[Contributing](https://github.com/dart-lang/sdk/wiki/Contributing). diff --git a/sdk_nnbd/bin/dart b/sdk_nnbd/bin/dart deleted file mode 100755 index 34cb80b8d7e..00000000000 --- a/sdk_nnbd/bin/dart +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2012, 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. - -function follow_links() { - file="$1" - while [ -h "$file" ]; do - # On Mac OS, readlink -f doesn't work. - file="$(readlink "$file")" - done - echo "$file" -} - -# Unlike $0, $BASH_SOURCE points to the absolute path of this file. -PROG_NAME="$(follow_links "$BASH_SOURCE")" - -# Handle the case where dart-sdk/bin has been symlinked to. -CUR_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)" - -if [[ `uname` == 'Darwin' ]]; -then - OUT_DIR="$CUR_DIR"/../../xcodebuild/ -else - OUT_DIR="$CUR_DIR"/../../out/ -fi - -if [ -z "$DART_CONFIGURATION" ]; -then - DIRS=$( ls "$OUT_DIR" ) - # list of possible configurations in decreasing desirability - CONFIGS=("ReleaseX64" "ReleaseIA32" "DebugX64" "DebugIA32" - "ReleaseARM" "ReleaseARM64" "DebugARM" "DebugARM64" ) - DART_CONFIGURATION="None" - for CONFIG in ${CONFIGS[*]} - do - for DIR in $DIRS; - do - if [ "$CONFIG" = "$DIR" ]; - then - # choose most desirable configuration that is available and break - DART_CONFIGURATION="$DIR" - break 2 - fi - done - done - if [ "$DART_CONFIGURATION" = "None" ] - then - echo "No valid dart configuration found in $OUT_DIR" - exit 1 - fi -fi - -BIN_DIR="$OUT_DIR$DART_CONFIGURATION" - -exec "$BIN_DIR"/dart "$@" diff --git a/sdk_nnbd/bin/dart.bat b/sdk_nnbd/bin/dart.bat deleted file mode 100644 index a6a24de3684..00000000000 --- a/sdk_nnbd/bin/dart.bat +++ /dev/null @@ -1,16 +0,0 @@ -@echo off -REM Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file -REM for details. All rights reserved. Use of this source code is governed by a -REM BSD-style license that can be found in the LICENSE file. - -set SCRIPTPATH=%~dp0 - -REM Does the path have a trailing slash? If so, remove it. -if %SCRIPTPATH:~-1%== set SCRIPTPATH=%SCRIPTPATH:~0,-1% - -REM DART_CONFIGURATION defaults to ReleaseX64 -if "%DART_CONFIGURATION%"=="" set DART_CONFIGURATION=ReleaseX64 - -set arguments=%* - -"%SCRIPTPATH%\..\..\out\%DART_CONFIGURATION%\dart.exe" %arguments% diff --git a/sdk_nnbd/bin/dart2js b/sdk_nnbd/bin/dart2js deleted file mode 100755 index 9c562ecfcee..00000000000 --- a/sdk_nnbd/bin/dart2js +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2012, 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. - -function follow_links() { - file="$1" - while [ -h "$file" ]; do - # On Mac OS, readlink -f doesn't work. - file="$(readlink "$file")" - done - echo "$file" -} - -# Unlike $0, $BASH_SOURCE points to the absolute path of this file. -PROG_NAME="$(follow_links "$BASH_SOURCE")" - -# Handle the case where dart-sdk/bin has been symlinked to. -BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)" - -SDK_DIR="$(cd "${BIN_DIR}/.." ; pwd -P)" - -DART="$BIN_DIR/dart" - -unset EXTRA_OPTIONS -declare -a EXTRA_OPTIONS - -if test -t 1; then - # Stdout is a terminal. - if test 8 -le `tput colors`; then - # Stdout has at least 8 colors, so enable colors. - EXTRA_OPTIONS+=('--enable-diagnostic-colors') - fi -fi - -unset EXTRA_VM_OPTIONS -declare -a EXTRA_VM_OPTIONS - -case $0 in - *_developer) - EXTRA_VM_OPTIONS+=('--enable-asserts') - ;; -esac - -# We allow extra vm options to be passed in through an environment variable. -if [[ $DART_VM_OPTIONS ]]; then - read -a OPTIONS <<< "$DART_VM_OPTIONS" - EXTRA_VM_OPTIONS+=("${OPTIONS[@]}") -fi - -DART_ROOT="$(cd "${SDK_DIR}/.." ; pwd -P)" - -DART2JS="package:compiler/src/dart2js.dart" - -exec "$DART" "--packages=$DART_ROOT/.packages" --enable-experiment=non-nullable "${EXTRA_VM_OPTIONS[@]}" "$DART2JS" "${EXTRA_OPTIONS[@]}" "$@" diff --git a/sdk_nnbd/bin/dart2js.bat b/sdk_nnbd/bin/dart2js.bat deleted file mode 100644 index 9341ad8a2b3..00000000000 --- a/sdk_nnbd/bin/dart2js.bat +++ /dev/null @@ -1,60 +0,0 @@ -@echo off -REM Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file -REM for details. All rights reserved. Use of this source code is governed by a -REM BSD-style license that can be found in the LICENSE file. - -setlocal -rem Handle the case where dart-sdk/bin has been symlinked to. -set DIR_NAME_WITH_SLASH=%~dp0 -set DIR_NAME=%DIR_NAME_WITH_SLASH:~0,-1%% -call :follow_links "%DIR_NAME%", RETURNED_BIN_DIR -rem Get rid of surrounding quotes. -for %%i in ("%RETURNED_BIN_DIR%") do set BIN_DIR=%%~fi - -rem Get absolute full name for SDK_DIR. -for %%i in ("%BIN_DIR%\..\") do set SDK_DIR=%%~fi - -rem Remove trailing backslash if there is one -IF %SDK_DIR:~-1%==\ set SDK_DIR=%SDK_DIR:~0,-1% - -set DART=%BIN_DIR%\dart - -set EXTRA_OPTIONS= -set EXTRA_VM_OPTIONS= - -if _%DART2JS_DEVELOPER_MODE%_ == _1_ ( - set EXTRA_VM_OPTIONS=%EXTRA_VM_OPTIONS% --enable-asserts -) - -rem We allow extra vm options to be passed in through an environment variable. -if not "_%DART_VM_OPTIONS%_" == "__" ( - set EXTRA_VM_OPTIONS=%EXTRA_VM_OPTIONS% %DART_VM_OPTIONS% -) - -rem Get absolute full name for DART_ROOT. -for %%i in ("%SDK_DIR%\..\") do set DART_ROOT=%%~fi - -rem Remove trailing backslash if there is one -if %DART_ROOT:~-1%==\ set DART_ROOT=%DART_ROOT:~0,-1% - -set DART2JS=%DART_ROOT%\pkg\compiler\lib\src\dart2js.dart - -"%DART%" "--packages=%DART_ROOT%\.packages" %EXTRA_VM_OPTIONS% "%DART2JS%" %EXTRA_OPTIONS% %* - -endlocal - -exit /b %errorlevel% - -:follow_links -setlocal -for %%i in (%1) do set result=%%~fi -set current= -for /f "usebackq tokens=2 delims=[]" %%i in (`dir /a:l "%~dp1" 2^>nul ^ - ^| %SystemRoot%\System32\find.exe "> %~n1 [" 2^>nul`) do ( - set current=%%i -) -if not "%current%"=="" call :follow_links "%current%", result -endlocal & set %~2=%result% -goto :eof - -:end diff --git a/sdk_nnbd/bin/dart2js_developer b/sdk_nnbd/bin/dart2js_developer deleted file mode 100755 index 226d1a935e9..00000000000 --- a/sdk_nnbd/bin/dart2js_developer +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2012, 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. - -. ${BASH_SOURCE%_developer} diff --git a/sdk_nnbd/bin/dart2js_developer.bat b/sdk_nnbd/bin/dart2js_developer.bat deleted file mode 100644 index c4a2959ecfb..00000000000 --- a/sdk_nnbd/bin/dart2js_developer.bat +++ /dev/null @@ -1,10 +0,0 @@ -@echo off -REM Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file -REM for details. All rights reserved. Use of this source code is governed by a -REM BSD-style license that can be found in the LICENSE file. - -setlocal -set DART2JS_DEVELOPER_MODE=1 -call "%~dp0dart2js.bat" %* -endlocal -exit /b %errorlevel% diff --git a/sdk_nnbd/bin/dart2js_sdk b/sdk_nnbd/bin/dart2js_sdk deleted file mode 100755 index 03999f9d6c8..00000000000 --- a/sdk_nnbd/bin/dart2js_sdk +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2012, 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. - -function follow_links() { - file="$1" - while [ -h "$file" ]; do - # On Mac OS, readlink -f doesn't work. - file="$(readlink "$file")" - done - echo "$file" -} - -# Unlike $0, $BASH_SOURCE points to the absolute path of this file. -PROG_NAME="$(follow_links "$BASH_SOURCE")" - -# Handle the case where dart-sdk/bin has been symlinked to. -BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)" - -SDK_DIR="$(cd "${BIN_DIR}/.." ; pwd -P)" - -DART="$BIN_DIR/dart" - -SNAPSHOT_DIR="$BIN_DIR/snapshots" -SNAPSHOT="$SNAPSHOT_DIR/dart2js.dart.snapshot" - -unset EXTRA_OPTIONS -declare -a EXTRA_OPTIONS - -if test -t 1; then - # Stdout is a terminal. - if test 8 -le `tput colors`; then - # Stdout has at least 8 colors, so enable colors. - EXTRA_OPTIONS+=('--enable-diagnostic-colors') - fi -fi - -unset EXTRA_VM_OPTIONS -declare -a EXTRA_VM_OPTIONS - -if test -f "$SNAPSHOT"; then - EXTRA_OPTIONS+=("--libraries-spec=$SDK_DIR/lib/libraries.json") -fi - -case $0 in - *_developer) - EXTRA_VM_OPTIONS+=('--enable-asserts') - ;; -esac - -# We allow extra vm options to be passed in through an environment variable. -if [[ $DART_VM_OPTIONS ]]; then - read -a OPTIONS <<< "$DART_VM_OPTIONS" - EXTRA_VM_OPTIONS+=("${OPTIONS[@]}") -fi - -exec "$DART" --enable-experiment=non-nullable "${EXTRA_VM_OPTIONS[@]}" "$SNAPSHOT" "${EXTRA_OPTIONS[@]}" "$@" diff --git a/sdk_nnbd/bin/dart2js_sdk.bat b/sdk_nnbd/bin/dart2js_sdk.bat deleted file mode 100755 index 8485cdc7dfb..00000000000 --- a/sdk_nnbd/bin/dart2js_sdk.bat +++ /dev/null @@ -1,57 +0,0 @@ -@echo off -REM Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file -REM for details. All rights reserved. Use of this source code is governed by a -REM BSD-style license that can be found in the LICENSE file. - -setlocal -rem Handle the case where dart-sdk/bin has been symlinked to. -set DIR_NAME_WITH_SLASH=%~dp0 -set DIR_NAME=%DIR_NAME_WITH_SLASH:~0,-1%% -call :follow_links "%DIR_NAME%", RETURNED_BIN_DIR -rem Get rid of surrounding quotes. -for %%i in ("%RETURNED_BIN_DIR%") do set BIN_DIR=%%~fi - -rem Get absolute full name for SDK_DIR. -for %%i in ("%BIN_DIR%\..\") do set SDK_DIR=%%~fi - -rem Remove trailing backslash if there is one -IF %SDK_DIR:~-1%==\ set SDK_DIR=%SDK_DIR:~0,-1% - -set DART=%BIN_DIR%\dart -set SNAPSHOT=%BIN_DIR%\snapshots\dart2js.dart.snapshot - -set EXTRA_OPTIONS= -set EXTRA_VM_OPTIONS= - -if _%DART2JS_DEVELOPER_MODE%_ == _1_ ( - set EXTRA_VM_OPTIONS=%EXTRA_VM_OPTIONS% --enable-asserts -) - -if exist "%SNAPSHOT%" ( - set EXTRA_OPTIONS=%EXTRA_OPTIONS% "--libraries-spec=%SDK_DIR%\lib\libraries.json" -) - -rem We allow extra vm options to be passed in through an environment variable. -if not "_%DART_VM_OPTIONS%_" == "__" ( - set EXTRA_VM_OPTIONS=%EXTRA_VM_OPTIONS% %DART_VM_OPTIONS% -) - -"%DART%" %EXTRA_VM_OPTIONS% "%SNAPSHOT%" %EXTRA_OPTIONS% %* - -endlocal - -exit /b %errorlevel% - -:follow_links -setlocal -for %%i in (%1) do set result=%%~fi -set current= -for /f "usebackq tokens=2 delims=[]" %%i in (`dir /a:l "%~dp1" 2^>nul ^ - ^| find "> %~n1 [" 2^>nul`) do ( - set current=%%i -) -if not "%current%"=="" call :follow_links "%current%", result -endlocal & set %~2=%result% -goto :eof - -:end diff --git a/sdk_nnbd/bin/dart2native b/sdk_nnbd/bin/dart2native deleted file mode 100755 index 29f29d751f7..00000000000 --- a/sdk_nnbd/bin/dart2native +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2019, 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. - -# Run dart2native.dart.snapshot on the Dart VM - -function follow_links() { - file="$1" - while [ -h "$file" ]; do - # On Mac OS, readlink -f doesn't work. - file="$(readlink "$file")" - done - echo "$file" -} - -# Unlike $0, $BASH_SOURCE points to the absolute path of this file. -PROG_NAME="$(follow_links "$BASH_SOURCE")" - -# Handle the case where dart-sdk/bin has been symlinked to. -BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)" -SNAPSHOTS_DIR="${BIN_DIR}/snapshots" -DART="$BIN_DIR/dart" - -exec "$DART" "${SNAPSHOTS_DIR}/dart2native.dart.snapshot" $* diff --git a/sdk_nnbd/bin/dart2native.bat b/sdk_nnbd/bin/dart2native.bat deleted file mode 100644 index 631dce8d080..00000000000 --- a/sdk_nnbd/bin/dart2native.bat +++ /dev/null @@ -1,43 +0,0 @@ -@echo off -REM Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file -REM for details. All rights reserved. Use of this source code is governed by a -REM BSD-style license that can be found in the LICENSE file. - -setlocal -rem Handle the case where dart-sdk/bin has been symlinked to. -set DIR_NAME_WITH_SLASH=%~dp0 -set DIR_NAME=%DIR_NAME_WITH_SLASH:~0,-1%% -call :follow_links "%DIR_NAME%", RETURNED_BIN_DIR -rem Get rid of surrounding quotes. -for %%i in ("%RETURNED_BIN_DIR%") do set BIN_DIR=%%~fi - -set DART=%BIN_DIR%\dart - -"%DART%" "%BIN_DIR%\snapshots\dart2native.dart.snapshot" %* - -endlocal - -exit /b %errorlevel% - -rem Follow the symbolic links (junctions points) using `dir to determine the -rem canonical path. Output with a link looks something like this -rem -rem 01/03/2013 10:11 PM abc def -rem [c:\dart_bleeding\dart-repo.9\dart\out\ReleaseIA32\dart-sdk] -rem -rem So in the output of 'dir /a:l "targetdir"' we are looking for a filename -rem surrounded by right angle bracket and left square bracket. Once we get -rem the filename, which is name of the link, we recursively follow that. -:follow_links -setlocal -for %%i in (%1) do set result=%%~fi -set current= -for /f "usebackq tokens=2 delims=[]" %%i in (`dir /a:l "%~dp1" 2^>nul ^ - ^| %SystemRoot%\System32\find.exe "> %~n1 [" 2^>nul`) do ( - set current=%%i -) -if not "%current%"=="" call :follow_links "%current%", result -endlocal & set %~2=%result% -goto :eof - -:end diff --git a/sdk_nnbd/bin/dartanalyzer b/sdk_nnbd/bin/dartanalyzer deleted file mode 100755 index 0574603a0b1..00000000000 --- a/sdk_nnbd/bin/dartanalyzer +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2013, 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. - -# Run dartanalyzer.dart on the Dart VM. This script assumes the Dart repo's -# directory structure. - -function follow_links() { - file="$1" - while [ -h "$file" ]; do - # On Mac OS, readlink -f doesn't work. - file="$(readlink "$file")" - done - echo "$file" -} - -# Unlike $0, $BASH_SOURCE points to the absolute path of this file. -PROG_NAME="$(follow_links "$BASH_SOURCE")" - -# Handle the case where dart-sdk/bin has been symlinked to. -BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)" -SDK_DIR="$(cd "${BIN_DIR}/.." ; pwd -P)" - -SDK_ARG="--dart-sdk=$SDK_DIR" - -DART="$BIN_DIR/dart" - -unset EXTRA_VM_OPTIONS -declare -a EXTRA_VM_OPTIONS -EXTRA_VM_OPTIONS+=("--enable_experiment=non-nullable") - -case $0 in - *_developer) - EXTRA_VM_OPTIONS+=('--enable-asserts') - ;; -esac - -# We allow extra vm options to be passed in through an environment variable. -if [[ $DART_VM_OPTIONS ]]; then - read -a OPTIONS <<< "$DART_VM_OPTIONS" - EXTRA_VM_OPTIONS+=("${OPTIONS[@]}") -fi - -DART_ROOT="$(cd "${SDK_DIR}/.." ; pwd -P)" - -ANALYZER="$DART_ROOT/pkg/analyzer_cli/bin/analyzer.dart" - -DEV_OPTIONS="--use-analysis-driver-memory-byte-store" - -exec "$DART" "--packages=$DART_ROOT/.packages" "${EXTRA_VM_OPTIONS[@]}" "$ANALYZER" "$DEV_OPTIONS" "$SDK_ARG" "$@" diff --git a/sdk_nnbd/bin/dartanalyzer.bat b/sdk_nnbd/bin/dartanalyzer.bat deleted file mode 100644 index efa3a6a84d7..00000000000 --- a/sdk_nnbd/bin/dartanalyzer.bat +++ /dev/null @@ -1,70 +0,0 @@ -@echo off -REM Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file -REM for details. All rights reserved. Use of this source code is governed by a -REM BSD-style license that can be found in the LICENSE file. - -setlocal -rem Handle the case where dart-sdk/bin has been symlinked to. -set DIR_NAME_WITH_SLASH=%~dp0 -set DIR_NAME=%DIR_NAME_WITH_SLASH:~0,-1%% -call :follow_links "%DIR_NAME%", RETURNED_BIN_DIR -rem Get rid of surrounding quotes. -for %%i in ("%RETURNED_BIN_DIR%") do set BIN_DIR=%%~fi - -set DART=%BIN_DIR%\dart - -rem Get absolute full name for SDK_DIR. -for %%i in ("%BIN_DIR%\..\") do set SDK_DIR=%%~fi - -rem Remove trailing backslash if there is one -if %SDK_DIR:~-1%==\ set SDK_DIR=%SDK_DIR:~0,-1% - -set SDK_ARG=--dart-sdk=%SDK_DIR% - -set EXTRA_VM_OPTIONS= - -if _%DARTANALYZER_DEVELOPER_MODE%_ == _1_ ( - set EXTRA_VM_OPTIONS=%EXTRA_VM_OPTIONS% --enable_asserts -) - -rem We allow extra vm options to be passed in through an environment variable. -if not "_%DART_VM_OPTIONS%_" == "__" ( - set EXTRA_VM_OPTIONS=%EXTRA_VM_OPTIONS% %DART_VM_OPTIONS% -) - -rem Get absolute full name for DART_ROOT. -for %%i in ("%SDK_DIR%\..\") do set DART_ROOT=%%~fi - -rem Remove trailing backslash if there is one -if %DART_ROOT:~-1%==\ set DART_ROOT=%DART_ROOT:~0,-1% - -set ANALYZER=%DART_ROOT%\pkg\analyzer_cli\bin\analyzer.dart - -"%DART%" "--packages=%DART_ROOT%\.packages" %EXTRA_VM_OPTIONS% "%ANALYZER%" "%SDK_ARG%" %* - -endlocal - -exit /b %errorlevel% - -rem Follow the symbolic links (junctions points) using `dir to determine the -rem canonical path. Output with a link looks something like this -rem -rem 01/03/2013 10:11 PM abc def -rem [c:\dart_bleeding\dart-repo.9\dart\out\ReleaseIA32\dart-sdk] -rem -rem So in the output of 'dir /a:l "targetdir"' we are looking for a filename -rem surrounded by right angle bracket and left square bracket. Once we get -rem the filename, which is name of the link, we recursively follow that. -:follow_links -setlocal -for %%i in (%1) do set result=%%~fi -set current= -for /f "usebackq tokens=2 delims=[]" %%i in (`dir /a:l "%~dp1" 2^>nul ^ - ^| %SystemRoot%\System32\find.exe "> %~n1 [" 2^>nul`) do ( - set current=%%i -) -if not "%current%"=="" call :follow_links "%current%", result -endlocal & set %~2=%result% -goto :eof - -:end diff --git a/sdk_nnbd/bin/dartanalyzer_developer b/sdk_nnbd/bin/dartanalyzer_developer deleted file mode 100755 index 373dc67111a..00000000000 --- a/sdk_nnbd/bin/dartanalyzer_developer +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2014, 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. - -. ${BASH_SOURCE%_developer} diff --git a/sdk_nnbd/bin/dartanalyzer_developer.bat b/sdk_nnbd/bin/dartanalyzer_developer.bat deleted file mode 100644 index b560fe8d3c0..00000000000 --- a/sdk_nnbd/bin/dartanalyzer_developer.bat +++ /dev/null @@ -1,10 +0,0 @@ -@echo off -REM Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file -REM for details. All rights reserved. Use of this source code is governed by a -REM BSD-style license that can be found in the LICENSE file. - -setlocal -set DARTANALYZER_DEVELOPER_MODE=1 -call "%~dp0dartanalyzer.bat" %* -endlocal -exit /b %errorlevel% diff --git a/sdk_nnbd/bin/dartanalyzer_sdk b/sdk_nnbd/bin/dartanalyzer_sdk deleted file mode 100755 index 88f4deb0434..00000000000 --- a/sdk_nnbd/bin/dartanalyzer_sdk +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2013, 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. - -# Run dartanalyzer.dart on the Dart VM. This script assumes the Dart SDK's -# directory structure. - -function follow_links() { - file="$1" - while [ -h "$file" ]; do - # On Mac OS, readlink -f doesn't work. - file="$(readlink "$file")" - done - echo "$file" -} - -# Unlike $0, $BASH_SOURCE points to the absolute path of this file. -PROG_NAME="$(follow_links "$BASH_SOURCE")" - -# Handle the case where dart-sdk/bin has been symlinked to. -BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)" -SDK_DIR="$(cd "${BIN_DIR}/.." ; pwd -P)" - -SDK_ARG="--dart-sdk=$SDK_DIR" - -SNAPSHOT="$BIN_DIR/snapshots/dartanalyzer.dart.snapshot" - -# We are running the snapshot in the built SDK. -DART="$BIN_DIR/dart" -exec "$DART" --enable_experiment=non-nullable "$SNAPSHOT" "$SDK_ARG" "$@" diff --git a/sdk_nnbd/bin/dartanalyzer_sdk.bat b/sdk_nnbd/bin/dartanalyzer_sdk.bat deleted file mode 100644 index ab66885f7a4..00000000000 --- a/sdk_nnbd/bin/dartanalyzer_sdk.bat +++ /dev/null @@ -1,52 +0,0 @@ -@echo off -REM Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file -REM for details. All rights reserved. Use of this source code is governed by a -REM BSD-style license that can be found in the LICENSE file. - -setlocal -rem Handle the case where dart-sdk/bin has been symlinked to. -set DIR_NAME_WITH_SLASH=%~dp0 -set DIR_NAME=%DIR_NAME_WITH_SLASH:~0,-1%% -call :follow_links "%DIR_NAME%", RETURNED_BIN_DIR -rem Get rid of surrounding quotes. -for %%i in ("%RETURNED_BIN_DIR%") do set BIN_DIR=%%~fi - -set DART=%BIN_DIR%\dart -set SNAPSHOT=%BIN_DIR%\snapshots\dartanalyzer.dart.snapshot - -rem Get absolute full name for SDK_DIR. -for %%i in ("%BIN_DIR%\..\") do set SDK_DIR=%%~fi - -rem Remove trailing backslash if there is one -if %SDK_DIR:~-1%==\ set SDK_DIR=%SDK_DIR:~0,-1% - -set SDK_ARG=--dart-sdk=%SDK_DIR% - -"%DART%" "%SNAPSHOT%" "%SDK_ARG%" %* - -endlocal - -exit /b %errorlevel% - -rem Follow the symbolic links (junctions points) using `dir to determine the -rem canonical path. Output with a link looks something like this -rem -rem 01/03/2013 10:11 PM abc def -rem [c:\dart_bleeding\dart-repo.9\dart\out\ReleaseIA32\dart-sdk] -rem -rem So in the output of 'dir /a:l "targetdir"' we are looking for a filename -rem surrounded by right angle bracket and left square bracket. Once we get -rem the filename, which is name of the link, we recursively follow that. -:follow_links -setlocal -for %%i in (%1) do set result=%%~fi -set current= -for /f "usebackq tokens=2 delims=[]" %%i in (`dir /a:l "%~dp1" 2^>nul ^ - ^| find "> %~n1 [" 2^>nul`) do ( - set current=%%i -) -if not "%current%"=="" call :follow_links "%current%", result -endlocal & set %~2=%result% -goto :eof - -:end diff --git a/sdk_nnbd/bin/dartdevc b/sdk_nnbd/bin/dartdevc deleted file mode 100755 index c2c25d903ab..00000000000 --- a/sdk_nnbd/bin/dartdevc +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2013, 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. - -# Run dev compiler on the Dart VM. This script assumes the Dart repo's -# directory structure. - -function follow_links() { - file="$1" - while [ -h "$file" ]; do - # On Mac OS, readlink -f doesn't work. - file="$(readlink "$file")" - done - echo "$file" -} - -# Unlike $0, $BASH_SOURCE points to the absolute path of this file. -PROG_NAME="$(follow_links "$BASH_SOURCE")" - -# Handle the case where dart-sdk/bin has been symlinked to. -BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)" -SDK_DIR="$(cd "${BIN_DIR}/.." ; pwd -P)" - -SDK_ARG="--dart-sdk=$SDK_DIR" - -DART="$BIN_DIR/dart" - -unset EXTRA_VM_OPTIONS -declare -a EXTRA_VM_OPTIONS - -case $0 in - *_developer) - EXTRA_VM_OPTIONS+=('--checked') - ;; -esac - -# We allow extra vm options to be passed in through an environment variable. -if [[ $DART_VM_OPTIONS ]]; then - read -a OPTIONS <<< "$DART_VM_OPTIONS" - EXTRA_VM_OPTIONS+=("${OPTIONS[@]}") -fi - -DART_ROOT="$(cd "${SDK_DIR}/.." ; pwd -P)" - -DEV_COMPILER="$DART_ROOT/pkg/dev_compiler/bin/dartdevc.dart" - -exec "$DART" "--packages=$DART_ROOT/.packages" --enable_experiment=non-nullable "${EXTRA_VM_OPTIONS[@]}" "$DEV_COMPILER" "$SDK_ARG" "$@" diff --git a/sdk_nnbd/bin/dartdevc.bat b/sdk_nnbd/bin/dartdevc.bat deleted file mode 100644 index fec39e46448..00000000000 --- a/sdk_nnbd/bin/dartdevc.bat +++ /dev/null @@ -1,66 +0,0 @@ -@echo off -REM Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file -REM for details. All rights reserved. Use of this source code is governed by a -REM BSD-style license that can be found in the LICENSE file. - -setlocal -rem Handle the case where dart-sdk/bin has been symlinked to. -set DIR_NAME_WITH_SLASH=%~dp0 -set DIR_NAME=%DIR_NAME_WITH_SLASH:~0,-1%% -call :follow_links "%DIR_NAME%", RETURNED_BIN_DIR -rem Get rid of surrounding quotes. -for %%i in ("%RETURNED_BIN_DIR%") do set BIN_DIR=%%~fi - -set DART=%BIN_DIR%\dart - -rem Get absolute full name for SDK_DIR. -for %%i in ("%BIN_DIR%\..\") do set SDK_DIR=%%~fi - -rem Remove trailing backslash if there is one -if %SDK_DIR:~-1%==\ set SDK_DIR=%SDK_DIR:~0,-1% - -set SDK_ARG=--dart-sdk=%SDK_DIR% - -set EXTRA_VM_OPTIONS= - -rem We allow extra vm options to be passed in through an environment variable. -if not "_%DART_VM_OPTIONS%_" == "__" ( - set EXTRA_VM_OPTIONS=%EXTRA_VM_OPTIONS% %DART_VM_OPTIONS% -) - -rem Get absolute full name for DART_ROOT. -for %%i in ("%SDK_DIR%\..\") do set DART_ROOT=%%~fi - -rem Remove trailing backslash if there is one -if %DART_ROOT:~-1%==\ set DART_ROOT=%DART_ROOT:~0,-1% - -set DEV_COMPILER=%DART_ROOT%\third_party\pkg\dev_compiler\bin\dartdevc.dart - -"%DART%" "--packages=%DART_ROOT%\.packages" %EXTRA_VM_OPTIONS% "DEV_COMPILER%" "%SDK_ARG%" %* - -endlocal - -exit /b %errorlevel% - -rem Follow the symbolic links (junctions points) using `dir to determine the -rem canonical path. Output with a link looks something like this -rem -rem 01/03/2013 10:11 PM abc def -rem [c:\dart_bleeding\dart-repo.9\dart\out\ReleaseIA32\dart-sdk] -rem -rem So in the output of 'dir /a:l "targetdir"' we are looking for a filename -rem surrounded by right angle bracket and left square bracket. Once we get -rem the filename, which is name of the link, we recursively follow that. -:follow_links -setlocal -for %%i in (%1) do set result=%%~fi -set current= -for /f "usebackq tokens=2 delims=[]" %%i in (`dir /a:l "%~dp1" 2^>nul ^ - ^| find "> %~n1 [" 2^>nul`) do ( - set current=%%i -) -if not "%current%"=="" call :follow_links "%current%", result -endlocal & set %~2=%result% -goto :eof - -:end diff --git a/sdk_nnbd/bin/dartdevc_sdk b/sdk_nnbd/bin/dartdevc_sdk deleted file mode 100755 index c687bdd9472..00000000000 --- a/sdk_nnbd/bin/dartdevc_sdk +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2013, 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. - -# Run dev compiler on the Dart VM. This script assumes the Dart SDK's -# directory structure. - -function follow_links() { - file="$1" - while [ -h "$file" ]; do - # On Mac OS, readlink -f doesn't work. - file="$(readlink "$file")" - done - echo "$file" -} - -# Unlike $0, $BASH_SOURCE points to the absolute path of this file. -PROG_NAME="$(follow_links "$BASH_SOURCE")" - -# Handle the case where dart-sdk/bin has been symlinked to. -BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)" - -SNAPSHOT="$BIN_DIR/snapshots/dartdevc.dart.snapshot" - -# We are running the snapshot in the built SDK. -DART="$BIN_DIR/dart" - -unset EXTRA_VM_OPTIONS -declare -a EXTRA_VM_OPTIONS - -# We allow extra vm options to be passed in through an environment variable. -if [[ $DART_VM_OPTIONS ]]; then - read -a OPTIONS <<< "$DART_VM_OPTIONS" - EXTRA_VM_OPTIONS+=("${OPTIONS[@]}") -fi - -exec "$DART" --enable_experiment=non-nullable "${EXTRA_VM_OPTIONS[@]}" "$SNAPSHOT" "$@" diff --git a/sdk_nnbd/bin/dartdevc_sdk.bat b/sdk_nnbd/bin/dartdevc_sdk.bat deleted file mode 100644 index ce027a9dc24..00000000000 --- a/sdk_nnbd/bin/dartdevc_sdk.bat +++ /dev/null @@ -1,59 +0,0 @@ -@echo off -REM Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file -REM for details. All rights reserved. Use of this source code is governed by a -REM BSD-style license that can be found in the LICENSE file. - -setlocal -rem Handle the case where dart-sdk/bin has been symlinked to. -set DIR_NAME_WITH_SLASH=%~dp0 -set DIR_NAME=%DIR_NAME_WITH_SLASH:~0,-1%% -call :follow_links "%DIR_NAME%", RETURNED_BIN_DIR -rem Get rid of surrounding quotes. -for %%i in ("%RETURNED_BIN_DIR%") do set BIN_DIR=%%~fi - -set DART=%BIN_DIR%\dart -set SNAPSHOT=%BIN_DIR%\snapshots\dartdevc.dart.snapshot - -rem Get absolute full name for SDK_DIR. -for %%i in ("%BIN_DIR%\..\") do set SDK_DIR=%%~fi - -rem Remove trailing backslash if there is one -if %SDK_DIR:~-1%==\ set SDK_DIR=%SDK_DIR:~0,-1% - -set SDK_ARG=--dart-sdk=%SDK_DIR% - -set EXTRA_VM_OPTIONS= - -rem We allow extra vm options to be passed in through an environment variable. -if not "_%DART_VM_OPTIONS%_" == "__" ( - set EXTRA_VM_OPTIONS=%EXTRA_VM_OPTIONS% %DART_VM_OPTIONS% -) - -"%DART%" %EXTRA_VM_OPTIONS% "%SNAPSHOT%" "%SDK_ARG%" %* - -endlocal - -exit /b %errorlevel% - -rem Follow the symbolic links (junctions points) using `dir to determine the -rem canonical path. Output with a link looks something like this -rem -rem 01/03/2013 10:11 PM abc def -rem [c:\dart_bleeding\dart-repo.9\dart\out\ReleaseIA32\dart-sdk] -rem -rem So in the output of 'dir /a:l "targetdir"' we are looking for a filename -rem surrounded by right angle bracket and left square bracket. Once we get -rem the filename, which is name of the link, we recursively follow that. -:follow_links -setlocal -for %%i in (%1) do set result=%%~fi -set current= -for /f "usebackq tokens=2 delims=[]" %%i in (`dir /a:l "%~dp1" 2^>nul ^ - ^| find "> %~n1 ["`) do ( - set current=%%i -) -if not "%current%"=="" call :follow_links "%current%", result -endlocal & set %~2=%result% -goto :eof - -:end diff --git a/sdk_nnbd/bin/dartdoc b/sdk_nnbd/bin/dartdoc deleted file mode 100755 index e9584c1ced7..00000000000 --- a/sdk_nnbd/bin/dartdoc +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash -# 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. - -function follow_links() { - file="$1" - while [ -h "$file" ]; do - # On Mac OS, readlink -f doesn't work. - file="$(readlink "$file")" - done - echo "$file" -} - -# Unlike $0, $BASH_SOURCE points to the absolute path of this file. -PROG_NAME="$(follow_links "$BASH_SOURCE")" - -# Handle the case where dart-sdk/bin has been symlinked to. -BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)" -SDK_DIR="$(cd "${BIN_DIR}/.." ; pwd -P)" - -SNAPSHOT="$BIN_DIR/snapshots/dartdoc.dart.snapshot" - -# We are running the snapshot in the built SDK. -DART="$BIN_DIR/dart" -exec "$DART" "--packages=$BIN_DIR/resources/dartdoc/.packages" "$SNAPSHOT" "$@" diff --git a/sdk_nnbd/bin/dartdoc.bat b/sdk_nnbd/bin/dartdoc.bat deleted file mode 100644 index 876eb0e2a4e..00000000000 --- a/sdk_nnbd/bin/dartdoc.bat +++ /dev/null @@ -1,44 +0,0 @@ -@echo off -REM Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file -REM for details. All rights reserved. Use of this source code is governed by a -REM BSD-style license that can be found in the LICENSE file. - -setlocal -rem Handle the case where dart-sdk/bin has been symlinked to. -set DIR_NAME_WITH_SLASH=%~dp0 -set DIR_NAME=%DIR_NAME_WITH_SLASH:~0,-1%% -call :follow_links "%DIR_NAME%", RETURNED_BIN_DIR -rem Get rid of surrounding quotes. -for %%i in ("%RETURNED_BIN_DIR%") do set BIN_DIR=%%~fi - -set DART=%BIN_DIR%\dart -set SNAPSHOT=%BIN_DIR%\snapshots\dartdoc.dart.snapshot - -"%DART%" "--packages=%BIN_DIR%/resources/dartdoc/.packages" "%SNAPSHOT%" %* - -endlocal - -exit /b %errorlevel% - -rem Follow the symbolic links (junctions points) using `dir to determine the -rem canonical path. Output with a link looks something like this -rem -rem 01/03/2013 10:11 PM abc def -rem [c:\dart_bleeding\dart-repo.9\dart\out\ReleaseIA32\dart-sdk] -rem -rem So in the output of 'dir /a:l "targetdir"' we are looking for a filename -rem surrounded by right angle bracket and left square bracket. Once we get -rem the filename, which is name of the link, we recursively follow that. -:follow_links -setlocal -for %%i in (%1) do set result=%%~fi -set current= -for /f "usebackq tokens=2 delims=[]" %%i in (`dir /a:l "%~dp1" 2^>nul ^ - ^| %SystemRoot%\System32\find.exe "> %~n1 [" 2^>nul`) do ( - set current=%%i -) -if not "%current%"=="" call :follow_links "%current%", result -endlocal & set %~2=%result% -goto :eof - -:end diff --git a/sdk_nnbd/bin/dartfix b/sdk_nnbd/bin/dartfix deleted file mode 100755 index bbeb80d42bb..00000000000 --- a/sdk_nnbd/bin/dartfix +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2013, 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. - -# Run dartfix.dart on the Dart VM. This script assumes the Dart SDK's -# directory structure. - -function follow_links() { - file="$1" - while [ -h "$file" ]; do - # On Mac OS, readlink -f doesn't work. - file="$(readlink "$file")" - done - echo "$file" -} - -# Unlike $0, $BASH_SOURCE points to the absolute path of this file. -PROG_NAME="$(follow_links "$BASH_SOURCE")" - -# Handle the case where dart-sdk/bin has been symlinked to. -BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)" - -SNAPSHOT="$BIN_DIR/snapshots/dartfix.dart.snapshot" - -# We are running the snapshot in the built SDK. -DART="$BIN_DIR/dart" -exec "$DART" "$SNAPSHOT" "$@" diff --git a/sdk_nnbd/bin/dartfix.bat b/sdk_nnbd/bin/dartfix.bat deleted file mode 100644 index 4241694f990..00000000000 --- a/sdk_nnbd/bin/dartfix.bat +++ /dev/null @@ -1,44 +0,0 @@ -@echo off -REM Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file -REM for details. All rights reserved. Use of this source code is governed by a -REM BSD-style license that can be found in the LICENSE file. - -setlocal -rem Handle the case where dart-sdk/bin has been symlinked to. -set DIR_NAME_WITH_SLASH=%~dp0 -set DIR_NAME=%DIR_NAME_WITH_SLASH:~0,-1%% -call :follow_links "%DIR_NAME%", RETURNED_BIN_DIR -rem Get rid of surrounding quotes. -for %%i in ("%RETURNED_BIN_DIR%") do set BIN_DIR=%%~fi - -set DART=%BIN_DIR%\dart -set SNAPSHOT=%BIN_DIR%\snapshots\dartfix.dart.snapshot - -"%DART%" "%SNAPSHOT%" %* - -endlocal - -exit /b %errorlevel% - -rem Follow the symbolic links (junctions points) using `dir to determine the -rem canonical path. Output with a link looks something like this -rem -rem 01/03/2013 10:11 PM abc def -rem [c:\dart_bleeding\dart-repo.9\dart\out\ReleaseIA32\dart-sdk] -rem -rem So in the output of 'dir /a:l "targetdir"' we are looking for a filename -rem surrounded by right angle bracket and left square bracket. Once we get -rem the filename, which is name of the link, we recursively follow that. -:follow_links -setlocal -for %%i in (%1) do set result=%%~fi -set current= -for /f "usebackq tokens=2 delims=[]" %%i in (`dir /a:l "%~dp1" 2^>nul ^ - ^| find "> %~n1 [" 2^>nul`) do ( - set current=%%i -) -if not "%current%"=="" call :follow_links "%current%", result -endlocal & set %~2=%result% -goto :eof - -:end diff --git a/sdk_nnbd/bin/dartfmt b/sdk_nnbd/bin/dartfmt deleted file mode 100755 index ad541407ae5..00000000000 --- a/sdk_nnbd/bin/dartfmt +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2013, 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. - -# Run dart_style/bin/format.dart on the Dart VM. This script assumes the Dart -# repo's directory structure. - -function follow_links() { - file="$1" - while [ -h "$file" ]; do - # On Mac OS, readlink -f doesn't work. - file="$(readlink "$file")" - done - echo "$file" -} - -# Unlike $0, $BASH_SOURCE points to the absolute path of this file. -PROG_NAME="$(follow_links "$BASH_SOURCE")" - -# Handle the case where dart-sdk/bin has been symlinked to. -BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)" -SDK_DIR="$(cd "${BIN_DIR}/.." ; pwd -P)" - -DART="$BIN_DIR/dart" - -DART_ROOT="$(cd "${SDK_DIR}/.." ; pwd -P)" - -DARTFMT="$DART_ROOT/third_party/pkg_tested/dart_style/bin/format.dart" - -exec "$DART" "--packages=$DART_ROOT/.packages" "$DARTFMT" "$@" diff --git a/sdk_nnbd/bin/dartfmt.bat b/sdk_nnbd/bin/dartfmt.bat deleted file mode 100644 index 7a7412bbbb4..00000000000 --- a/sdk_nnbd/bin/dartfmt.bat +++ /dev/null @@ -1,57 +0,0 @@ -@echo off -REM Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file -REM for details. All rights reserved. Use of this source code is governed by a -REM BSD-style license that can be found in the LICENSE file. - -setlocal -rem Handle the case where dart-sdk/bin has been symlinked to. -set DIR_NAME_WITH_SLASH=%~dp0 -set DIR_NAME=%DIR_NAME_WITH_SLASH:~0,-1%% -call :follow_links "%DIR_NAME%", RETURNED_BIN_DIR -rem Get rid of surrounding quotes. -for %%i in ("%RETURNED_BIN_DIR%") do set BIN_DIR=%%~fi - -set DART=%BIN_DIR%\dart - -rem Get absolute full name for SDK_DIR. -for %%i in ("%BIN_DIR%\..\") do set SDK_DIR=%%~fi - -rem Remove trailing backslash if there is one -if %SDK_DIR:~-1%==\ set SDK_DIR=%SDK_DIR:~0,-1% - -rem Get absolute full name for DART_ROOT. -for %%i in ("%SDK_DIR%\..\") do set DART_ROOT=%%~fi - -rem Remove trailing backslash if there is one -if %DART_ROOT:~-1%==\ set DART_ROOT=%DART_ROOT:~0,-1% - -set DARTFMT=%DART_ROOT%\third_party\pkg_tested\dart_style\bin\format.dart - -"%DART%" "--packages=%DART_ROOT%\.packages" "%DARTFMT%" %* - -endlocal - -exit /b %errorlevel% - -rem Follow the symbolic links (junctions points) using `dir to determine the -rem canonical path. Output with a link looks something like this -rem -rem 01/03/2013 10:11 PM abc def -rem [c:\dart_bleeding\dart-repo.9\dart\out\ReleaseIA32\dart-sdk] -rem -rem So in the output of 'dir /a:l "targetdir"' we are looking for a filename -rem surrounded by right angle bracket and left square bracket. Once we get -rem the filename, which is name of the link, we recursively follow that. -:follow_links -setlocal -for %%i in (%1) do set result=%%~fi -set current= -for /f "usebackq tokens=2 delims=[]" %%i in (`dir /a:l "%~dp1" 2^>nul ^ - ^| %SystemRoot%\System32\find.exe "> %~n1 [" 2^>nul`) do ( - set current=%%i -) -if not "%current%"=="" call :follow_links "%current%", result -endlocal & set %~2=%result% -goto :eof - -:end diff --git a/sdk_nnbd/bin/dartfmt_sdk b/sdk_nnbd/bin/dartfmt_sdk deleted file mode 100755 index 273733ce217..00000000000 --- a/sdk_nnbd/bin/dartfmt_sdk +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash -# 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. - -# Run dart_style/bin/format.dart on the Dart VM. This script assumes the Dart -# SDK's directory structure. - -function follow_links() { - file="$1" - while [ -h "$file" ]; do - # On Mac OS, readlink -f doesn't work. - file="$(readlink "$file")" - done - echo "$file" -} - -# Unlike $0, $BASH_SOURCE points to the absolute path of this file. -PROG_NAME="$(follow_links "$BASH_SOURCE")" - -# Handle the case where dart-sdk/bin has been symlinked to. -BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)" -SDK_DIR="$(cd "${BIN_DIR}/.." ; pwd -P)" - -SNAPSHOT="$BIN_DIR/snapshots/dartfmt.dart.snapshot" - -# We are running the snapshot in the built SDK. -DART="$BIN_DIR/dart" -exec "$DART" "$SNAPSHOT" "$@" diff --git a/sdk_nnbd/bin/dartfmt_sdk.bat b/sdk_nnbd/bin/dartfmt_sdk.bat deleted file mode 100644 index 295b9779492..00000000000 --- a/sdk_nnbd/bin/dartfmt_sdk.bat +++ /dev/null @@ -1,44 +0,0 @@ -@echo off -REM Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file -REM for details. All rights reserved. Use of this source code is governed by a -REM BSD-style license that can be found in the LICENSE file. - -setlocal -rem Handle the case where dart-sdk/bin has been symlinked to. -set DIR_NAME_WITH_SLASH=%~dp0 -set DIR_NAME=%DIR_NAME_WITH_SLASH:~0,-1%% -call :follow_links "%DIR_NAME%", RETURNED_BIN_DIR -rem Get rid of surrounding quotes. -for %%i in ("%RETURNED_BIN_DIR%") do set BIN_DIR=%%~fi - -set DART=%BIN_DIR%\dart -set SNAPSHOT=%BIN_DIR%\snapshots\dartfmt.dart.snapshot - -"%DART%" "%SNAPSHOT%" %* - -endlocal - -exit /b %errorlevel% - -rem Follow the symbolic links (junctions points) using `dir to determine the -rem canonical path. Output with a link looks something like this -rem -rem 01/03/2013 10:11 PM abc def -rem [c:\dart_bleeding\dart-repo.9\dart\out\ReleaseIA32\dart-sdk] -rem -rem So in the output of 'dir /a:l "targetdir"' we are looking for a filename -rem surrounded by right angle bracket and left square bracket. Once we get -rem the filename, which is name of the link, we recursively follow that. -:follow_links -setlocal -for %%i in (%1) do set result=%%~fi -set current= -for /f "usebackq tokens=2 delims=[]" %%i in (`dir /a:l "%~dp1" 2^>nul ^ - ^| find "> %~n1 ["`) do ( - set current=%%i -) -if not "%current%"=="" call :follow_links "%current%", result -endlocal & set %~2=%result% -goto :eof - -:end diff --git a/sdk_nnbd/bin/pub b/sdk_nnbd/bin/pub deleted file mode 100755 index 85ad5d6b0eb..00000000000 --- a/sdk_nnbd/bin/pub +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2012, 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. - -# Run pub.dart on the Dart VM. This script is only used when running pub from -# within the Dart source repo. The shipped SDK instead uses "pub_sdk", which is -# renamed to "pub" when the SDK is built. - -function follow_links() { - file="$1" - while [ -h "$file" ]; do - # On Mac OS, readlink -f doesn't work. - file="$(readlink "$file")" - done - echo "$file" -} - -# Unlike $0, $BASH_SOURCE points to the absolute path of this file. -PROG_NAME="$(follow_links "$BASH_SOURCE")" - -# Handle the case where dart-sdk/bin has been symlinked to. -BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)" - -SDK_DIR="$(cd "${BIN_DIR}/.." ; pwd -P)" - -SNAPSHOT="$BIN_DIR/snapshots/pub.dart.snapshot" - -unset VM_OPTIONS -declare -a VM_OPTIONS - -if [[ `uname` == 'Darwin' ]]; -then - OUT_DIR="$BIN_DIR"/../../xcodebuild/ -else - OUT_DIR="$BIN_DIR"/../../out/ -fi - -# Allow extra VM options to be passed in through an environment variable. -if [[ $DART_VM_OPTIONS ]]; then - read -a OPTIONS <<< "$DART_VM_OPTIONS" - VM_OPTIONS+=("${OPTIONS[@]}") -fi - -if [ -z "$DART_CONFIGURATION" ]; -then - DIRS=$( ls "$OUT_DIR" ) - # list of possible configurations in decreasing desirability - CONFIGS=("ReleaseX64" "ReleaseIA32" "DebugX64" "DebugIA32" - "ReleaseARM" "ReleaseARM64" "DebugARM" "DebugARM64" ) - DART_CONFIGURATION="None" - for CONFIG in ${CONFIGS[*]} - do - for DIR in $DIRS; - do - if [ "$CONFIG" = "$DIR" ]; - then - # choose most desirable configuration that is available and break - DART_CONFIGURATION="$DIR" - break 2 - fi - done - done - if [ "$DART_CONFIGURATION" = "None" ] - then - echo "No valid dart configuration found in $OUT_DIR" - exit 1 - fi -fi - -if [[ `uname` == 'Darwin' ]]; -then - BUILD_DIR="$SDK_DIR/../xcodebuild/$DART_CONFIGURATION" -else - BUILD_DIR="$SDK_DIR/../out/$DART_CONFIGURATION" -fi - -# Use the Dart binary in the built SDK so pub can find the version file next -# to it. -DART="$BUILD_DIR/dart-sdk/bin/dart" - -# Run pub. -PUB="$SDK_DIR/../third_party/pkg/pub/bin/pub.dart" -exec "$DART" "--packages=$SDK_DIR/../.packages" "${VM_OPTIONS[@]}" "$PUB" "$@" diff --git a/sdk_nnbd/bin/pub.bat b/sdk_nnbd/bin/pub.bat deleted file mode 100644 index 7eb8b0dde42..00000000000 --- a/sdk_nnbd/bin/pub.bat +++ /dev/null @@ -1,56 +0,0 @@ -@echo off -REM Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file -REM for details. All rights reserved. Use of this source code is governed by a -REM BSD-style license that can be found in the LICENSE file. - -rem Run pub.dart on the Dart VM. This script is only used when running pub from -rem within the Dart source repo. The shipped SDK instead uses "pub_sdk.bat", -rem which is renamed to "pub.bat" when the SDK is built. - -setlocal -rem Handle the case where dart-sdk/bin has been symlinked to. -set DIR_NAME_WITH_SLASH=%~dp0 -set DIR_NAME=%DIR_NAME_WITH_SLASH:~0,-1%% -call :follow_links "%DIR_NAME%", RETURNED_BIN_DIR -rem Get rid of surrounding quotes. -for %%i in ("%RETURNED_BIN_DIR%") do set BIN_DIR=%%~fi - -rem Get absolute full name for SDK_DIR. -for %%i in ("%BIN_DIR%\..\") do set SDK_DIR=%%~fi - -rem Remove trailing backslash if there is one -IF %SDK_DIR:~-1%==\ set SDK_DIR=%SDK_DIR:~0,-1% - -set VM_OPTIONS= - -rem We allow extra vm options to be passed in through an environment variable. -if not "_%DART_VM_OPTIONS%_" == "__" ( - set VM_OPTIONS=%VM_OPTIONS% %DART_VM_OPTIONS% -) - -rem Use the Dart binary in the built SDK so pub can find the version file next -rem to it. -set BUILD_DIR=%SDK_DIR%\..\out\ReleaseX64 -set DART=%BUILD_DIR%\dart-sdk\bin\dart - -rem Run pub. -set PUB="%SDK_DIR%\..\third_party\pkg\pub\bin\pub.dart" -"%DART%" "--packages=%SDK_DIR%\..\.packages" %VM_OPTIONS% "%PUB%" %* - -endlocal - -exit /b %errorlevel% - -:follow_links -setlocal -for %%i in (%1) do set result=%%~fi -set current= -for /f "usebackq tokens=2 delims=[]" %%i in (`dir /a:l "%~dp1" 2^>nul ^ - ^| %SystemRoot%\System32\find.exe "> %~n1 [" 2^>nul`) do ( - set current=%%i -) -if not "%current%"=="" call :follow_links "%current%", result -endlocal & set %~2=%result% -goto :eof - -:end diff --git a/sdk_nnbd/bin/pub_sdk b/sdk_nnbd/bin/pub_sdk deleted file mode 100755 index 4d298784c24..00000000000 --- a/sdk_nnbd/bin/pub_sdk +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2014, 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. - -# Run pub.dart on the Dart VM. This script assumes the Dart SDK's directory -# structure. - -function follow_links() { - file="$1" - while [ -h "$file" ]; do - # On Mac OS, readlink -f doesn't work. - file="$(readlink "$file")" - done - echo "$file" -} - -function array_contains() { - local needle="$1" - local element - shift - for element; do [ "$element" = "$needle" ] && return 0; done - return 1 -} - -# Unlike $0, $BASH_SOURCE points to the absolute path of this file. -PROG_NAME="$(follow_links "$BASH_SOURCE")" - -# Handle the case where dart-sdk/bin has been symlinked to. -BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)" - - -unset VM_OPTIONS -declare -a VM_OPTIONS - -# Allow extra VM options to be passed in through an environment variable. -if [[ $DART_VM_OPTIONS ]]; then - read -a OPTIONS <<< "$DART_VM_OPTIONS" - VM_OPTIONS+=("${OPTIONS[@]}") -fi - -# Run the pub snapshot. -DART="$BIN_DIR/dart" -if array_contains "--no-preview-dart-2" "${VM_OPTIONS[@]}"; then - echo "Pub no longer supports Dart 1" - exit -1 -else - SNAPSHOT="$BIN_DIR/snapshots/pub.dart.snapshot" - exec "$DART" "${VM_OPTIONS[@]}" "$SNAPSHOT" "$@" -fi diff --git a/sdk_nnbd/bin/pub_sdk.bat b/sdk_nnbd/bin/pub_sdk.bat deleted file mode 100644 index bde0e4a638c..00000000000 --- a/sdk_nnbd/bin/pub_sdk.bat +++ /dev/null @@ -1,53 +0,0 @@ -@echo off -REM Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file -REM for details. All rights reserved. Use of this source code is governed by a -REM BSD-style license that can be found in the LICENSE file. - -setlocal -rem Handle the case where dart-sdk/bin has been symlinked to. -set DIR_NAME_WITH_SLASH=%~dp0 -set DIR_NAME=%DIR_NAME_WITH_SLASH:~0,-1%% -call :follow_links "%DIR_NAME%", RETURNED_BIN_DIR -rem Get rid of surrounding quotes. -for %%i in ("%RETURNED_BIN_DIR%") do set BIN_DIR=%%~fi - -rem Get absolute full name for SDK_DIR. -for %%i in ("%BIN_DIR%\..\") do set SDK_DIR=%%~fi - -rem Remove trailing backslash if there is one -IF %SDK_DIR:~-1%==\ set SDK_DIR=%SDK_DIR:~0,-1% - -set VM_OPTIONS= -set USING_DART_1= - -rem We allow extra vm options to be passed in through an environment variable. -if not "_%DART_VM_OPTIONS%_" == "__" ( - set VM_OPTIONS=%VM_OPTIONS% %DART_VM_OPTIONS% - for %%o in (%DART_VM_OPTIONS%) do ( - if "%%o" equ "--no-preview-dart-2" set USING_DART_1=y - ) -) - -if defined USING_DART_1 ( - echo "Pub no longer supports Dart 1" -) else ( - "%BIN_DIR%\dart" %VM_OPTIONS% "%BIN_DIR%\snapshots\pub.dart.snapshot" %* -) - -endlocal - -exit /b %errorlevel% - -:follow_links -setlocal -for %%i in (%1) do set result=%%~fi -set current= -for /f "usebackq tokens=2 delims=[]" %%i in (`dir /a:l "%~dp1" 2^>nul ^ - ^| find "> %~n1 [" 2^>nul`) do ( - set current=%%i -) -if not "%current%"=="" call :follow_links "%current%", result -endlocal & set %~2=%result% -goto :eof - -:end diff --git a/sdk_nnbd/lib/_http/crypto.dart b/sdk_nnbd/lib/_http/crypto.dart deleted file mode 100644 index f29a15b6eb0..00000000000 --- a/sdk_nnbd/lib/_http/crypto.dart +++ /dev/null @@ -1,455 +0,0 @@ -// Copyright (c) 2012, 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. - -part of dart._http; - -class _CryptoUtils { - static const int PAD = 61; // '=' - static const int CR = 13; // '\r' - static const int LF = 10; // '\n' - static const int LINE_LENGTH = 76; - - static const String _encodeTable = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - - static const String _encodeTableUrlSafe = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; - - // Lookup table used for finding Base 64 alphabet index of a given byte. - // -2 : Outside Base 64 alphabet. - // -1 : '\r' or '\n' - // 0 : = (Padding character). - // >0 : Base 64 alphabet index of given byte. - static const List _decodeTable = const [ - -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -1, -2, -2, -1, -2, -2, // - -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, // - -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 62, -2, 62, -2, 63, // - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -2, -2, -2, 00, -2, -2, // - -2, 00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, // - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -2, -2, -2, -2, 63, // - -2, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, // - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -2, -2, -2, -2, -2, // - -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, // - -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, // - -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, // - -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, // - -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, // - -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, // - -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, // - -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2 - ]; - - static Random _rng = new Random.secure(); - - static Uint8List getRandomBytes(int count) { - final Uint8List result = new Uint8List(count); - for (int i = 0; i < count; i++) { - result[i] = _rng.nextInt(0xff); - } - return result; - } - - static String bytesToHex(List bytes) { - var result = new StringBuffer(); - for (var part in bytes) { - result.write('${part < 16 ? '0' : ''}${part.toRadixString(16)}'); - } - return result.toString(); - } - - static String bytesToBase64(List bytes, - [bool urlSafe = false, bool addLineSeparator = false]) { - int len = bytes.length; - if (len == 0) { - return ""; - } - final String lookup = urlSafe ? _encodeTableUrlSafe : _encodeTable; - // Size of 24 bit chunks. - final int remainderLength = len.remainder(3) as int; - final int chunkLength = len - remainderLength; - // Size of base output. - int outputLen = ((len ~/ 3) * 4) + ((remainderLength > 0) ? 4 : 0); - // Add extra for line separators. - if (addLineSeparator) { - outputLen += ((outputLen - 1) ~/ LINE_LENGTH) << 1; - } - List out = new List.filled(outputLen, 0); - - // Encode 24 bit chunks. - int j = 0, i = 0, c = 0; - while (i < chunkLength) { - int x = ((bytes[i++] << 16) & 0xFFFFFF) | - ((bytes[i++] << 8) & 0xFFFFFF) | - bytes[i++]; - out[j++] = lookup.codeUnitAt(x >> 18); - out[j++] = lookup.codeUnitAt((x >> 12) & 0x3F); - out[j++] = lookup.codeUnitAt((x >> 6) & 0x3F); - out[j++] = lookup.codeUnitAt(x & 0x3f); - // Add optional line separator for each 76 char output. - if (addLineSeparator && ++c == 19 && j < outputLen - 2) { - out[j++] = CR; - out[j++] = LF; - c = 0; - } - } - - // If input length if not a multiple of 3, encode remaining bytes and - // add padding. - if (remainderLength == 1) { - int x = bytes[i]; - out[j++] = lookup.codeUnitAt(x >> 2); - out[j++] = lookup.codeUnitAt((x << 4) & 0x3F); - out[j++] = PAD; - out[j++] = PAD; - } else if (remainderLength == 2) { - int x = bytes[i]; - int y = bytes[i + 1]; - out[j++] = lookup.codeUnitAt(x >> 2); - out[j++] = lookup.codeUnitAt(((x << 4) | (y >> 4)) & 0x3F); - out[j++] = lookup.codeUnitAt((y << 2) & 0x3F); - out[j++] = PAD; - } - - return new String.fromCharCodes(out); - } - - static List base64StringToBytes(String input, - [bool ignoreInvalidCharacters = true]) { - int len = input.length; - if (len == 0) { - return new List.empty(); - } - - // Count '\r', '\n' and illegal characters, For illegal characters, - // if [ignoreInvalidCharacters] is false, throw an exception. - int extrasLen = 0; - for (int i = 0; i < len; i++) { - int c = _decodeTable[input.codeUnitAt(i)]; - if (c < 0) { - extrasLen++; - if (c == -2 && !ignoreInvalidCharacters) { - throw new FormatException('Invalid character: ${input[i]}'); - } - } - } - - if ((len - extrasLen) % 4 != 0) { - throw new FormatException('''Size of Base 64 characters in Input - must be a multiple of 4. Input: $input'''); - } - - // Count pad characters, ignore illegal characters at the end. - int padLength = 0; - for (int i = len - 1; i >= 0; i--) { - int currentCodeUnit = input.codeUnitAt(i); - if (_decodeTable[currentCodeUnit] > 0) break; - if (currentCodeUnit == PAD) padLength++; - } - int outputLen = (((len - extrasLen) * 6) >> 3) - padLength; - List out = new List.filled(outputLen, 0); - - for (int i = 0, o = 0; o < outputLen;) { - // Accumulate 4 valid 6 bit Base 64 characters into an int. - int x = 0; - for (int j = 4; j > 0;) { - int c = _decodeTable[input.codeUnitAt(i++)]; - if (c >= 0) { - x = ((x << 6) & 0xFFFFFF) | c; - j--; - } - } - out[o++] = x >> 16; - if (o < outputLen) { - out[o++] = (x >> 8) & 0xFF; - if (o < outputLen) out[o++] = x & 0xFF; - } - } - return out; - } -} - -// Constants. -const _MASK_8 = 0xff; -const _MASK_32 = 0xffffffff; -const _BITS_PER_BYTE = 8; -const _BYTES_PER_WORD = 4; - -// Base class encapsulating common behavior for cryptographic hash -// functions. -abstract class _HashBase { - // Hasher state. - final int _chunkSizeInWords; - final bool _bigEndianWords; - int _lengthInBytes = 0; - List _pendingData; - List _currentChunk; - List _h; - bool _digestCalled = false; - - _HashBase(this._chunkSizeInWords, int digestSizeInWords, this._bigEndianWords) - : _pendingData = [], - _currentChunk = new List.filled(_chunkSizeInWords, 0), - _h = new List.filled(digestSizeInWords, 0); - - // Update the hasher with more data. - add(List data) { - if (_digestCalled) { - throw new StateError( - 'Hash update method called after digest was retrieved'); - } - _lengthInBytes += data.length; - _pendingData.addAll(data); - _iterate(); - } - - // Finish the hash computation and return the digest string. - List close() { - if (_digestCalled) { - return _resultAsBytes(); - } - _digestCalled = true; - _finalizeData(); - _iterate(); - assert(_pendingData.length == 0); - return _resultAsBytes(); - } - - // Returns the block size of the hash in bytes. - int get blockSize { - return _chunkSizeInWords * _BYTES_PER_WORD; - } - - // Create a fresh instance of this Hash. - newInstance(); - - // One round of the hash computation. - _updateHash(List m); - - // Helper methods. - _add32(x, y) => (x + y) & _MASK_32; - _roundUp(val, n) => (val + n - 1) & -n; - - // Rotate left limiting to unsigned 32-bit values. - int _rotl32(int val, int shift) { - var mod_shift = shift & 31; - return ((val << mod_shift) & _MASK_32) | - ((val & _MASK_32) >> (32 - mod_shift)); - } - - // Compute the final result as a list of bytes from the hash words. - List _resultAsBytes() { - var result = []; - for (var i = 0; i < _h.length; i++) { - result.addAll(_wordToBytes(_h[i])); - } - return result; - } - - // Converts a list of bytes to a chunk of 32-bit words. - _bytesToChunk(List data, int dataIndex) { - assert((data.length - dataIndex) >= (_chunkSizeInWords * _BYTES_PER_WORD)); - - for (var wordIndex = 0; wordIndex < _chunkSizeInWords; wordIndex++) { - var w3 = _bigEndianWords ? data[dataIndex] : data[dataIndex + 3]; - var w2 = _bigEndianWords ? data[dataIndex + 1] : data[dataIndex + 2]; - var w1 = _bigEndianWords ? data[dataIndex + 2] : data[dataIndex + 1]; - var w0 = _bigEndianWords ? data[dataIndex + 3] : data[dataIndex]; - dataIndex += 4; - var word = (w3 & 0xff) << 24; - word |= (w2 & _MASK_8) << 16; - word |= (w1 & _MASK_8) << 8; - word |= (w0 & _MASK_8); - _currentChunk[wordIndex] = word; - } - } - - // Convert a 32-bit word to four bytes. - List _wordToBytes(int word) { - List bytes = new List.filled(_BYTES_PER_WORD, 0); - bytes[0] = (word >> (_bigEndianWords ? 24 : 0)) & _MASK_8; - bytes[1] = (word >> (_bigEndianWords ? 16 : 8)) & _MASK_8; - bytes[2] = (word >> (_bigEndianWords ? 8 : 16)) & _MASK_8; - bytes[3] = (word >> (_bigEndianWords ? 0 : 24)) & _MASK_8; - return bytes; - } - - // Iterate through data updating the hash computation for each - // chunk. - _iterate() { - var len = _pendingData.length; - var chunkSizeInBytes = _chunkSizeInWords * _BYTES_PER_WORD; - if (len >= chunkSizeInBytes) { - var index = 0; - for (; (len - index) >= chunkSizeInBytes; index += chunkSizeInBytes) { - _bytesToChunk(_pendingData, index); - _updateHash(_currentChunk); - } - _pendingData = _pendingData.sublist(index, len); - } - } - - // Finalize the data. Add a 1 bit to the end of the message. Expand with - // 0 bits and add the length of the message. - _finalizeData() { - _pendingData.add(0x80); - var contentsLength = _lengthInBytes + 9; - var chunkSizeInBytes = _chunkSizeInWords * _BYTES_PER_WORD; - var finalizedLength = _roundUp(contentsLength, chunkSizeInBytes); - var zeroPadding = finalizedLength - contentsLength; - for (var i = 0; i < zeroPadding; i++) { - _pendingData.add(0); - } - var lengthInBits = _lengthInBytes * _BITS_PER_BYTE; - assert(lengthInBits < pow(2, 32)); - if (_bigEndianWords) { - _pendingData.addAll(_wordToBytes(0)); - _pendingData.addAll(_wordToBytes(lengthInBits & _MASK_32)); - } else { - _pendingData.addAll(_wordToBytes(lengthInBits & _MASK_32)); - _pendingData.addAll(_wordToBytes(0)); - } - } -} - -// The MD5 hasher is used to compute an MD5 message digest. -class _MD5 extends _HashBase { - _MD5() : super(16, 4, false) { - _h[0] = 0x67452301; - _h[1] = 0xefcdab89; - _h[2] = 0x98badcfe; - _h[3] = 0x10325476; - } - - // Returns a new instance of this Hash. - _MD5 newInstance() { - return new _MD5(); - } - - static const _k = const [ - 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, // - 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, // - 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340, // - 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, // - 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, // - 0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, // - 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa, // - 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, // - 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, // - 0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, // - 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 - ]; - - static const _r = const [ - 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, // - 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4, 11, // - 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15, 21, 6, // - 10, 15, 21, 6, 10, 15, 21 - ]; - - // Compute one iteration of the MD5 algorithm with a chunk of - // 16 32-bit pieces. - void _updateHash(List m) { - assert(m.length == 16); - - var a = _h[0]; - var b = _h[1]; - var c = _h[2]; - var d = _h[3]; - - var t0; - var t1; - - for (var i = 0; i < 64; i++) { - if (i < 16) { - t0 = (b & c) | ((~b & _MASK_32) & d); - t1 = i; - } else if (i < 32) { - t0 = (d & b) | ((~d & _MASK_32) & c); - t1 = ((5 * i) + 1) % 16; - } else if (i < 48) { - t0 = b ^ c ^ d; - t1 = ((3 * i) + 5) % 16; - } else { - t0 = c ^ (b | (~d & _MASK_32)); - t1 = (7 * i) % 16; - } - - var temp = d; - d = c; - c = b; - b = _add32( - b, _rotl32(_add32(_add32(a, t0), _add32(_k[i], m[t1])), _r[i])); - a = temp; - } - - _h[0] = _add32(a, _h[0]); - _h[1] = _add32(b, _h[1]); - _h[2] = _add32(c, _h[2]); - _h[3] = _add32(d, _h[3]); - } -} - -// The SHA1 hasher is used to compute an SHA1 message digest. -class _SHA1 extends _HashBase { - List _w; - - // Construct a SHA1 hasher object. - _SHA1() - : _w = List.filled(80, 0), - super(16, 5, true) { - _h[0] = 0x67452301; - _h[1] = 0xEFCDAB89; - _h[2] = 0x98BADCFE; - _h[3] = 0x10325476; - _h[4] = 0xC3D2E1F0; - } - - // Returns a new instance of this Hash. - _SHA1 newInstance() { - return new _SHA1(); - } - - // Compute one iteration of the SHA1 algorithm with a chunk of - // 16 32-bit pieces. - void _updateHash(List m) { - assert(m.length == 16); - - var a = _h[0]; - var b = _h[1]; - var c = _h[2]; - var d = _h[3]; - var e = _h[4]; - - for (var i = 0; i < 80; i++) { - if (i < 16) { - _w[i] = m[i]; - } else { - var n = _w[i - 3] ^ _w[i - 8] ^ _w[i - 14] ^ _w[i - 16]; - _w[i] = _rotl32(n, 1); - } - var t = _add32(_add32(_rotl32(a, 5), e), _w[i]); - if (i < 20) { - t = _add32(_add32(t, (b & c) | (~b & d)), 0x5A827999); - } else if (i < 40) { - t = _add32(_add32(t, (b ^ c ^ d)), 0x6ED9EBA1); - } else if (i < 60) { - t = _add32(_add32(t, (b & c) | (b & d) | (c & d)), 0x8F1BBCDC); - } else { - t = _add32(_add32(t, b ^ c ^ d), 0xCA62C1D6); - } - - e = d; - d = c; - c = _rotl32(b, 30); - b = a; - a = t & _MASK_32; - } - - _h[0] = _add32(a, _h[0]); - _h[1] = _add32(b, _h[1]); - _h[2] = _add32(c, _h[2]); - _h[3] = _add32(d, _h[3]); - _h[4] = _add32(e, _h[4]); - } -} diff --git a/sdk_nnbd/lib/_http/embedder_config.dart b/sdk_nnbd/lib/_http/embedder_config.dart deleted file mode 100644 index 730bc2ddb61..00000000000 --- a/sdk_nnbd/lib/_http/embedder_config.dart +++ /dev/null @@ -1,11 +0,0 @@ -// 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. - -part of dart._http; - -/// Embedder-specific `dart:_http` configuration. - -/// [HttpClient] will disallow HTTP URLs if this value is set to `false`. -@pragma("vm:entry-point") -bool _embedderAllowsHttp = true; diff --git a/sdk_nnbd/lib/_http/http.dart b/sdk_nnbd/lib/_http/http.dart deleted file mode 100644 index 6db8524ad46..00000000000 --- a/sdk_nnbd/lib/_http/http.dart +++ /dev/null @@ -1,2282 +0,0 @@ -// Copyright (c) 2013, 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 dart._http; - -import 'dart:async'; -import 'dart:collection' - show - HashMap, - HashSet, - Queue, - ListQueue, - LinkedList, - LinkedListEntry, - UnmodifiableMapView; -import 'dart:convert'; -import 'dart:developer' hide log; -import 'dart:_internal' - show Since, valueOfNonNullableParamWithDefault, HttpStatus; -import 'dart:math'; -import 'dart:io'; -import 'dart:typed_data'; - -part 'crypto.dart'; -part 'embedder_config.dart'; -part 'http_date.dart'; -part 'http_headers.dart'; -part 'http_impl.dart'; -part 'http_parser.dart'; -part 'http_session.dart'; -part 'overrides.dart'; -part 'websocket.dart'; -part 'websocket_impl.dart'; - -/** - * A server that delivers content, such as web pages, using the HTTP protocol. - * - * The HttpServer is a [Stream] that provides [HttpRequest] objects. Each - * HttpRequest has an associated [HttpResponse] object. - * The server responds to a request by writing to that HttpResponse object. - * The following example shows how to bind an HttpServer to an IPv6 - * [InternetAddress] on port 80 (the standard port for HTTP servers) - * and how to listen for requests. - * Port 80 is the default HTTP port. However, on most systems accessing - * this requires super-user privileges. For local testing consider - * using a non-reserved port (1024 and above). - * - * import 'dart:io'; - * - * main() { - * HttpServer - * .bind(InternetAddress.anyIPv6, 80) - * .then((server) { - * server.listen((HttpRequest request) { - * request.response.write('Hello, world!'); - * request.response.close(); - * }); - * }); - * } - * - * Incomplete requests, in which all or part of the header is missing, are - * ignored, and no exceptions or HttpRequest objects are generated for them. - * Likewise, when writing to an HttpResponse, any [Socket] exceptions are - * ignored and any future writes are ignored. - * - * The HttpRequest exposes the request headers and provides the request body, - * if it exists, as a Stream of data. If the body is unread, it is drained - * when the server writes to the HttpResponse or closes it. - * - * ## Bind with a secure HTTPS connection - * - * Use [bindSecure] to create an HTTPS server. - * - * The server presents a certificate to the client. The certificate - * chain and the private key are set in the [SecurityContext] - * object that is passed to [bindSecure]. - * - * import 'dart:io'; - * import "dart:isolate"; - * - * main() { - * SecurityContext context = new SecurityContext(); - * var chain = - * Platform.script.resolve('certificates/server_chain.pem') - * .toFilePath(); - * var key = - * Platform.script.resolve('certificates/server_key.pem') - * .toFilePath(); - * context.useCertificateChain(chain); - * context.usePrivateKey(key, password: 'dartdart'); - * - * HttpServer - * .bindSecure(InternetAddress.anyIPv6, - * 443, - * context) - * .then((server) { - * server.listen((HttpRequest request) { - * request.response.write('Hello, world!'); - * request.response.close(); - * }); - * }); - * } - * - * The certificates and keys are PEM files, which can be created and - * managed with the tools in OpenSSL. - * - * ## Connect to a server socket - * - * You can use the [listenOn] constructor to attach an HTTP server to - * a [ServerSocket]. - * - * import 'dart:io'; - * - * main() { - * ServerSocket.bind(InternetAddress.anyIPv6, 80) - * .then((serverSocket) { - * HttpServer httpserver = new HttpServer.listenOn(serverSocket); - * serverSocket.listen((Socket socket) { - * socket.write('Hello, client.'); - * }); - * }); - * } - * - * ## Other resources - * - * * HttpServer is a Stream. Refer to the [Stream] class for information - * about the streaming qualities of an HttpServer. - * Pausing the subscription of the stream, pauses at the OS level. - * - * * The [shelf](https://pub.dev/packages/shelf) - * package on pub.dev contains a set of high-level classes that, - * together with this class, makes it easy to provide content through HTTP - * servers. - */ -abstract class HttpServer implements Stream { - /** - * Gets and sets the default value of the `Server` header for all responses - * generated by this [HttpServer]. - * - * If [serverHeader] is `null`, no `Server` header will be added to each - * response. - * - * The default value is `null`. - */ - String? serverHeader; - - /** - * Default set of headers added to all response objects. - * - * By default the following headers are in this set: - * - * Content-Type: text/plain; charset=utf-8 - * X-Frame-Options: SAMEORIGIN - * X-Content-Type-Options: nosniff - * X-XSS-Protection: 1; mode=block - * - * If the `Server` header is added here and the `serverHeader` is set as - * well then the value of `serverHeader` takes precedence. - */ - HttpHeaders get defaultResponseHeaders; - - /** - * Whether the [HttpServer] should compress the content, if possible. - * - * The content can only be compressed when the response is using - * chunked Transfer-Encoding and the incoming request has `gzip` - * as an accepted encoding in the Accept-Encoding header. - * - * The default value is `false` (compression disabled). - * To enable, set `autoCompress` to `true`. - */ - bool autoCompress = false; - - /** - * Gets or sets the timeout used for idle keep-alive connections. If no - * further request is seen within [idleTimeout] after the previous request was - * completed, the connection is dropped. - * - * Default is 120 seconds. - * - * Note that it may take up to `2 * idleTimeout` before a idle connection is - * aborted. - * - * To disable, set [idleTimeout] to `null`. - */ - Duration? idleTimeout = const Duration(seconds: 120); - - /** - * Starts listening for HTTP requests on the specified [address] and - * [port]. - * - * The [address] can either be a [String] or an - * [InternetAddress]. If [address] is a [String], [bind] will - * perform a [InternetAddress.lookup] and use the first value in the - * list. To listen on the loopback adapter, which will allow only - * incoming connections from the local host, use the value - * [InternetAddress.loopbackIPv4] or - * [InternetAddress.loopbackIPv6]. To allow for incoming - * connection from the network use either one of the values - * [InternetAddress.anyIPv4] or [InternetAddress.anyIPv6] to - * bind to all interfaces or the IP address of a specific interface. - * - * If an IP version 6 (IPv6) address is used, both IP version 6 - * (IPv6) and version 4 (IPv4) connections will be accepted. To - * restrict this to version 6 (IPv6) only, use [v6Only] to set - * version 6 only. However, if the address is - * [InternetAddress.loopbackIPv6], only IP version 6 (IPv6) connections - * will be accepted. - * - * If [port] has the value 0 an ephemeral port will be chosen by - * the system. The actual port used can be retrieved using the - * [port] getter. - * - * The optional argument [backlog] can be used to specify the listen - * backlog for the underlying OS listen setup. If [backlog] has the - * value of 0 (the default) a reasonable value will be chosen by - * the system. - * - * The optional argument [shared] specifies whether additional HttpServer - * objects can bind to the same combination of `address`, `port` and `v6Only`. - * If `shared` is `true` and more `HttpServer`s from this isolate or other - * isolates are bound to the port, then the incoming connections will be - * distributed among all the bound `HttpServer`s. Connections can be - * distributed over multiple isolates this way. - */ - static Future bind(address, int port, - {int backlog = 0, bool v6Only = false, bool shared = false}) => - _HttpServer.bind(address, port, backlog, v6Only, shared); - - /** - * The [address] can either be a [String] or an - * [InternetAddress]. If [address] is a [String], [bind] will - * perform a [InternetAddress.lookup] and use the first value in the - * list. To listen on the loopback adapter, which will allow only - * incoming connections from the local host, use the value - * [InternetAddress.loopbackIPv4] or - * [InternetAddress.loopbackIPv6]. To allow for incoming - * connection from the network use either one of the values - * [InternetAddress.anyIPv4] or [InternetAddress.anyIPv6] to - * bind to all interfaces or the IP address of a specific interface. - * - * If an IP version 6 (IPv6) address is used, both IP version 6 - * (IPv6) and version 4 (IPv4) connections will be accepted. To - * restrict this to version 6 (IPv6) only, use [v6Only] to set - * version 6 only. - * - * If [port] has the value 0 an ephemeral port will be chosen by - * the system. The actual port used can be retrieved using the - * [port] getter. - * - * The optional argument [backlog] can be used to specify the listen - * backlog for the underlying OS listen setup. If [backlog] has the - * value of 0 (the default) a reasonable value will be chosen by - * the system. - * - * If [requestClientCertificate] is true, the server will - * request clients to authenticate with a client certificate. - * The server will advertise the names of trusted issuers of client - * certificates, getting them from a [SecurityContext], where they have been - * set using [SecurityContext.setClientAuthorities]. - * - * The optional argument [shared] specifies whether additional HttpServer - * objects can bind to the same combination of `address`, `port` and `v6Only`. - * If `shared` is `true` and more `HttpServer`s from this isolate or other - * isolates are bound to the port, then the incoming connections will be - * distributed among all the bound `HttpServer`s. Connections can be - * distributed over multiple isolates this way. - */ - - static Future bindSecure( - address, int port, SecurityContext context, - {int backlog = 0, - bool v6Only = false, - bool requestClientCertificate = false, - bool shared = false}) => - _HttpServer.bindSecure(address, port, context, backlog, v6Only, - requestClientCertificate, shared); - - /** - * Attaches the HTTP server to an existing [ServerSocket]. When the - * [HttpServer] is closed, the [HttpServer] will just detach itself, - * closing current connections but not closing [serverSocket]. - */ - factory HttpServer.listenOn(ServerSocket serverSocket) => - new _HttpServer.listenOn(serverSocket); - - /** - * Permanently stops this [HttpServer] from listening for new - * connections. This closes the [Stream] of [HttpRequest]s with a - * done event. The returned future completes when the server is - * stopped. For a server started using [bind] or [bindSecure] this - * means that the port listened on no longer in use. - * - * If [force] is `true`, active connections will be closed immediately. - */ - Future close({bool force = false}); - - /** - * The port that the server is listening on. - * - * This is the actual port used when a port of zero is - * specified in the [bind] or [bindSecure] call. - */ - int get port; - - /** - * The address that the server is listening on. - * - * This is the actual address used when the original address - * was specified as a hostname. - */ - InternetAddress get address; - - /** - * Sets the timeout, in seconds, for sessions of this [HttpServer]. - * - * The default timeout is 20 minutes. - */ - set sessionTimeout(int timeout); - - /** - * A [HttpConnectionsInfo] object summarizing the number of - * current connections handled by the server. - */ - HttpConnectionsInfo connectionsInfo(); -} - -/** - * Summary statistics about an [HttpServer]s current socket connections. - */ -class HttpConnectionsInfo { - /** - * Total number of socket connections. - */ - int total = 0; - - /** - * Number of active connections where actual request/response - * processing is active. - */ - int active = 0; - - /** - * Number of idle connections held by clients as persistent connections. - */ - int idle = 0; - - /** - * Number of connections which are preparing to close. - * - * Note: These connections are also part of the [active] count as they might - * still be sending data to the client before finally closing. - */ - int closing = 0; -} - -/** - * Headers for HTTP requests and responses. - * - * In some situations, headers are immutable: - * - * * [HttpRequest] and [HttpClientResponse] always have immutable headers. - * - * * [HttpResponse] and [HttpClientRequest] have immutable headers - * from the moment the body is written to. - * - * In these situations, the mutating methods throw exceptions. - * - * For all operations on HTTP headers the header name is - * case-insensitive. - * - * To set the value of a header use the `set()` method: - * - * request.headers.set(HttpHeaders.cacheControlHeader, - * 'max-age=3600, must-revalidate'); - * - * To retrieve the value of a header use the `value()` method: - * - * print(request.headers.value(HttpHeaders.userAgentHeader)); - * - * An `HttpHeaders` object holds a list of values for each name - * as the standard allows. In most cases a name holds only a single value, - * The most common mode of operation is to use `set()` for setting a value, - * and `value()` for retrieving a value. - */ -abstract class HttpHeaders { - static const acceptHeader = "accept"; - static const acceptCharsetHeader = "accept-charset"; - static const acceptEncodingHeader = "accept-encoding"; - static const acceptLanguageHeader = "accept-language"; - static const acceptRangesHeader = "accept-ranges"; - static const ageHeader = "age"; - static const allowHeader = "allow"; - static const authorizationHeader = "authorization"; - static const cacheControlHeader = "cache-control"; - static const connectionHeader = "connection"; - static const contentEncodingHeader = "content-encoding"; - static const contentLanguageHeader = "content-language"; - static const contentLengthHeader = "content-length"; - static const contentLocationHeader = "content-location"; - static const contentMD5Header = "content-md5"; - static const contentRangeHeader = "content-range"; - static const contentTypeHeader = "content-type"; - static const dateHeader = "date"; - static const etagHeader = "etag"; - static const expectHeader = "expect"; - static const expiresHeader = "expires"; - static const fromHeader = "from"; - static const hostHeader = "host"; - static const ifMatchHeader = "if-match"; - static const ifModifiedSinceHeader = "if-modified-since"; - static const ifNoneMatchHeader = "if-none-match"; - static const ifRangeHeader = "if-range"; - static const ifUnmodifiedSinceHeader = "if-unmodified-since"; - static const lastModifiedHeader = "last-modified"; - static const locationHeader = "location"; - static const maxForwardsHeader = "max-forwards"; - static const pragmaHeader = "pragma"; - static const proxyAuthenticateHeader = "proxy-authenticate"; - static const proxyAuthorizationHeader = "proxy-authorization"; - static const rangeHeader = "range"; - static const refererHeader = "referer"; - static const retryAfterHeader = "retry-after"; - static const serverHeader = "server"; - static const teHeader = "te"; - static const trailerHeader = "trailer"; - static const transferEncodingHeader = "transfer-encoding"; - static const upgradeHeader = "upgrade"; - static const userAgentHeader = "user-agent"; - static const varyHeader = "vary"; - static const viaHeader = "via"; - static const warningHeader = "warning"; - static const wwwAuthenticateHeader = "www-authenticate"; - - @Deprecated("Use acceptHeader instead") - static const ACCEPT = acceptHeader; - @Deprecated("Use acceptCharsetHeader instead") - static const ACCEPT_CHARSET = acceptCharsetHeader; - @Deprecated("Use acceptEncodingHeader instead") - static const ACCEPT_ENCODING = acceptEncodingHeader; - @Deprecated("Use acceptLanguageHeader instead") - static const ACCEPT_LANGUAGE = acceptLanguageHeader; - @Deprecated("Use acceptRangesHeader instead") - static const ACCEPT_RANGES = acceptRangesHeader; - @Deprecated("Use ageHeader instead") - static const AGE = ageHeader; - @Deprecated("Use allowHeader instead") - static const ALLOW = allowHeader; - @Deprecated("Use authorizationHeader instead") - static const AUTHORIZATION = authorizationHeader; - @Deprecated("Use cacheControlHeader instead") - static const CACHE_CONTROL = cacheControlHeader; - @Deprecated("Use connectionHeader instead") - static const CONNECTION = connectionHeader; - @Deprecated("Use contentEncodingHeader instead") - static const CONTENT_ENCODING = contentEncodingHeader; - @Deprecated("Use contentLanguageHeader instead") - static const CONTENT_LANGUAGE = contentLanguageHeader; - @Deprecated("Use contentLengthHeader instead") - static const CONTENT_LENGTH = contentLengthHeader; - @Deprecated("Use contentLocationHeader instead") - static const CONTENT_LOCATION = contentLocationHeader; - @Deprecated("Use contentMD5Header instead") - static const CONTENT_MD5 = contentMD5Header; - @Deprecated("Use contentRangeHeader instead") - static const CONTENT_RANGE = contentRangeHeader; - @Deprecated("Use contentTypeHeader instead") - static const CONTENT_TYPE = contentTypeHeader; - @Deprecated("Use dateHeader instead") - static const DATE = dateHeader; - @Deprecated("Use etagHeader instead") - static const ETAG = etagHeader; - @Deprecated("Use expectHeader instead") - static const EXPECT = expectHeader; - @Deprecated("Use expiresHeader instead") - static const EXPIRES = expiresHeader; - @Deprecated("Use fromHeader instead") - static const FROM = fromHeader; - @Deprecated("Use hostHeader instead") - static const HOST = hostHeader; - @Deprecated("Use ifMatchHeader instead") - static const IF_MATCH = ifMatchHeader; - @Deprecated("Use ifModifiedSinceHeader instead") - static const IF_MODIFIED_SINCE = ifModifiedSinceHeader; - @Deprecated("Use ifNoneMatchHeader instead") - static const IF_NONE_MATCH = ifNoneMatchHeader; - @Deprecated("Use ifRangeHeader instead") - static const IF_RANGE = ifRangeHeader; - @Deprecated("Use ifUnmodifiedSinceHeader instead") - static const IF_UNMODIFIED_SINCE = ifUnmodifiedSinceHeader; - @Deprecated("Use lastModifiedHeader instead") - static const LAST_MODIFIED = lastModifiedHeader; - @Deprecated("Use locationHeader instead") - static const LOCATION = locationHeader; - @Deprecated("Use maxForwardsHeader instead") - static const MAX_FORWARDS = maxForwardsHeader; - @Deprecated("Use pragmaHeader instead") - static const PRAGMA = pragmaHeader; - @Deprecated("Use proxyAuthenticateHeader instead") - static const PROXY_AUTHENTICATE = proxyAuthenticateHeader; - @Deprecated("Use proxyAuthorizationHeader instead") - static const PROXY_AUTHORIZATION = proxyAuthorizationHeader; - @Deprecated("Use rangeHeader instead") - static const RANGE = rangeHeader; - @Deprecated("Use refererHeader instead") - static const REFERER = refererHeader; - @Deprecated("Use retryAfterHeader instead") - static const RETRY_AFTER = retryAfterHeader; - @Deprecated("Use serverHeader instead") - static const SERVER = serverHeader; - @Deprecated("Use teHeader instead") - static const TE = teHeader; - @Deprecated("Use trailerHeader instead") - static const TRAILER = trailerHeader; - @Deprecated("Use transferEncodingHeader instead") - static const TRANSFER_ENCODING = transferEncodingHeader; - @Deprecated("Use upgradeHeader instead") - static const UPGRADE = upgradeHeader; - @Deprecated("Use userAgentHeader instead") - static const USER_AGENT = userAgentHeader; - @Deprecated("Use varyHeader instead") - static const VARY = varyHeader; - @Deprecated("Use viaHeader instead") - static const VIA = viaHeader; - @Deprecated("Use warningHeader instead") - static const WARNING = warningHeader; - @Deprecated("Use wwwAuthenticateHeader instead") - static const WWW_AUTHENTICATE = wwwAuthenticateHeader; - - // Cookie headers from RFC 6265. - static const cookieHeader = "cookie"; - static const setCookieHeader = "set-cookie"; - - @Deprecated("Use cookieHeader instead") - static const COOKIE = cookieHeader; - @Deprecated("Use setCookieHeader instead") - static const SET_COOKIE = setCookieHeader; - - // TODO(39783): Document this. - static const generalHeaders = const [ - cacheControlHeader, - connectionHeader, - dateHeader, - pragmaHeader, - trailerHeader, - transferEncodingHeader, - upgradeHeader, - viaHeader, - warningHeader - ]; - - @Deprecated("Use generalHeaders instead") - static const GENERAL_HEADERS = generalHeaders; - - static const entityHeaders = const [ - allowHeader, - contentEncodingHeader, - contentLanguageHeader, - contentLengthHeader, - contentLocationHeader, - contentMD5Header, - contentRangeHeader, - contentTypeHeader, - expiresHeader, - lastModifiedHeader - ]; - - @Deprecated("Use entityHeaders instead") - static const ENTITY_HEADERS = entityHeaders; - - static const responseHeaders = const [ - acceptRangesHeader, - ageHeader, - etagHeader, - locationHeader, - proxyAuthenticateHeader, - retryAfterHeader, - serverHeader, - varyHeader, - wwwAuthenticateHeader - ]; - - @Deprecated("Use responseHeaders instead") - static const RESPONSE_HEADERS = responseHeaders; - - static const requestHeaders = const [ - acceptHeader, - acceptCharsetHeader, - acceptEncodingHeader, - acceptLanguageHeader, - authorizationHeader, - expectHeader, - fromHeader, - hostHeader, - ifMatchHeader, - ifModifiedSinceHeader, - ifNoneMatchHeader, - ifRangeHeader, - ifUnmodifiedSinceHeader, - maxForwardsHeader, - proxyAuthorizationHeader, - rangeHeader, - refererHeader, - teHeader, - userAgentHeader - ]; - - @Deprecated("Use requestHeaders instead") - static const REQUEST_HEADERS = requestHeaders; - - /** - * The date specified by the [dateHeader] header, if any. - */ - DateTime? date; - - /** - * The date and time specified by the [expiresHeader] header, if any. - */ - DateTime? expires; - - /** - * The date and time specified by the [ifModifiedSinceHeader] header, if any. - */ - DateTime? ifModifiedSince; - - /** - * The value of the [hostHeader] header, if any. - */ - String? host; - - /** - * The value of the port part of the [hostHeader] header, if any. - */ - int? port; - - /** - * The [ContentType] of the [contentTypeHeader] header, if any. - */ - ContentType? contentType; - - /** - * The value of the [contentLengthHeader] header, if any. - * - * The value is negative if there is no content length set. - */ - int contentLength = -1; - - /** - * Whether the connection is persistent (keep-alive). - */ - late bool persistentConnection; - - /** - * Whether the connection uses chunked transfer encoding. - * - * Reflects and modifies the value of the [transferEncodingHeader] header. - */ - late bool chunkedTransferEncoding; - - /** - * The values for the header named [name]. - * - * Returns null if there is no header with the provided name, - * otherwise returns a new list containing the current values. - * Not that modifying the list does not change the header. - */ - List? operator [](String name); - - /** - * Convenience method for the value for a single valued header. - * - * The value must not have more than one value. - * - * Returns `null` if there is no header with the provided name. - */ - String? value(String name); - - /** - * Adds a header value. - * - * The header named [name] will have a string value derived from [value] - * added to its list of values. - * - * Some headers are single valued, and for these, adding a value will - * replace a previous value. If the [value] is a [DateTime], an - * HTTP date format will be applied. If the value is an [Iterable], - * each element will be added separately. For all other - * types the default [Object.toString] method will be used. - * - * Header names are converted to lower-case unless - * [preserveHeaderCase] is set to true. If two header names are - * the same when converted to lower-case, they are considered to be - * the same header, with one set of values. - * - * The current case of the a header name is that of the name used by - * the last [set] or [add] call for that header. - */ - void add(String name, Object value, - {@Since("2.8") bool preserveHeaderCase = false}); - - /** - * Sets the header [name] to [value]. - * - * Removes all existing values for the header named [name] and - * then [add]s [value] to it. - */ - void set(String name, Object value, - {@Since("2.8") bool preserveHeaderCase = false}); - - /** - * Removes a specific value for a header name. - * - * Some headers have system supplied values which cannot be removed. - * For all other headers and values, the [value] is converted to a string - * in the same way as for [add], then that string value is removed from the - * current values of [name]. - * If there are no remaining values for [name], the header is no longer - * considered present. - */ - void remove(String name, Object value); - - /** - * Removes all values for the specified header name. - * - * Some headers have system supplied values which cannot be removed. - * All other values for [name] are removed. - * If there are no remaining values for [name], the header is no longer - * considered present. - */ - void removeAll(String name); - - /** - * Performs the [action] on each header. - * - * The [action] function is called with each header's name and a list - * of the header's values. The casing of the name string is determined by - * the last [add] or [set] operation for that particular header, - * which defaults to lower-casing the header name unless explicitly - * set to preserve the case. - */ - void forEach(void action(String name, List values)); - - /** - * Disables folding for the header named [name] when sending the HTTP header. - * - * By default, multiple header values are folded into a - * single header line by separating the values with commas. - * - * The 'set-cookie' header has folding disabled by default. - */ - void noFolding(String name); - - /** - * Removes all headers. - * - * Some headers have system supplied values which cannot be removed. - * All other header values are removed, and header names with not - * remaining values are no longer considered present. - */ - void clear(); -} - -/** - * Representation of a header value in the form: - * ```dart - * value; parameter1=value1; parameter2=value2 - * ``` - * - * [HeaderValue] can be used to conveniently build and parse header - * values on this form. - * - * Parameter values can be omitted, in which case the value is parsed as `null`. - * Values can be doubled quoted to allow characters outside of the RFC 7230 - * token characters and backslash sequences can be used to represent the double - * quote and backslash characters themselves. - * - * To build an "accepts" header with the value - * - * text/plain; q=0.3, text/html - * - * use code like this: - * - * HttpClientRequest request = ...; - * var v = new HeaderValue("text/plain", {"q": "0.3"}); - * request.headers.add(HttpHeaders.acceptHeader, v); - * request.headers.add(HttpHeaders.acceptHeader, "text/html"); - * - * To parse the header values use the [parse] static method. - * - * HttpRequest request = ...; - * List values = request.headers[HttpHeaders.acceptHeader]; - * values.forEach((value) { - * HeaderValue v = HeaderValue.parse(value); - * // Use v.value and v.parameters - * }); - * - * An instance of [HeaderValue] is immutable. - */ -abstract class HeaderValue { - /** - * Creates a new header value object setting the value and parameters. - */ - factory HeaderValue( - [String value = "", Map parameters = const {}]) { - return new _HeaderValue(value, parameters); - } - - /** - * Creates a new header value object from parsing a header value - * string with both value and optional parameters. - */ - static HeaderValue parse(String value, - {String parameterSeparator = ";", - String? valueSeparator, - bool preserveBackslash = false}) { - return _HeaderValue.parse(value, - parameterSeparator: parameterSeparator, - valueSeparator: valueSeparator, - preserveBackslash: preserveBackslash); - } - - /** - * The value of the header. - */ - String get value; - - /** - * A map of parameters. - * - * This map cannot be modified. - */ - Map get parameters; - - /** - * Returns the formatted string representation in the form: - * ``` - * value; parameter1=value1; parameter2=value2 - * ``` - */ - String toString(); -} - -abstract class HttpSession implements Map { - /** - * The id of the current session. - */ - String get id; - - /** - * Destroys the session. - * - * This terminates the session and any further - * connections with this id will be given a new id and session. - */ - void destroy(); - - /** - * Sets a callback that will be called when the session is timed out. - * - * Calling this again will overwrite the previous value. - */ - void set onTimeout(void callback()); - - /** - * Whether the session has not yet been sent to the client. - */ - bool get isNew; -} - -/** - * A MIME/IANA media type used as the value of the [contentTypeHeader] header. - * - * A [ContentType] is immutable. - */ -abstract class ContentType implements HeaderValue { - /** - * Content type for plain text using UTF-8 encoding. - * - * text/plain; charset=utf-8 - */ - static final text = new ContentType("text", "plain", charset: "utf-8"); - @Deprecated("Use text instead") - static final TEXT = text; - - /** - * Content type for HTML using UTF-8 encoding. - * - * text/html; charset=utf-8 - */ - static final html = new ContentType("text", "html", charset: "utf-8"); - @Deprecated("Use html instead") - static final HTML = html; - - /** - * Content type for JSON using UTF-8 encoding. - * - * application/json; charset=utf-8 - */ - static final json = new ContentType("application", "json", charset: "utf-8"); - @Deprecated("Use json instead") - static final JSON = json; - - /** - * Content type for binary data. - * - * application/octet-stream - */ - static final binary = new ContentType("application", "octet-stream"); - @Deprecated("Use binary instead") - static final BINARY = binary; - - /** - * Creates a new content type object setting the primary type and - * sub type. The charset and additional parameters can also be set - * using [charset] and [parameters]. If charset is passed and - * [parameters] contains charset as well the passed [charset] will - * override the value in parameters. Keys passed in parameters will be - * converted to lower case. The `charset` entry, whether passed as `charset` - * or in `parameters`, will have its value converted to lower-case. - */ - factory ContentType(String primaryType, String subType, - {String? charset, Map parameters = const {}}) { - return new _ContentType(primaryType, subType, charset, parameters); - } - - /** - * Creates a new content type object from parsing a Content-Type - * header value. As primary type, sub type and parameter names and - * values are not case sensitive all these values will be converted - * to lower case. Parsing this string - * - * text/html; charset=utf-8 - * - * will create a content type object with primary type "text", - * subtype "html" and parameter "charset" with value "utf-8". - * There may be more parameters supplied, but they are not recognized - * by this class. - */ - static ContentType parse(String value) { - return _ContentType.parse(value); - } - - /** - * Gets the MIME type and subtype, without any parameters. - * - * For the full content type `text/html;charset=utf-8`, - * the [mimeType] value is the string `text/html`. - */ - String get mimeType; - - /** - * Gets the primary type. - * - * For the full content type `text/html;charset=utf-8`, - * the [primaryType] value is the string `text`. - */ - String get primaryType; - - /** - * Gets the subtype. - * - * For the full content type `text/html;charset=utf-8`, - * the [subType] value is the string `html`. - * May be the empty string. - */ - String get subType; - - /** - * Gets the character set, if any. - * - * For the full content type `text/html;charset=utf-8`, - * the [charset] value is the string `utf-8`. - */ - String? get charset; -} - -/** - * Representation of a cookie. For cookies received by the server as Cookie - * header values only [name] and [value] properties will be set. When building a - * cookie for the 'set-cookie' header in the server and when receiving cookies - * in the client as 'set-cookie' headers all fields can be used. - */ -abstract class Cookie { - /** - * The name of the cookie. - * - * Must be a `token` as specified in RFC 6265. - * - * The allowed characters in a `token` are the visible ASCII characters, - * U+0021 (`!`) through U+007E (`~`), except the separator characters: - * `(`, `)`, `<`, `>`, `@`, `,`, `;`, `:`, `\`, `"`, `/`, `[`, `]`, `?`, `=`, - * `{`, and `}`. - */ - late String name; - - /** - * The value of the cookie. - * - * Must be a `cookie-value` as specified in RFC 6265. - * - * The allowed characters in a cookie value are the visible ASCII characters, - * U+0021 (`!`) through U+007E (`~`) except the characters: - * `"`, `,`, `;` and `\`. - * Cookie values may be wrapped in a single pair of double quotes - * (U+0022, `"`). - */ - late String value; - - /** - * The time at which the cookie expires. - */ - DateTime? expires; - - /** - * The number of seconds until the cookie expires. A zero or negative value - * means the cookie has expired. - */ - int? maxAge; - - /** - * The domain that the cookie applies to. - */ - String? domain; - - /** - * The path within the [domain] that the cookie applies to. - */ - String? path; - - /** - * Whether to only send this cookie on secure connections. - */ - bool secure = false; - - /** - * Whether the cookie is only sent in the HTTP request and is not made - * available to client side scripts. - */ - bool httpOnly = false; - - /** - * Creates a new cookie setting the name and value. - * - * [name] and [value] must be composed of valid characters according to RFC - * 6265. - * - * By default the value of `httpOnly` will be set to `true`. - */ - factory Cookie(String name, String value) => new _Cookie(name, value); - - /** - * Creates a new cookie by parsing a header value from a 'set-cookie' - * header. - */ - factory Cookie.fromSetCookieValue(String value) { - return new _Cookie.fromSetCookieValue(value); - } - - /** - * Returns the formatted string representation of the cookie. The - * string representation can be used for for setting the Cookie or - * 'set-cookie' headers - */ - String toString(); -} - -/** - * A server-side object - * that contains the content of and information about an HTTP request. - * - * __Note__: Check out the - * [http_server](https://pub.dev/packages/http_server) - * package, which makes working with the low-level - * dart:io HTTP server subsystem easier. - * - * `HttpRequest` objects are generated by an [HttpServer], - * which listens for HTTP requests on a specific host and port. - * For each request received, the HttpServer, which is a [Stream], - * generates an `HttpRequest` object and adds it to the stream. - * - * An `HttpRequest` object delivers the body content of the request - * as a stream of byte lists. - * The object also contains information about the request, - * such as the method, URI, and headers. - * - * In the following code, an HttpServer listens - * for HTTP requests. When the server receives a request, - * it uses the HttpRequest object's `method` property to dispatch requests. - * - * final HOST = InternetAddress.loopbackIPv4; - * final PORT = 80; - * - * HttpServer.bind(HOST, PORT).then((_server) { - * _server.listen((HttpRequest request) { - * switch (request.method) { - * case 'GET': - * handleGetRequest(request); - * break; - * case 'POST': - * ... - * } - * }, - * onError: handleError); // listen() failed. - * }).catchError(handleError); - * - * An HttpRequest object provides access to the associated [HttpResponse] - * object through the response property. - * The server writes its response to the body of the HttpResponse object. - * For example, here's a function that responds to a request: - * - * void handleGetRequest(HttpRequest req) { - * HttpResponse res = req.response; - * res.write('Received request ${req.method}: ${req.uri.path}'); - * res.close(); - * } - */ -abstract class HttpRequest implements Stream { - /** - * The content length of the request body. - * - * If the size of the request body is not known in advance, - * this value is -1. - */ - int get contentLength; - - /** - * The method, such as 'GET' or 'POST', for the request. - */ - String get method; - - /** - * The URI for the request. - * - * This provides access to the - * path and query string for the request. - */ - Uri get uri; - - /** - * The requested URI for the request. - * - * The returned URI is reconstructed by using http-header fields, to access - * otherwise lost information, e.g. host and scheme. - * - * To reconstruct the scheme, first 'X-Forwarded-Proto' is checked, and then - * falling back to server type. - * - * To reconstruct the host, first 'X-Forwarded-Host' is checked, then 'Host' - * and finally calling back to server. - */ - Uri get requestedUri; - - /** - * The request headers. - * - * The returned [HttpHeaders] are immutable. - */ - HttpHeaders get headers; - - /** - * The cookies in the request, from the "Cookie" headers. - */ - List get cookies; - - /** - * The persistent connection state signaled by the client. - */ - bool get persistentConnection; - - /** - * The client certificate of the client making the request. - * - * This value is null if the connection is not a secure TLS or SSL connection, - * or if the server does not request a client certificate, or if the client - * does not provide one. - */ - X509Certificate? get certificate; - - /** - * The session for the given request. - * - * If the session is being initialized by this call, - * [HttpSession.isNew] is true for the returned session. - * See [HttpServer.sessionTimeout] on how to change default timeout. - */ - HttpSession get session; - - /** - * The HTTP protocol version used in the request, - * either "1.0" or "1.1". - */ - String get protocolVersion; - - /** - * Information about the client connection. - * - * Returns `null` if the socket is not available. - */ - HttpConnectionInfo? get connectionInfo; - - /** - * The [HttpResponse] object, used for sending back the response to the - * client. - * - * If the [contentLength] of the body isn't 0, and the body isn't being read, - * any write calls on the [HttpResponse] automatically drain the request - * body. - */ - HttpResponse get response; -} - -/** - * An HTTP response, which returns the headers and data - * from the server to the client in response to an HTTP request. - * - * Every HttpRequest object provides access to the associated [HttpResponse] - * object through the `response` property. - * The server sends its response to the client by writing to the - * HttpResponse object. - * - * ## Writing the response - * - * This class implements [IOSink]. - * After the header has been set up, the methods - * from IOSink, such as `writeln()`, can be used to write - * the body of the HTTP response. - * Use the `close()` method to close the response and send it to the client. - * - * server.listen((HttpRequest request) { - * request.response.write('Hello, world!'); - * request.response.close(); - * }); - * - * When one of the IOSink methods is used for the - * first time, the request header is sent. Calling any methods that - * change the header after it is sent throws an exception. - * - * ## Setting the headers - * - * The HttpResponse object has a number of properties for setting up - * the HTTP headers of the response. - * When writing string data through the IOSink, the encoding used - * is determined from the "charset" parameter of the - * "Content-Type" header. - * - * HttpResponse response = ... - * response.headers.contentType - * = new ContentType("application", "json", charset: "utf-8"); - * response.write(...); // Strings written will be UTF-8 encoded. - * - * If no charset is provided the default of ISO-8859-1 (Latin 1) will - * be used. - * - * HttpResponse response = ... - * response.headers.add(HttpHeaders.contentTypeHeader, "text/plain"); - * response.write(...); // Strings written will be ISO-8859-1 encoded. - * - * An exception is thrown if you use the `write()` method - * while an unsupported content-type is set. - */ -abstract class HttpResponse implements IOSink { - // TODO(ajohnsen): Add documentation of how to pipe a file to the response. - /** - * Gets and sets the content length of the response. If the size of - * the response is not known in advance set the content length to - * -1, which is also the default if not set. - */ - int contentLength = -1; - - /** - * The status code of the response. - * - * Any integer value is accepted. For - * the official HTTP status codes use the fields from - * [HttpStatus]. If no status code is explicitly set the default - * value [HttpStatus.ok] is used. - * - * The status code must be set before the body is written - * to. Setting the status code after writing to the response body or - * closing the response will throw a `StateError`. - */ - int statusCode = HttpStatus.ok; - - /** - * The reason phrase for the response. - * - * If no reason phrase is explicitly set, a default reason phrase is provided. - * - * The reason phrase must be set before the body is written - * to. Setting the reason phrase after writing to the response body - * or closing the response will throw a [StateError]. - */ - late String reasonPhrase; - - /** - * Gets and sets the persistent connection state. The initial value - * of this property is the persistent connection state from the - * request. - */ - late bool persistentConnection; - - /** - * Set and get the [deadline] for the response. The deadline is timed from the - * time it's set. Setting a new deadline will override any previous deadline. - * When a deadline is exceeded, the response will be closed and any further - * data ignored. - * - * To disable a deadline, set the [deadline] to `null`. - * - * The [deadline] is `null` by default. - */ - Duration? deadline; - - /** - * Gets or sets if the [HttpResponse] should buffer output. - * - * Default value is `true`. - * - * __Note__: Disabling buffering of the output can result in very poor - * performance, when writing many small chunks. - */ - bool bufferOutput = true; - - /** - * Returns the response headers. - * - * The response headers can be modified until the response body is - * written to or closed. After that they become immutable. - */ - HttpHeaders get headers; - - /** - * Cookies to set in the client (in the 'set-cookie' header). - */ - List get cookies; - - /** - * Respond with a redirect to [location]. - * - * The URI in [location] should be absolute, but there are no checks - * to enforce that. - * - * By default the HTTP status code `HttpStatus.movedTemporarily` - * (`302`) is used for the redirect, but an alternative one can be - * specified using the [status] argument. - * - * This method will also call `close`, and the returned future is - * the future returned by `close`. - */ - Future redirect(Uri location, {int status = HttpStatus.movedTemporarily}); - - /** - * Detaches the underlying socket from the HTTP server. When the - * socket is detached the HTTP server will no longer perform any - * operations on it. - * - * This is normally used when a HTTP upgrade request is received - * and the communication should continue with a different protocol. - * - * If [writeHeaders] is `true`, the status line and [headers] will be written - * to the socket before it's detached. If `false`, the socket is detached - * immediately, without any data written to the socket. Default is `true`. - */ - Future detachSocket({bool writeHeaders = true}); - - /** - * Gets information about the client connection. Returns `null` if the - * socket is not available. - */ - HttpConnectionInfo? get connectionInfo; -} - -/** - * A client that receives content, such as web pages, from - * a server using the HTTP protocol. - * - * HttpClient contains a number of methods to send an [HttpClientRequest] - * to an Http server and receive an [HttpClientResponse] back. - * For example, you can use the [get], [getUrl], [post], and [postUrl] methods - * for GET and POST requests, respectively. - * - * ## Making a simple GET request: an example - * - * A `getUrl` request is a two-step process, triggered by two [Future]s. - * When the first future completes with a [HttpClientRequest], the underlying - * network connection has been established, but no data has been sent. - * In the callback function for the first future, the HTTP headers and body - * can be set on the request. Either the first write to the request object - * or a call to [close] sends the request to the server. - * - * When the HTTP response is received from the server, - * the second future, which is returned by close, - * completes with an [HttpClientResponse] object. - * This object provides access to the headers and body of the response. - * The body is available as a stream implemented by HttpClientResponse. - * If a body is present, it must be read. Otherwise, it leads to resource - * leaks. Consider using [HttpClientResponse.drain] if the body is unused. - * - * HttpClient client = new HttpClient(); - * client.getUrl(Uri.parse("http://www.example.com/")) - * .then((HttpClientRequest request) { - * // Optionally set up headers... - * // Optionally write to the request object... - * // Then call close. - * ... - * return request.close(); - * }) - * .then((HttpClientResponse response) { - * // Process the response. - * ... - * }); - * - * The future for [HttpClientRequest] is created by methods such as - * [getUrl] and [open]. - * - * ## HTTPS connections - * - * An HttpClient can make HTTPS requests, connecting to a server using - * the TLS (SSL) secure networking protocol. Calling [getUrl] with an - * https: scheme will work automatically, if the server's certificate is - * signed by a root CA (certificate authority) on the default list of - * well-known trusted CAs, compiled by Mozilla. - * - * To add a custom trusted certificate authority, or to send a client - * certificate to servers that request one, pass a [SecurityContext] object - * as the optional `context` argument to the `HttpClient` constructor. - * The desired security options can be set on the [SecurityContext] object. - * - * ## Headers - * - * All HttpClient requests set the following header by default: - * - * Accept-Encoding: gzip - * - * This allows the HTTP server to use gzip compression for the body if - * possible. If this behavior is not desired set the - * `Accept-Encoding` header to something else. - * To turn off gzip compression of the response, clear this header: - * - * request.headers.removeAll(HttpHeaders.acceptEncodingHeader) - * - * ## Closing the HttpClient - * - * The HttpClient supports persistent connections and caches network - * connections to reuse them for multiple requests whenever - * possible. This means that network connections can be kept open for - * some time after a request has completed. Use HttpClient.close - * to force the HttpClient object to shut down and to close the idle - * network connections. - * - * ## Turning proxies on and off - * - * By default the HttpClient uses the proxy configuration available - * from the environment, see [findProxyFromEnvironment]. To turn off - * the use of proxies set the [findProxy] property to - * `null`. - * - * HttpClient client = new HttpClient(); - * client.findProxy = null; - */ -abstract class HttpClient { - static const int defaultHttpPort = 80; - @Deprecated("Use defaultHttpPort instead") - static const int DEFAULT_HTTP_PORT = defaultHttpPort; - - static const int defaultHttpsPort = 443; - @Deprecated("Use defaultHttpsPort instead") - static const int DEFAULT_HTTPS_PORT = defaultHttpsPort; - - /// Enable logging of HTTP requests from all [HttpClient]s to the developer - /// timeline. - /// - /// Default is `false`. - static set enableTimelineLogging(bool value) { - _enableTimelineLogging = - valueOfNonNullableParamWithDefault(value, false); - } - - /// Current state of HTTP request logging from all [HttpClient]s to the - /// developer timeline. - /// - /// Default is `false`. - static bool get enableTimelineLogging => _enableTimelineLogging; - - static bool _enableTimelineLogging = false; - - /// Gets and sets the idle timeout of non-active persistent (keep-alive) - /// connections. - /// - /// The default value is 15 seconds. - Duration idleTimeout = const Duration(seconds: 15); - - /// Gets and sets the connection timeout. - /// - /// When connecting to a new host exceeds this timeout, a [SocketException] - /// is thrown. The timeout applies only to connections initiated after the - /// timeout is set. - /// - /// When this is `null`, the OS default timeout is used. The default is - /// `null`. - Duration? connectionTimeout; - - /** - * Gets and sets the maximum number of live connections, to a single host. - * - * Increasing this number may lower performance and take up unwanted - * system resources. - * - * To disable, set to `null`. - * - * Default is `null`. - */ - int? maxConnectionsPerHost; - - /** - * Gets and sets whether the body of a response will be automatically - * uncompressed. - * - * The body of an HTTP response can be compressed. In most - * situations providing the un-compressed body is most - * convenient. Therefore the default behavior is to un-compress the - * body. However in some situations (e.g. implementing a transparent - * proxy) keeping the uncompressed stream is required. - * - * NOTE: Headers in the response are never modified. This means - * that when automatic un-compression is turned on the value of the - * header `Content-Length` will reflect the length of the original - * compressed body. Likewise the header `Content-Encoding` will also - * have the original value indicating compression. - * - * NOTE: Automatic un-compression is only performed if the - * `Content-Encoding` header value is `gzip`. - * - * This value affects all responses produced by this client after the - * value is changed. - * - * To disable, set to `false`. - * - * Default is `true`. - */ - bool autoUncompress = true; - - /// Gets and sets the default value of the `User-Agent` header for all requests - /// generated by this [HttpClient]. - /// - /// The default value is `Dart/ (dart:io)`. - /// - /// If the userAgent is set to `null`, no default `User-Agent` header will be - /// added to each request. - String? userAgent; - - factory HttpClient({SecurityContext? context}) { - HttpOverrides? overrides = HttpOverrides.current; - if (overrides == null) { - return new _HttpClient(context); - } - return overrides.createHttpClient(context); - } - - /** - * Opens a HTTP connection. - * - * The HTTP method to use is specified in [method], the server is - * specified using [host] and [port], and the path (including - * a possible query) is specified using [path]. - * The path may also contain a URI fragment, which will be ignored. - * - * The `Host` header for the request will be set to the value [host]:[port] - * (if [host] is an IP address, it will still be used in the `Host` header). - * This can be overridden through the [HttpClientRequest] interface before - * the request is sent. - * - * For additional information on the sequence of events during an - * HTTP transaction, and the objects returned by the futures, see - * the overall documentation for the class [HttpClient]. - */ - Future open( - String method, String host, int port, String path); - - /** - * Opens a HTTP connection. - * - * The HTTP method is specified in [method] and the URL to use in - * [url]. - * - * The `Host` header for the request will be set to the value - * [Uri.host]:[Uri.port] from [url] (if [url.host] is an IP address, it will - * still be used in the `Host` header). This can be overridden through the - * [HttpClientRequest] interface before the request is sent. - * - * For additional information on the sequence of events during an - * HTTP transaction, and the objects returned by the futures, see - * the overall documentation for the class [HttpClient]. - */ - Future openUrl(String method, Uri url); - - /** - * Opens a HTTP connection using the GET method. - * - * The server is specified using [host] and [port], and the path - * (including a possible query) is specified using - * [path]. - * - * See [open] for details. - */ - Future get(String host, int port, String path); - - /** - * Opens a HTTP connection using the GET method. - * - * The URL to use is specified in [url]. - * - * See [openUrl] for details. - */ - Future getUrl(Uri url); - - /** - * Opens a HTTP connection using the POST method. - * - * The server is specified using [host] and [port], and the path - * (including a possible query) is specified using - * [path]. - * - * See [open] for details. - */ - Future post(String host, int port, String path); - - /** - * Opens a HTTP connection using the POST method. - * - * The URL to use is specified in [url]. - * - * See [openUrl] for details. - */ - Future postUrl(Uri url); - - /** - * Opens a HTTP connection using the PUT method. - * - * The server is specified using [host] and [port], and the path - * (including a possible query) is specified using [path]. - * - * See [open] for details. - */ - Future put(String host, int port, String path); - - /** - * Opens a HTTP connection using the PUT method. - * - * The URL to use is specified in [url]. - * - * See [openUrl] for details. - */ - Future putUrl(Uri url); - - /** - * Opens a HTTP connection using the DELETE method. - * - * The server is specified using [host] and [port], and the path - * (including a possible query) is specified using [path]. - * - * See [open] for details. - */ - Future delete(String host, int port, String path); - - /** - * Opens a HTTP connection using the DELETE method. - * - * The URL to use is specified in [url]. - * - * See [openUrl] for details. - */ - Future deleteUrl(Uri url); - - /** - * Opens a HTTP connection using the PATCH method. - * - * The server is specified using [host] and [port], and the path - * (including a possible query) is specified using [path]. - * - * See [open] for details. - */ - Future patch(String host, int port, String path); - - /** - * Opens a HTTP connection using the PATCH method. - * - * The URL to use is specified in [url]. - * - * See [openUrl] for details. - */ - Future patchUrl(Uri url); - - /** - * Opens a HTTP connection using the HEAD method. - * - * The server is specified using [host] and [port], and the path - * (including a possible query) is specified using [path]. - * - * See [open] for details. - */ - Future head(String host, int port, String path); - - /** - * Opens a HTTP connection using the HEAD method. - * - * The URL to use is specified in [url]. - * - * See [openUrl] for details. - */ - Future headUrl(Uri url); - - /** - * Sets the function to be called when a site is requesting - * authentication. The URL requested and the security realm from the - * server are passed in the arguments [url] and [realm]. - * - * The function returns a [Future] which should complete when the - * authentication has been resolved. If credentials cannot be - * provided the [Future] should complete with `false`. If - * credentials are available the function should add these using - * [addCredentials] before completing the [Future] with the value - * `true`. - * - * If the [Future] completes with `true` the request will be retried - * using the updated credentials, however, the retried request will not - * carry the original request payload. Otherwise response processing will - * continue normally. - * - * If it is known that the remote server requires authentication for all - * requests, it is advisable to use [addCredentials] directly, or manually - * set the `'authorization'` header on the request to avoid the overhead - * of a failed request, or issues due to missing request payload on retried - * request. - */ - void set authenticate(Future f(Uri url, String scheme, String realm)?); - - /** - * Add credentials to be used for authorizing HTTP requests. - */ - void addCredentials(Uri url, String realm, HttpClientCredentials credentials); - - /** - * Sets the function used to resolve the proxy server to be used for - * opening a HTTP connection to the specified [url]. If this - * function is not set, direct connections will always be used. - * - * The string returned by [f] must be in the format used by browser - * PAC (proxy auto-config) scripts. That is either - * - * "DIRECT" - * - * for using a direct connection or - * - * "PROXY host:port" - * - * for using the proxy server `host` on port `port`. - * - * A configuration can contain several configuration elements - * separated by semicolons, e.g. - * - * "PROXY host:port; PROXY host2:port2; DIRECT" - * - * The static function [findProxyFromEnvironment] on this class can - * be used to implement proxy server resolving based on environment - * variables. - */ - void set findProxy(String f(Uri url)?); - - /** - * Function for resolving the proxy server to be used for a HTTP - * connection from the proxy configuration specified through - * environment variables. - * - * The following environment variables are taken into account: - * - * http_proxy - * https_proxy - * no_proxy - * HTTP_PROXY - * HTTPS_PROXY - * NO_PROXY - * - * [:http_proxy:] and [:HTTP_PROXY:] specify the proxy server to use for - * http:// urls. Use the format [:hostname:port:]. If no port is used a - * default of 1080 will be used. If both are set the lower case one takes - * precedence. - * - * [:https_proxy:] and [:HTTPS_PROXY:] specify the proxy server to use for - * https:// urls. Use the format [:hostname:port:]. If no port is used a - * default of 1080 will be used. If both are set the lower case one takes - * precedence. - * - * [:no_proxy:] and [:NO_PROXY:] specify a comma separated list of - * postfixes of hostnames for which not to use the proxy - * server. E.g. the value "localhost,127.0.0.1" will make requests - * to both "localhost" and "127.0.0.1" not use a proxy. If both are set - * the lower case one takes precedence. - * - * To activate this way of resolving proxies assign this function to - * the [findProxy] property on the [HttpClient]. - * - * HttpClient client = new HttpClient(); - * client.findProxy = HttpClient.findProxyFromEnvironment; - * - * If you don't want to use the system environment you can use a - * different one by wrapping the function. - * - * HttpClient client = new HttpClient(); - * client.findProxy = (url) { - * return HttpClient.findProxyFromEnvironment( - * url, environment: {"http_proxy": ..., "no_proxy": ...}); - * } - * - * If a proxy requires authentication it is possible to configure - * the username and password as well. Use the format - * [:username:password@hostname:port:] to include the username and - * password. Alternatively the API [addProxyCredentials] can be used - * to set credentials for proxies which require authentication. - */ - static String findProxyFromEnvironment(Uri url, - {Map? environment}) { - HttpOverrides? overrides = HttpOverrides.current; - if (overrides == null) { - return _HttpClient._findProxyFromEnvironment(url, environment); - } - return overrides.findProxyFromEnvironment(url, environment); - } - - /** - * Sets the function to be called when a proxy is requesting - * authentication. Information on the proxy in use and the security - * realm for the authentication are passed in the arguments [host], - * [port] and [realm]. - * - * The function returns a [Future] which should complete when the - * authentication has been resolved. If credentials cannot be - * provided the [Future] should complete with `false`. If - * credentials are available the function should add these using - * [addProxyCredentials] before completing the [Future] with the value - * `true`. - * - * If the [Future] completes with `true` the request will be retried - * using the updated credentials. Otherwise response processing will - * continue normally. - */ - void set authenticateProxy( - Future f(String host, int port, String scheme, String realm)?); - - /** - * Add credentials to be used for authorizing HTTP proxies. - */ - void addProxyCredentials( - String host, int port, String realm, HttpClientCredentials credentials); - - /** - * Sets a callback that will decide whether to accept a secure connection - * with a server certificate that cannot be authenticated by any of our - * trusted root certificates. - * - * When an secure HTTP request if made, using this HttpClient, and the - * server returns a server certificate that cannot be authenticated, the - * callback is called asynchronously with the [X509Certificate] object and - * the server's hostname and port. If the value of [badCertificateCallback] - * is `null`, the bad certificate is rejected, as if the callback - * returned `false` - * - * If the callback returns true, the secure connection is accepted and the - * [:Future:] that was returned from the call making the - * request completes with a valid HttpRequest object. If the callback returns - * false, the [:Future:] completes with an exception. - * - * If a bad certificate is received on a connection attempt, the library calls - * the function that was the value of badCertificateCallback at the time - * the request is made, even if the value of badCertificateCallback - * has changed since then. - */ - void set badCertificateCallback( - bool callback(X509Certificate cert, String host, int port)?); - - /// Shuts down the HTTP client. - /// - /// If [force] is `false` (the default) the [HttpClient] will be kept alive - /// until all active connections are done. If [force] is `true` any active - /// connections will be closed to immediately release all resources. These - /// closed connections will receive an error event to indicate that the client - /// was shut down. In both cases trying to establish a new connection after - /// calling [close] will throw an exception. - void close({bool force = false}); -} - -/** - * HTTP request for a client connection. - * - * To set up a request, set the headers using the headers property - * provided in this class and write the data to the body of the request. - * HttpClientRequest is an [IOSink]. Use the methods from IOSink, - * such as writeCharCode(), to write the body of the HTTP - * request. When one of the IOSink methods is used for the first - * time, the request header is sent. Calling any methods that - * change the header after it is sent throws an exception. - * - * When writing string data through the [IOSink] the - * encoding used is determined from the "charset" parameter of - * the "Content-Type" header. - * - * HttpClientRequest request = ... - * request.headers.contentType - * = new ContentType("application", "json", charset: "utf-8"); - * request.write(...); // Strings written will be UTF-8 encoded. - * - * If no charset is provided the default of ISO-8859-1 (Latin 1) is - * be used. - * - * HttpClientRequest request = ... - * request.headers.add(HttpHeaders.contentTypeHeader, "text/plain"); - * request.write(...); // Strings written will be ISO-8859-1 encoded. - * - * An exception is thrown if you use an unsupported encoding and the - * `write()` method being used takes a string parameter. - */ -abstract class HttpClientRequest implements IOSink { - /** - * The requested persistent connection state. - * - * The default value is `true`. - */ - bool persistentConnection = true; - - /** - * Whether to follow redirects automatically. - * - * Set this property to `false` if this request should not - * automatically follow redirects. The default is `true`. - * - * Automatic redirect will only happen for "GET" and "HEAD" requests - * and only for the status codes [HttpStatus.movedPermanently] - * (301), [HttpStatus.found] (302), - * [HttpStatus.movedTemporarily] (302, alias for - * [HttpStatus.found]), [HttpStatus.seeOther] (303) and - * [HttpStatus.temporaryRedirect] (307). For - * [HttpStatus.seeOther] (303) automatic redirect will also happen - * for "POST" requests with the method changed to "GET" when - * following the redirect. - * - * All headers added to the request will be added to the redirection - * request(s). However, any body send with the request will not be - * part of the redirection request(s). - */ - bool followRedirects = true; - - /** - * Set this property to the maximum number of redirects to follow - * when [followRedirects] is `true`. If this number is exceeded - * an error event will be added with a [RedirectException]. - * - * The default value is 5. - */ - int maxRedirects = 5; - - /** - * The method of the request. - */ - String get method; - - /** - * The uri of the request. - */ - Uri get uri; - - /// Gets and sets the content length of the request. - /// - /// If the size of the request is not known in advance set content length to - /// -1, which is also the default. - int contentLength = -1; - - /** - * Gets or sets if the [HttpClientRequest] should buffer output. - * - * Default value is `true`. - * - * __Note__: Disabling buffering of the output can result in very poor - * performance, when writing many small chunks. - */ - bool bufferOutput = true; - - /** - * Returns the client request headers. - * - * The client request headers can be modified until the client - * request body is written to or closed. After that they become - * immutable. - */ - HttpHeaders get headers; - - /** - * Cookies to present to the server (in the 'cookie' header). - */ - List get cookies; - - /// A [HttpClientResponse] future that will complete once the response is - /// available. - /// - /// If an error occurs before the response is available, this future will - /// complete with an error. - Future get done; - - /** - * Close the request for input. Returns the value of [done]. - */ - Future close(); - - /// Gets information about the client connection. - /// - /// Returns `null` if the socket is not available. - HttpConnectionInfo? get connectionInfo; -} - -/** - * HTTP response for a client connection. - * - * The body of a [HttpClientResponse] object is a - * [Stream] of data from the server. Listen to the body to handle - * the data and be notified when the entire body is received. - * - * new HttpClient().get('localhost', 80, '/file.txt') - * .then((HttpClientRequest request) => request.close()) - * .then((HttpClientResponse response) { - * response.transform(utf8.decoder).listen((contents) { - * // handle data - * }); - * }); - */ -abstract class HttpClientResponse implements Stream> { - /** - * Returns the status code. - * - * The status code must be set before the body is written - * to. Setting the status code after writing to the body will throw - * a `StateError`. - */ - int get statusCode; - - /** - * Returns the reason phrase associated with the status code. - * - * The reason phrase must be set before the body is written - * to. Setting the reason phrase after writing to the body will throw - * a `StateError`. - */ - String get reasonPhrase; - - /** - * Returns the content length of the response body. Returns -1 if the size of - * the response body is not known in advance. - * - * If the content length needs to be set, it must be set before the - * body is written to. Setting the content length after writing to the body - * will throw a `StateError`. - */ - int get contentLength; - - /// The compression state of the response. - /// - /// This specifies whether the response bytes were compressed when they were - /// received across the wire and whether callers will receive compressed - /// or uncompressed bytes when they listed to this response's byte stream. - @Since("2.4") - HttpClientResponseCompressionState get compressionState; - - /** - * Gets the persistent connection state returned by the server. - * - * If the persistent connection state needs to be set, it must be - * set before the body is written to. Setting the persistent connection state - * after writing to the body will throw a `StateError`. - */ - bool get persistentConnection; - - /** - * Returns whether the status code is one of the normal redirect - * codes [HttpStatus.movedPermanently], [HttpStatus.found], - * [HttpStatus.movedTemporarily], [HttpStatus.seeOther] and - * [HttpStatus.temporaryRedirect]. - */ - bool get isRedirect; - - /** - * Returns the series of redirects this connection has been through. The - * list will be empty if no redirects were followed. [redirects] will be - * updated both in the case of an automatic and a manual redirect. - */ - List get redirects; - - /** - * Redirects this connection to a new URL. The default value for - * [method] is the method for the current request. The default value - * for [url] is the value of the [HttpHeaders.locationHeader] header of - * the current response. All body data must have been read from the - * current response before calling [redirect]. - * - * All headers added to the request will be added to the redirection - * request. However, any body sent with the request will not be - * part of the redirection request. - * - * If [followLoops] is set to `true`, redirect will follow the redirect, - * even if the URL was already visited. The default value is `false`. - * - * The method will ignore [HttpClientRequest.maxRedirects] - * and will always perform the redirect. - */ - Future redirect( - [String? method, Uri? url, bool? followLoops]); - - /** - * Returns the client response headers. - * - * The client response headers are immutable. - */ - HttpHeaders get headers; - - /** - * Detach the underlying socket from the HTTP client. When the - * socket is detached the HTTP client will no longer perform any - * operations on it. - * - * This is normally used when a HTTP upgrade is negotiated and the - * communication should continue with a different protocol. - */ - Future detachSocket(); - - /** - * Cookies set by the server (from the 'set-cookie' header). - */ - List get cookies; - - /** - * Returns the certificate of the HTTPS server providing the response. - * Returns null if the connection is not a secure TLS or SSL connection. - */ - X509Certificate? get certificate; - - /** - * Gets information about the client connection. Returns `null` if the socket - * is not available. - */ - HttpConnectionInfo? get connectionInfo; -} - -/// Enum that specifies the compression state of the byte stream of an -/// [HttpClientResponse]. -/// -/// The values herein allow callers to answer the following questions as they -/// pertain to an [HttpClientResponse]: -/// -/// * Can the value of the response's `Content-Length` HTTP header be trusted? -/// * Does the caller need to manually decompress the response's byte stream? -/// -/// This enum is accessed via the [HttpClientResponse.compressionState] value. -@Since("2.4") -enum HttpClientResponseCompressionState { - /// The body of the HTTP response was received and remains in an uncompressed - /// state. - /// - /// In this state, the value of the `Content-Length` HTTP header, if - /// specified (non-negative), should match the number of bytes produced by - /// the response's byte stream. - notCompressed, - - /// The body of the HTTP response was originally compressed, but by virtue of - /// the [HttpClient.autoUncompress] configuration option, it has been - /// automatically uncompressed. - /// - /// HTTP headers are not modified, so when a response has been uncompressed - /// in this way, the value of the `Content-Length` HTTP header cannot be - /// trusted, as it will contain the compressed content length, whereas the - /// stream of bytes produced by the response will contain uncompressed bytes. - decompressed, - - /// The body of the HTTP response contains compressed bytes. - /// - /// In this state, the value of the `Content-Length` HTTP header, if - /// specified (non-negative), should match the number of bytes produced by - /// the response's byte stream. - /// - /// If the caller wishes to manually uncompress the body of the response, - /// it should consult the value of the `Content-Encoding` HTTP header to see - /// what type of compression has been applied. See - /// for more information. - compressed, -} - -abstract class HttpClientCredentials {} - -/** - * Represents credentials for basic authentication. - */ -abstract class HttpClientBasicCredentials extends HttpClientCredentials { - factory HttpClientBasicCredentials(String username, String password) => - new _HttpClientBasicCredentials(username, password); -} - -/** - * Represents credentials for digest authentication. Digest - * authentication is only supported for servers using the MD5 - * algorithm and quality of protection (qop) of either "none" or - * "auth". - */ -abstract class HttpClientDigestCredentials extends HttpClientCredentials { - factory HttpClientDigestCredentials(String username, String password) => - new _HttpClientDigestCredentials(username, password); -} - -/** - * Information about an [HttpRequest], [HttpResponse], [HttpClientRequest], or - * [HttpClientResponse] connection. - */ -abstract class HttpConnectionInfo { - InternetAddress get remoteAddress; - int get remotePort; - int get localPort; -} - -/** - * Redirect information. - */ -abstract class RedirectInfo { - /** - * Returns the status code used for the redirect. - */ - int get statusCode; - - /** - * Returns the method used for the redirect. - */ - String get method; - - /** - * Returns the location for the redirect. - */ - Uri get location; -} - -/** - * When detaching a socket from either the [:HttpServer:] or the - * [:HttpClient:] due to a HTTP connection upgrade there might be - * unparsed data already read from the socket. This unparsed data - * together with the detached socket is returned in an instance of - * this class. - */ -abstract class DetachedSocket { - Socket get socket; - List get unparsedData; -} - -class HttpException implements IOException { - final String message; - final Uri? uri; - - const HttpException(this.message, {this.uri}); - - String toString() { - var b = new StringBuffer()..write('HttpException: ')..write(message); - var uri = this.uri; - if (uri != null) { - b.write(', uri = $uri'); - } - return b.toString(); - } -} - -class RedirectException implements HttpException { - final String message; - final List redirects; - - const RedirectException(this.message, this.redirects); - - String toString() => "RedirectException: $message"; - - Uri get uri => redirects.last.location; -} diff --git a/sdk_nnbd/lib/_http/http_date.dart b/sdk_nnbd/lib/_http/http_date.dart deleted file mode 100644 index 5fd2f345d8d..00000000000 --- a/sdk_nnbd/lib/_http/http_date.dart +++ /dev/null @@ -1,352 +0,0 @@ -// Copyright (c) 2012, 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. - -part of dart._http; - -/** - * Utility functions for working with dates with HTTP specific date - * formats. - */ -class HttpDate { - // From RFC-2616 section "3.3.1 Full Date", - // http://tools.ietf.org/html/rfc2616#section-3.3.1 - // - // HTTP-date = rfc1123-date | rfc850-date | asctime-date - // rfc1123-date = wkday "," SP date1 SP time SP "GMT" - // rfc850-date = weekday "," SP date2 SP time SP "GMT" - // asctime-date = wkday SP date3 SP time SP 4DIGIT - // date1 = 2DIGIT SP month SP 4DIGIT - // ; day month year (e.g., 02 Jun 1982) - // date2 = 2DIGIT "-" month "-" 2DIGIT - // ; day-month-year (e.g., 02-Jun-82) - // date3 = month SP ( 2DIGIT | ( SP 1DIGIT )) - // ; month day (e.g., Jun 2) - // time = 2DIGIT ":" 2DIGIT ":" 2DIGIT - // ; 00:00:00 - 23:59:59 - // wkday = "Mon" | "Tue" | "Wed" - // | "Thu" | "Fri" | "Sat" | "Sun" - // weekday = "Monday" | "Tuesday" | "Wednesday" - // | "Thursday" | "Friday" | "Saturday" | "Sunday" - // month = "Jan" | "Feb" | "Mar" | "Apr" - // | "May" | "Jun" | "Jul" | "Aug" - // | "Sep" | "Oct" | "Nov" | "Dec" - - /** - * Format a date according to - * [RFC-1123](http://tools.ietf.org/html/rfc1123 "RFC-1123"), - * e.g. `Thu, 1 Jan 1970 00:00:00 GMT`. - */ - static String format(DateTime date) { - const List wkday = const ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]; - const List month = const [ - "Jan", - "Feb", - "Mar", - "Apr", - "May", - "Jun", - "Jul", - "Aug", - "Sep", - "Oct", - "Nov", - "Dec" - ]; - - DateTime d = date.toUtc(); - StringBuffer sb = new StringBuffer() - ..write(wkday[d.weekday - 1]) - ..write(", ") - ..write(d.day <= 9 ? "0" : "") - ..write(d.day.toString()) - ..write(" ") - ..write(month[d.month - 1]) - ..write(" ") - ..write(d.year.toString()) - ..write(d.hour <= 9 ? " 0" : " ") - ..write(d.hour.toString()) - ..write(d.minute <= 9 ? ":0" : ":") - ..write(d.minute.toString()) - ..write(d.second <= 9 ? ":0" : ":") - ..write(d.second.toString()) - ..write(" GMT"); - return sb.toString(); - } - - /** - * Parse a date string in either of the formats - * [RFC-1123](http://tools.ietf.org/html/rfc1123 "RFC-1123"), - * [RFC-850](http://tools.ietf.org/html/rfc850 "RFC-850") or - * ANSI C's asctime() format. These formats are listed here. - * - * Thu, 1 Jan 1970 00:00:00 GMT - * Thursday, 1-Jan-1970 00:00:00 GMT - * Thu Jan 1 00:00:00 1970 - * - * For more information see [RFC-2616 section - * 3.1.1](http://tools.ietf.org/html/rfc2616#section-3.3.1 - * "RFC-2616 section 3.1.1"). - */ - static DateTime parse(String date) { - final int SP = 32; - const List wkdays = const ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]; - const List weekdays = const [ - "Monday", - "Tuesday", - "Wednesday", - "Thursday", - "Friday", - "Saturday", - "Sunday" - ]; - const List months = const [ - "Jan", - "Feb", - "Mar", - "Apr", - "May", - "Jun", - "Jul", - "Aug", - "Sep", - "Oct", - "Nov", - "Dec" - ]; - - final int formatRfc1123 = 0; - final int formatRfc850 = 1; - final int formatAsctime = 2; - - int index = 0; - String tmp; - - void expect(String s) { - if (date.length - index < s.length) { - throw new HttpException("Invalid HTTP date $date"); - } - String tmp = date.substring(index, index + s.length); - if (tmp != s) { - throw new HttpException("Invalid HTTP date $date"); - } - index += s.length; - } - - int expectWeekday() { - int weekday; - // The formatting of the weekday signals the format of the date string. - int pos = date.indexOf(",", index); - if (pos == -1) { - int pos = date.indexOf(" ", index); - if (pos == -1) throw new HttpException("Invalid HTTP date $date"); - tmp = date.substring(index, pos); - index = pos + 1; - weekday = wkdays.indexOf(tmp); - if (weekday != -1) { - return formatAsctime; - } - } else { - tmp = date.substring(index, pos); - index = pos + 1; - weekday = wkdays.indexOf(tmp); - if (weekday != -1) { - return formatRfc1123; - } - weekday = weekdays.indexOf(tmp); - if (weekday != -1) { - return formatRfc850; - } - } - throw new HttpException("Invalid HTTP date $date"); - } - - int expectMonth(String separator) { - int pos = date.indexOf(separator, index); - if (pos - index != 3) throw new HttpException("Invalid HTTP date $date"); - tmp = date.substring(index, pos); - index = pos + 1; - int month = months.indexOf(tmp); - if (month != -1) return month; - throw new HttpException("Invalid HTTP date $date"); - } - - int expectNum(String separator) { - int pos; - if (separator.length > 0) { - pos = date.indexOf(separator, index); - } else { - pos = date.length; - } - String tmp = date.substring(index, pos); - index = pos + separator.length; - try { - int value = int.parse(tmp); - return value; - } on FormatException { - throw new HttpException("Invalid HTTP date $date"); - } - } - - void expectEnd() { - if (index != date.length) { - throw new HttpException("Invalid HTTP date $date"); - } - } - - int format = expectWeekday(); - int year; - int month; - int day; - int hours; - int minutes; - int seconds; - if (format == formatAsctime) { - month = expectMonth(" "); - if (date.codeUnitAt(index) == SP) index++; - day = expectNum(" "); - hours = expectNum(":"); - minutes = expectNum(":"); - seconds = expectNum(" "); - year = expectNum(""); - } else { - expect(" "); - day = expectNum(format == formatRfc1123 ? " " : "-"); - month = expectMonth(format == formatRfc1123 ? " " : "-"); - year = expectNum(" "); - hours = expectNum(":"); - minutes = expectNum(":"); - seconds = expectNum(" "); - expect("GMT"); - } - expectEnd(); - return new DateTime.utc(year, month + 1, day, hours, minutes, seconds, 0); - } - - // Parse a cookie date string. - static DateTime _parseCookieDate(String date) { - const List monthsLowerCase = const [ - "jan", - "feb", - "mar", - "apr", - "may", - "jun", - "jul", - "aug", - "sep", - "oct", - "nov", - "dec" - ]; - - int position = 0; - - Never error() { - throw new HttpException("Invalid cookie date $date"); - } - - bool isEnd() => position == date.length; - - bool isDelimiter(String s) { - int char = s.codeUnitAt(0); - if (char == 0x09) return true; - if (char >= 0x20 && char <= 0x2F) return true; - if (char >= 0x3B && char <= 0x40) return true; - if (char >= 0x5B && char <= 0x60) return true; - if (char >= 0x7B && char <= 0x7E) return true; - return false; - } - - bool isNonDelimiter(String s) { - int char = s.codeUnitAt(0); - if (char >= 0x00 && char <= 0x08) return true; - if (char >= 0x0A && char <= 0x1F) return true; - if (char >= 0x30 && char <= 0x39) return true; // Digit - if (char == 0x3A) return true; // ':' - if (char >= 0x41 && char <= 0x5A) return true; // Alpha - if (char >= 0x61 && char <= 0x7A) return true; // Alpha - if (char >= 0x7F && char <= 0xFF) return true; // Alpha - return false; - } - - bool isDigit(String s) { - int char = s.codeUnitAt(0); - if (char > 0x2F && char < 0x3A) return true; - return false; - } - - int getMonth(String month) { - if (month.length < 3) return -1; - return monthsLowerCase.indexOf(month.substring(0, 3)); - } - - int toInt(String s) { - int index = 0; - for (; index < s.length && isDigit(s[index]); index++); - return int.parse(s.substring(0, index)); - } - - var tokens = []; - while (!isEnd()) { - while (!isEnd() && isDelimiter(date[position])) position++; - int start = position; - while (!isEnd() && isNonDelimiter(date[position])) position++; - tokens.add(date.substring(start, position).toLowerCase()); - while (!isEnd() && isDelimiter(date[position])) position++; - } - - String? timeStr; - String? dayOfMonthStr; - String? monthStr; - String? yearStr; - - for (var token in tokens) { - if (token.length < 1) continue; - if (timeStr == null && - token.length >= 5 && - isDigit(token[0]) && - (token[1] == ":" || (isDigit(token[1]) && token[2] == ":"))) { - timeStr = token; - } else if (dayOfMonthStr == null && isDigit(token[0])) { - dayOfMonthStr = token; - } else if (monthStr == null && getMonth(token) >= 0) { - monthStr = token; - } else if (yearStr == null && - token.length >= 2 && - isDigit(token[0]) && - isDigit(token[1])) { - yearStr = token; - } - } - - if (timeStr == null || - dayOfMonthStr == null || - monthStr == null || - yearStr == null) { - error(); - } - - int year = toInt(yearStr); - if (year >= 70 && year <= 99) - year += 1900; - else if (year >= 0 && year <= 69) year += 2000; - if (year < 1601) error(); - - int dayOfMonth = toInt(dayOfMonthStr); - if (dayOfMonth < 1 || dayOfMonth > 31) error(); - - int month = getMonth(monthStr) + 1; - - var timeList = timeStr.split(":"); - if (timeList.length != 3) error(); - int hour = toInt(timeList[0]); - int minute = toInt(timeList[1]); - int second = toInt(timeList[2]); - if (hour > 23) error(); - if (minute > 59) error(); - if (second > 59) error(); - - return new DateTime.utc(year, month, dayOfMonth, hour, minute, second, 0); - } -} diff --git a/sdk_nnbd/lib/_http/http_headers.dart b/sdk_nnbd/lib/_http/http_headers.dart deleted file mode 100644 index ae8b4829bdb..00000000000 --- a/sdk_nnbd/lib/_http/http_headers.dart +++ /dev/null @@ -1,1105 +0,0 @@ -// Copyright (c) 2013, 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. - -part of dart._http; - -class _HttpHeaders implements HttpHeaders { - final Map> _headers; - // The original header names keyed by the lowercase header names. - Map? _originalHeaderNames; - final String protocolVersion; - - bool _mutable = true; // Are the headers currently mutable? - List? _noFoldingHeaders; - - int _contentLength = -1; - bool _persistentConnection = true; - bool _chunkedTransferEncoding = false; - String? _host; - int? _port; - - final int _defaultPortForScheme; - - _HttpHeaders(this.protocolVersion, - {int defaultPortForScheme = HttpClient.defaultHttpPort, - _HttpHeaders? initialHeaders}) - : _headers = new HashMap>(), - _defaultPortForScheme = defaultPortForScheme { - if (initialHeaders != null) { - initialHeaders._headers.forEach((name, value) => _headers[name] = value); - _contentLength = initialHeaders._contentLength; - _persistentConnection = initialHeaders._persistentConnection; - _chunkedTransferEncoding = initialHeaders._chunkedTransferEncoding; - _host = initialHeaders._host; - _port = initialHeaders._port; - } - if (protocolVersion == "1.0") { - _persistentConnection = false; - _chunkedTransferEncoding = false; - } - } - - List? operator [](String name) => _headers[_validateField(name)]; - - String? value(String name) { - name = _validateField(name); - List? values = _headers[name]; - if (values == null) return null; - assert(values.isNotEmpty); - if (values.length > 1) { - throw new HttpException("More than one value for header $name"); - } - return values[0]; - } - - void add(String name, value, {bool preserveHeaderCase = false}) { - _checkMutable(); - String lowercaseName = _validateField(name); - - if (preserveHeaderCase && name != lowercaseName) { - (_originalHeaderNames ??= {})[lowercaseName] = name; - } else { - _originalHeaderNames?.remove(lowercaseName); - } - _addAll(lowercaseName, value); - } - - void _addAll(String name, value) { - if (value is Iterable) { - for (var v in value) { - _add(name, _validateValue(v)); - } - } else { - _add(name, _validateValue(value)); - } - } - - void set(String name, Object value, {bool preserveHeaderCase = false}) { - _checkMutable(); - String lowercaseName = _validateField(name); - _headers.remove(lowercaseName); - _originalHeaderNames?.remove(lowercaseName); - if (lowercaseName == HttpHeaders.transferEncodingHeader) { - _chunkedTransferEncoding = false; - } - if (preserveHeaderCase && name != lowercaseName) { - (_originalHeaderNames ??= {})[lowercaseName] = name; - } - _addAll(lowercaseName, value); - } - - void remove(String name, Object value) { - _checkMutable(); - name = _validateField(name); - value = _validateValue(value); - List? values = _headers[name]; - if (values != null) { - values.remove(_valueToString(value)); - if (values.length == 0) { - _headers.remove(name); - _originalHeaderNames?.remove(name); - } - } - if (name == HttpHeaders.transferEncodingHeader && value == "chunked") { - _chunkedTransferEncoding = false; - } - } - - void removeAll(String name) { - _checkMutable(); - name = _validateField(name); - _headers.remove(name); - _originalHeaderNames?.remove(name); - } - - void forEach(void action(String name, List values)) { - _headers.forEach((String name, List values) { - String originalName = _originalHeaderName(name); - action(originalName, values); - }); - } - - void noFolding(String name) { - name = _validateField(name); - (_noFoldingHeaders ??= []).add(name); - } - - bool get persistentConnection => _persistentConnection; - - void set persistentConnection(bool persistentConnection) { - _checkMutable(); - if (persistentConnection == _persistentConnection) return; - final originalName = _originalHeaderName(HttpHeaders.connectionHeader); - if (persistentConnection) { - if (protocolVersion == "1.1") { - remove(HttpHeaders.connectionHeader, "close"); - } else { - if (_contentLength < 0) { - throw new HttpException( - "Trying to set 'Connection: Keep-Alive' on HTTP 1.0 headers with " - "no ContentLength"); - } - add(originalName, "keep-alive", preserveHeaderCase: true); - } - } else { - if (protocolVersion == "1.1") { - add(originalName, "close", preserveHeaderCase: true); - } else { - remove(HttpHeaders.connectionHeader, "keep-alive"); - } - } - _persistentConnection = persistentConnection; - } - - int get contentLength => _contentLength; - - void set contentLength(int contentLength) { - _checkMutable(); - if (protocolVersion == "1.0" && - persistentConnection && - contentLength == -1) { - throw new HttpException( - "Trying to clear ContentLength on HTTP 1.0 headers with " - "'Connection: Keep-Alive' set"); - } - if (_contentLength == contentLength) return; - _contentLength = contentLength; - if (_contentLength >= 0) { - if (chunkedTransferEncoding) chunkedTransferEncoding = false; - _set(HttpHeaders.contentLengthHeader, contentLength.toString()); - } else { - _headers.remove(HttpHeaders.contentLengthHeader); - if (protocolVersion == "1.1") { - chunkedTransferEncoding = true; - } - } - } - - bool get chunkedTransferEncoding => _chunkedTransferEncoding; - - void set chunkedTransferEncoding(bool chunkedTransferEncoding) { - _checkMutable(); - if (chunkedTransferEncoding && protocolVersion == "1.0") { - throw new HttpException( - "Trying to set 'Transfer-Encoding: Chunked' on HTTP 1.0 headers"); - } - if (chunkedTransferEncoding == _chunkedTransferEncoding) return; - if (chunkedTransferEncoding) { - List? values = _headers[HttpHeaders.transferEncodingHeader]; - if (values == null || !values.contains("chunked")) { - // Headers does not specify chunked encoding - add it if set. - _addValue(HttpHeaders.transferEncodingHeader, "chunked"); - } - contentLength = -1; - } else { - // Headers does specify chunked encoding - remove it if not set. - remove(HttpHeaders.transferEncodingHeader, "chunked"); - } - _chunkedTransferEncoding = chunkedTransferEncoding; - } - - String? get host => _host; - - void set host(String? host) { - _checkMutable(); - _host = host; - _updateHostHeader(); - } - - int? get port => _port; - - void set port(int? port) { - _checkMutable(); - _port = port; - _updateHostHeader(); - } - - DateTime? get ifModifiedSince { - List? values = _headers[HttpHeaders.ifModifiedSinceHeader]; - if (values != null) { - assert(values.isNotEmpty); - try { - return HttpDate.parse(values[0]); - } on Exception { - return null; - } - } - return null; - } - - void set ifModifiedSince(DateTime? ifModifiedSince) { - _checkMutable(); - if (ifModifiedSince == null) { - _headers.remove(HttpHeaders.ifModifiedSinceHeader); - } else { - // Format "ifModifiedSince" header with date in Greenwich Mean Time (GMT). - String formatted = HttpDate.format(ifModifiedSince.toUtc()); - _set(HttpHeaders.ifModifiedSinceHeader, formatted); - } - } - - DateTime? get date { - List? values = _headers[HttpHeaders.dateHeader]; - if (values != null) { - assert(values.isNotEmpty); - try { - return HttpDate.parse(values[0]); - } on Exception { - return null; - } - } - return null; - } - - void set date(DateTime? date) { - _checkMutable(); - if (date == null) { - _headers.remove(HttpHeaders.dateHeader); - } else { - // Format "DateTime" header with date in Greenwich Mean Time (GMT). - String formatted = HttpDate.format(date.toUtc()); - _set(HttpHeaders.dateHeader, formatted); - } - } - - DateTime? get expires { - List? values = _headers[HttpHeaders.expiresHeader]; - if (values != null) { - assert(values.isNotEmpty); - try { - return HttpDate.parse(values[0]); - } on Exception { - return null; - } - } - return null; - } - - void set expires(DateTime? expires) { - _checkMutable(); - if (expires == null) { - _headers.remove(HttpHeaders.expiresHeader); - } else { - // Format "Expires" header with date in Greenwich Mean Time (GMT). - String formatted = HttpDate.format(expires.toUtc()); - _set(HttpHeaders.expiresHeader, formatted); - } - } - - ContentType? get contentType { - var values = _headers[HttpHeaders.contentTypeHeader]; - if (values != null) { - return ContentType.parse(values[0]); - } else { - return null; - } - } - - void set contentType(ContentType? contentType) { - _checkMutable(); - if (contentType == null) { - _headers.remove(HttpHeaders.contentTypeHeader); - } else { - _set(HttpHeaders.contentTypeHeader, contentType.toString()); - } - } - - void clear() { - _checkMutable(); - _headers.clear(); - _contentLength = -1; - _persistentConnection = true; - _chunkedTransferEncoding = false; - _host = null; - _port = null; - } - - // [name] must be a lower-case version of the name. - void _add(String name, value) { - assert(name == _validateField(name)); - // Use the length as index on what method to call. This is notable - // faster than computing hash and looking up in a hash-map. - switch (name.length) { - case 4: - if (HttpHeaders.dateHeader == name) { - _addDate(name, value); - return; - } - if (HttpHeaders.hostHeader == name) { - _addHost(name, value); - return; - } - break; - case 7: - if (HttpHeaders.expiresHeader == name) { - _addExpires(name, value); - return; - } - break; - case 10: - if (HttpHeaders.connectionHeader == name) { - _addConnection(name, value); - return; - } - break; - case 12: - if (HttpHeaders.contentTypeHeader == name) { - _addContentType(name, value); - return; - } - break; - case 14: - if (HttpHeaders.contentLengthHeader == name) { - _addContentLength(name, value); - return; - } - break; - case 17: - if (HttpHeaders.transferEncodingHeader == name) { - _addTransferEncoding(name, value); - return; - } - if (HttpHeaders.ifModifiedSinceHeader == name) { - _addIfModifiedSince(name, value); - return; - } - } - _addValue(name, value); - } - - void _addContentLength(String name, value) { - if (value is int) { - contentLength = value; - } else if (value is String) { - contentLength = int.parse(value); - } else { - throw new HttpException("Unexpected type for header named $name"); - } - } - - void _addTransferEncoding(String name, value) { - if (value == "chunked") { - chunkedTransferEncoding = true; - } else { - _addValue(HttpHeaders.transferEncodingHeader, value); - } - } - - void _addDate(String name, value) { - if (value is DateTime) { - date = value; - } else if (value is String) { - _set(HttpHeaders.dateHeader, value); - } else { - throw new HttpException("Unexpected type for header named $name"); - } - } - - void _addExpires(String name, value) { - if (value is DateTime) { - expires = value; - } else if (value is String) { - _set(HttpHeaders.expiresHeader, value); - } else { - throw new HttpException("Unexpected type for header named $name"); - } - } - - void _addIfModifiedSince(String name, value) { - if (value is DateTime) { - ifModifiedSince = value; - } else if (value is String) { - _set(HttpHeaders.ifModifiedSinceHeader, value); - } else { - throw new HttpException("Unexpected type for header named $name"); - } - } - - void _addHost(String name, value) { - if (value is String) { - int pos = value.indexOf(":"); - if (pos == -1) { - _host = value; - _port = HttpClient.defaultHttpPort; - } else { - if (pos > 0) { - _host = value.substring(0, pos); - } else { - _host = null; - } - if (pos + 1 == value.length) { - _port = HttpClient.defaultHttpPort; - } else { - try { - _port = int.parse(value.substring(pos + 1)); - } on FormatException { - _port = null; - } - } - } - _set(HttpHeaders.hostHeader, value); - } else { - throw new HttpException("Unexpected type for header named $name"); - } - } - - void _addConnection(String name, value) { - var lowerCaseValue = value.toLowerCase(); - if (lowerCaseValue == 'close') { - _persistentConnection = false; - } else if (lowerCaseValue == 'keep-alive') { - _persistentConnection = true; - } - _addValue(name, value); - } - - void _addContentType(String name, value) { - _set(HttpHeaders.contentTypeHeader, value); - } - - void _addValue(String name, Object value) { - List values = (_headers[name] ??= []); - values.add(_valueToString(value)); - } - - String _valueToString(Object value) { - if (value is DateTime) { - return HttpDate.format(value); - } else if (value is String) { - return value; // TODO(39784): no _validateValue? - } else { - return _validateValue(value.toString()) as String; - } - } - - void _set(String name, String value) { - assert(name == _validateField(name)); - _headers[name] = [value]; - } - - void _checkMutable() { - if (!_mutable) throw new HttpException("HTTP headers are not mutable"); - } - - void _updateHostHeader() { - var host = _host; - if (host != null) { - bool defaultPort = _port == null || _port == _defaultPortForScheme; - _set("host", defaultPort ? host : "$host:$_port"); - } - } - - bool _foldHeader(String name) { - if (name == HttpHeaders.setCookieHeader) return false; - var noFoldingHeaders = _noFoldingHeaders; - return noFoldingHeaders == null || !noFoldingHeaders.contains(name); - } - - void _finalize() { - _mutable = false; - } - - void _build(BytesBuilder builder) { - _headers.forEach((String name, List values) { - String originalName = _originalHeaderName(name); - bool fold = _foldHeader(name); - var nameData = originalName.codeUnits; - builder.add(nameData); - builder.addByte(_CharCode.COLON); - builder.addByte(_CharCode.SP); - for (int i = 0; i < values.length; i++) { - if (i > 0) { - if (fold) { - builder.addByte(_CharCode.COMMA); - builder.addByte(_CharCode.SP); - } else { - builder.addByte(_CharCode.CR); - builder.addByte(_CharCode.LF); - builder.add(nameData); - builder.addByte(_CharCode.COLON); - builder.addByte(_CharCode.SP); - } - } - builder.add(values[i].codeUnits); - } - builder.addByte(_CharCode.CR); - builder.addByte(_CharCode.LF); - }); - } - - String toString() { - StringBuffer sb = new StringBuffer(); - _headers.forEach((String name, List values) { - String originalName = _originalHeaderName(name); - sb..write(originalName)..write(": "); - bool fold = _foldHeader(name); - for (int i = 0; i < values.length; i++) { - if (i > 0) { - if (fold) { - sb.write(", "); - } else { - sb..write("\n")..write(originalName)..write(": "); - } - } - sb.write(values[i]); - } - sb.write("\n"); - }); - return sb.toString(); - } - - List _parseCookies() { - // Parse a Cookie header value according to the rules in RFC 6265. - var cookies = []; - void parseCookieString(String s) { - int index = 0; - - bool done() => index == -1 || index == s.length; - - void skipWS() { - while (!done()) { - if (s[index] != " " && s[index] != "\t") return; - index++; - } - } - - String parseName() { - int start = index; - while (!done()) { - if (s[index] == " " || s[index] == "\t" || s[index] == "=") break; - index++; - } - return s.substring(start, index); - } - - String parseValue() { - int start = index; - while (!done()) { - if (s[index] == " " || s[index] == "\t" || s[index] == ";") break; - index++; - } - return s.substring(start, index); - } - - bool expect(String expected) { - if (done()) return false; - if (s[index] != expected) return false; - index++; - return true; - } - - while (!done()) { - skipWS(); - if (done()) return; - String name = parseName(); - skipWS(); - if (!expect("=")) { - index = s.indexOf(';', index); - continue; - } - skipWS(); - String value = parseValue(); - try { - cookies.add(new _Cookie(name, value)); - } catch (_) { - // Skip it, invalid cookie data. - } - skipWS(); - if (done()) return; - if (!expect(";")) { - index = s.indexOf(';', index); - continue; - } - } - } - - List? values = _headers[HttpHeaders.cookieHeader]; - if (values != null) { - values.forEach((headerValue) => parseCookieString(headerValue)); - } - return cookies; - } - - static String _validateField(String field) { - for (var i = 0; i < field.length; i++) { - if (!_HttpParser._isTokenChar(field.codeUnitAt(i))) { - throw new FormatException( - "Invalid HTTP header field name: ${json.encode(field)}", field, i); - } - } - return field.toLowerCase(); - } - - static Object _validateValue(Object value) { - if (value is! String) return value; - for (var i = 0; i < (value as String).length; i++) { - if (!_HttpParser._isValueChar((value as String).codeUnitAt(i))) { - throw new FormatException( - "Invalid HTTP header field value: ${json.encode(value)}", value, i); - } - } - return value; - } - - String _originalHeaderName(String name) { - // TODO: Update syntax to_originalHeaderNames?[name]. - return _originalHeaderNames?.[name] ?? name; - } -} - -class _HeaderValue implements HeaderValue { - String _value; - Map? _parameters; - Map? _unmodifiableParameters; - - _HeaderValue([this._value = "", Map parameters = const {}]) { - // TODO(40614): Remove once non-nullability is sound. - Map? nullableParameters = parameters; - if (nullableParameters != null && nullableParameters.isNotEmpty) { - _parameters = new HashMap.from(nullableParameters); - } - } - - static _HeaderValue parse(String value, - {String parameterSeparator = ";", - String? valueSeparator, - bool preserveBackslash = false}) { - // Parse the string. - var result = new _HeaderValue(); - result._parse(value, parameterSeparator, valueSeparator, preserveBackslash); - return result; - } - - String get value => _value; - - Map _ensureParameters() => - _parameters ??= {}; - - Map get parameters => - _unmodifiableParameters ??= UnmodifiableMapView(_ensureParameters()); - - static bool _isToken(String token) { - if (token.isEmpty) { - return false; - } - final delimiters = "\"(),/:;<=>?@[\]{}"; - for (int i = 0; i < token.length; i++) { - int codeUnit = token.codeUnitAt(i); - if (codeUnit <= 32 || - codeUnit >= 127 || - delimiters.indexOf(token[i]) >= 0) { - return false; - } - } - return true; - } - - String toString() { - StringBuffer sb = new StringBuffer(); - sb.write(_value); - var parameters = this._parameters; - if (parameters != null && parameters.length > 0) { - parameters.forEach((String name, String? value) { - sb..write("; ")..write(name); - if (value != null) { - sb.write("="); - if (_isToken(value)) { - sb.write(value); - } else { - sb.write('"'); - int start = 0; - for (int i = 0; i < value.length; i++) { - // Can use codeUnitAt here instead. - int codeUnit = value.codeUnitAt(i); - if (codeUnit == 92 /* backslash */ || - codeUnit == 34 /* double quote */) { - sb.write(value.substring(start, i)); - sb.write(r'\'); - start = i; - } - } - sb..write(value.substring(start))..write('"'); - } - } - }); - } - return sb.toString(); - } - - void _parse(String s, String parameterSeparator, String? valueSeparator, - bool preserveBackslash) { - int index = 0; - - bool done() => index == s.length; - - void skipWS() { - while (!done()) { - if (s[index] != " " && s[index] != "\t") return; - index++; - } - } - - String parseValue() { - int start = index; - while (!done()) { - var char = s[index]; - if (char == " " || - char == "\t" || - char == valueSeparator || - char == parameterSeparator) break; - index++; - } - return s.substring(start, index); - } - - void expect(String expected) { - if (done() || s[index] != expected) { - throw new HttpException("Failed to parse header value"); - } - index++; - } - - bool maybeExpect(String expected) { - if (done() || !s.startsWith(expected, index)) { - return false; - } - index++; - return true; - } - - void parseParameters() { - var parameters = _ensureParameters(); - - String parseParameterName() { - int start = index; - while (!done()) { - var char = s[index]; - if (char == " " || - char == "\t" || - char == "=" || - char == parameterSeparator || - char == valueSeparator) break; - index++; - } - return s.substring(start, index).toLowerCase(); - } - - String parseParameterValue() { - if (!done() && s[index] == "\"") { - // Parse quoted value. - StringBuffer sb = new StringBuffer(); - index++; - while (!done()) { - var char = s[index]; - if (char == "\\") { - if (index + 1 == s.length) { - throw new HttpException("Failed to parse header value"); - } - if (preserveBackslash && s[index + 1] != "\"") { - sb.write(char); - } - index++; - } else if (char == "\"") { - index++; - return sb.toString(); - } - char = s[index]; - sb.write(char); - index++; - } - throw new HttpException("Failed to parse header value"); - } else { - // Parse non-quoted value. - return parseValue(); - } - } - - while (!done()) { - skipWS(); - if (done()) return; - String name = parseParameterName(); - skipWS(); - if (maybeExpect("=")) { - skipWS(); - String value = parseParameterValue(); - if (name == 'charset' && this is _ContentType) { - // Charset parameter of ContentTypes are always lower-case. - value = value.toLowerCase(); - } - parameters[name] = value; - skipWS(); - } else if (name.isNotEmpty) { - parameters[name] = null; - } - if (done()) return; - // TODO: Implement support for multi-valued parameters. - if (s[index] == valueSeparator) return; - expect(parameterSeparator); - } - } - - skipWS(); - _value = parseValue(); - skipWS(); - if (done()) return; - if (s[index] == valueSeparator) return; - maybeExpect(parameterSeparator); - parseParameters(); - } -} - -class _ContentType extends _HeaderValue implements ContentType { - String _primaryType = ""; - String _subType = ""; - - _ContentType(String primaryType, String subType, String? charset, - Map parameters) - : _primaryType = primaryType, - _subType = subType, - super("") { - // TODO(40614): Remove once non-nullability is sound. - String emptyIfNull(String? string) => string ?? ""; - _primaryType = emptyIfNull(_primaryType); - _subType = emptyIfNull(_subType); - _value = "$_primaryType/$_subType"; - // TODO(40614): Remove once non-nullability is sound. - Map? nullableParameters = parameters; - if (nullableParameters != null) { - var parameterMap = _ensureParameters(); - nullableParameters.forEach((String key, String? value) { - String lowerCaseKey = key.toLowerCase(); - if (lowerCaseKey == "charset") { - value = value?.toLowerCase(); - } - parameterMap[lowerCaseKey] = value; - }); - } - if (charset != null) { - _ensureParameters()["charset"] = charset.toLowerCase(); - } - } - - _ContentType._(); - - static _ContentType parse(String value) { - var result = new _ContentType._(); - result._parse(value, ";", null, false); - int index = result._value.indexOf("/"); - if (index == -1 || index == (result._value.length - 1)) { - result._primaryType = result._value.trim().toLowerCase(); - } else { - result._primaryType = - result._value.substring(0, index).trim().toLowerCase(); - result._subType = result._value.substring(index + 1).trim().toLowerCase(); - } - return result; - } - - String get mimeType => '$primaryType/$subType'; - - String get primaryType => _primaryType; - - String get subType => _subType; - - String? get charset => parameters["charset"]; -} - -class _Cookie implements Cookie { - String _name; - String _value; - DateTime? expires; - int? maxAge; - String? domain; - String? path; - bool httpOnly = false; - bool secure = false; - - _Cookie(String name, String value) - : _name = _validateName(name), - _value = _validateValue(value), - httpOnly = true; - - String get name => _name; - String get value => _value; - - set name(String newName) { - _validateName(newName); - _name = newName; - } - - set value(String newValue) { - _validateValue(newValue); - _value = newValue; - } - - _Cookie.fromSetCookieValue(String value) - : _name = "", - _value = "" { - // Parse the 'set-cookie' header value. - _parseSetCookieValue(value); - } - - // Parse a 'set-cookie' header value according to the rules in RFC 6265. - void _parseSetCookieValue(String s) { - int index = 0; - - bool done() => index == s.length; - - String parseName() { - int start = index; - while (!done()) { - if (s[index] == "=") break; - index++; - } - return s.substring(start, index).trim(); - } - - String parseValue() { - int start = index; - while (!done()) { - if (s[index] == ";") break; - index++; - } - return s.substring(start, index).trim(); - } - - void parseAttributes() { - String parseAttributeName() { - int start = index; - while (!done()) { - if (s[index] == "=" || s[index] == ";") break; - index++; - } - return s.substring(start, index).trim().toLowerCase(); - } - - String parseAttributeValue() { - int start = index; - while (!done()) { - if (s[index] == ";") break; - index++; - } - return s.substring(start, index).trim().toLowerCase(); - } - - while (!done()) { - String name = parseAttributeName(); - String value = ""; - if (!done() && s[index] == "=") { - index++; // Skip the = character. - value = parseAttributeValue(); - } - if (name == "expires") { - expires = HttpDate._parseCookieDate(value); - } else if (name == "max-age") { - maxAge = int.parse(value); - } else if (name == "domain") { - domain = value; - } else if (name == "path") { - path = value; - } else if (name == "httponly") { - httpOnly = true; - } else if (name == "secure") { - secure = true; - } - if (!done()) index++; // Skip the ; character - } - } - - _name = _validateName(parseName()); - if (done() || _name.length == 0) { - throw new HttpException("Failed to parse header value [$s]"); - } - index++; // Skip the = character. - _value = _validateValue(parseValue()); - if (done()) return; - index++; // Skip the ; character. - parseAttributes(); - } - - String toString() { - StringBuffer sb = new StringBuffer(); - sb..write(_name)..write("=")..write(_value); - var expires = this.expires; - if (expires != null) { - sb..write("; Expires=")..write(HttpDate.format(expires)); - } - if (maxAge != null) { - sb..write("; Max-Age=")..write(maxAge); - } - if (domain != null) { - sb..write("; Domain=")..write(domain); - } - if (path != null) { - sb..write("; Path=")..write(path); - } - if (secure) sb.write("; Secure"); - if (httpOnly) sb.write("; HttpOnly"); - return sb.toString(); - } - - static String _validateName(String newName) { - const separators = const [ - "(", - ")", - "<", - ">", - "@", - ",", - ";", - ":", - "\\", - '"', - "/", - "[", - "]", - "?", - "=", - "{", - "}" - ]; - if (newName == null) throw new ArgumentError.notNull("name"); - for (int i = 0; i < newName.length; i++) { - int codeUnit = newName.codeUnitAt(i); - if (codeUnit <= 32 || - codeUnit >= 127 || - separators.indexOf(newName[i]) >= 0) { - throw new FormatException( - "Invalid character in cookie name, code unit: '$codeUnit'", - newName, - i); - } - } - return newName; - } - - static String _validateValue(String newValue) { - if (newValue == null) throw new ArgumentError.notNull("value"); - // Per RFC 6265, consider surrounding "" as part of the value, but otherwise - // double quotes are not allowed. - int start = 0; - int end = newValue.length; - if (2 <= newValue.length && - newValue.codeUnits[start] == 0x22 && - newValue.codeUnits[end - 1] == 0x22) { - start++; - end--; - } - - for (int i = start; i < end; i++) { - int codeUnit = newValue.codeUnits[i]; - if (!(codeUnit == 0x21 || - (codeUnit >= 0x23 && codeUnit <= 0x2B) || - (codeUnit >= 0x2D && codeUnit <= 0x3A) || - (codeUnit >= 0x3C && codeUnit <= 0x5B) || - (codeUnit >= 0x5D && codeUnit <= 0x7E))) { - throw new FormatException( - "Invalid character in cookie value, code unit: '$codeUnit'", - newValue, - i); - } - } - return newValue; - } -} diff --git a/sdk_nnbd/lib/_http/http_impl.dart b/sdk_nnbd/lib/_http/http_impl.dart deleted file mode 100644 index 766b567316f..00000000000 --- a/sdk_nnbd/lib/_http/http_impl.dart +++ /dev/null @@ -1,3377 +0,0 @@ -// Copyright (c) 2013, 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. - -part of dart._http; - -int _nextServiceId = 1; - -// TODO(ajohnsen): Use other way of getting a unique id. -abstract class _ServiceObject { - int __serviceId = 0; - int get _serviceId { - if (__serviceId == 0) __serviceId = _nextServiceId++; - return __serviceId; - } - - Map _toJSON(bool ref); - - String get _servicePath => "$_serviceTypePath/$_serviceId"; - - String get _serviceTypePath; - - String get _serviceTypeName; - - String _serviceType(bool ref) { - if (ref) return "@$_serviceTypeName"; - return _serviceTypeName; - } -} - -class _CopyingBytesBuilder implements BytesBuilder { - // Start with 1024 bytes. - static const int _INIT_SIZE = 1024; - - static final _emptyList = new Uint8List(0); - - int _length = 0; - Uint8List _buffer; - - _CopyingBytesBuilder([int initialCapacity = 0]) - : _buffer = (initialCapacity <= 0) - ? _emptyList - : new Uint8List(_pow2roundup(initialCapacity)); - - void add(List bytes) { - int bytesLength = bytes.length; - if (bytesLength == 0) return; - int required = _length + bytesLength; - if (_buffer.length < required) { - _grow(required); - } - assert(_buffer.length >= required); - if (bytes is Uint8List) { - _buffer.setRange(_length, required, bytes); - } else { - for (int i = 0; i < bytesLength; i++) { - _buffer[_length + i] = bytes[i]; - } - } - _length = required; - } - - void addByte(int byte) { - if (_buffer.length == _length) { - // The grow algorithm always at least doubles. - // If we added one to _length it would quadruple unnecessarily. - _grow(_length); - } - assert(_buffer.length > _length); - _buffer[_length] = byte; - _length++; - } - - void _grow(int required) { - // We will create a list in the range of 2-4 times larger than - // required. - int newSize = required * 2; - if (newSize < _INIT_SIZE) { - newSize = _INIT_SIZE; - } else { - newSize = _pow2roundup(newSize); - } - var newBuffer = new Uint8List(newSize); - newBuffer.setRange(0, _buffer.length, _buffer); - _buffer = newBuffer; - } - - Uint8List takeBytes() { - if (_length == 0) return _emptyList; - var buffer = - new Uint8List.view(_buffer.buffer, _buffer.offsetInBytes, _length); - clear(); - return buffer; - } - - Uint8List toBytes() { - if (_length == 0) return _emptyList; - return new Uint8List.fromList( - new Uint8List.view(_buffer.buffer, _buffer.offsetInBytes, _length)); - } - - int get length => _length; - - bool get isEmpty => _length == 0; - - bool get isNotEmpty => _length != 0; - - void clear() { - _length = 0; - _buffer = _emptyList; - } - - static int _pow2roundup(int x) { - assert(x > 0); - --x; - x |= x >> 1; - x |= x >> 2; - x |= x >> 4; - x |= x >> 8; - x |= x >> 16; - return x + 1; - } -} - -const int _OUTGOING_BUFFER_SIZE = 8 * 1024; - -typedef void _BytesConsumer(List bytes); - -class _HttpIncoming extends Stream { - final int _transferLength; - final Completer _dataCompleter = new Completer(); - Stream _stream; - - bool fullBodyRead = false; - - // Common properties. - final _HttpHeaders headers; - bool upgraded = false; - - // ClientResponse properties. - int? statusCode; - String? reasonPhrase; - - // Request properties. - String? method; - Uri? uri; - - bool hasSubscriber = false; - - // The transfer length if the length of the message body as it - // appears in the message (RFC 2616 section 4.4). This can be -1 if - // the length of the massage body is not known due to transfer - // codings. - int get transferLength => _transferLength; - - _HttpIncoming(this.headers, this._transferLength, this._stream); - - StreamSubscription listen(void onData(Uint8List event)?, - {Function? onError, void onDone()?, bool? cancelOnError}) { - hasSubscriber = true; - return _stream.handleError((error) { - throw new HttpException(error.message, uri: uri); - }).listen(onData, - onError: onError, onDone: onDone, cancelOnError: cancelOnError); - } - - // Is completed once all data have been received. - Future get dataDone => _dataCompleter.future; - - void close(bool closing) { - fullBodyRead = true; - hasSubscriber = true; - _dataCompleter.complete(closing); - } -} - -abstract class _HttpInboundMessageListInt extends Stream> { - final _HttpIncoming _incoming; - List? _cookies; - - _HttpInboundMessageListInt(this._incoming); - - List get cookies => _cookies ??= headers._parseCookies(); - - _HttpHeaders get headers => _incoming.headers; - String get protocolVersion => headers.protocolVersion; - int get contentLength => headers.contentLength; - bool get persistentConnection => headers.persistentConnection; -} - -abstract class _HttpInboundMessage extends Stream { - final _HttpIncoming _incoming; - List? _cookies; - - _HttpInboundMessage(this._incoming); - - List get cookies => _cookies ??= headers._parseCookies(); - - _HttpHeaders get headers => _incoming.headers; - String get protocolVersion => headers.protocolVersion; - int get contentLength => headers.contentLength; - bool get persistentConnection => headers.persistentConnection; -} - -class _HttpRequest extends _HttpInboundMessage implements HttpRequest { - final HttpResponse response; - - final _HttpServer _httpServer; - - final _HttpConnection _httpConnection; - - _HttpSession? _session; - - Uri? _requestedUri; - - _HttpRequest(this.response, _HttpIncoming _incoming, this._httpServer, - this._httpConnection) - : super(_incoming) { - if (headers.protocolVersion == "1.1") { - response.headers - ..chunkedTransferEncoding = true - ..persistentConnection = headers.persistentConnection; - } - - if (_httpServer._sessionManagerInstance != null) { - // Map to session if exists. - var sessionIds = cookies - .where((cookie) => cookie.name.toUpperCase() == _DART_SESSION_ID) - .map((cookie) => cookie.value); - for (var sessionId in sessionIds) { - var session = _httpServer._sessionManager.getSession(sessionId); - _session = session; - if (session != null) { - session._markSeen(); - break; - } - } - } - } - - StreamSubscription listen(void onData(Uint8List event)?, - {Function? onError, void onDone()?, bool? cancelOnError}) { - return _incoming.listen(onData, - onError: onError, onDone: onDone, cancelOnError: cancelOnError); - } - - Uri get uri => _incoming.uri!; - - Uri get requestedUri { - var requestedUri = _requestedUri; - if (requestedUri != null) return requestedUri; - var proto = headers['x-forwarded-proto']; - var scheme = proto != null - ? proto.first - : _httpConnection._socket is SecureSocket ? "https" : "http"; - var hostList = headers['x-forwarded-host']; - String host; - if (hostList != null) { - host = hostList.first; - } else { - hostList = headers[HttpHeaders.hostHeader]; - if (hostList != null) { - host = hostList.first; - } else { - host = "${_httpServer.address.host}:${_httpServer.port}"; - } - } - return _requestedUri = Uri.parse("$scheme://$host$uri"); - } - - String get method => _incoming.method!; - - HttpSession get session { - var session = _session; - if (session != null && !session._destroyed) { - return session; - } - // Create session, store it in connection, and return. - return _session = _httpServer._sessionManager.createSession(); - } - - HttpConnectionInfo? get connectionInfo => _httpConnection.connectionInfo; - - X509Certificate? get certificate { - var socket = _httpConnection._socket; - if (socket is SecureSocket) return socket.peerCertificate; - return null; - } -} - -class _HttpClientResponse extends _HttpInboundMessageListInt - implements HttpClientResponse { - List get redirects => _httpRequest._responseRedirects; - - // The HttpClient this response belongs to. - final _HttpClient _httpClient; - - // The HttpClientRequest of this response. - final _HttpClientRequest _httpRequest; - - // The compression state of this response. - final HttpClientResponseCompressionState compressionState; - - _HttpClientResponse( - _HttpIncoming _incoming, this._httpRequest, this._httpClient) - : compressionState = _getCompressionState(_httpClient, _incoming.headers), - super(_incoming) { - // Set uri for potential exceptions. - _incoming.uri = _httpRequest.uri; - } - - static HttpClientResponseCompressionState _getCompressionState( - _HttpClient httpClient, _HttpHeaders headers) { - if (headers.value(HttpHeaders.contentEncodingHeader) == "gzip") { - return httpClient.autoUncompress - ? HttpClientResponseCompressionState.decompressed - : HttpClientResponseCompressionState.compressed; - } else { - return HttpClientResponseCompressionState.notCompressed; - } - } - - int get statusCode => _incoming.statusCode!; - String get reasonPhrase => _incoming.reasonPhrase!; - - X509Certificate? get certificate { - var socket = _httpRequest._httpClientConnection._socket; - if (socket is SecureSocket) return socket.peerCertificate; - return null; - } - - List get cookies { - var cookies = _cookies; - if (cookies != null) return cookies; - cookies = []; - List? values = headers[HttpHeaders.setCookieHeader]; - if (values != null) { - for (var value in values) { - cookies.add(new Cookie.fromSetCookieValue(value)); - } - } - _cookies = cookies; - return cookies; - } - - bool get isRedirect { - if (_httpRequest.method == "GET" || _httpRequest.method == "HEAD") { - return statusCode == HttpStatus.movedPermanently || - statusCode == HttpStatus.found || - statusCode == HttpStatus.seeOther || - statusCode == HttpStatus.temporaryRedirect; - } else if (_httpRequest.method == "POST") { - return statusCode == HttpStatus.seeOther; - } - return false; - } - - Future redirect( - [String? method, Uri? url, bool? followLoops]) { - if (method == null) { - // Set method as defined by RFC 2616 section 10.3.4. - if (statusCode == HttpStatus.seeOther && _httpRequest.method == "POST") { - method = "GET"; - } else { - method = _httpRequest.method; - } - } - if (url == null) { - String? location = headers.value(HttpHeaders.locationHeader); - if (location == null) { - throw new StateError("Response has no Location header for redirect"); - } - url = Uri.parse(location); - } - if (followLoops != true) { - for (var redirect in redirects) { - if (redirect.location == url) { - return new Future.error( - new RedirectException("Redirect loop detected", redirects)); - } - } - } - return _httpClient - ._openUrlFromRequest(method, url, _httpRequest) - .then((request) { - request._responseRedirects - ..addAll(this.redirects) - ..add(new _RedirectInfo(statusCode, method!, url!)); - return request.close(); - }); - } - - StreamSubscription listen(void onData(Uint8List event)?, - {Function? onError, void onDone()?, bool? cancelOnError}) { - if (_incoming.upgraded) { - // If upgraded, the connection is already 'removed' form the client. - // Since listening to upgraded data is 'bogus', simply close and - // return empty stream subscription. - _httpRequest._httpClientConnection.destroy(); - return new Stream.empty().listen(null, onDone: onDone); - } - Stream stream = _incoming; - if (compressionState == HttpClientResponseCompressionState.decompressed) { - stream = stream - .cast>() - .transform(gzip.decoder) - .transform(const _ToUint8List()); - } - return stream.listen(onData, - onError: onError, onDone: onDone, cancelOnError: cancelOnError); - } - - Future detachSocket() { - _httpClient._connectionClosed(_httpRequest._httpClientConnection); - return _httpRequest._httpClientConnection.detachSocket(); - } - - HttpConnectionInfo? get connectionInfo => _httpRequest.connectionInfo; - - bool get _shouldAuthenticateProxy { - // Only try to authenticate if there is a challenge in the response. - List? challenge = headers[HttpHeaders.proxyAuthenticateHeader]; - return statusCode == HttpStatus.proxyAuthenticationRequired && - challenge != null && - challenge.length == 1; - } - - bool get _shouldAuthenticate { - // Only try to authenticate if there is a challenge in the response. - List? challenge = headers[HttpHeaders.wwwAuthenticateHeader]; - return statusCode == HttpStatus.unauthorized && - challenge != null && - challenge.length == 1; - } - - Future _authenticate(bool proxyAuth) { - _httpRequest._timeline?.instant('Authentication'); - Future retry() { - _httpRequest._timeline?.instant('Retrying'); - // Drain body and retry. - return drain().then((_) { - return _httpClient - ._openUrlFromRequest( - _httpRequest.method, _httpRequest.uri, _httpRequest) - .then((request) => request.close()); - }); - } - - List? authChallenge() { - return proxyAuth - ? headers[HttpHeaders.proxyAuthenticateHeader] - : headers[HttpHeaders.wwwAuthenticateHeader]; - } - - _Credentials? findCredentials(_AuthenticationScheme scheme) { - return proxyAuth - ? _httpClient._findProxyCredentials(_httpRequest._proxy, scheme) - : _httpClient._findCredentials(_httpRequest.uri, scheme); - } - - void removeCredentials(_Credentials cr) { - if (proxyAuth) { - _httpClient._removeProxyCredentials(cr); - } else { - _httpClient._removeCredentials(cr); - } - } - - Future requestAuthentication( - _AuthenticationScheme scheme, String? realm) { - if (proxyAuth) { - var authenticateProxy = _httpClient._authenticateProxy; - if (authenticateProxy == null) { - return new Future.value(false); - } - var proxy = _httpRequest._proxy; - return authenticateProxy( - proxy.host, proxy.port, scheme.toString(), realm); - } else { - var authenticate = _httpClient._authenticate; - if (authenticate == null) { - return new Future.value(false); - } - return authenticate(_httpRequest.uri, scheme.toString(), realm); - } - } - - List challenge = authChallenge()!; - assert(challenge.length == 1); - _HeaderValue header = - _HeaderValue.parse(challenge[0], parameterSeparator: ","); - _AuthenticationScheme scheme = - new _AuthenticationScheme.fromString(header.value); - String? realm = header.parameters["realm"]; - - // See if any matching credentials are available. - var cr = findCredentials(scheme); - if (cr != null) { - // For basic authentication don't retry already used credentials - // as they must have already been added to the request causing - // this authenticate response. - if (cr.scheme == _AuthenticationScheme.BASIC && !cr.used) { - // Credentials were found, prepare for retrying the request. - return retry(); - } - - // Digest authentication only supports the MD5 algorithm. - if (cr.scheme == _AuthenticationScheme.DIGEST) { - var algorithm = header.parameters["algorithm"]; - if (algorithm == null || algorithm.toLowerCase() == "md5") { - var nonce = cr.nonce; - if (nonce == null || nonce == header.parameters["nonce"]) { - // If the nonce is not set then this is the first authenticate - // response for these credentials. Set up authentication state. - if (nonce == null) { - cr - ..nonce = header.parameters["nonce"] - ..algorithm = "MD5" - ..qop = header.parameters["qop"] - ..nonceCount = 0; - } - // Credentials were found, prepare for retrying the request. - return retry(); - } else { - var staleHeader = header.parameters["stale"]; - if (staleHeader != null && staleHeader.toLowerCase() == "true") { - // If stale is true retry with new nonce. - cr.nonce = header.parameters["nonce"]; - // Credentials were found, prepare for retrying the request. - return retry(); - } - } - } - } - } - - // Ask for more credentials if none found or the one found has - // already been used. If it has already been used it must now be - // invalid and is removed. - if (cr != null) { - removeCredentials(cr); - cr = null; - } - return requestAuthentication(scheme, realm).then((credsAvailable) { - if (credsAvailable) { - cr = _httpClient._findCredentials(_httpRequest.uri, scheme); - return retry(); - } else { - // No credentials available, complete with original response. - return this; - } - }); - } -} - -class _ToUint8List extends Converter, Uint8List> { - const _ToUint8List(); - - Uint8List convert(List input) => Uint8List.fromList(input); - - Sink> startChunkedConversion(Sink sink) { - return _Uint8ListConversionSink(sink); - } -} - -class _Uint8ListConversionSink implements Sink> { - const _Uint8ListConversionSink(this._target); - - final Sink _target; - - void add(List data) { - _target.add(Uint8List.fromList(data)); - } - - void close() { - _target.close(); - } -} - -class _StreamSinkImpl implements StreamSink { - final StreamConsumer _target; - final _doneCompleter = new Completer(); - StreamController? _controllerInstance; - Completer? _controllerCompleter; - bool _isClosed = false; - bool _isBound = false; - bool _hasError = false; - - _StreamSinkImpl(this._target); - - void add(T data) { - if (_isClosed) { - throw StateError("StreamSink is closed"); - } - _controller.add(data); - } - - void addError(Object error, [StackTrace? stackTrace]) { - if (_isClosed) { - throw StateError("StreamSink is closed"); - } - _controller.addError(error, stackTrace); - } - - Future addStream(Stream stream) { - if (_isBound) { - throw new StateError("StreamSink is already bound to a stream"); - } - _isBound = true; - if (_hasError) return done; - // Wait for any sync operations to complete. - Future targetAddStream() { - return _target.addStream(stream).whenComplete(() { - _isBound = false; - }); - } - - var controller = _controllerInstance; - if (controller == null) return targetAddStream(); - var future = _controllerCompleter!.future; - controller.close(); - return future.then((_) => targetAddStream()); - } - - Future flush() { - if (_isBound) { - throw new StateError("StreamSink is bound to a stream"); - } - var controller = _controllerInstance; - if (controller == null) return new Future.value(this); - // Adding an empty stream-controller will return a future that will complete - // when all data is done. - _isBound = true; - var future = _controllerCompleter!.future; - controller.close(); - return future.whenComplete(() { - _isBound = false; - }); - } - - Future close() { - if (_isBound) { - throw new StateError("StreamSink is bound to a stream"); - } - if (!_isClosed) { - _isClosed = true; - var controller = _controllerInstance; - if (controller != null) { - controller.close(); - } else { - _closeTarget(); - } - } - return done; - } - - void _closeTarget() { - _target.close().then(_completeDoneValue, onError: _completeDoneError); - } - - Future get done => _doneCompleter.future; - - void _completeDoneValue(value) { - if (!_doneCompleter.isCompleted) { - _doneCompleter.complete(value); - } - } - - void _completeDoneError(Object error, StackTrace stackTrace) { - if (!_doneCompleter.isCompleted) { - _hasError = true; - _doneCompleter.completeError(error, stackTrace); - } - } - - StreamController get _controller { - if (_isBound) { - throw new StateError("StreamSink is bound to a stream"); - } - if (_isClosed) { - throw new StateError("StreamSink is closed"); - } - if (_controllerInstance == null) { - _controllerInstance = new StreamController(sync: true); - _controllerCompleter = new Completer(); - _target.addStream(_controller.stream).then((_) { - if (_isBound) { - // A new stream takes over - forward values to that stream. - _controllerCompleter!.complete(this); - _controllerCompleter = null; - _controllerInstance = null; - } else { - // No new stream, .close was called. Close _target. - _closeTarget(); - } - }, onError: (Object error, StackTrace stackTrace) { - if (_isBound) { - // A new stream takes over - forward errors to that stream. - _controllerCompleter!.completeError(error, stackTrace); - _controllerCompleter = null; - _controllerInstance = null; - } else { - // No new stream. No need to close target, as it has already - // failed. - _completeDoneError(error, stackTrace); - } - }); - } - return _controllerInstance!; - } -} - -class _IOSinkImpl extends _StreamSinkImpl> implements IOSink { - Encoding _encoding; - bool _encodingMutable = true; - - _IOSinkImpl(StreamConsumer> target, this._encoding) : super(target); - - Encoding get encoding => _encoding; - - void set encoding(Encoding value) { - if (!_encodingMutable) { - throw new StateError("IOSink encoding is not mutable"); - } - _encoding = value; - } - - void write(Object? obj) { - String string = '$obj'; - if (string.isEmpty) return; - add(_encoding.encode(string)); - } - - void writeAll(Iterable objects, [String separator = ""]) { - Iterator iterator = objects.iterator; - if (!iterator.moveNext()) return; - if (separator.isEmpty) { - do { - write(iterator.current); - } while (iterator.moveNext()); - } else { - write(iterator.current); - while (iterator.moveNext()) { - write(separator); - write(iterator.current); - } - } - } - - void writeln([Object? object = ""]) { - write(object); - write("\n"); - } - - void writeCharCode(int charCode) { - write(new String.fromCharCode(charCode)); - } -} - -abstract class _HttpOutboundMessage extends _IOSinkImpl { - // Used to mark when the body should be written. This is used for HEAD - // requests and in error handling. - bool _encodingSet = false; - - bool _bufferOutput = true; - - final Uri _uri; - final _HttpOutgoing _outgoing; - - final _HttpHeaders headers; - - _HttpOutboundMessage(Uri uri, String protocolVersion, _HttpOutgoing outgoing, - {_HttpHeaders? initialHeaders}) - : _uri = uri, - headers = new _HttpHeaders(protocolVersion, - defaultPortForScheme: uri.scheme == 'https' - ? HttpClient.defaultHttpsPort - : HttpClient.defaultHttpPort, - initialHeaders: initialHeaders), - _outgoing = outgoing, - super(outgoing, latin1) { - _outgoing.outbound = this; - _encodingMutable = false; - } - - int get contentLength => headers.contentLength; - void set contentLength(int contentLength) { - headers.contentLength = contentLength; - } - - bool get persistentConnection => headers.persistentConnection; - void set persistentConnection(bool p) { - headers.persistentConnection = p; - } - - bool get bufferOutput => _bufferOutput; - void set bufferOutput(bool bufferOutput) { - if (_outgoing.headersWritten) throw new StateError("Header already sent"); - _bufferOutput = bufferOutput; - } - - Encoding get encoding { - if (_encodingSet && _outgoing.headersWritten) { - return _encoding; - } - String charset; - var contentType = headers.contentType; - if (contentType != null && contentType.charset != null) { - charset = contentType.charset!; - } else { - charset = "iso-8859-1"; - } - return Encoding.getByName(charset) ?? latin1; - } - - void add(List data) { - if (data.length == 0) return; - super.add(data); - } - - void write(Object? obj) { - if (!_encodingSet) { - _encoding = encoding; - _encodingSet = true; - } - super.write(obj); - } - - void _writeHeader(); - - bool get _isConnectionClosed => false; -} - -class _HttpResponse extends _HttpOutboundMessage - implements HttpResponse { - int _statusCode = 200; - String? _reasonPhrase; - List? _cookies; - _HttpRequest? _httpRequest; - Duration? _deadline; - Timer? _deadlineTimer; - - _HttpResponse(Uri uri, String protocolVersion, _HttpOutgoing outgoing, - HttpHeaders defaultHeaders, String? serverHeader) - : super(uri, protocolVersion, outgoing, - initialHeaders: defaultHeaders as _HttpHeaders) { - if (serverHeader != null) { - headers.set(HttpHeaders.serverHeader, serverHeader); - } - } - - bool get _isConnectionClosed => _httpRequest!._httpConnection._isClosing; - - List get cookies => _cookies ??= []; - - int get statusCode => _statusCode; - void set statusCode(int statusCode) { - if (_outgoing.headersWritten) throw new StateError("Header already sent"); - _statusCode = statusCode; - } - - String get reasonPhrase => _findReasonPhrase(statusCode); - void set reasonPhrase(String reasonPhrase) { - if (_outgoing.headersWritten) throw new StateError("Header already sent"); - _reasonPhrase = reasonPhrase; - } - - Future redirect(Uri location, {int status = HttpStatus.movedTemporarily}) { - if (_outgoing.headersWritten) throw new StateError("Header already sent"); - statusCode = status; - headers.set(HttpHeaders.locationHeader, location.toString()); - return close(); - } - - Future detachSocket({bool writeHeaders = true}) { - if (_outgoing.headersWritten) throw new StateError("Headers already sent"); - deadline = null; // Be sure to stop any deadline. - var future = _httpRequest!._httpConnection.detachSocket(); - if (writeHeaders) { - var headersFuture = - _outgoing.writeHeaders(drainRequest: false, setOutgoing: false); - assert(headersFuture == null); - } else { - // Imitate having written the headers. - _outgoing.headersWritten = true; - } - // Close connection so the socket is 'free'. - close(); - done.catchError((_) { - // Catch any error on done, as they automatically will be - // propagated to the websocket. - }); - return future; - } - - HttpConnectionInfo? get connectionInfo => _httpRequest!.connectionInfo; - - Duration? get deadline => _deadline; - - void set deadline(Duration? d) { - _deadlineTimer?.cancel(); - _deadline = d; - - if (d == null) return; - _deadlineTimer = new Timer(d, () { - _httpRequest!._httpConnection.destroy(); - }); - } - - void _writeHeader() { - BytesBuilder buffer = new _CopyingBytesBuilder(_OUTGOING_BUFFER_SIZE); - - // Write status line. - if (headers.protocolVersion == "1.1") { - buffer.add(_Const.HTTP11); - } else { - buffer.add(_Const.HTTP10); - } - buffer.addByte(_CharCode.SP); - buffer.add(statusCode.toString().codeUnits); - buffer.addByte(_CharCode.SP); - buffer.add(reasonPhrase.codeUnits); - buffer.addByte(_CharCode.CR); - buffer.addByte(_CharCode.LF); - - var session = _httpRequest!._session; - if (session != null && !session._destroyed) { - // Mark as not new. - session._isNew = false; - // Make sure we only send the current session id. - bool found = false; - for (int i = 0; i < cookies.length; i++) { - if (cookies[i].name.toUpperCase() == _DART_SESSION_ID) { - cookies[i] - ..value = session.id - ..httpOnly = true - ..path = "/"; - found = true; - } - } - if (!found) { - var cookie = new Cookie(_DART_SESSION_ID, session.id); - cookies.add(cookie - ..httpOnly = true - ..path = "/"); - } - } - // Add all the cookies set to the headers. - _cookies?.forEach((cookie) { - headers.add(HttpHeaders.setCookieHeader, cookie); - }); - - headers._finalize(); - - // Write headers. - headers._build(buffer); - buffer.addByte(_CharCode.CR); - buffer.addByte(_CharCode.LF); - Uint8List headerBytes = buffer.takeBytes(); - _outgoing.setHeader(headerBytes, headerBytes.length); - } - - String _findReasonPhrase(int statusCode) { - var reasonPhrase = _reasonPhrase; - if (reasonPhrase != null) { - return reasonPhrase; - } - - switch (statusCode) { - case HttpStatus.continue_: - return "Continue"; - case HttpStatus.switchingProtocols: - return "Switching Protocols"; - case HttpStatus.ok: - return "OK"; - case HttpStatus.created: - return "Created"; - case HttpStatus.accepted: - return "Accepted"; - case HttpStatus.nonAuthoritativeInformation: - return "Non-Authoritative Information"; - case HttpStatus.noContent: - return "No Content"; - case HttpStatus.resetContent: - return "Reset Content"; - case HttpStatus.partialContent: - return "Partial Content"; - case HttpStatus.multipleChoices: - return "Multiple Choices"; - case HttpStatus.movedPermanently: - return "Moved Permanently"; - case HttpStatus.found: - return "Found"; - case HttpStatus.seeOther: - return "See Other"; - case HttpStatus.notModified: - return "Not Modified"; - case HttpStatus.useProxy: - return "Use Proxy"; - case HttpStatus.temporaryRedirect: - return "Temporary Redirect"; - case HttpStatus.badRequest: - return "Bad Request"; - case HttpStatus.unauthorized: - return "Unauthorized"; - case HttpStatus.paymentRequired: - return "Payment Required"; - case HttpStatus.forbidden: - return "Forbidden"; - case HttpStatus.notFound: - return "Not Found"; - case HttpStatus.methodNotAllowed: - return "Method Not Allowed"; - case HttpStatus.notAcceptable: - return "Not Acceptable"; - case HttpStatus.proxyAuthenticationRequired: - return "Proxy Authentication Required"; - case HttpStatus.requestTimeout: - return "Request Time-out"; - case HttpStatus.conflict: - return "Conflict"; - case HttpStatus.gone: - return "Gone"; - case HttpStatus.lengthRequired: - return "Length Required"; - case HttpStatus.preconditionFailed: - return "Precondition Failed"; - case HttpStatus.requestEntityTooLarge: - return "Request Entity Too Large"; - case HttpStatus.requestUriTooLong: - return "Request-URI Too Long"; - case HttpStatus.unsupportedMediaType: - return "Unsupported Media Type"; - case HttpStatus.requestedRangeNotSatisfiable: - return "Requested range not satisfiable"; - case HttpStatus.expectationFailed: - return "Expectation Failed"; - case HttpStatus.internalServerError: - return "Internal Server Error"; - case HttpStatus.notImplemented: - return "Not Implemented"; - case HttpStatus.badGateway: - return "Bad Gateway"; - case HttpStatus.serviceUnavailable: - return "Service Unavailable"; - case HttpStatus.gatewayTimeout: - return "Gateway Time-out"; - case HttpStatus.httpVersionNotSupported: - return "Http Version not supported"; - default: - return "Status $statusCode"; - } - } -} - -class _HttpClientRequest extends _HttpOutboundMessage - implements HttpClientRequest { - final String method; - final Uri uri; - final List cookies = []; - - // The HttpClient this request belongs to. - final _HttpClient _httpClient; - final _HttpClientConnection _httpClientConnection; - final TimelineTask? _timeline; - - final Completer _responseCompleter = - new Completer(); - - final _Proxy _proxy; - - Future? _response; - - // TODO(ajohnsen): Get default value from client? - bool _followRedirects = true; - - int _maxRedirects = 5; - - List _responseRedirects = []; - - _HttpClientRequest(_HttpOutgoing outgoing, Uri uri, this.method, this._proxy, - this._httpClient, this._httpClientConnection, this._timeline) - : uri = uri, - super(uri, "1.1", outgoing) { - _timeline?.instant('Request initiated'); - // GET and HEAD have 'content-length: 0' by default. - if (method == "GET" || method == "HEAD") { - contentLength = 0; - } else { - headers.chunkedTransferEncoding = true; - } - - _responseCompleter.future.then((response) { - _timeline?.instant('Response receieved'); - Map formatConnectionInfo() => { - 'localPort': response.connectionInfo?.localPort, - 'remoteAddress': response.connectionInfo?.remoteAddress.address, - 'remotePort': response.connectionInfo?.remotePort, - }; - - Map formatHeaders() { - final headers = >{}; - response.headers.forEach((name, values) { - headers[name] = values; - }); - return headers; - } - - List> formatRedirectInfo() { - final redirects = >[]; - for (final redirect in response.redirects) { - redirects.add({ - 'location': redirect.location.toString(), - 'method': redirect.method, - 'statusCode': redirect.statusCode, - }); - } - return redirects; - } - - _timeline?.finish(arguments: { - // TODO(bkonyi): consider exposing certificate information? - // 'certificate': response.certificate, - 'requestHeaders': outgoing.outbound!.headers._headers, - 'compressionState': response.compressionState.toString(), - 'connectionInfo': formatConnectionInfo(), - 'contentLength': response.contentLength, - 'cookies': [for (final cookie in response.cookies) cookie.toString()], - 'responseHeaders': formatHeaders(), - 'isRedirect': response.isRedirect, - 'persistentConnection': response.persistentConnection, - 'reasonPhrase': response.reasonPhrase, - 'redirects': formatRedirectInfo(), - 'statusCode': response.statusCode, - }); - }, onError: (e) {}); - } - - Future get done => _response ??= - Future.wait([_responseCompleter.future, super.done], eagerError: true) - .then((list) => list[0]); - - Future close() { - super.close(); - return done; - } - - int get maxRedirects => _maxRedirects; - void set maxRedirects(int maxRedirects) { - if (_outgoing.headersWritten) throw new StateError("Request already sent"); - _maxRedirects = maxRedirects; - } - - bool get followRedirects => _followRedirects; - void set followRedirects(bool followRedirects) { - if (_outgoing.headersWritten) throw new StateError("Request already sent"); - _followRedirects = followRedirects; - } - - HttpConnectionInfo? get connectionInfo => - _httpClientConnection.connectionInfo; - - void _onIncoming(_HttpIncoming incoming) { - var response = new _HttpClientResponse(incoming, this, _httpClient); - Future future; - if (followRedirects && response.isRedirect) { - if (response.redirects.length < maxRedirects) { - // Redirect and drain response. - future = response - .drain() - .then((_) => response.redirect()); - } else { - // End with exception, too many redirects. - future = response.drain().then((_) { - return new Future.error(new RedirectException( - "Redirect limit exceeded", response.redirects)); - }); - } - } else if (response._shouldAuthenticateProxy) { - future = response._authenticate(true); - } else if (response._shouldAuthenticate) { - future = response._authenticate(false); - } else { - future = new Future.value(response); - } - future.then((v) => _responseCompleter.complete(v), - onError: _responseCompleter.completeError); - } - - void _onError(error, StackTrace stackTrace) { - _responseCompleter.completeError(error, stackTrace); - } - - // Generate the request URI based on the method and proxy. - String _requestUri() { - // Generate the request URI starting from the path component. - String uriStartingFromPath() { - String result = uri.path; - if (result.isEmpty) result = "/"; - if (uri.hasQuery) { - result = "${result}?${uri.query}"; - } - return result; - } - - if (_proxy.isDirect) { - return uriStartingFromPath(); - } else { - if (method == "CONNECT") { - // For the connect method the request URI is the host:port of - // the requested destination of the tunnel (see RFC 2817 - // section 5.2) - return "${uri.host}:${uri.port}"; - } else { - if (_httpClientConnection._proxyTunnel) { - return uriStartingFromPath(); - } else { - return uri.removeFragment().toString(); - } - } - } - } - - void _writeHeader() { - BytesBuilder buffer = new _CopyingBytesBuilder(_OUTGOING_BUFFER_SIZE); - - // Write the request method. - buffer.add(method.codeUnits); - buffer.addByte(_CharCode.SP); - // Write the request URI. - buffer.add(_requestUri().codeUnits); - buffer.addByte(_CharCode.SP); - // Write HTTP/1.1. - buffer.add(_Const.HTTP11); - buffer.addByte(_CharCode.CR); - buffer.addByte(_CharCode.LF); - - // Add the cookies to the headers. - if (!cookies.isEmpty) { - StringBuffer sb = new StringBuffer(); - for (int i = 0; i < cookies.length; i++) { - if (i > 0) sb.write("; "); - sb..write(cookies[i].name)..write("=")..write(cookies[i].value); - } - headers.add(HttpHeaders.cookieHeader, sb.toString()); - } - - headers._finalize(); - - // Write headers. - headers._build(buffer); - buffer.addByte(_CharCode.CR); - buffer.addByte(_CharCode.LF); - Uint8List headerBytes = buffer.takeBytes(); - _outgoing.setHeader(headerBytes, headerBytes.length); - } -} - -// Used by _HttpOutgoing as a target of a chunked converter for gzip -// compression. -class _HttpGZipSink extends ByteConversionSink { - final _BytesConsumer _consume; - _HttpGZipSink(this._consume); - - void add(List chunk) { - _consume(chunk); - } - - void addSlice(List chunk, int start, int end, bool isLast) { - if (chunk is Uint8List) { - _consume(new Uint8List.view( - chunk.buffer, chunk.offsetInBytes + start, end - start)); - } else { - _consume(chunk.sublist(start, end - start)); - } - } - - void close() {} -} - -// The _HttpOutgoing handles all of the following: -// - Buffering -// - GZip compression -// - Content-Length validation. -// - Errors. -// -// Most notable is the GZip compression, that uses a double-buffering system, -// one before gzip (_gzipBuffer) and one after (_buffer). -class _HttpOutgoing implements StreamConsumer> { - static const List _footerAndChunk0Length = const [ - _CharCode.CR, - _CharCode.LF, - 0x30, - _CharCode.CR, - _CharCode.LF, - _CharCode.CR, - _CharCode.LF - ]; - - static const List _chunk0Length = const [ - 0x30, - _CharCode.CR, - _CharCode.LF, - _CharCode.CR, - _CharCode.LF - ]; - - final Completer _doneCompleter = new Completer(); - final Socket socket; - - bool ignoreBody = false; - bool headersWritten = false; - - Uint8List? _buffer; - int _length = 0; - - Future? _closeFuture; - - bool chunked = false; - int _pendingChunkedFooter = 0; - - int? contentLength; - int _bytesWritten = 0; - - bool _gzip = false; - ByteConversionSink? _gzipSink; - // _gzipAdd is set iff the sink is being added to. It's used to specify where - // gzipped data should be taken (sometimes a controller, sometimes a socket). - _BytesConsumer? _gzipAdd; - Uint8List? _gzipBuffer; - int _gzipBufferLength = 0; - - bool _socketError = false; - - _HttpOutboundMessage? outbound; - - _HttpOutgoing(this.socket); - - // Returns either a future or 'null', if it was able to write headers - // immediately. - Future? writeHeaders( - {bool drainRequest = true, bool setOutgoing = true}) { - if (headersWritten) return null; - headersWritten = true; - Future? drainFuture; - bool gzip = false; - var response = outbound!; - if (response is _HttpResponse) { - // Server side. - if (response._httpRequest!._httpServer.autoCompress && - response.bufferOutput && - response.headers.chunkedTransferEncoding) { - List? acceptEncodings = - response._httpRequest!.headers[HttpHeaders.acceptEncodingHeader]; - List? contentEncoding = - response.headers[HttpHeaders.contentEncodingHeader]; - if (acceptEncodings != null && - contentEncoding == null && - acceptEncodings - .expand((list) => list.split(",")) - .any((encoding) => encoding.trim().toLowerCase() == "gzip")) { - response.headers.set(HttpHeaders.contentEncodingHeader, "gzip"); - gzip = true; - } - } - if (drainRequest && !response._httpRequest!._incoming.hasSubscriber) { - drainFuture = response._httpRequest!.drain().catchError((_) {}); - } - } else { - drainRequest = false; - } - if (!ignoreBody) { - if (setOutgoing) { - int contentLength = response.headers.contentLength; - if (response.headers.chunkedTransferEncoding) { - chunked = true; - if (gzip) this.gzip = true; - } else if (contentLength >= 0) { - this.contentLength = contentLength; - } - } - if (drainFuture != null) { - return drainFuture.then((_) => response._writeHeader()); - } - } - response._writeHeader(); - return null; - } - - Future addStream(Stream> stream) { - if (_socketError) { - stream.listen(null).cancel(); - return new Future.value(outbound); - } - if (ignoreBody) { - stream.drain().catchError((_) {}); - var future = writeHeaders(); - if (future != null) { - return future.then((_) => close()); - } - return close(); - } - // Use new stream so we are able to pause (see below listen). The - // alternative is to use stream.extand, but that won't give us a way of - // pausing. - var controller = new StreamController>(sync: true); - - void onData(List data) { - if (_socketError) return; - if (data.length == 0) return; - if (chunked) { - if (_gzip) { - _gzipAdd = controller.add; - _addGZipChunk(data, _gzipSink!.add); - _gzipAdd = null; - return; - } - _addChunk(_chunkHeader(data.length), controller.add); - _pendingChunkedFooter = 2; - } else { - var contentLength = this.contentLength; - if (contentLength != null) { - _bytesWritten += data.length; - if (_bytesWritten > contentLength) { - controller.addError(new HttpException( - "Content size exceeds specified contentLength. " - "$_bytesWritten bytes written while expected " - "$contentLength. " - "[${new String.fromCharCodes(data)}]")); - return; - } - } - } - _addChunk(data, controller.add); - } - - var sub = stream.listen(onData, - onError: controller.addError, - onDone: controller.close, - cancelOnError: true); - controller.onPause = sub.pause; - controller.onResume = sub.resume; - // Write headers now that we are listening to the stream. - if (!headersWritten) { - var future = writeHeaders(); - if (future != null) { - // While incoming is being drained, the pauseFuture is non-null. Pause - // output until it's drained. - sub.pause(future); - } - } - return socket.addStream(controller.stream).then((_) { - return outbound; - }, onError: (error, stackTrace) { - // Be sure to close it in case of an error. - if (_gzip) _gzipSink!.close(); - _socketError = true; - _doneCompleter.completeError(error, stackTrace); - if (_ignoreError(error)) { - return outbound; - } else { - throw error; - } - }); - } - - Future close() { - // If we are already closed, return that future. - var closeFuture = _closeFuture; - if (closeFuture != null) return closeFuture; - - var outbound = this.outbound!; - // If we earlier saw an error, return immediate. The notification to - // _Http*Connection is already done. - if (_socketError) return new Future.value(outbound); - if (outbound._isConnectionClosed) return new Future.value(outbound); - if (!headersWritten && !ignoreBody) { - if (outbound.headers.contentLength == -1) { - // If no body was written, ignoreBody is false (it's not a HEAD - // request) and the content-length is unspecified, set contentLength to - // 0. - outbound.headers.chunkedTransferEncoding = false; - outbound.headers.contentLength = 0; - } else if (outbound.headers.contentLength > 0) { - var error = new HttpException( - "No content even though contentLength was specified to be " - "greater than 0: ${outbound.headers.contentLength}.", - uri: outbound._uri); - _doneCompleter.completeError(error); - return _closeFuture = new Future.error(error); - } - } - // If contentLength was specified, validate it. - var contentLength = this.contentLength; - if (contentLength != null) { - if (_bytesWritten < contentLength) { - var error = new HttpException( - "Content size below specified contentLength. " - " $_bytesWritten bytes written but expected " - "$contentLength.", - uri: outbound._uri); - _doneCompleter.completeError(error); - return _closeFuture = new Future.error(error); - } - } - - Future finalize() { - // In case of chunked encoding (and gzip), handle remaining gzip data and - // append the 'footer' for chunked encoding. - if (chunked) { - if (_gzip) { - _gzipAdd = socket.add; - if (_gzipBufferLength > 0) { - _gzipSink!.add(new Uint8List.view(_gzipBuffer!.buffer, - _gzipBuffer!.offsetInBytes, _gzipBufferLength)); - } - _gzipBuffer = null; - _gzipSink!.close(); - _gzipAdd = null; - } - _addChunk(_chunkHeader(0), socket.add); - } - // Add any remaining data in the buffer. - if (_length > 0) { - socket.add(new Uint8List.view( - _buffer!.buffer, _buffer!.offsetInBytes, _length)); - } - // Clear references, for better GC. - _buffer = null; - // And finally flush it. As we support keep-alive, never close it from - // here. Once the socket is flushed, we'll be able to reuse it (signaled - // by the 'done' future). - return socket.flush().then((_) { - _doneCompleter.complete(socket); - return outbound; - }, onError: (error, stackTrace) { - _doneCompleter.completeError(error, stackTrace); - if (_ignoreError(error)) { - return outbound; - } else { - throw error; - } - }); - } - - var future = writeHeaders(); - if (future != null) { - return _closeFuture = future.whenComplete(finalize); - } - return _closeFuture = finalize(); - } - - Future get done => _doneCompleter.future; - - void setHeader(List data, int length) { - assert(_length == 0); - _buffer = data as Uint8List; - _length = length; - } - - void set gzip(bool value) { - _gzip = value; - if (value) { - _gzipBuffer = new Uint8List(_OUTGOING_BUFFER_SIZE); - assert(_gzipSink == null); - _gzipSink = new ZLibEncoder(gzip: true) - .startChunkedConversion(new _HttpGZipSink((data) { - // We are closing down prematurely, due to an error. Discard. - if (_gzipAdd == null) return; - _addChunk(_chunkHeader(data.length), _gzipAdd!); - _pendingChunkedFooter = 2; - _addChunk(data, _gzipAdd!); - })); - } - } - - bool _ignoreError(error) => - (error is SocketException || error is TlsException) && - outbound is HttpResponse; - - void _addGZipChunk(List chunk, void add(List data)) { - var bufferOutput = outbound!.bufferOutput; - if (!bufferOutput) { - add(chunk); - return; - } - var gzipBuffer = _gzipBuffer!; - if (chunk.length > gzipBuffer.length - _gzipBufferLength) { - add(new Uint8List.view( - gzipBuffer.buffer, gzipBuffer.offsetInBytes, _gzipBufferLength)); - _gzipBuffer = new Uint8List(_OUTGOING_BUFFER_SIZE); - _gzipBufferLength = 0; - } - if (chunk.length > _OUTGOING_BUFFER_SIZE) { - add(chunk); - } else { - var currentLength = _gzipBufferLength; - var newLength = currentLength + chunk.length; - _gzipBuffer!.setRange(currentLength, newLength, chunk); - _gzipBufferLength = newLength; - } - } - - void _addChunk(List chunk, void add(List data)) { - var bufferOutput = outbound!.bufferOutput; - if (!bufferOutput) { - if (_buffer != null) { - // If _buffer is not null, we have not written the header yet. Write - // it now. - add(new Uint8List.view( - _buffer!.buffer, _buffer!.offsetInBytes, _length)); - _buffer = null; - _length = 0; - } - add(chunk); - return; - } - if (chunk.length > _buffer!.length - _length) { - add(new Uint8List.view(_buffer!.buffer, _buffer!.offsetInBytes, _length)); - _buffer = new Uint8List(_OUTGOING_BUFFER_SIZE); - _length = 0; - } - if (chunk.length > _OUTGOING_BUFFER_SIZE) { - add(chunk); - } else { - _buffer!.setRange(_length, _length + chunk.length, chunk); - _length += chunk.length; - } - } - - List _chunkHeader(int length) { - const hexDigits = const [ - 0x30, - 0x31, - 0x32, - 0x33, - 0x34, - 0x35, - 0x36, - 0x37, - 0x38, - 0x39, - 0x41, - 0x42, - 0x43, - 0x44, - 0x45, - 0x46 - ]; - if (length == 0) { - if (_pendingChunkedFooter == 2) return _footerAndChunk0Length; - return _chunk0Length; - } - int size = _pendingChunkedFooter; - int len = length; - // Compute a fast integer version of (log(length + 1) / log(16)).ceil(). - while (len > 0) { - size++; - len >>= 4; - } - var footerAndHeader = new Uint8List(size + 2); - if (_pendingChunkedFooter == 2) { - footerAndHeader[0] = _CharCode.CR; - footerAndHeader[1] = _CharCode.LF; - } - int index = size; - while (index > _pendingChunkedFooter) { - footerAndHeader[--index] = hexDigits[length & 15]; - length = length >> 4; - } - footerAndHeader[size + 0] = _CharCode.CR; - footerAndHeader[size + 1] = _CharCode.LF; - return footerAndHeader; - } -} - -class _HttpClientConnection { - final String key; - final Socket _socket; - final bool _proxyTunnel; - final SecurityContext? _context; - final _HttpParser _httpParser; - StreamSubscription? _subscription; - final _HttpClient _httpClient; - bool _dispose = false; - Timer? _idleTimer; - bool closed = false; - Uri? _currentUri; - - Completer<_HttpIncoming>? _nextResponseCompleter; - Future? _streamFuture; - - _HttpClientConnection(this.key, this._socket, this._httpClient, - [this._proxyTunnel = false, this._context]) - : _httpParser = new _HttpParser.responseParser() { - _httpParser.listenToStream(_socket); - - // Set up handlers on the parser here, so we are sure to get 'onDone' from - // the parser. - _subscription = _httpParser.listen((incoming) { - // Only handle one incoming response at the time. Keep the - // stream paused until the response have been processed. - _subscription!.pause(); - // We assume the response is not here, until we have send the request. - if (_nextResponseCompleter == null) { - throw new HttpException( - "Unexpected response (unsolicited response without request).", - uri: _currentUri); - } - - // Check for status code '100 Continue'. In that case just - // consume that response as the final response will follow - // it. There is currently no API for the client to wait for - // the '100 Continue' response. - if (incoming.statusCode == 100) { - incoming.drain().then((_) { - _subscription!.resume(); - }).catchError((dynamic error, StackTrace stackTrace) { - _nextResponseCompleter!.completeError( - new HttpException(error.message, uri: _currentUri), stackTrace); - _nextResponseCompleter = null; - }); - } else { - _nextResponseCompleter!.complete(incoming); - _nextResponseCompleter = null; - } - }, onError: (dynamic error, StackTrace stackTrace) { - _nextResponseCompleter?.completeError( - new HttpException(error.message, uri: _currentUri), stackTrace); - _nextResponseCompleter = null; - }, onDone: () { - _nextResponseCompleter?.completeError(new HttpException( - "Connection closed before response was received", - uri: _currentUri)); - _nextResponseCompleter = null; - close(); - }); - } - - _HttpClientRequest send( - Uri uri, int port, String method, _Proxy proxy, TimelineTask? timeline) { - if (closed) { - throw new HttpException("Socket closed before request was sent", - uri: uri); - } - _currentUri = uri; - // Start with pausing the parser. - _subscription!.pause(); - if (method == "CONNECT") { - // Parser will ignore Content-Length or Transfer-Encoding header - _httpParser.connectMethod = true; - } - _ProxyCredentials? proxyCreds; // Credentials used to authorize proxy. - _SiteCredentials? creds; // Credentials used to authorize this request. - var outgoing = new _HttpOutgoing(_socket); - // Create new request object, wrapping the outgoing connection. - var request = new _HttpClientRequest( - outgoing, uri, method, proxy, _httpClient, this, timeline); - // For the Host header an IPv6 address must be enclosed in []'s. - var host = uri.host; - if (host.contains(':')) host = "[$host]"; - request.headers - ..host = host - ..port = port - ..add(HttpHeaders.acceptEncodingHeader, "gzip"); - if (_httpClient.userAgent != null) { - request.headers.add(HttpHeaders.userAgentHeader, _httpClient.userAgent!); - } - if (proxy.isAuthenticated) { - // If the proxy configuration contains user information use that - // for proxy basic authorization. - String auth = _CryptoUtils.bytesToBase64( - utf8.encode("${proxy.username}:${proxy.password}")); - request.headers.set(HttpHeaders.proxyAuthorizationHeader, "Basic $auth"); - } else if (!proxy.isDirect && _httpClient._proxyCredentials.length > 0) { - proxyCreds = _httpClient._findProxyCredentials(proxy); - if (proxyCreds != null) { - proxyCreds.authorize(request); - } - } - if (uri.userInfo != null && !uri.userInfo.isEmpty) { - // If the URL contains user information use that for basic - // authorization. - String auth = _CryptoUtils.bytesToBase64(utf8.encode(uri.userInfo)); - request.headers.set(HttpHeaders.authorizationHeader, "Basic $auth"); - } else { - // Look for credentials. - creds = _httpClient._findCredentials(uri); - if (creds != null) { - creds.authorize(request); - } - } - - // Start sending the request (lazy, delayed until the user provides - // data). - _httpParser.isHead = method == "HEAD"; - _streamFuture = outgoing.done.then((Socket s) { - // Request sent, set up response completer. - var nextResponseCompleter = new Completer<_HttpIncoming>(); - _nextResponseCompleter = nextResponseCompleter; - - // Listen for response. - nextResponseCompleter.future.then((incoming) { - _currentUri = null; - incoming.dataDone.then((closing) { - if (incoming.upgraded) { - _httpClient._connectionClosed(this); - startTimer(); - return; - } - if (closed) return; - if (!closing && - !_dispose && - incoming.headers.persistentConnection && - request.persistentConnection) { - // Return connection, now we are done. - _httpClient._returnConnection(this); - _subscription!.resume(); - } else { - destroy(); - } - }); - // For digest authentication if proxy check if the proxy - // requests the client to start using a new nonce for proxy - // authentication. - if (proxyCreds != null && - proxyCreds.scheme == _AuthenticationScheme.DIGEST) { - var authInfo = incoming.headers["proxy-authentication-info"]; - if (authInfo != null && authInfo.length == 1) { - var header = - _HeaderValue.parse(authInfo[0], parameterSeparator: ','); - var nextnonce = header.parameters["nextnonce"]; - if (nextnonce != null) proxyCreds.nonce = nextnonce; - } - } - // For digest authentication check if the server requests the - // client to start using a new nonce. - if (creds != null && creds.scheme == _AuthenticationScheme.DIGEST) { - var authInfo = incoming.headers["authentication-info"]; - if (authInfo != null && authInfo.length == 1) { - var header = - _HeaderValue.parse(authInfo[0], parameterSeparator: ','); - var nextnonce = header.parameters["nextnonce"]; - if (nextnonce != null) creds.nonce = nextnonce; - } - } - request._onIncoming(incoming); - }) - // If we see a state error, we failed to get the 'first' - // element. - .catchError((error) { - throw new HttpException("Connection closed before data was received", - uri: uri); - }, test: (error) => error is StateError).catchError((error, stackTrace) { - // We are done with the socket. - destroy(); - request._onError(error, stackTrace); - }); - - // Resume the parser now we have a handler. - _subscription!.resume(); - return s; - }); - Future.value(_streamFuture).catchError((e) { - destroy(); - }); - return request; - } - - Future detachSocket() { - return _streamFuture!.then( - (_) => new _DetachedSocket(_socket, _httpParser.detachIncoming())); - } - - void destroy() { - closed = true; - _httpClient._connectionClosed(this); - _socket.destroy(); - } - - void close() { - closed = true; - _httpClient._connectionClosed(this); - _streamFuture! - .timeout(_httpClient.idleTimeout) - .then((_) => _socket.destroy()); - } - - Future<_HttpClientConnection> createProxyTunnel( - String host, - int port, - _Proxy proxy, - bool callback(X509Certificate certificate), - TimelineTask? timeline) { - timeline?.instant('Establishing proxy tunnel', arguments: { - 'proxyInfo': { - if (proxy.host != null) 'host': proxy.host, - if (proxy.port != null) - 'port': proxy.port, - if (proxy.username != null) - 'username': proxy.username, - // TODO(bkonyi): is this something we would want to surface? Initial - // thought is no. - // if (proxy.password != null) - // 'password': proxy.password, - 'isDirect': proxy.isDirect, - } - }); - final method = "CONNECT"; - final uri = Uri(host: host, port: port); - _HttpClient._startRequestTimelineEvent(timeline, method, uri); - _HttpClientRequest request = - send(Uri(host: host, port: port), port, method, proxy, timeline); - if (proxy.isAuthenticated) { - // If the proxy configuration contains user information use that - // for proxy basic authorization. - String auth = _CryptoUtils.bytesToBase64( - utf8.encode("${proxy.username}:${proxy.password}")); - request.headers.set(HttpHeaders.proxyAuthorizationHeader, "Basic $auth"); - } - return request.close().then((response) { - if (response.statusCode != HttpStatus.ok) { - final error = "Proxy failed to establish tunnel " - "(${response.statusCode} ${response.reasonPhrase})"; - timeline?.instant(error); - throw new HttpException(error, uri: request.uri); - } - var socket = (response as _HttpClientResponse) - ._httpRequest - ._httpClientConnection - ._socket; - return SecureSocket.secure(socket, - host: host, context: _context, onBadCertificate: callback); - }).then((secureSocket) { - String key = _HttpClientConnection.makeKey(true, host, port); - timeline?.instant('Proxy tunnel established'); - return new _HttpClientConnection( - key, secureSocket, request._httpClient, true); - }); - } - - HttpConnectionInfo? get connectionInfo => _HttpConnectionInfo.create(_socket); - - static makeKey(bool isSecure, String host, int port) { - return isSecure ? "ssh:$host:$port" : "$host:$port"; - } - - void stopTimer() { - _idleTimer?.cancel(); - _idleTimer = null; - } - - void startTimer() { - assert(_idleTimer == null); - _idleTimer = new Timer(_httpClient.idleTimeout, () { - _idleTimer = null; - close(); - }); - } -} - -class _ConnectionInfo { - final _HttpClientConnection connection; - final _Proxy proxy; - - _ConnectionInfo(this.connection, this.proxy); -} - -class _ConnectionTarget { - // Unique key for this connection target. - final String key; - final String host; - final int port; - final bool isSecure; - final SecurityContext? context; - final Set<_HttpClientConnection> _idle = new HashSet(); - final Set<_HttpClientConnection> _active = new HashSet(); - final Set _socketTasks = new HashSet(); - final Queue _pending = new ListQueue(); - int _connecting = 0; - - _ConnectionTarget( - this.key, this.host, this.port, this.isSecure, this.context); - - bool get isEmpty => _idle.isEmpty && _active.isEmpty && _connecting == 0; - - bool get hasIdle => _idle.isNotEmpty; - - bool get hasActive => _active.isNotEmpty || _connecting > 0; - - _HttpClientConnection takeIdle() { - assert(hasIdle); - _HttpClientConnection connection = _idle.first; - _idle.remove(connection); - connection.stopTimer(); - _active.add(connection); - return connection; - } - - _checkPending() { - if (_pending.isNotEmpty) { - _pending.removeFirst()(); - } - } - - void addNewActive(_HttpClientConnection connection) { - _active.add(connection); - } - - void returnConnection(_HttpClientConnection connection) { - assert(_active.contains(connection)); - _active.remove(connection); - _idle.add(connection); - connection.startTimer(); - _checkPending(); - } - - void connectionClosed(_HttpClientConnection connection) { - assert(!_active.contains(connection) || !_idle.contains(connection)); - _active.remove(connection); - _idle.remove(connection); - _checkPending(); - } - - void close(bool force) { - // Always cancel pending socket connections. - for (var t in _socketTasks.toList()) { - // Make sure the socket is destroyed if the ConnectionTask is cancelled. - t.socket.then((s) { - s.destroy(); - }, onError: (e) {}); - t.cancel(); - } - if (force) { - for (var c in _idle.toList()) { - c.destroy(); - } - for (var c in _active.toList()) { - c.destroy(); - } - } else { - for (var c in _idle.toList()) { - c.close(); - } - } - } - - Future<_ConnectionInfo> connect(String uriHost, int uriPort, _Proxy proxy, - _HttpClient client, TimelineTask? timeline) { - if (hasIdle) { - var connection = takeIdle(); - client._connectionsChanged(); - return new Future.value(new _ConnectionInfo(connection, proxy)); - } - var maxConnectionsPerHost = client.maxConnectionsPerHost; - if (maxConnectionsPerHost != null && - _active.length + _connecting >= maxConnectionsPerHost) { - var completer = new Completer<_ConnectionInfo>(); - _pending.add(() { - completer.complete(connect(uriHost, uriPort, proxy, client, timeline)); - }); - return completer.future; - } - var currentBadCertificateCallback = client._badCertificateCallback; - - bool callback(X509Certificate certificate) { - if (currentBadCertificateCallback == null) return false; - return currentBadCertificateCallback(certificate, uriHost, uriPort); - } - - Future connectionTask = (isSecure && proxy.isDirect - ? SecureSocket.startConnect(host, port, - context: context, onBadCertificate: callback) - : Socket.startConnect(host, port)); - _connecting++; - return connectionTask.then((ConnectionTask task) { - _socketTasks.add(task); - Future socketFuture = task.socket; - final Duration? connectionTimeout = client.connectionTimeout; - if (connectionTimeout != null) { - socketFuture = socketFuture.timeout(connectionTimeout, onTimeout: () { - _socketTasks.remove(task); - task.cancel(); - return null; - }); - } - return socketFuture.then((socket) { - // When there is a timeout, there is a race in which the connectionTask - // Future won't be completed with an error before the socketFuture here - // is completed with 'null' by the onTimeout callback above. In this - // case, propagate a SocketException as specified by the - // HttpClient.connectionTimeout docs. - _connecting--; - if (socket == null) { - assert(connectionTimeout != null); - throw new SocketException( - "HTTP connection timed out after ${connectionTimeout}, " - "host: ${host}, port: ${port}"); - } - socket.setOption(SocketOption.tcpNoDelay, true); - var connection = - new _HttpClientConnection(key, socket, client, false, context); - if (isSecure && !proxy.isDirect) { - connection._dispose = true; - return connection - .createProxyTunnel(uriHost, uriPort, proxy, callback, timeline) - .then((tunnel) { - client - ._getConnectionTarget(uriHost, uriPort, true) - .addNewActive(tunnel); - _socketTasks.remove(task); - return new _ConnectionInfo(tunnel, proxy); - }); - } else { - addNewActive(connection); - _socketTasks.remove(task); - return new _ConnectionInfo(connection, proxy); - } - }, onError: (error) { - _socketTasks.remove(task); - _checkPending(); - throw error; - }); - }, onError: (error) { - _connecting--; - throw error; - }); - } -} - -typedef bool BadCertificateCallback(X509Certificate cr, String host, int port); - -class _HttpClient implements HttpClient { - bool _closing = false; - bool _closingForcefully = false; - final Map _connectionTargets = - new HashMap(); - final List<_Credentials> _credentials = []; - final List<_ProxyCredentials> _proxyCredentials = []; - final SecurityContext? _context; - Function? _authenticate; - Function? _authenticateProxy; - Function? _findProxy = HttpClient.findProxyFromEnvironment; - Duration _idleTimeout = const Duration(seconds: 15); - BadCertificateCallback? _badCertificateCallback; - - Duration get idleTimeout => _idleTimeout; - - Duration? connectionTimeout; - - int? maxConnectionsPerHost; - - bool autoUncompress = true; - - String? userAgent = _getHttpVersion(); - - _HttpClient(this._context); - - void set idleTimeout(Duration timeout) { - _idleTimeout = timeout; - for (var c in _connectionTargets.values) { - for (var idle in c._idle) { - // Reset timer. This is fine, as it's not happening often. - idle.stopTimer(); - idle.startTimer(); - } - } - } - - set badCertificateCallback( - bool callback(X509Certificate cert, String host, int port)?) { - _badCertificateCallback = callback; - } - - Future open( - String method, String host, int port, String path) { - const int hashMark = 0x23; - const int questionMark = 0x3f; - int fragmentStart = path.length; - int queryStart = path.length; - for (int i = path.length - 1; i >= 0; i--) { - var char = path.codeUnitAt(i); - if (char == hashMark) { - fragmentStart = i; - queryStart = i; - } else if (char == questionMark) { - queryStart = i; - } - } - String? query; - if (queryStart < fragmentStart) { - query = path.substring(queryStart + 1, fragmentStart); - path = path.substring(0, queryStart); - } - Uri uri = new Uri( - scheme: "http", host: host, port: port, path: path, query: query); - return _openUrl(method, uri); - } - - Future openUrl(String method, Uri url) => - _openUrl(method, url); - - Future get(String host, int port, String path) => - open("get", host, port, path); - - Future getUrl(Uri url) => _openUrl("get", url); - - Future post(String host, int port, String path) => - open("post", host, port, path); - - Future postUrl(Uri url) => _openUrl("post", url); - - Future put(String host, int port, String path) => - open("put", host, port, path); - - Future putUrl(Uri url) => _openUrl("put", url); - - Future delete(String host, int port, String path) => - open("delete", host, port, path); - - Future deleteUrl(Uri url) => _openUrl("delete", url); - - Future head(String host, int port, String path) => - open("head", host, port, path); - - Future headUrl(Uri url) => _openUrl("head", url); - - Future patch(String host, int port, String path) => - open("patch", host, port, path); - - Future patchUrl(Uri url) => _openUrl("patch", url); - - void close({bool force = false}) { - _closing = true; - _closingForcefully = force; - _closeConnections(_closingForcefully); - assert(!_connectionTargets.values.any((s) => s.hasIdle)); - assert( - !force || !_connectionTargets.values.any((s) => s._active.isNotEmpty)); - } - - set authenticate(Future f(Uri url, String scheme, String realm)?) { - _authenticate = f; - } - - void addCredentials(Uri url, String realm, HttpClientCredentials cr) { - _credentials - .add(new _SiteCredentials(url, realm, cr as _HttpClientCredentials)); - } - - set authenticateProxy( - Future f(String host, int port, String scheme, String realm)?) { - _authenticateProxy = f; - } - - void addProxyCredentials( - String host, int port, String realm, HttpClientCredentials cr) { - _proxyCredentials.add( - new _ProxyCredentials(host, port, realm, cr as _HttpClientCredentials)); - } - - set findProxy(String f(Uri uri)?) => _findProxy = f; - - static void _startRequestTimelineEvent( - TimelineTask? timeline, String method, Uri uri) { - timeline?.start('HTTP CLIENT ${method.toUpperCase()}', arguments: { - 'method': method.toUpperCase(), - 'uri': uri.toString(), - }); - } - - /// Whether HTTP requests are currently allowed. - /// - /// If the [Zone] variable `#dart.library.io.allow_http` is set to a boolean, - /// it determines whether the HTTP protocol is allowed. If the zone variable - /// is set to any other non-null value, HTTP is not allowed. - /// Otherwise, if the `dart.library.io.allow_http` environment flag - /// is set to `false`, HTTP is not allowed. - /// Otherwise, [_embedderAllowsHttp] determines the result. - bool get _isHttpAllowed { - final zoneOverride = Zone.current[#dart.library.io.allow_http]; - if (zoneOverride != null) return true == zoneOverride; - bool envOverride = - bool.fromEnvironment("dart.library.io.allow_http", defaultValue: true); - return envOverride && _embedderAllowsHttp; - } - - bool _isLoopback(String host) { - if (host.isEmpty) return false; - if ("localhost" == host) return true; - try { - return InternetAddress(host).isLoopback; - } on ArgumentError { - return false; - } - } - - Future<_HttpClientRequest> _openUrl(String method, Uri uri) { - if (_closing) { - throw new StateError("Client is closed"); - } - - // Ignore any fragments on the request URI. - uri = uri.removeFragment(); - - if (method == null) { - throw new ArgumentError(method); - } - if (method != "CONNECT") { - if (uri.host.isEmpty) { - throw new ArgumentError("No host specified in URI $uri"); - } else if (uri.scheme != "http" && uri.scheme != "https") { - throw new ArgumentError( - "Unsupported scheme '${uri.scheme}' in URI $uri"); - } - } - - bool isSecure = uri.isScheme("https"); - if (!_isHttpAllowed && !isSecure && !_isLoopback(uri.host)) { - throw new StateError( - "Insecure HTTP is not allowed by the current platform: $uri"); - } - - int port = uri.port; - if (port == 0) { - port = - isSecure ? HttpClient.defaultHttpsPort : HttpClient.defaultHttpPort; - } - // Check to see if a proxy server should be used for this connection. - var proxyConf = const _ProxyConfiguration.direct(); - var findProxy = _findProxy; - if (findProxy != null) { - // TODO(sgjesse): Keep a map of these as normally only a few - // configuration strings will be used. - try { - proxyConf = new _ProxyConfiguration(findProxy(uri)); - } catch (error, stackTrace) { - return new Future.error(error, stackTrace); - } - } - TimelineTask? timeline; - // TODO(bkonyi): do we want this to be opt-in? - if (HttpClient.enableTimelineLogging) { - timeline = TimelineTask(filterKey: 'HTTP/client'); - _startRequestTimelineEvent(timeline, method, uri); - } - return _getConnection(uri.host, port, proxyConf, isSecure, timeline).then( - (_ConnectionInfo info) { - _HttpClientRequest send(_ConnectionInfo info) { - timeline?.instant('Connection established'); - return info.connection - .send(uri, port, method.toUpperCase(), info.proxy, timeline); - } - - // If the connection was closed before the request was sent, create - // and use another connection. - if (info.connection.closed) { - return _getConnection(uri.host, port, proxyConf, isSecure, timeline) - .then(send); - } - return send(info); - }, onError: (error) { - timeline?.finish(arguments: { - 'error': error.toString(), - }); - throw error; - }); - } - - Future<_HttpClientRequest> _openUrlFromRequest( - String method, Uri uri, _HttpClientRequest previous) { - // If the new URI is relative (to either '/' or some sub-path), - // construct a full URI from the previous one. - Uri resolved = previous.uri.resolveUri(uri); - return _openUrl(method, resolved).then((_HttpClientRequest request) { - request - // Only follow redirects if initial request did. - ..followRedirects = previous.followRedirects - // Allow same number of redirects. - ..maxRedirects = previous.maxRedirects; - // Copy headers. - for (var header in previous.headers._headers.keys) { - if (request.headers[header] == null) { - request.headers.set(header, previous.headers[header]!); - } - } - return request - ..headers.chunkedTransferEncoding = false - ..contentLength = 0; - }); - } - - // Return a live connection to the idle pool. - void _returnConnection(_HttpClientConnection connection) { - _connectionTargets[connection.key]!.returnConnection(connection); - _connectionsChanged(); - } - - // Remove a closed connection from the active set. - void _connectionClosed(_HttpClientConnection connection) { - connection.stopTimer(); - var connectionTarget = _connectionTargets[connection.key]; - if (connectionTarget != null) { - connectionTarget.connectionClosed(connection); - if (connectionTarget.isEmpty) { - _connectionTargets.remove(connection.key); - } - _connectionsChanged(); - } - } - - void _connectionsChanged() { - if (_closing) { - _closeConnections(_closingForcefully); - } - } - - void _closeConnections(bool force) { - for (var connectionTarget in _connectionTargets.values.toList()) { - connectionTarget.close(force); - } - } - - _ConnectionTarget _getConnectionTarget(String host, int port, bool isSecure) { - String key = _HttpClientConnection.makeKey(isSecure, host, port); - return _connectionTargets.putIfAbsent(key, () { - return new _ConnectionTarget(key, host, port, isSecure, _context); - }); - } - - // Get a new _HttpClientConnection, from the matching _ConnectionTarget. - Future<_ConnectionInfo> _getConnection(String uriHost, int uriPort, - _ProxyConfiguration proxyConf, bool isSecure, TimelineTask? timeline) { - Iterator<_Proxy> proxies = proxyConf.proxies.iterator; - - Future<_ConnectionInfo> connect(error) { - if (!proxies.moveNext()) return new Future.error(error); - _Proxy proxy = proxies.current; - String host = proxy.isDirect ? uriHost : proxy.host!; - int port = proxy.isDirect ? uriPort : proxy.port!; - return _getConnectionTarget(host, port, isSecure) - .connect(uriHost, uriPort, proxy, this, timeline) - // On error, continue with next proxy. - .catchError(connect); - } - - return connect(new HttpException("No proxies given")); - } - - _SiteCredentials? _findCredentials(Uri url, [_AuthenticationScheme? scheme]) { - // Look for credentials. - _SiteCredentials? cr = - _credentials.fold(null, (_SiteCredentials? prev, value) { - var siteCredentials = value as _SiteCredentials; - if (siteCredentials.applies(url, scheme)) { - if (prev == null) return value; - return siteCredentials.uri.path.length > prev.uri.path.length - ? siteCredentials - : prev; - } else { - return prev; - } - }); - return cr; - } - - _ProxyCredentials? _findProxyCredentials(_Proxy proxy, - [_AuthenticationScheme? scheme]) { - // Look for credentials. - for (var current in _proxyCredentials) { - if (current.applies(proxy, scheme)) { - return current; - } - } - return null; - } - - void _removeCredentials(_Credentials cr) { - int index = _credentials.indexOf(cr); - if (index != -1) { - _credentials.removeAt(index); - } - } - - void _removeProxyCredentials(_Credentials cr) { - _proxyCredentials.remove(cr); - } - - static String _findProxyFromEnvironment( - Uri url, Map? environment) { - String? checkNoProxy(String? option) { - if (option == null) return null; - Iterator names = option.split(",").map((s) => s.trim()).iterator; - while (names.moveNext()) { - var name = names.current; - if ((name.startsWith("[") && - name.endsWith("]") && - "[${url.host}]" == name) || - (name.isNotEmpty && url.host.endsWith(name))) { - return "DIRECT"; - } - } - return null; - } - - String? checkProxy(String? option) { - if (option == null) return null; - option = option.trim(); - if (option.isEmpty) return null; - int pos = option.indexOf("://"); - if (pos >= 0) { - option = option.substring(pos + 3); - } - pos = option.indexOf("/"); - if (pos >= 0) { - option = option.substring(0, pos); - } - // Add default port if no port configured. - if (option.indexOf("[") == 0) { - var pos = option.lastIndexOf(":"); - if (option.indexOf("]") > pos) option = "$option:1080"; - } else { - if (option.indexOf(":") == -1) option = "$option:1080"; - } - return "PROXY $option"; - } - - // Default to using the process current environment. - if (environment == null) environment = _platformEnvironmentCache; - - String? proxyCfg; - - String? noProxy = environment["no_proxy"] ?? environment["NO_PROXY"]; - proxyCfg = checkNoProxy(noProxy); - if (proxyCfg != null) { - return proxyCfg; - } - - if (url.scheme == "http") { - String? proxy = environment["http_proxy"] ?? environment["HTTP_PROXY"]; - proxyCfg = checkProxy(proxy); - if (proxyCfg != null) { - return proxyCfg; - } - } else if (url.scheme == "https") { - String? proxy = environment["https_proxy"] ?? environment["HTTPS_PROXY"]; - proxyCfg = checkProxy(proxy); - if (proxyCfg != null) { - return proxyCfg; - } - } - return "DIRECT"; - } - - static Map _platformEnvironmentCache = Platform.environment; -} - -class _HttpConnection extends LinkedListEntry<_HttpConnection> - with _ServiceObject { - static const _ACTIVE = 0; - static const _IDLE = 1; - static const _CLOSING = 2; - static const _DETACHED = 3; - - // Use HashMap, as we don't need to keep order. - static Map _connections = - new HashMap(); - - final /*_ServerSocket*/ _socket; - final _HttpServer _httpServer; - final _HttpParser _httpParser; - int _state = _IDLE; - StreamSubscription? _subscription; - bool _idleMark = false; - Future? _streamFuture; - - _HttpConnection(this._socket, this._httpServer) - : _httpParser = new _HttpParser.requestParser() { - _connections[_serviceId] = this; - _httpParser.listenToStream(_socket); - _subscription = _httpParser.listen((incoming) { - _httpServer._markActive(this); - // If the incoming was closed, close the connection. - incoming.dataDone.then((closing) { - if (closing) destroy(); - }); - // Only handle one incoming request at the time. Keep the - // stream paused until the request has been send. - _subscription!.pause(); - _state = _ACTIVE; - var outgoing = new _HttpOutgoing(_socket); - var response = new _HttpResponse( - incoming.uri!, - incoming.headers.protocolVersion, - outgoing, - _httpServer.defaultResponseHeaders, - _httpServer.serverHeader); - // Parser found badRequest and sent out Response. - if (incoming.statusCode == HttpStatus.badRequest) { - response.statusCode = HttpStatus.badRequest; - } - var request = new _HttpRequest(response, incoming, _httpServer, this); - _streamFuture = outgoing.done.then((_) { - response.deadline = null; - if (_state == _DETACHED) return; - if (response.persistentConnection && - request.persistentConnection && - incoming.fullBodyRead && - !_httpParser.upgrade && - !_httpServer.closed) { - _state = _IDLE; - _idleMark = false; - _httpServer._markIdle(this); - // Resume the subscription for incoming requests as the - // request is now processed. - _subscription!.resume(); - } else { - // Close socket, keep-alive not used or body sent before - // received data was handled. - destroy(); - } - }, onError: (_) { - destroy(); - }); - outgoing.ignoreBody = request.method == "HEAD"; - response._httpRequest = request; - _httpServer._handleRequest(request); - }, onDone: () { - destroy(); - }, onError: (error) { - // Ignore failed requests that was closed before headers was received. - destroy(); - }); - } - - void markIdle() { - _idleMark = true; - } - - bool get isMarkedIdle => _idleMark; - - void destroy() { - if (_state == _CLOSING || _state == _DETACHED) return; - _state = _CLOSING; - _socket.destroy(); - _httpServer._connectionClosed(this); - _connections.remove(_serviceId); - } - - Future detachSocket() { - _state = _DETACHED; - // Remove connection from server. - _httpServer._connectionClosed(this); - - _HttpDetachedIncoming detachedIncoming = _httpParser.detachIncoming(); - - return _streamFuture!.then((_) { - _connections.remove(_serviceId); - return new _DetachedSocket(_socket, detachedIncoming); - }); - } - - HttpConnectionInfo? get connectionInfo => _HttpConnectionInfo.create(_socket); - - bool get _isActive => _state == _ACTIVE; - bool get _isIdle => _state == _IDLE; - bool get _isClosing => _state == _CLOSING; - bool get _isDetached => _state == _DETACHED; - - String get _serviceTypePath => 'io/http/serverconnections'; - String get _serviceTypeName => 'HttpServerConnection'; - - Map _toJSON(bool ref) { - var name = "${_socket.address.host}:${_socket.port} <-> " - "${_socket.remoteAddress.host}:${_socket.remotePort}"; - var r = { - 'id': _servicePath, - 'type': _serviceType(ref), - 'name': name, - 'user_name': name, - }; - if (ref) { - return r; - } - r['server'] = _httpServer._toJSON(true); - try { - r['socket'] = _socket._toJSON(true); - } catch (_) { - r['socket'] = { - 'id': _servicePath, - 'type': '@Socket', - 'name': 'UserSocket', - 'user_name': 'UserSocket', - }; - } - switch (_state) { - case _ACTIVE: - r['state'] = "Active"; - break; - case _IDLE: - r['state'] = "Idle"; - break; - case _CLOSING: - r['state'] = "Closing"; - break; - case _DETACHED: - r['state'] = "Detached"; - break; - default: - r['state'] = 'Unknown'; - break; - } - return r; - } -} - -// HTTP server waiting for socket connections. -class _HttpServer extends Stream - with _ServiceObject - implements HttpServer { - // Use default Map so we keep order. - static Map _servers = new Map(); - - String? serverHeader; - final HttpHeaders defaultResponseHeaders = _initDefaultResponseHeaders(); - bool autoCompress = false; - - Duration? _idleTimeout; - Timer? _idleTimer; - - static Future bind( - address, int port, int backlog, bool v6Only, bool shared) { - return ServerSocket.bind(address, port, - backlog: backlog, v6Only: v6Only, shared: shared) - .then((socket) { - return new _HttpServer._(socket, true); - }); - } - - static Future bindSecure( - address, - int port, - SecurityContext? context, - int backlog, - bool v6Only, - bool requestClientCertificate, - bool shared) { - return SecureServerSocket.bind(address, port, context, - backlog: backlog, - v6Only: v6Only, - requestClientCertificate: requestClientCertificate, - shared: shared) - .then((socket) { - return new _HttpServer._(socket, true); - }); - } - - _HttpServer._(this._serverSocket, this._closeServer) - : _controller = new StreamController(sync: true) { - _controller.onCancel = close; - idleTimeout = const Duration(seconds: 120); - _servers[_serviceId] = this; - } - - _HttpServer.listenOn(this._serverSocket) - : _closeServer = false, - _controller = new StreamController(sync: true) { - _controller.onCancel = close; - idleTimeout = const Duration(seconds: 120); - _servers[_serviceId] = this; - } - - static HttpHeaders _initDefaultResponseHeaders() { - var defaultResponseHeaders = new _HttpHeaders('1.1'); - defaultResponseHeaders.contentType = ContentType.text; - defaultResponseHeaders.set('X-Frame-Options', 'SAMEORIGIN'); - defaultResponseHeaders.set('X-Content-Type-Options', 'nosniff'); - defaultResponseHeaders.set('X-XSS-Protection', '1; mode=block'); - return defaultResponseHeaders; - } - - Duration? get idleTimeout => _idleTimeout; - - void set idleTimeout(Duration? duration) { - var idleTimer = _idleTimer; - if (idleTimer != null) { - idleTimer.cancel(); - _idleTimer = null; - } - _idleTimeout = duration; - if (duration != null) { - _idleTimer = new Timer.periodic(duration, (_) { - for (var idle in _idleConnections.toList()) { - if (idle.isMarkedIdle) { - idle.destroy(); - } else { - idle.markIdle(); - } - } - }); - } - } - - StreamSubscription listen(void onData(HttpRequest event)?, - {Function? onError, void onDone()?, bool? cancelOnError}) { - _serverSocket.listen((Socket socket) { - socket.setOption(SocketOption.tcpNoDelay, true); - // Accept the client connection. - _HttpConnection connection = new _HttpConnection(socket, this); - _idleConnections.add(connection); - }, onError: (error, stackTrace) { - // Ignore HandshakeExceptions as they are bound to a single request, - // and are not fatal for the server. - if (error is! HandshakeException) { - _controller.addError(error, stackTrace); - } - }, onDone: _controller.close); - return _controller.stream.listen(onData, - onError: onError, onDone: onDone, cancelOnError: cancelOnError); - } - - Future close({bool force = false}) { - closed = true; - Future result; - if (_serverSocket != null && _closeServer) { - result = _serverSocket.close(); - } else { - result = new Future.value(); - } - idleTimeout = null; - if (force) { - for (var c in _activeConnections.toList()) { - c.destroy(); - } - assert(_activeConnections.isEmpty); - } - for (var c in _idleConnections.toList()) { - c.destroy(); - } - _maybePerformCleanup(); - return result; - } - - void _maybePerformCleanup() { - var sessionManager = _sessionManagerInstance; - if (closed && - _idleConnections.isEmpty && - _activeConnections.isEmpty && - sessionManager != null) { - sessionManager.close(); - _sessionManagerInstance = null; - _servers.remove(_serviceId); - } - } - - int get port { - if (closed) throw new HttpException("HttpServer is not bound to a socket"); - return _serverSocket.port; - } - - InternetAddress get address { - if (closed) throw new HttpException("HttpServer is not bound to a socket"); - return _serverSocket.address; - } - - set sessionTimeout(int timeout) { - _sessionManager.sessionTimeout = timeout; - } - - void _handleRequest(_HttpRequest request) { - if (!closed) { - _controller.add(request); - } else { - request._httpConnection.destroy(); - } - } - - void _connectionClosed(_HttpConnection connection) { - // Remove itself from either idle or active connections. - connection.unlink(); - _maybePerformCleanup(); - } - - void _markIdle(_HttpConnection connection) { - _activeConnections.remove(connection); - _idleConnections.add(connection); - } - - void _markActive(_HttpConnection connection) { - _idleConnections.remove(connection); - _activeConnections.add(connection); - } - - // Lazy init. - _HttpSessionManager get _sessionManager => - _sessionManagerInstance ??= _HttpSessionManager(); - - HttpConnectionsInfo connectionsInfo() { - HttpConnectionsInfo result = new HttpConnectionsInfo(); - result.total = _activeConnections.length + _idleConnections.length; - _activeConnections.forEach((_HttpConnection conn) { - if (conn._isActive) { - result.active++; - } else { - assert(conn._isClosing); - result.closing++; - } - }); - _idleConnections.forEach((_HttpConnection conn) { - result.idle++; - assert(conn._isIdle); - }); - return result; - } - - String get _serviceTypePath => 'io/http/servers'; - String get _serviceTypeName => 'HttpServer'; - - Map _toJSON(bool ref) { - var r = { - 'id': _servicePath, - 'type': _serviceType(ref), - 'name': '${address.host}:$port', - 'user_name': '${address.host}:$port', - }; - if (ref) { - return r; - } - try { - r['socket'] = _serverSocket._toJSON(true); - } catch (_) { - r['socket'] = { - 'id': _servicePath, - 'type': '@Socket', - 'name': 'UserSocket', - 'user_name': 'UserSocket', - }; - } - r['port'] = port; - r['address'] = address.host; - r['active'] = _activeConnections.map((c) => c._toJSON(true)).toList(); - r['idle'] = _idleConnections.map((c) => c._toJSON(true)).toList(); - r['closed'] = closed; - return r; - } - - _HttpSessionManager? _sessionManagerInstance; - - // Indicated if the http server has been closed. - bool closed = false; - - // The server listen socket. Untyped as it can be both ServerSocket and - // SecureServerSocket. - final dynamic /*ServerSocket|SecureServerSocket*/ _serverSocket; - final bool _closeServer; - - // Set of currently connected clients. - final LinkedList<_HttpConnection> _activeConnections = - new LinkedList<_HttpConnection>(); - final LinkedList<_HttpConnection> _idleConnections = - new LinkedList<_HttpConnection>(); - StreamController _controller; -} - -class _ProxyConfiguration { - static const String PROXY_PREFIX = "PROXY "; - static const String DIRECT_PREFIX = "DIRECT"; - - _ProxyConfiguration(String configuration) : proxies = <_Proxy>[] { - if (configuration == null) { - throw new HttpException("Invalid proxy configuration $configuration"); - } - List list = configuration.split(";"); - list.forEach((String proxy) { - proxy = proxy.trim(); - if (!proxy.isEmpty) { - if (proxy.startsWith(PROXY_PREFIX)) { - String? username; - String? password; - // Skip the "PROXY " prefix. - proxy = proxy.substring(PROXY_PREFIX.length).trim(); - // Look for proxy authentication. - int at = proxy.indexOf("@"); - if (at != -1) { - String userinfo = proxy.substring(0, at).trim(); - proxy = proxy.substring(at + 1).trim(); - int colon = userinfo.indexOf(":"); - if (colon == -1 || colon == 0 || colon == proxy.length - 1) { - throw new HttpException( - "Invalid proxy configuration $configuration"); - } - username = userinfo.substring(0, colon).trim(); - password = userinfo.substring(colon + 1).trim(); - } - // Look for proxy host and port. - int colon = proxy.lastIndexOf(":"); - if (colon == -1 || colon == 0 || colon == proxy.length - 1) { - throw new HttpException( - "Invalid proxy configuration $configuration"); - } - String host = proxy.substring(0, colon).trim(); - if (host.startsWith("[") && host.endsWith("]")) { - host = host.substring(1, host.length - 1); - } - String portString = proxy.substring(colon + 1).trim(); - int port; - try { - port = int.parse(portString); - } on FormatException catch (e) { - throw new HttpException( - "Invalid proxy configuration $configuration, " - "invalid port '$portString'"); - } - proxies.add(new _Proxy(host, port, username, password)); - } else if (proxy.trim() == DIRECT_PREFIX) { - proxies.add(new _Proxy.direct()); - } else { - throw new HttpException("Invalid proxy configuration $configuration"); - } - } - }); - } - - const _ProxyConfiguration.direct() : proxies = const [const _Proxy.direct()]; - - final List<_Proxy> proxies; -} - -class _Proxy { - final String? host; - final int? port; - final String? username; - final String? password; - final bool isDirect; - - const _Proxy(String this.host, int this.port, this.username, this.password) - : isDirect = false; - const _Proxy.direct() - : host = null, - port = null, - username = null, - password = null, - isDirect = true; - - bool get isAuthenticated => username != null; -} - -class _HttpConnectionInfo implements HttpConnectionInfo { - InternetAddress remoteAddress; - int remotePort; - int localPort; - - _HttpConnectionInfo(this.remoteAddress, this.remotePort, this.localPort); - - static _HttpConnectionInfo? create(Socket socket) { - if (socket == null) return null; - try { - return _HttpConnectionInfo( - socket.remoteAddress, socket.remotePort, socket.port); - } catch (e) {} - return null; - } -} - -class _DetachedSocket extends Stream implements Socket { - final Stream _incoming; - final Socket _socket; - - _DetachedSocket(this._socket, this._incoming); - - StreamSubscription listen(void onData(Uint8List event)?, - {Function? onError, void onDone()?, bool? cancelOnError}) { - return _incoming.listen(onData, - onError: onError, onDone: onDone, cancelOnError: cancelOnError); - } - - Encoding get encoding => _socket.encoding; - - void set encoding(Encoding value) { - _socket.encoding = value; - } - - void write(Object? obj) { - _socket.write(obj); - } - - void writeln([Object? obj = ""]) { - _socket.writeln(obj); - } - - void writeCharCode(int charCode) { - _socket.writeCharCode(charCode); - } - - void writeAll(Iterable objects, [String separator = ""]) { - _socket.writeAll(objects, separator); - } - - void add(List bytes) { - _socket.add(bytes); - } - - void addError(Object error, [StackTrace? stackTrace]) => - _socket.addError(error, stackTrace); - - Future addStream(Stream> stream) { - return _socket.addStream(stream); - } - - void destroy() { - _socket.destroy(); - } - - Future flush() => _socket.flush(); - - Future close() => _socket.close(); - - Future get done => _socket.done; - - int get port => _socket.port; - - InternetAddress get address => _socket.address; - - InternetAddress get remoteAddress => _socket.remoteAddress; - - int get remotePort => _socket.remotePort; - - bool setOption(SocketOption option, bool enabled) { - return _socket.setOption(option, enabled); - } - - Uint8List getRawOption(RawSocketOption option) { - return _socket.getRawOption(option); - } - - void setRawOption(RawSocketOption option) { - _socket.setRawOption(option); - } - - Map _toJSON(bool ref) { - return (_socket as dynamic)._toJSON(ref); - } -} - -class _AuthenticationScheme { - final int _scheme; - - static const UNKNOWN = const _AuthenticationScheme(-1); - static const BASIC = const _AuthenticationScheme(0); - static const DIGEST = const _AuthenticationScheme(1); - - const _AuthenticationScheme(this._scheme); - - factory _AuthenticationScheme.fromString(String scheme) { - if (scheme.toLowerCase() == "basic") return BASIC; - if (scheme.toLowerCase() == "digest") return DIGEST; - return UNKNOWN; - } - - String toString() { - if (this == BASIC) return "Basic"; - if (this == DIGEST) return "Digest"; - return "Unknown"; - } -} - -abstract class _Credentials { - _HttpClientCredentials credentials; - String realm; - bool used = false; - - // Digest specific fields. - String? ha1; - String? nonce; - String? algorithm; - String? qop; - int? nonceCount; - - _Credentials(this.credentials, this.realm) { - if (credentials.scheme == _AuthenticationScheme.DIGEST) { - // Calculate the H(A1) value once. There is no mentioning of - // username/password encoding in RFC 2617. However there is an - // open draft for adding an additional accept-charset parameter to - // the WWW-Authenticate and Proxy-Authenticate headers, see - // http://tools.ietf.org/html/draft-reschke-basicauth-enc-06. For - // now always use UTF-8 encoding. - var creds = credentials as _HttpClientDigestCredentials; - var hasher = new _MD5() - ..add(utf8.encode(creds.username)) - ..add([_CharCode.COLON]) - ..add(realm.codeUnits) - ..add([_CharCode.COLON]) - ..add(utf8.encode(creds.password)); - ha1 = _CryptoUtils.bytesToHex(hasher.close()); - } - } - - _AuthenticationScheme get scheme => credentials.scheme; - - void authorize(HttpClientRequest request); -} - -class _SiteCredentials extends _Credentials { - Uri uri; - - _SiteCredentials(this.uri, realm, _HttpClientCredentials creds) - : super(creds, realm); - - bool applies(Uri uri, _AuthenticationScheme? scheme) { - if (scheme != null && credentials.scheme != scheme) return false; - if (uri.host != this.uri.host) return false; - int thisPort = - this.uri.port == 0 ? HttpClient.defaultHttpPort : this.uri.port; - int otherPort = uri.port == 0 ? HttpClient.defaultHttpPort : uri.port; - if (otherPort != thisPort) return false; - return uri.path.startsWith(this.uri.path); - } - - void authorize(HttpClientRequest request) { - // Digest credentials cannot be used without a nonce from the - // server. - if (credentials.scheme == _AuthenticationScheme.DIGEST && nonce == null) { - return; - } - credentials.authorize(this, request as _HttpClientRequest); - used = true; - } -} - -class _ProxyCredentials extends _Credentials { - String host; - int port; - - _ProxyCredentials(this.host, this.port, realm, _HttpClientCredentials creds) - : super(creds, realm); - - bool applies(_Proxy proxy, _AuthenticationScheme? scheme) { - if (scheme != null && credentials.scheme != scheme) return false; - return proxy.host == host && proxy.port == port; - } - - void authorize(HttpClientRequest request) { - // Digest credentials cannot be used without a nonce from the - // server. - if (credentials.scheme == _AuthenticationScheme.DIGEST && nonce == null) { - return; - } - credentials.authorizeProxy(this, request as _HttpClientRequest); - } -} - -abstract class _HttpClientCredentials implements HttpClientCredentials { - _AuthenticationScheme get scheme; - void authorize(_Credentials credentials, _HttpClientRequest request); - void authorizeProxy(_ProxyCredentials credentials, HttpClientRequest request); -} - -class _HttpClientBasicCredentials extends _HttpClientCredentials - implements HttpClientBasicCredentials { - String username; - String password; - - _HttpClientBasicCredentials(this.username, this.password); - - _AuthenticationScheme get scheme => _AuthenticationScheme.BASIC; - - String authorization() { - // There is no mentioning of username/password encoding in RFC - // 2617. However there is an open draft for adding an additional - // accept-charset parameter to the WWW-Authenticate and - // Proxy-Authenticate headers, see - // http://tools.ietf.org/html/draft-reschke-basicauth-enc-06. For - // now always use UTF-8 encoding. - String auth = - _CryptoUtils.bytesToBase64(utf8.encode("$username:$password")); - return "Basic $auth"; - } - - void authorize(_Credentials _, HttpClientRequest request) { - request.headers.set(HttpHeaders.authorizationHeader, authorization()); - } - - void authorizeProxy(_ProxyCredentials _, HttpClientRequest request) { - request.headers.set(HttpHeaders.proxyAuthorizationHeader, authorization()); - } -} - -class _HttpClientDigestCredentials extends _HttpClientCredentials - implements HttpClientDigestCredentials { - String username; - String password; - - _HttpClientDigestCredentials(this.username, this.password); - - _AuthenticationScheme get scheme => _AuthenticationScheme.DIGEST; - - String authorization(_Credentials credentials, _HttpClientRequest request) { - String requestUri = request._requestUri(); - _MD5 hasher = new _MD5() - ..add(request.method.codeUnits) - ..add([_CharCode.COLON]) - ..add(requestUri.codeUnits); - var ha2 = _CryptoUtils.bytesToHex(hasher.close()); - - bool isAuth = false; - String cnonce = ""; - String nc = ""; - hasher = new _MD5() - ..add(credentials.ha1!.codeUnits) - ..add([_CharCode.COLON]); - if (credentials.qop == "auth") { - isAuth = true; - cnonce = _CryptoUtils.bytesToHex(_CryptoUtils.getRandomBytes(4)); - var nonceCount = credentials.nonceCount! + 1; - credentials.nonceCount = nonceCount; - nc = nonceCount.toRadixString(16).padLeft(9, "0"); - hasher - ..add(credentials.nonce!.codeUnits) - ..add([_CharCode.COLON]) - ..add(nc.codeUnits) - ..add([_CharCode.COLON]) - ..add(cnonce.codeUnits) - ..add([_CharCode.COLON]) - ..add("auth".codeUnits) - ..add([_CharCode.COLON]) - ..add(ha2.codeUnits); - } else { - hasher - ..add(credentials.nonce!.codeUnits) - ..add([_CharCode.COLON]) - ..add(ha2.codeUnits); - } - var response = _CryptoUtils.bytesToHex(hasher.close()); - - StringBuffer buffer = new StringBuffer() - ..write('Digest ') - ..write('username="$username"') - ..write(', realm="${credentials.realm}"') - ..write(', nonce="${credentials.nonce}"') - ..write(', uri="$requestUri"') - ..write(', algorithm="${credentials.algorithm}"'); - if (isAuth) { - buffer - ..write(', qop="auth"') - ..write(', cnonce="$cnonce"') - ..write(', nc="$nc"'); - } - buffer.write(', response="$response"'); - return buffer.toString(); - } - - void authorize(_Credentials credentials, HttpClientRequest request) { - request.headers.set(HttpHeaders.authorizationHeader, - authorization(credentials, request as _HttpClientRequest)); - } - - void authorizeProxy( - _ProxyCredentials credentials, HttpClientRequest request) { - request.headers.set(HttpHeaders.proxyAuthorizationHeader, - authorization(credentials, request as _HttpClientRequest)); - } -} - -class _RedirectInfo implements RedirectInfo { - final int statusCode; - final String method; - final Uri location; - const _RedirectInfo(this.statusCode, this.method, this.location); -} - -String _getHttpVersion() { - var version = Platform.version; - // Only include major and minor version numbers. - int index = version.indexOf('.', version.indexOf('.') + 1); - version = version.substring(0, index); - return 'Dart/$version (dart:io)'; -} diff --git a/sdk_nnbd/lib/_http/http_parser.dart b/sdk_nnbd/lib/_http/http_parser.dart deleted file mode 100644 index 94597897490..00000000000 --- a/sdk_nnbd/lib/_http/http_parser.dart +++ /dev/null @@ -1,1160 +0,0 @@ -// Copyright (c) 2013, 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. - -part of dart._http; - -// Global constants. -class _Const { - // Bytes for "HTTP". - static const HTTP = const [72, 84, 84, 80]; - // Bytes for "HTTP/1.". - static const HTTP1DOT = const [72, 84, 84, 80, 47, 49, 46]; - // Bytes for "HTTP/1.0". - static const HTTP10 = const [72, 84, 84, 80, 47, 49, 46, 48]; - // Bytes for "HTTP/1.1". - static const HTTP11 = const [72, 84, 84, 80, 47, 49, 46, 49]; - - static const bool T = true; - static const bool F = false; - // Loopup-map for the following characters: '()<>@,;:\\"/[]?={} \t'. - static const SEPARATOR_MAP = const [ - F, F, F, F, F, F, F, F, F, T, F, F, F, F, F, F, F, F, F, F, F, F, F, F, // - F, F, F, F, F, F, F, F, T, F, T, F, F, F, F, F, T, T, F, F, T, F, F, T, // - F, F, F, F, F, F, F, F, F, F, T, T, T, T, T, T, T, F, F, F, F, F, F, F, // - F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, T, T, T, F, F, // - F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, // - F, F, F, T, F, T, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, // - F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, // - F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, // - F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, // - F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, // - F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F - ]; -} - -// Frequently used character codes. -class _CharCode { - static const int HT = 9; - static const int LF = 10; - static const int CR = 13; - static const int SP = 32; - static const int AMPERSAND = 38; - static const int COMMA = 44; - static const int DASH = 45; - static const int SLASH = 47; - static const int ZERO = 48; - static const int ONE = 49; - static const int COLON = 58; - static const int SEMI_COLON = 59; - static const int EQUAL = 61; -} - -// States of the HTTP parser state machine. -class _State { - static const int START = 0; - static const int METHOD_OR_RESPONSE_HTTP_VERSION = 1; - static const int RESPONSE_HTTP_VERSION = 2; - static const int REQUEST_LINE_METHOD = 3; - static const int REQUEST_LINE_URI = 4; - static const int REQUEST_LINE_HTTP_VERSION = 5; - static const int REQUEST_LINE_ENDING = 6; - static const int RESPONSE_LINE_STATUS_CODE = 7; - static const int RESPONSE_LINE_REASON_PHRASE = 8; - static const int RESPONSE_LINE_ENDING = 9; - static const int HEADER_START = 10; - static const int HEADER_FIELD = 11; - static const int HEADER_VALUE_START = 12; - static const int HEADER_VALUE = 13; - static const int HEADER_VALUE_FOLDING_OR_ENDING = 14; - static const int HEADER_VALUE_FOLD_OR_END = 15; - static const int HEADER_ENDING = 16; - - static const int CHUNK_SIZE_STARTING_CR = 17; - static const int CHUNK_SIZE_STARTING_LF = 18; - static const int CHUNK_SIZE = 19; - static const int CHUNK_SIZE_EXTENSION = 20; - static const int CHUNK_SIZE_ENDING = 21; - static const int CHUNKED_BODY_DONE_CR = 22; - static const int CHUNKED_BODY_DONE_LF = 23; - static const int BODY = 24; - static const int CLOSED = 25; - static const int UPGRADED = 26; - static const int FAILURE = 27; - - static const int FIRST_BODY_STATE = CHUNK_SIZE_STARTING_CR; -} - -// HTTP version of the request or response being parsed. -class _HttpVersion { - static const int UNDETERMINED = 0; - static const int HTTP10 = 1; - static const int HTTP11 = 2; -} - -// States of the HTTP parser state machine. -class _MessageType { - static const int UNDETERMINED = 0; - static const int REQUEST = 1; - static const int RESPONSE = 0; -} - -/** - * The _HttpDetachedStreamSubscription takes a subscription and some extra data, - * and makes it possible to "inject" the data in from of other data events - * from the subscription. - * - * It does so by overriding pause/resume, so that once the - * _HttpDetachedStreamSubscription is resumed, it'll deliver the data before - * resuming the underlaying subscription. - */ -class _HttpDetachedStreamSubscription implements StreamSubscription { - StreamSubscription _subscription; - Uint8List? _injectData; - Function? _userOnData; - bool _isCanceled = false; - bool _scheduled = false; - int _pauseCount = 1; - - _HttpDetachedStreamSubscription( - this._subscription, this._injectData, this._userOnData); - - bool get isPaused => _subscription.isPaused; - - Future asFuture([T? futureValue]) => - _subscription.asFuture(futureValue as T); - - Future cancel() { - _isCanceled = true; - _injectData = null; - return _subscription.cancel(); - } - - void onData(void handleData(Uint8List data)?) { - _userOnData = handleData; - _subscription.onData(handleData); - } - - void onDone(void handleDone()?) { - _subscription.onDone(handleDone); - } - - void onError(Function? handleError) { - _subscription.onError(handleError); - } - - void pause([Future? resumeSignal]) { - if (_injectData == null) { - _subscription.pause(resumeSignal); - } else { - _pauseCount++; - if (resumeSignal != null) { - resumeSignal.whenComplete(resume); - } - } - } - - void resume() { - if (_injectData == null) { - _subscription.resume(); - } else { - _pauseCount--; - _maybeScheduleData(); - } - } - - void _maybeScheduleData() { - if (_scheduled) return; - if (_pauseCount != 0) return; - _scheduled = true; - scheduleMicrotask(() { - _scheduled = false; - if (_pauseCount > 0 || _isCanceled) return; - var data = _injectData; - _injectData = null; - // To ensure that 'subscription.isPaused' is false, we resume the - // subscription here. This is fine as potential events are delayed. - _subscription.resume(); - _userOnData?.call(data); - }); - } -} - -class _HttpDetachedIncoming extends Stream { - final StreamSubscription? subscription; - final Uint8List? bufferedData; - - _HttpDetachedIncoming(this.subscription, this.bufferedData); - - StreamSubscription listen(void onData(Uint8List event)?, - {Function? onError, void onDone()?, bool? cancelOnError}) { - var subscription = this.subscription; - if (subscription != null) { - subscription - ..onData(onData) - ..onError(onError) - ..onDone(onDone); - if (bufferedData == null) { - return subscription..resume(); - } - return new _HttpDetachedStreamSubscription( - subscription, bufferedData, onData) - ..resume(); - } else { - // TODO(26379): add test for this branch. - return new Stream.fromIterable([bufferedData!]).listen(onData, - onError: onError, onDone: onDone, cancelOnError: cancelOnError); - } - } -} - -/** - * HTTP parser which parses the data stream given to [consume]. - * - * If an HTTP parser error occurs, the parser will signal an error to either - * the current _HttpIncoming or the _parser itself. - * - * The connection upgrades (e.g. switching from HTTP/1.1 to the - * WebSocket protocol) is handled in a special way. If connection - * upgrade is specified in the headers, then on the callback to - * [:responseStart:] the [:upgrade:] property on the [:HttpParser:] - * object will be [:true:] indicating that from now on the protocol is - * not HTTP anymore and no more callbacks will happen, that is - * [:dataReceived:] and [:dataEnd:] are not called in this case as - * there is no more HTTP data. After the upgrade the method - * [:readUnparsedData:] can be used to read any remaining bytes in the - * HTTP parser which are part of the protocol the connection is - * upgrading to. These bytes cannot be processed by the HTTP parser - * and should be handled according to whatever protocol is being - * upgraded to. - */ -class _HttpParser extends Stream<_HttpIncoming> { - // State. - bool _parserCalled = false; - - // The data that is currently being parsed. - Uint8List? _buffer; - int _index = -1; - - final bool _requestParser; - int _state = _State.START; - int? _httpVersionIndex; - int _messageType = _MessageType.UNDETERMINED; - int _statusCode = 0; - int _statusCodeLength = 0; - final List _method = []; - final List _uriOrReasonPhrase = []; - final List _headerField = []; - final List _headerValue = []; - // The limit for method, uriOrReasonPhrase, header field and value - int _headerSizeLimit = 8 * 1024; - - int _httpVersion = _HttpVersion.UNDETERMINED; - int _transferLength = -1; - bool _persistentConnection = false; - bool _connectionUpgrade = false; - bool _chunked = false; - - bool _noMessageBody = false; - int _remainingContent = -1; - bool _contentLength = false; - bool _transferEncoding = false; - bool connectMethod = false; - - _HttpHeaders? _headers; - - // The limit for parsing chunk size - int _chunkSizeLimit = 0x7FFFFFFF; - - // The current incoming connection. - _HttpIncoming? _incoming; - StreamSubscription? _socketSubscription; - bool _paused = true; - bool _bodyPaused = false; - final StreamController<_HttpIncoming> _controller; - StreamController? _bodyController; - - factory _HttpParser.requestParser() { - return new _HttpParser._(true); - } - - factory _HttpParser.responseParser() { - return new _HttpParser._(false); - } - - _HttpParser._(this._requestParser) - : _controller = new StreamController<_HttpIncoming>(sync: true) { - _controller - ..onListen = () { - _paused = false; - } - ..onPause = () { - _paused = true; - _pauseStateChanged(); - } - ..onResume = () { - _paused = false; - _pauseStateChanged(); - } - ..onCancel = () { - _socketSubscription?.cancel(); - }; - _reset(); - } - - StreamSubscription<_HttpIncoming> listen(void onData(_HttpIncoming event)?, - {Function? onError, void onDone()?, bool? cancelOnError}) { - return _controller.stream.listen(onData, - onError: onError, onDone: onDone, cancelOnError: cancelOnError); - } - - void listenToStream(Stream stream) { - // Listen to the stream and handle data accordingly. When a - // _HttpIncoming is created, _dataPause, _dataResume, _dataDone is - // given to provide a way of controlling the parser. - // TODO(ajohnsen): Remove _dataPause, _dataResume and _dataDone and clean up - // how the _HttpIncoming signals the parser. - _socketSubscription = - stream.listen(_onData, onError: _controller.addError, onDone: _onDone); - } - - void _parse() { - try { - _doParse(); - } catch (e, s) { - if (_state >= _State.CHUNK_SIZE_STARTING_CR && _state <= _State.BODY) { - _state = _State.FAILURE; - _reportBodyError(e, s); - } else { - _state = _State.FAILURE; - _reportHttpError(e, s); - } - } - } - - // Process end of headers. Returns true if the parser should stop - // parsing and return. This will be in case of either an upgrade - // request or a request or response with an empty body. - bool _headersEnd() { - var headers = _headers!; - // If method is CONNECT, response parser should ignore any Content-Length or - // Transfer-Encoding header fields in a successful response. - // [RFC 7231](https://tools.ietf.org/html/rfc7231#section-4.3.6) - if (!_requestParser && - _statusCode >= 200 && - _statusCode < 300 && - connectMethod) { - _transferLength = -1; - headers.chunkedTransferEncoding = false; - _chunked = false; - headers.removeAll(HttpHeaders.contentLengthHeader); - headers.removeAll(HttpHeaders.transferEncodingHeader); - } - headers._mutable = false; - - _transferLength = headers.contentLength; - // Ignore the Content-Length header if Transfer-Encoding - // is chunked (RFC 2616 section 4.4) - if (_chunked) _transferLength = -1; - - // If a request message has neither Content-Length nor - // Transfer-Encoding the message must not have a body (RFC - // 2616 section 4.3). - if (_messageType == _MessageType.REQUEST && - _transferLength < 0 && - _chunked == false) { - _transferLength = 0; - } - if (_connectionUpgrade) { - _state = _State.UPGRADED; - _transferLength = 0; - } - var incoming = _createIncoming(_transferLength); - if (_requestParser) { - incoming.method = new String.fromCharCodes(_method); - incoming.uri = Uri.parse(new String.fromCharCodes(_uriOrReasonPhrase)); - } else { - incoming.statusCode = _statusCode; - incoming.reasonPhrase = new String.fromCharCodes(_uriOrReasonPhrase); - } - _method.clear(); - _uriOrReasonPhrase.clear(); - if (_connectionUpgrade) { - incoming.upgraded = true; - _parserCalled = false; - _closeIncoming(); - _controller.add(incoming); - return true; - } - if (_transferLength == 0 || - (_messageType == _MessageType.RESPONSE && _noMessageBody)) { - _reset(); - _closeIncoming(); - _controller.add(incoming); - return false; - } else if (_chunked) { - _state = _State.CHUNK_SIZE; - _remainingContent = 0; - } else if (_transferLength > 0) { - _remainingContent = _transferLength; - _state = _State.BODY; - } else { - // Neither chunked nor content length. End of body - // indicated by close. - _state = _State.BODY; - } - _parserCalled = false; - _controller.add(incoming); - return true; - } - - // From RFC 2616. - // generic-message = start-line - // *(message-header CRLF) - // CRLF - // [ message-body ] - // start-line = Request-Line | Status-Line - // Request-Line = Method SP Request-URI SP HTTP-Version CRLF - // Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF - // message-header = field-name ":" [ field-value ] - void _doParse() { - assert(!_parserCalled); - _parserCalled = true; - if (_state == _State.CLOSED) { - throw HttpException("Data on closed connection"); - } - if (_state == _State.FAILURE) { - throw HttpException("Data on failed connection"); - } - while (_buffer != null && - _index < _buffer!.length && - _state != _State.FAILURE && - _state != _State.UPGRADED) { - // Depending on _incoming, we either break on _bodyPaused or _paused. - if ((_incoming != null && _bodyPaused) || - (_incoming == null && _paused)) { - _parserCalled = false; - return; - } - int index = _index; - int byte = _buffer![index]; - _index = index + 1; - switch (_state) { - case _State.START: - if (byte == _Const.HTTP[0]) { - // Start parsing method or HTTP version. - _httpVersionIndex = 1; - _state = _State.METHOD_OR_RESPONSE_HTTP_VERSION; - } else { - // Start parsing method. - if (!_isTokenChar(byte)) { - throw HttpException("Invalid request method"); - } - _addWithValidation(_method, byte); - if (!_requestParser) { - throw HttpException("Invalid response line"); - } - _state = _State.REQUEST_LINE_METHOD; - } - break; - - case _State.METHOD_OR_RESPONSE_HTTP_VERSION: - var httpVersionIndex = _httpVersionIndex!; - if (httpVersionIndex < _Const.HTTP.length && - byte == _Const.HTTP[httpVersionIndex]) { - // Continue parsing HTTP version. - _httpVersionIndex = httpVersionIndex + 1; - } else if (httpVersionIndex == _Const.HTTP.length && - byte == _CharCode.SLASH) { - // HTTP/ parsed. As method is a token this cannot be a - // method anymore. - _httpVersionIndex = httpVersionIndex + 1; - if (_requestParser) { - throw HttpException("Invalid request line"); - } - _state = _State.RESPONSE_HTTP_VERSION; - } else { - // Did not parse HTTP version. Expect method instead. - for (int i = 0; i < httpVersionIndex; i++) { - _addWithValidation(_method, _Const.HTTP[i]); - } - if (byte == _CharCode.SP) { - _state = _State.REQUEST_LINE_URI; - } else { - _addWithValidation(_method, byte); - _httpVersion = _HttpVersion.UNDETERMINED; - if (!_requestParser) { - throw HttpException("Invalid response line"); - } - _state = _State.REQUEST_LINE_METHOD; - } - } - break; - - case _State.RESPONSE_HTTP_VERSION: - var httpVersionIndex = _httpVersionIndex!; - if (httpVersionIndex < _Const.HTTP1DOT.length) { - // Continue parsing HTTP version. - _expect(byte, _Const.HTTP1DOT[httpVersionIndex]); - _httpVersionIndex = httpVersionIndex + 1; - } else if (httpVersionIndex == _Const.HTTP1DOT.length && - byte == _CharCode.ONE) { - // HTTP/1.1 parsed. - _httpVersion = _HttpVersion.HTTP11; - _persistentConnection = true; - _httpVersionIndex = httpVersionIndex + 1; - } else if (httpVersionIndex == _Const.HTTP1DOT.length && - byte == _CharCode.ZERO) { - // HTTP/1.0 parsed. - _httpVersion = _HttpVersion.HTTP10; - _persistentConnection = false; - _httpVersionIndex = httpVersionIndex + 1; - } else if (httpVersionIndex == _Const.HTTP1DOT.length + 1) { - _expect(byte, _CharCode.SP); - // HTTP version parsed. - _state = _State.RESPONSE_LINE_STATUS_CODE; - } else { - throw HttpException( - "Invalid response line, failed to parse HTTP version"); - } - break; - - case _State.REQUEST_LINE_METHOD: - if (byte == _CharCode.SP) { - _state = _State.REQUEST_LINE_URI; - } else { - if (_Const.SEPARATOR_MAP[byte] || - byte == _CharCode.CR || - byte == _CharCode.LF) { - throw HttpException("Invalid request method"); - } - _addWithValidation(_method, byte); - } - break; - - case _State.REQUEST_LINE_URI: - if (byte == _CharCode.SP) { - if (_uriOrReasonPhrase.length == 0) { - throw HttpException("Invalid request, empty URI"); - } - _state = _State.REQUEST_LINE_HTTP_VERSION; - _httpVersionIndex = 0; - } else { - if (byte == _CharCode.CR || byte == _CharCode.LF) { - throw HttpException("Invalid request, unexpected $byte in URI"); - } - _addWithValidation(_uriOrReasonPhrase, byte); - } - break; - - case _State.REQUEST_LINE_HTTP_VERSION: - var httpVersionIndex = _httpVersionIndex!; - if (httpVersionIndex < _Const.HTTP1DOT.length) { - _expect(byte, _Const.HTTP11[httpVersionIndex]); - _httpVersionIndex = httpVersionIndex + 1; - } else if (_httpVersionIndex == _Const.HTTP1DOT.length) { - if (byte == _CharCode.ONE) { - // HTTP/1.1 parsed. - _httpVersion = _HttpVersion.HTTP11; - _persistentConnection = true; - _httpVersionIndex = httpVersionIndex + 1; - } else if (byte == _CharCode.ZERO) { - // HTTP/1.0 parsed. - _httpVersion = _HttpVersion.HTTP10; - _persistentConnection = false; - _httpVersionIndex = httpVersionIndex + 1; - } else { - throw HttpException("Invalid response, invalid HTTP version"); - } - } else { - if (byte == _CharCode.CR) { - _state = _State.REQUEST_LINE_ENDING; - } else { - _expect(byte, _CharCode.LF); - _messageType = _MessageType.REQUEST; - _state = _State.HEADER_START; - } - } - break; - - case _State.REQUEST_LINE_ENDING: - _expect(byte, _CharCode.LF); - _messageType = _MessageType.REQUEST; - _state = _State.HEADER_START; - break; - - case _State.RESPONSE_LINE_STATUS_CODE: - if (byte == _CharCode.SP) { - _state = _State.RESPONSE_LINE_REASON_PHRASE; - } else if (byte == _CharCode.CR) { - // Some HTTP servers does not follow the spec. and send - // \r\n right after the status code. - _state = _State.RESPONSE_LINE_ENDING; - } else { - _statusCodeLength++; - if (byte < 0x30 || byte > 0x39) { - throw HttpException("Invalid response status code with $byte"); - } else if (_statusCodeLength > 3) { - throw HttpException( - "Invalid response, status code is over 3 digits"); - } else { - _statusCode = _statusCode * 10 + byte - 0x30; - } - } - break; - - case _State.RESPONSE_LINE_REASON_PHRASE: - if (byte == _CharCode.CR) { - _state = _State.RESPONSE_LINE_ENDING; - } else { - if (byte == _CharCode.CR || byte == _CharCode.LF) { - throw HttpException( - "Invalid response, unexpected $byte in reason phrase"); - } - _addWithValidation(_uriOrReasonPhrase, byte); - } - break; - - case _State.RESPONSE_LINE_ENDING: - _expect(byte, _CharCode.LF); - _messageType == _MessageType.RESPONSE; - // Check whether this response will never have a body. - if (_statusCode <= 199 || _statusCode == 204 || _statusCode == 304) { - _noMessageBody = true; - } - _state = _State.HEADER_START; - break; - - case _State.HEADER_START: - _headers = new _HttpHeaders(version!); - if (byte == _CharCode.CR) { - _state = _State.HEADER_ENDING; - } else if (byte == _CharCode.LF) { - _state = _State.HEADER_ENDING; - _index = _index - 1; // Make the new state see the LF again. - } else { - // Start of new header field. - _addWithValidation(_headerField, _toLowerCaseByte(byte)); - _state = _State.HEADER_FIELD; - } - break; - - case _State.HEADER_FIELD: - if (byte == _CharCode.COLON) { - _state = _State.HEADER_VALUE_START; - } else { - if (!_isTokenChar(byte)) { - throw HttpException("Invalid header field name, with $byte"); - } - _addWithValidation(_headerField, _toLowerCaseByte(byte)); - } - break; - - case _State.HEADER_VALUE_START: - if (byte == _CharCode.CR) { - _state = _State.HEADER_VALUE_FOLDING_OR_ENDING; - } else if (byte == _CharCode.LF) { - _state = _State.HEADER_VALUE_FOLD_OR_END; - } else if (byte != _CharCode.SP && byte != _CharCode.HT) { - // Start of new header value. - _addWithValidation(_headerValue, byte); - _state = _State.HEADER_VALUE; - } - break; - - case _State.HEADER_VALUE: - if (byte == _CharCode.CR) { - _state = _State.HEADER_VALUE_FOLDING_OR_ENDING; - } else if (byte == _CharCode.LF) { - _state = _State.HEADER_VALUE_FOLD_OR_END; - } else { - _addWithValidation(_headerValue, byte); - } - break; - - case _State.HEADER_VALUE_FOLDING_OR_ENDING: - _expect(byte, _CharCode.LF); - _state = _State.HEADER_VALUE_FOLD_OR_END; - break; - - case _State.HEADER_VALUE_FOLD_OR_END: - if (byte == _CharCode.SP || byte == _CharCode.HT) { - _state = _State.HEADER_VALUE_START; - } else { - String headerField = new String.fromCharCodes(_headerField); - String headerValue = new String.fromCharCodes(_headerValue); - if (headerField == HttpHeaders.contentLengthHeader) { - // Content Length header should not have more than one occurance - // or coexist with Transfer Encoding header. - if (_contentLength || _transferEncoding) { - _statusCode = HttpStatus.badRequest; - } - _contentLength = true; - } else if (headerField == HttpHeaders.transferEncodingHeader) { - _transferEncoding = true; - if (_caseInsensitiveCompare("chunked".codeUnits, _headerValue)) { - _chunked = true; - } - if (_contentLength) { - _statusCode = HttpStatus.badRequest; - } - } - var headers = _headers!; - if (headerField == HttpHeaders.connectionHeader) { - List tokens = _tokenizeFieldValue(headerValue); - final bool isResponse = _messageType == _MessageType.RESPONSE; - final bool isUpgradeCode = - (_statusCode == HttpStatus.upgradeRequired) || - (_statusCode == HttpStatus.switchingProtocols); - for (int i = 0; i < tokens.length; i++) { - final bool isUpgrade = _caseInsensitiveCompare( - "upgrade".codeUnits, tokens[i].codeUnits); - if ((isUpgrade && !isResponse) || - (isUpgrade && isResponse && isUpgradeCode)) { - _connectionUpgrade = true; - } - headers._add(headerField, tokens[i]); - } - } else { - headers._add(headerField, headerValue); - } - _headerField.clear(); - _headerValue.clear(); - - if (byte == _CharCode.CR) { - _state = _State.HEADER_ENDING; - } else if (byte == _CharCode.LF) { - _state = _State.HEADER_ENDING; - _index = _index - 1; // Make the new state see the LF again. - } else { - // Start of new header field. - _state = _State.HEADER_FIELD; - _addWithValidation(_headerField, _toLowerCaseByte(byte)); - } - } - break; - - case _State.HEADER_ENDING: - _expect(byte, _CharCode.LF); - if (_headersEnd()) { - return; - } - break; - - case _State.CHUNK_SIZE_STARTING_CR: - _expect(byte, _CharCode.CR); - _state = _State.CHUNK_SIZE_STARTING_LF; - break; - - case _State.CHUNK_SIZE_STARTING_LF: - _expect(byte, _CharCode.LF); - _state = _State.CHUNK_SIZE; - break; - - case _State.CHUNK_SIZE: - if (byte == _CharCode.CR) { - _state = _State.CHUNK_SIZE_ENDING; - } else if (byte == _CharCode.SEMI_COLON) { - _state = _State.CHUNK_SIZE_EXTENSION; - } else { - int value = _expectHexDigit(byte); - // Checks whether (_remaingingContent * 16 + value) overflows. - if (_remainingContent > _chunkSizeLimit >> 4) { - throw HttpException('Chunk size overflows the integer'); - } - _remainingContent = _remainingContent * 16 + value; - } - break; - - case _State.CHUNK_SIZE_EXTENSION: - if (byte == _CharCode.CR) { - _state = _State.CHUNK_SIZE_ENDING; - } - break; - - case _State.CHUNK_SIZE_ENDING: - _expect(byte, _CharCode.LF); - if (_remainingContent > 0) { - _state = _State.BODY; - } else { - _state = _State.CHUNKED_BODY_DONE_CR; - } - break; - - case _State.CHUNKED_BODY_DONE_CR: - _expect(byte, _CharCode.CR); - _state = _State.CHUNKED_BODY_DONE_LF; - break; - - case _State.CHUNKED_BODY_DONE_LF: - _expect(byte, _CharCode.LF); - _reset(); - _closeIncoming(); - break; - - case _State.BODY: - // The body is not handled one byte at a time but in blocks. - _index = _index - 1; - var buffer = _buffer!; - int dataAvailable = buffer.length - _index; - if (_remainingContent >= 0 && dataAvailable > _remainingContent) { - dataAvailable = _remainingContent; - } - // Always present the data as a view. This way we can handle all - // cases like this, and the user will not experience different data - // typed (which could lead to polymorphic user code). - Uint8List data = new Uint8List.view( - buffer.buffer, buffer.offsetInBytes + _index, dataAvailable); - _bodyController!.add(data); - if (_remainingContent != -1) { - _remainingContent -= data.length; - } - _index = _index + data.length; - if (_remainingContent == 0) { - if (!_chunked) { - _reset(); - _closeIncoming(); - } else { - _state = _State.CHUNK_SIZE_STARTING_CR; - } - } - break; - - case _State.FAILURE: - // Should be unreachable. - assert(false); - break; - - default: - // Should be unreachable. - assert(false); - break; - } - } - - _parserCalled = false; - var buffer = _buffer; - if (buffer != null && _index == buffer.length) { - // If all data is parsed release the buffer and resume receiving - // data. - _releaseBuffer(); - if (_state != _State.UPGRADED && _state != _State.FAILURE) { - _socketSubscription!.resume(); - } - } - } - - void _onData(Uint8List buffer) { - _socketSubscription!.pause(); - assert(_buffer == null); - _buffer = buffer; - _index = 0; - _parse(); - } - - void _onDone() { - // onDone cancels the subscription. - _socketSubscription = null; - if (_state == _State.CLOSED || _state == _State.FAILURE) return; - - if (_incoming != null) { - if (_state != _State.UPGRADED && - !(_state == _State.START && !_requestParser) && - !(_state == _State.BODY && !_chunked && _transferLength == -1)) { - _reportBodyError( - HttpException("Connection closed while receiving data")); - } - _closeIncoming(true); - _controller.close(); - return; - } - // If the connection is idle the HTTP stream is closed. - if (_state == _State.START) { - if (!_requestParser) { - _reportHttpError( - HttpException("Connection closed before full header was received")); - } - _controller.close(); - return; - } - - if (_state == _State.UPGRADED) { - _controller.close(); - return; - } - - if (_state < _State.FIRST_BODY_STATE) { - _state = _State.FAILURE; - // Report the error through the error callback if any. Otherwise - // throw the error. - _reportHttpError( - HttpException("Connection closed before full header was received")); - _controller.close(); - return; - } - - if (!_chunked && _transferLength == -1) { - _state = _State.CLOSED; - } else { - _state = _State.FAILURE; - // Report the error through the error callback if any. Otherwise - // throw the error. - _reportHttpError( - HttpException("Connection closed before full body was received")); - } - _controller.close(); - } - - String? get version { - switch (_httpVersion) { - case _HttpVersion.HTTP10: - return "1.0"; - case _HttpVersion.HTTP11: - return "1.1"; - } - return null; - } - - int get messageType => _messageType; - int get transferLength => _transferLength; - bool get upgrade => _connectionUpgrade && _state == _State.UPGRADED; - bool get persistentConnection => _persistentConnection; - - void set isHead(bool value) { - _noMessageBody = valueOfNonNullableParamWithDefault(value, false); - } - - _HttpDetachedIncoming detachIncoming() { - // Simulate detached by marking as upgraded. - _state = _State.UPGRADED; - return new _HttpDetachedIncoming(_socketSubscription, readUnparsedData()); - } - - Uint8List? readUnparsedData() { - var buffer = _buffer; - if (buffer == null) return null; - var index = _index; - if (index == buffer.length) return null; - var result = buffer.sublist(index); - _releaseBuffer(); - return result; - } - - void _reset() { - if (_state == _State.UPGRADED) return; - _state = _State.START; - _messageType = _MessageType.UNDETERMINED; - _headerField.clear(); - _headerValue.clear(); - _method.clear(); - _uriOrReasonPhrase.clear(); - - _statusCode = 0; - _statusCodeLength = 0; - - _httpVersion = _HttpVersion.UNDETERMINED; - _transferLength = -1; - _persistentConnection = false; - _connectionUpgrade = false; - _chunked = false; - - _noMessageBody = false; - _remainingContent = -1; - - _contentLength = false; - _transferEncoding = false; - - _headers = null; - } - - void _releaseBuffer() { - _buffer = null; - _index = -1; - } - - static bool _isTokenChar(int byte) { - return byte > 31 && byte < 128 && !_Const.SEPARATOR_MAP[byte]; - } - - static bool _isValueChar(int byte) { - return (byte > 31 && byte < 128) || - (byte == _CharCode.SP) || - (byte == _CharCode.HT); - } - - static List _tokenizeFieldValue(String headerValue) { - List tokens = []; - int start = 0; - int index = 0; - while (index < headerValue.length) { - if (headerValue[index] == ",") { - tokens.add(headerValue.substring(start, index)); - start = index + 1; - } else if (headerValue[index] == " " || headerValue[index] == "\t") { - start++; - } - index++; - } - tokens.add(headerValue.substring(start, index)); - return tokens; - } - - static int _toLowerCaseByte(int x) { - // Optimized version: - // - 0x41 is 'A' - // - 0x7f is ASCII mask - // - 26 is the number of alpha characters. - // - 0x20 is the delta between lower and upper chars. - return (((x - 0x41) & 0x7f) < 26) ? (x | 0x20) : x; - } - - // expected should already be lowercase. - static bool _caseInsensitiveCompare(List expected, List value) { - if (expected.length != value.length) return false; - for (int i = 0; i < expected.length; i++) { - if (expected[i] != _toLowerCaseByte(value[i])) return false; - } - return true; - } - - void _expect(int val1, int val2) { - if (val1 != val2) { - throw HttpException("Failed to parse HTTP, $val1 does not match $val2"); - } - } - - int _expectHexDigit(int byte) { - if (0x30 <= byte && byte <= 0x39) { - return byte - 0x30; // 0 - 9 - } else if (0x41 <= byte && byte <= 0x46) { - return byte - 0x41 + 10; // A - F - } else if (0x61 <= byte && byte <= 0x66) { - return byte - 0x61 + 10; // a - f - } else { - throw HttpException( - "Failed to parse HTTP, $byte is expected to be a Hex digit"); - } - } - - void _addWithValidation(List list, int byte) { - if (list.length < _headerSizeLimit) { - list.add(byte); - } else { - _reportSizeLimitError(); - } - } - - void _reportSizeLimitError() { - String method = ""; - switch (_state) { - case _State.START: - case _State.METHOD_OR_RESPONSE_HTTP_VERSION: - case _State.REQUEST_LINE_METHOD: - method = "Method"; - break; - - case _State.REQUEST_LINE_URI: - method = "URI"; - break; - - case _State.RESPONSE_LINE_REASON_PHRASE: - method = "Reason phrase"; - break; - - case _State.HEADER_START: - case _State.HEADER_FIELD: - method = "Header field"; - break; - - case _State.HEADER_VALUE_START: - case _State.HEADER_VALUE: - method = "Header value"; - break; - - default: - throw UnsupportedError("Unexpected state: $_state"); - break; - } - throw HttpException("$method exceeds the $_headerSizeLimit size limit"); - } - - _HttpIncoming _createIncoming(int transferLength) { - assert(_incoming == null); - assert(_bodyController == null); - assert(!_bodyPaused); - var controller = - _bodyController = new StreamController(sync: true); - var incoming = _incoming = - new _HttpIncoming(_headers!, transferLength, controller.stream); - controller - ..onListen = () { - if (incoming != _incoming) return; - assert(_bodyPaused); - _bodyPaused = false; - _pauseStateChanged(); - } - ..onPause = () { - if (incoming != _incoming) return; - assert(!_bodyPaused); - _bodyPaused = true; - _pauseStateChanged(); - } - ..onResume = () { - if (incoming != _incoming) return; - assert(_bodyPaused); - _bodyPaused = false; - _pauseStateChanged(); - } - ..onCancel = () { - if (incoming != _incoming) return; - _socketSubscription?.cancel(); - _closeIncoming(true); - _controller.close(); - }; - _bodyPaused = true; - _pauseStateChanged(); - return incoming; - } - - void _closeIncoming([bool closing = false]) { - // Ignore multiple close (can happen in re-entrance). - var tmp = _incoming; - if (tmp == null) return; - tmp.close(closing); - _incoming = null; - var controller = _bodyController; - if (controller != null) { - controller.close(); - _bodyController = null; - } - _bodyPaused = false; - _pauseStateChanged(); - } - - void _pauseStateChanged() { - if (_incoming != null) { - if (!_bodyPaused && !_parserCalled) { - _parse(); - } - } else { - if (!_paused && !_parserCalled) { - _parse(); - } - } - } - - void _reportHttpError(error, [stackTrace]) { - _socketSubscription?.cancel(); - _state = _State.FAILURE; - _controller.addError(error, stackTrace); - _controller.close(); - } - - void _reportBodyError(error, [stackTrace]) { - _socketSubscription?.cancel(); - _state = _State.FAILURE; - _bodyController?.addError(error, stackTrace); - // In case of drain(), error event will close the stream. - _bodyController?.close(); - } -} diff --git a/sdk_nnbd/lib/_http/http_session.dart b/sdk_nnbd/lib/_http/http_session.dart deleted file mode 100644 index 407192a8620..00000000000 --- a/sdk_nnbd/lib/_http/http_session.dart +++ /dev/null @@ -1,203 +0,0 @@ -// Copyright (c) 2013, 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. - -part of dart._http; - -const String _DART_SESSION_ID = "DARTSESSID"; - -// A _HttpSession is a node in a double-linked list, with _next and _prev being -// the previous and next pointers. -class _HttpSession implements HttpSession { - // Destroyed marked. Used by the http connection to see if a session is valid. - bool _destroyed = false; - bool _isNew = true; - DateTime _lastSeen; - Function? _timeoutCallback; - _HttpSessionManager _sessionManager; - // Pointers in timeout queue. - _HttpSession? _prev; - _HttpSession? _next; - final String id; - - final Map _data = new HashMap(); - - _HttpSession(this._sessionManager, this.id) : _lastSeen = new DateTime.now(); - - void destroy() { - assert(!_destroyed); - _destroyed = true; - _sessionManager._removeFromTimeoutQueue(this); - _sessionManager._sessions.remove(id); - } - - // Mark the session as seen. This will reset the timeout and move the node to - // the end of the timeout queue. - void _markSeen() { - _lastSeen = new DateTime.now(); - _sessionManager._bumpToEnd(this); - } - - DateTime get lastSeen => _lastSeen; - - bool get isNew => _isNew; - - void set onTimeout(void callback()?) { - _timeoutCallback = callback; - } - - // Map implementation: - bool containsValue(value) => _data.containsValue(value); - bool containsKey(key) => _data.containsKey(key); - operator [](key) => _data[key]; - void operator []=(key, value) { - _data[key] = value; - } - - putIfAbsent(key, ifAbsent) => _data.putIfAbsent(key, ifAbsent); - addAll(Map other) => _data.addAll(other); - remove(key) => _data.remove(key); - void clear() { - _data.clear(); - } - - void forEach(void f(key, value)) { - _data.forEach(f); - } - - Iterable get entries => _data.entries; - - void addEntries(Iterable entries) { - _data.addEntries(entries); - } - - Map map(MapEntry transform(key, value)) => - _data.map(transform); - - void removeWhere(bool test(key, value)) { - _data.removeWhere(test); - } - - Map cast() => _data.cast(); - update(key, update(value), {ifAbsent()?}) => - _data.update(key, update, ifAbsent: ifAbsent); - - void updateAll(update(key, value)) { - _data.updateAll(update); - } - - Iterable get keys => _data.keys; - Iterable get values => _data.values; - int get length => _data.length; - bool get isEmpty => _data.isEmpty; - bool get isNotEmpty => _data.isNotEmpty; - - String toString() => 'HttpSession id:$id $_data'; -} - -// Private class used to manage all the active sessions. The sessions are stored -// in two ways: -// -// * In a map, mapping from ID to HttpSession. -// * In a linked list, used as a timeout queue. -class _HttpSessionManager { - Map _sessions; - int _sessionTimeout = 20 * 60; // 20 mins. - _HttpSession? _head; - _HttpSession? _tail; - Timer? _timer; - - _HttpSessionManager() : _sessions = {}; - - String createSessionId() { - const int _KEY_LENGTH = 16; // 128 bits. - var data = _CryptoUtils.getRandomBytes(_KEY_LENGTH); - return _CryptoUtils.bytesToHex(data); - } - - _HttpSession? getSession(String id) => _sessions[id]; - - _HttpSession createSession() { - var id = createSessionId(); - // TODO(ajohnsen): Consider adding a limit and throwing an exception. - // Should be very unlikely however. - while (_sessions.containsKey(id)) { - id = createSessionId(); - } - var session = _sessions[id] = new _HttpSession(this, id); - _addToTimeoutQueue(session); - return session; - } - - void set sessionTimeout(int timeout) { - _sessionTimeout = timeout; - _stopTimer(); - _startTimer(); - } - - void close() { - _stopTimer(); - } - - void _bumpToEnd(_HttpSession session) { - _removeFromTimeoutQueue(session); - _addToTimeoutQueue(session); - } - - void _addToTimeoutQueue(_HttpSession session) { - if (_head == null) { - assert(_tail == null); - _tail = _head = session; - _startTimer(); - } else { - assert(_timer != null); - var tail = _tail!; - // Add to end. - tail._next = session; - session._prev = tail; - _tail = session; - } - } - - void _removeFromTimeoutQueue(_HttpSession session) { - var next = session._next; - var prev = session._prev; - session._next = session._prev = null; - next?._prev = prev; - prev?._next = next; - if (_tail == session) { - _tail = prev; - } - if (_head == session) { - _head = next; - // We removed the head element, start new timer. - _stopTimer(); - _startTimer(); - } - } - - void _timerTimeout() { - _stopTimer(); // Clear timer. - var session = _head!; - session.destroy(); // Will remove the session from timeout queue and map. - session._timeoutCallback?.call(); - } - - void _startTimer() { - assert(_timer == null); - var head = _head; - if (head != null) { - int seconds = new DateTime.now().difference(head.lastSeen).inSeconds; - _timer = new Timer( - new Duration(seconds: _sessionTimeout - seconds), _timerTimeout); - } - } - - void _stopTimer() { - var timer = _timer; - if (timer != null) { - timer.cancel(); - _timer = null; - } - } -} diff --git a/sdk_nnbd/lib/_http/http_sources.gni b/sdk_nnbd/lib/_http/http_sources.gni deleted file mode 100644 index 1ce36b444f2..00000000000 --- a/sdk_nnbd/lib/_http/http_sources.gni +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright (c) 2017, 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. - -http_sdk_sources = [ - "http.dart", - - # The above file needs to be first if additional parts are added to the lib. - "crypto.dart", - "http_date.dart", - "http_headers.dart", - "http_impl.dart", - "http_parser.dart", - "http_session.dart", - "overrides.dart", - "websocket.dart", - "websocket_impl.dart", -] diff --git a/sdk_nnbd/lib/_http/overrides.dart b/sdk_nnbd/lib/_http/overrides.dart deleted file mode 100644 index bbd21eef792..00000000000 --- a/sdk_nnbd/lib/_http/overrides.dart +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (c) 2017, 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. - -part of dart._http; - -final _httpOverridesToken = new Object(); - -const _asyncRunZoned = runZoned; - -/// This class facilitates overriding [HttpClient] with a mock implementation. -/// It should be extended by another class in client code with overrides -/// that construct a mock implementation. The implementation in this base class -/// defaults to the actual [HttpClient] implementation. For example: -/// -/// ``` -/// class MyHttpClient implements HttpClient { -/// ... -/// // An implementation of the HttpClient interface -/// ... -/// } -/// -/// main() { -/// HttpOverrides.runZoned(() { -/// ... -/// // Operations will use MyHttpClient instead of the real HttpClient -/// // implementation whenever HttpClient is used. -/// ... -/// }, createHttpClient: (SecurityContext c) => new MyHttpClient(c)); -/// } -/// ``` -abstract class HttpOverrides { - static HttpOverrides? _global; - - static HttpOverrides? get current { - return Zone.current[_httpOverridesToken] ?? _global; - } - - /// The [HttpOverrides] to use in the root [Zone]. - /// - /// These are the [HttpOverrides] that will be used in the root Zone, and in - /// Zone's that do not set [HttpOverrides] and whose ancestors up to the root - /// Zone do not set [HttpOverrides]. - static set global(HttpOverrides? overrides) { - _global = overrides; - } - - /// Runs [body] in a fresh [Zone] using the provided overrides. - static R runZoned(R body(), - {HttpClient Function(SecurityContext?)? createHttpClient, - String Function(Uri uri, Map? environment)? - findProxyFromEnvironment}) { - HttpOverrides overrides = - new _HttpOverridesScope(createHttpClient, findProxyFromEnvironment); - return _asyncRunZoned(body, - zoneValues: {_httpOverridesToken: overrides}); - } - - /// Runs [body] in a fresh [Zone] using the overrides found in [overrides]. - /// - /// Note that [overrides] should be an instance of a class that extends - /// [HttpOverrides]. - static R runWithHttpOverrides(R body(), HttpOverrides overrides) { - return _asyncRunZoned(body, - zoneValues: {_httpOverridesToken: overrides}); - } - - /// Returns a new [HttpClient] using the given [context]. - /// - /// When this override is installed, this function overrides the behavior of - /// `new HttpClient`. - HttpClient createHttpClient(SecurityContext? context) { - return new _HttpClient(context); - } - - /// Resolves the proxy server to be used for HTTP connections. - /// - /// When this override is installed, this function overrides the behavior of - /// `HttpClient.findProxyFromEnvironment`. - String findProxyFromEnvironment(Uri url, Map? environment) { - return _HttpClient._findProxyFromEnvironment(url, environment); - } -} - -class _HttpOverridesScope extends HttpOverrides { - final HttpOverrides? _previous = HttpOverrides.current; - final HttpClient Function(SecurityContext?)? _createHttpClient; - final String Function(Uri uri, Map? environment)? - _findProxyFromEnvironment; - - _HttpOverridesScope(this._createHttpClient, this._findProxyFromEnvironment); - - @override - HttpClient createHttpClient(SecurityContext? context) { - var createHttpClient = _createHttpClient; - if (createHttpClient != null) return createHttpClient(context); - var previous = _previous; - if (previous != null) return previous.createHttpClient(context); - return super.createHttpClient(context); - } - - @override - String findProxyFromEnvironment(Uri url, Map? environment) { - var findProxyFromEnvironment = _findProxyFromEnvironment; - if (findProxyFromEnvironment != null) { - return findProxyFromEnvironment(url, environment); - } - var previous = _previous; - if (previous != null) { - return previous.findProxyFromEnvironment(url, environment); - } - return super.findProxyFromEnvironment(url, environment); - } -} diff --git a/sdk_nnbd/lib/_http/websocket.dart b/sdk_nnbd/lib/_http/websocket.dart deleted file mode 100644 index c9c6246c094..00000000000 --- a/sdk_nnbd/lib/_http/websocket.dart +++ /dev/null @@ -1,496 +0,0 @@ -// Copyright (c) 2013, 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. - -part of dart._http; - -/** - * WebSocket status codes used when closing a WebSocket connection. - */ -abstract class WebSocketStatus { - static const int normalClosure = 1000; - static const int goingAway = 1001; - static const int protocolError = 1002; - static const int unsupportedData = 1003; - static const int reserved1004 = 1004; - static const int noStatusReceived = 1005; - static const int abnormalClosure = 1006; - static const int invalidFramePayloadData = 1007; - static const int policyViolation = 1008; - static const int messageTooBig = 1009; - static const int missingMandatoryExtension = 1010; - static const int internalServerError = 1011; - static const int reserved1015 = 1015; - - @Deprecated("Use normalClosure instead") - static const int NORMAL_CLOSURE = normalClosure; - @Deprecated("Use goingAway instead") - static const int GOING_AWAY = goingAway; - @Deprecated("Use protocolError instead") - static const int PROTOCOL_ERROR = protocolError; - @Deprecated("Use unsupportedData instead") - static const int UNSUPPORTED_DATA = unsupportedData; - @Deprecated("Use reserved1004 instead") - static const int RESERVED_1004 = reserved1004; - @Deprecated("Use noStatusReceived instead") - static const int NO_STATUS_RECEIVED = noStatusReceived; - @Deprecated("Use abnormalClosure instead") - static const int ABNORMAL_CLOSURE = abnormalClosure; - @Deprecated("Use invalidFramePayloadData instead") - static const int INVALID_FRAME_PAYLOAD_DATA = invalidFramePayloadData; - @Deprecated("Use policyViolation instead") - static const int POLICY_VIOLATION = policyViolation; - @Deprecated("Use messageTooBig instead") - static const int MESSAGE_TOO_BIG = messageTooBig; - @Deprecated("Use missingMandatoryExtension instead") - static const int MISSING_MANDATORY_EXTENSION = missingMandatoryExtension; - @Deprecated("Use internalServerError instead") - static const int INTERNAL_SERVER_ERROR = internalServerError; - @Deprecated("Use reserved1015 instead") - static const int RESERVED_1015 = reserved1015; -} - -/// Options controlling compression in a [WebSocket]. -/// -/// A [CompressionOptions] instance can be passed to [WebSocket.connect], or -/// used in other similar places where [WebSocket] compression is configured. -/// -/// In most cases the default [compressionDefault] is sufficient, but in some -/// situations, it might be desirable to use different compression parameters, -/// for example to preserve memory on small devices. -class CompressionOptions { - /// Default [WebSocket] compression configuration. - /// - /// Enables compression with default window sizes and no reuse. This is the - /// default options used by [WebSocket.connect] if no [CompressionOptions] is - /// supplied. - /// - /// * `clientNoContextTakeover`: false - /// * `serverNoContextTakeover`: false - /// * `clientMaxWindowBits`: null (default maximal window size of 15 bits) - /// * `serverMaxWindowBits`: null (default maximal window size of 15 bits) - static const CompressionOptions compressionDefault = - const CompressionOptions(); - @Deprecated("Use compressionDefault instead") - static const CompressionOptions DEFAULT = compressionDefault; - - /// No-compression configuration. - /// - /// Disables compression when used as compression configuration for a - /// [WebSocket]. - static const CompressionOptions compressionOff = - const CompressionOptions(enabled: false); - @Deprecated("Use compressionOff instead") - static const CompressionOptions OFF = compressionOff; - - /// Whether the client will reuse its compression instances. - final bool clientNoContextTakeover; - - /// Whether the server will reuse its compression instances. - final bool serverNoContextTakeover; - - /// The maximal window size bit count requested by the client. - /// - /// The windows size for the compression is always a power of two, so the - /// number of bits precisely determines the window size. - /// - /// If set to `null`, the client has no preference, and the compression can - /// use up to its default maximum window size of 15 bits depending on the - /// server's preference. - final int? clientMaxWindowBits; - - /// The maximal window size bit count requested by the server. - /// - /// The windows size for the compression is always a power of two, so the - /// number of bits precisely determines the window size. - /// - /// If set to `null`, the server has no preference, and the compression can - /// use up to its default maximum window size of 15 bits depending on the - /// client's preference. - final int? serverMaxWindowBits; - - /// Whether WebSocket compression is enabled. - /// - /// If not enabled, the remaining fields have no effect, and the - /// [compressionOff] instance can, and should, be reused instead of creating a - /// new instance with compression disabled. - final bool enabled; - - const CompressionOptions( - {this.clientNoContextTakeover = false, - this.serverNoContextTakeover = false, - this.clientMaxWindowBits, - this.serverMaxWindowBits, - this.enabled = true}); - - /// Parses list of requested server headers to return server compression - /// response headers. - /// - /// Uses [serverMaxWindowBits] value if set, otherwise will attempt to use - /// value from headers. Defaults to [WebSocket.DEFAULT_WINDOW_BITS]. Returns a - /// [_CompressionMaxWindowBits] object which contains the response headers and - /// negotiated max window bits. - _CompressionMaxWindowBits _createServerResponseHeader( - HeaderValue? requested) { - var info = new _CompressionMaxWindowBits("", 0); - - String? part = requested?.parameters[_serverMaxWindowBits]; - if (part != null) { - if (part.length >= 2 && part.startsWith('0')) { - throw new ArgumentError("Illegal 0 padding on value."); - } else { - int mwb = serverMaxWindowBits ?? - int.tryParse(part) ?? - _WebSocketImpl.DEFAULT_WINDOW_BITS; - info.headerValue = "; server_max_window_bits=${mwb}"; - info.maxWindowBits = mwb; - } - } else { - info.headerValue = ""; - info.maxWindowBits = _WebSocketImpl.DEFAULT_WINDOW_BITS; - } - return info; - } - - /// Returns default values for client compression request headers. - String _createClientRequestHeader(HeaderValue? requested, int size) { - var info = ""; - - // If responding to a valid request, specify size - if (requested != null) { - info = "; client_max_window_bits=$size"; - } else { - // Client request. Specify default - if (clientMaxWindowBits == null) { - info = "; client_max_window_bits"; - } else { - info = "; client_max_window_bits=$clientMaxWindowBits"; - } - if (serverMaxWindowBits != null) { - info += "; server_max_window_bits=$serverMaxWindowBits"; - } - } - - return info; - } - - /// Create a Compression Header. - /// - /// If [requested] is null or contains client request headers, returns Client - /// compression request headers with default settings for - /// `client_max_window_bits` header value. If [requested] contains server - /// response headers this method returns a Server compression response header - /// negotiating the max window bits for both client and server as requested - /// `server_max_window_bits` value. This method returns a - /// [_CompressionMaxWindowBits] object with the response headers and - /// negotiated `maxWindowBits` value. - _CompressionMaxWindowBits _createHeader([HeaderValue? requested]) { - var info = new _CompressionMaxWindowBits("", 0); - if (!enabled) { - return info; - } - - info.headerValue = _WebSocketImpl.PER_MESSAGE_DEFLATE; - - if (clientNoContextTakeover && - (requested == null || - (requested != null && - requested.parameters.containsKey(_clientNoContextTakeover)))) { - info.headerValue += "; client_no_context_takeover"; - } - - if (serverNoContextTakeover && - (requested == null || - (requested != null && - requested.parameters.containsKey(_serverNoContextTakeover)))) { - info.headerValue += "; server_no_context_takeover"; - } - - var headerList = _createServerResponseHeader(requested); - info.headerValue += headerList.headerValue; - info.maxWindowBits = headerList.maxWindowBits; - - info.headerValue += - _createClientRequestHeader(requested, info.maxWindowBits); - - return info; - } -} - -/** - * The [WebSocketTransformer] provides the ability to upgrade a - * [HttpRequest] to a [WebSocket] connection. It supports both - * upgrading a single [HttpRequest] and upgrading a stream of - * [HttpRequest]s. - * - * To upgrade a single [HttpRequest] use the static [upgrade] method. - * - * HttpServer server; - * server.listen((request) { - * if (...) { - * WebSocketTransformer.upgrade(request).then((websocket) { - * ... - * }); - * } else { - * // Do normal HTTP request processing. - * } - * }); - * - * To transform a stream of [HttpRequest] events as it implements a - * stream transformer that transforms a stream of HttpRequest into a - * stream of WebSockets by upgrading each HttpRequest from the HTTP or - * HTTPS server, to the WebSocket protocol. - * - * server.transform(new WebSocketTransformer()).listen((webSocket) => ...); - * - * This transformer strives to implement WebSockets as specified by RFC6455. - */ -abstract class WebSocketTransformer - implements StreamTransformer { - /** - * Create a new [WebSocketTransformer]. - * - * If [protocolSelector] is provided, [protocolSelector] will be called to - * select what protocol to use, if any were provided by the client. - * [protocolSelector] is should return either a [String] or a [Future] - * completing with a [String]. The [String] must exist in the list of - * protocols. - * - * If [compression] is provided, the [WebSocket] created will be configured - * to negotiate with the specified [CompressionOptions]. If none is specified - * then the [WebSocket] will be created with the default [CompressionOptions]. - */ - factory WebSocketTransformer( - {/*String|Future*/ protocolSelector(List protocols)?, - CompressionOptions compression = CompressionOptions.compressionDefault}) { - return new _WebSocketTransformerImpl(protocolSelector, compression); - } - - /** - * Upgrades a [HttpRequest] to a [WebSocket] connection. If the - * request is not a valid WebSocket upgrade request an HTTP response - * with status code 500 will be returned. Otherwise the returned - * future will complete with the [WebSocket] when the upgrade process - * is complete. - * - * If [protocolSelector] is provided, [protocolSelector] will be called to - * select what protocol to use, if any were provided by the client. - * [protocolSelector] is should return either a [String] or a [Future] - * completing with a [String]. The [String] must exist in the list of - * protocols. - * - * If [compression] is provided, the [WebSocket] created will be configured - * to negotiate with the specified [CompressionOptions]. If none is specified - * then the [WebSocket] will be created with the default [CompressionOptions]. - */ - static Future upgrade(HttpRequest request, - {protocolSelector(List protocols)?, - CompressionOptions compression = CompressionOptions.compressionDefault}) { - return _WebSocketTransformerImpl._upgrade( - request, protocolSelector, compression); - } - - /** - * Checks whether the request is a valid WebSocket upgrade request. - */ - static bool isUpgradeRequest(HttpRequest request) { - return _WebSocketTransformerImpl._isUpgradeRequest(request); - } -} - -/** - * A two-way HTTP communication object for client or server applications. - * - * The stream exposes the messages received. A text message will be of type - * `String` and a binary message will be of type `List`. - */ -abstract class WebSocket - implements - Stream*/ >, - StreamSink*/ > { - /** - * Possible states of the connection. - */ - static const int connecting = 0; - static const int open = 1; - static const int closing = 2; - static const int closed = 3; - - @Deprecated("Use connecting instead") - static const int CONNECTING = connecting; - @Deprecated("Use open instead") - static const int OPEN = open; - @Deprecated("Use closing instead") - static const int CLOSING = closing; - @Deprecated("Use closed instead") - static const int CLOSED = closed; - - /** - * The interval between ping signals. - * - * A ping message is sent every [pingInterval], starting at the first - * [pingInterval] after a new value has been assigned or a pong message has - * been received. If a ping message is not answered by a pong message from the - * peer, the `WebSocket` is assumed disconnected and the connection is closed - * with a [WebSocketStatus.goingAway] close code. When a ping signal is sent, - * the pong message must be received within [pingInterval]. - * - * There are never two outstanding pings at any given time, and the next ping - * timer starts when the pong is received. - * - * Set the [pingInterval] to `null` to disable sending ping messages. - * - * The default value is `null`. - */ - Duration? pingInterval; - - /** - * Create a new WebSocket connection. The URL supplied in [url] - * must use the scheme `ws` or `wss`. - * - * The [protocols] argument is specifying the subprotocols the - * client is willing to speak. - * - * The [headers] argument is specifying additional HTTP headers for - * setting up the connection. This would typically be the `Origin` - * header and potentially cookies. The keys of the map are the header - * fields and the values are either String or List. - * - * If [headers] is provided, there are a number of headers - * which are controlled by the WebSocket connection process. These - * headers are: - * - * - `connection` - * - `sec-websocket-key` - * - `sec-websocket-protocol` - * - `sec-websocket-version` - * - `upgrade` - * - * If any of these are passed in the `headers` map they will be ignored. - * - * If the `url` contains user information this will be passed as basic - * authentication when setting up the connection. - */ - static Future connect(String url, - {Iterable? protocols, - Map? headers, - CompressionOptions compression = - CompressionOptions.compressionDefault}) => - _WebSocketImpl.connect(url, protocols, headers, compression: compression); - - @Deprecated('This constructor will be removed in Dart 2.0. Use `implements`' - ' instead of `extends` if implementing this abstract class.') - WebSocket(); - - /** - * Creates a WebSocket from an already-upgraded socket. - * - * The initial WebSocket handshake must have occurred prior to this call. A - * WebSocket client can automatically perform the handshake using - * [WebSocket.connect], while a server can do so using - * [WebSocketTransformer.upgrade]. To manually upgrade an [HttpRequest], - * [HttpResponse.detachSocket] may be called. - * - * [protocol] should be the protocol negotiated by this handshake, if any. - * - * [serverSide] must be passed explicitly. If it's `false`, the WebSocket will - * act as the client and mask the messages it sends. If it's `true`, it will - * act as the server and will not mask its messages. - * - * If [compression] is provided, the [WebSocket] created will be configured - * to negotiate with the specified [CompressionOptions]. If none is specified - * then the [WebSocket] will be created with the default [CompressionOptions]. - */ - factory WebSocket.fromUpgradedSocket(Socket socket, - {String? protocol, - bool? serverSide, - CompressionOptions compression = CompressionOptions.compressionDefault}) { - if (serverSide == null) { - throw new ArgumentError("The serverSide argument must be passed " - "explicitly to WebSocket.fromUpgradedSocket."); - } - return new _WebSocketImpl._fromSocket( - socket, protocol, compression, serverSide); - } - - /** - * Returns the current state of the connection. - */ - int get readyState; - - /** - * The extensions property is initially the empty string. After the - * WebSocket connection is established this string reflects the - * extensions used by the server. - */ - String get extensions; - - /** - * The protocol property is initially the empty string. After the - * WebSocket connection is established the value is the subprotocol - * selected by the server. If no subprotocol is negotiated the - * value will remain [:null:]. - */ - String? get protocol; - - /** - * The close code set when the WebSocket connection is closed. If - * there is no close code available this property will be [:null:] - */ - int? get closeCode; - - /** - * The close reason set when the WebSocket connection is closed. If - * there is no close reason available this property will be [:null:] - */ - String? get closeReason; - - /** - * Closes the WebSocket connection. Set the optional [code] and [reason] - * arguments to send close information to the remote peer. If they are - * omitted, the peer will see [WebSocketStatus.noStatusReceived] code - * with no reason. - */ - Future close([int? code, String? reason]); - - /** - * Sends data on the WebSocket connection. The data in [data] must - * be either a `String`, or a `List` holding bytes. - */ - void add(/*String|List*/ data); - - /** - * Sends data from a stream on WebSocket connection. Each data event from - * [stream] will be send as a single WebSocket frame. The data from [stream] - * must be either `String`s, or `List`s holding bytes. - */ - Future addStream(Stream stream); - - /** - * Sends a text message with the text represented by [bytes]. - * - * The [bytes] should be valid UTF-8 encoded Unicode characters. If they are - * not, the receiving end will close the connection. - */ - void addUtf8Text(List bytes); - - /** - * Gets the user agent used for WebSocket connections. - */ - static String? get userAgent => _WebSocketImpl.userAgent; - - /** - * Sets the user agent to use for WebSocket connections. - */ - static set userAgent(String? userAgent) { - _WebSocketImpl.userAgent = userAgent; - } -} - -class WebSocketException implements IOException { - final String message; - - const WebSocketException([this.message = ""]); - - String toString() => "WebSocketException: $message"; -} diff --git a/sdk_nnbd/lib/_http/websocket_impl.dart b/sdk_nnbd/lib/_http/websocket_impl.dart deleted file mode 100644 index 68d0f2950cf..00000000000 --- a/sdk_nnbd/lib/_http/websocket_impl.dart +++ /dev/null @@ -1,1325 +0,0 @@ -// Copyright (c) 2013, 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. - -part of dart._http; - -const String _webSocketGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; -const String _clientNoContextTakeover = "client_no_context_takeover"; -const String _serverNoContextTakeover = "server_no_context_takeover"; -const String _clientMaxWindowBits = "client_max_window_bits"; -const String _serverMaxWindowBits = "server_max_window_bits"; - -// Matches _WebSocketOpcode. -class _WebSocketMessageType { - static const int NONE = 0; - static const int TEXT = 1; - static const int BINARY = 2; -} - -class _WebSocketOpcode { - static const int CONTINUATION = 0; - static const int TEXT = 1; - static const int BINARY = 2; - static const int RESERVED_3 = 3; - static const int RESERVED_4 = 4; - static const int RESERVED_5 = 5; - static const int RESERVED_6 = 6; - static const int RESERVED_7 = 7; - static const int CLOSE = 8; - static const int PING = 9; - static const int PONG = 10; - static const int RESERVED_B = 11; - static const int RESERVED_C = 12; - static const int RESERVED_D = 13; - static const int RESERVED_E = 14; - static const int RESERVED_F = 15; -} - -class _EncodedString { - final List bytes; - _EncodedString(this.bytes); -} - -/** - * Stores the header and integer value derived from negotiation of - * client_max_window_bits and server_max_window_bits. headerValue will be - * set in the Websocket response headers. - */ -class _CompressionMaxWindowBits { - String headerValue; - int maxWindowBits; - _CompressionMaxWindowBits(this.headerValue, this.maxWindowBits); - String toString() => headerValue; -} - -/** - * The web socket protocol transformer handles the protocol byte stream - * which is supplied through the `handleData`. As the protocol is processed, - * it'll output frame data as either a List or String. - * - * Important information about usage: Be sure you use cancelOnError, so the - * socket will be closed when the processor encounter an error. Not using it - * will lead to undefined behaviour. - */ -class _WebSocketProtocolTransformer extends StreamTransformerBase, - dynamic /*List|_WebSocketPing|_WebSocketPong*/ > - implements EventSink> { - static const int START = 0; - static const int LEN_FIRST = 1; - static const int LEN_REST = 2; - static const int MASK = 3; - static const int PAYLOAD = 4; - static const int CLOSED = 5; - static const int FAILURE = 6; - static const int FIN = 0x80; - static const int RSV1 = 0x40; - static const int RSV2 = 0x20; - static const int RSV3 = 0x10; - static const int OPCODE = 0xF; - - int _state = START; - bool _fin = false; - bool _compressed = false; - int _opcode = -1; - int _len = -1; - bool _masked = false; - int _remainingLenBytes = -1; - int _remainingMaskingKeyBytes = 4; - int _remainingPayloadBytes = -1; - int _unmaskingIndex = 0; - int _currentMessageType = _WebSocketMessageType.NONE; - int closeCode = WebSocketStatus.NO_STATUS_RECEIVED; - String closeReason = ""; - - EventSink|_WebSocketPing|_WebSocketPong*/ >? _eventSink; - - final bool _serverSide; - final Uint8List _maskingBytes = Uint8List(4); - final BytesBuilder _payload = new BytesBuilder(copy: false); - - _WebSocketPerMessageDeflate? _deflate; - _WebSocketProtocolTransformer([this._serverSide = false, this._deflate]); - - Stream|_WebSocketPing|_WebSocketPong*/ > bind( - Stream> stream) { - return new Stream.eventTransformed(stream, (EventSink eventSink) { - if (_eventSink != null) { - throw new StateError("WebSocket transformer already used."); - } - _eventSink = eventSink; - return this; - }); - } - - void addError(Object error, [StackTrace? stackTrace]) { - // TODO(40614): Remove once non-nullability is sound. - ArgumentError.checkNotNull(error, "error"); - _eventSink!.addError(error, stackTrace); - } - - void close() { - _eventSink!.close(); - } - - /** - * Process data received from the underlying communication channel. - */ - void add(List bytes) { - var buffer = bytes is Uint8List ? bytes : new Uint8List.fromList(bytes); - int index = 0; - int lastIndex = buffer.length; - if (_state == CLOSED) { - throw new WebSocketException("Data on closed connection"); - } - if (_state == FAILURE) { - throw new WebSocketException("Data on failed connection"); - } - while ((index < lastIndex) && _state != CLOSED && _state != FAILURE) { - int byte = buffer[index]; - if (_state <= LEN_REST) { - if (_state == START) { - _fin = (byte & FIN) != 0; - - if ((byte & (RSV2 | RSV3)) != 0) { - // The RSV2, RSV3 bits must both be zero. - throw new WebSocketException("Protocol error"); - } - - _opcode = (byte & OPCODE); - - if (_opcode != _WebSocketOpcode.CONTINUATION) { - if ((byte & RSV1) != 0) { - _compressed = true; - } else { - _compressed = false; - } - } - - if (_opcode <= _WebSocketOpcode.BINARY) { - if (_opcode == _WebSocketOpcode.CONTINUATION) { - if (_currentMessageType == _WebSocketMessageType.NONE) { - throw new WebSocketException("Protocol error"); - } - } else { - assert(_opcode == _WebSocketOpcode.TEXT || - _opcode == _WebSocketOpcode.BINARY); - if (_currentMessageType != _WebSocketMessageType.NONE) { - throw new WebSocketException("Protocol error"); - } - _currentMessageType = _opcode; - } - } else if (_opcode >= _WebSocketOpcode.CLOSE && - _opcode <= _WebSocketOpcode.PONG) { - // Control frames cannot be fragmented. - if (!_fin) throw new WebSocketException("Protocol error"); - } else { - throw new WebSocketException("Protocol error"); - } - _state = LEN_FIRST; - } else if (_state == LEN_FIRST) { - _masked = (byte & 0x80) != 0; - _len = byte & 0x7F; - if (_isControlFrame() && _len > 125) { - throw new WebSocketException("Protocol error"); - } - if (_len == 126) { - _len = 0; - _remainingLenBytes = 2; - _state = LEN_REST; - } else if (_len == 127) { - _len = 0; - _remainingLenBytes = 8; - _state = LEN_REST; - } else { - assert(_len < 126); - _lengthDone(); - } - } else { - assert(_state == LEN_REST); - _len = _len << 8 | byte; - _remainingLenBytes--; - if (_remainingLenBytes == 0) { - _lengthDone(); - } - } - } else { - if (_state == MASK) { - _maskingBytes[4 - _remainingMaskingKeyBytes--] = byte; - if (_remainingMaskingKeyBytes == 0) { - _maskDone(); - } - } else { - assert(_state == PAYLOAD); - // The payload is not handled one byte at a time but in blocks. - int payloadLength = min(lastIndex - index, _remainingPayloadBytes); - _remainingPayloadBytes -= payloadLength; - // Unmask payload if masked. - if (_masked) { - _unmask(index, payloadLength, buffer); - } - // Control frame and data frame share _payloads. - _payload.add(new Uint8List.view( - buffer.buffer, buffer.offsetInBytes + index, payloadLength)); - index += payloadLength; - if (_isControlFrame()) { - if (_remainingPayloadBytes == 0) _controlFrameEnd(); - } else { - if (_currentMessageType != _WebSocketMessageType.TEXT && - _currentMessageType != _WebSocketMessageType.BINARY) { - throw new WebSocketException("Protocol error"); - } - if (_remainingPayloadBytes == 0) _messageFrameEnd(); - } - - // Hack - as we always do index++ below. - index--; - } - } - - // Move to the next byte. - index++; - } - } - - void _unmask(int index, int length, Uint8List buffer) { - const int BLOCK_SIZE = 16; - // Skip Int32x4-version if message is small. - if (length >= BLOCK_SIZE) { - // Start by aligning to 16 bytes. - final int startOffset = BLOCK_SIZE - (index & 15); - final int end = index + startOffset; - for (int i = index; i < end; i++) { - buffer[i] ^= _maskingBytes[_unmaskingIndex++ & 3]; - } - index += startOffset; - length -= startOffset; - final int blockCount = length ~/ BLOCK_SIZE; - if (blockCount > 0) { - // Create mask block. - int mask = 0; - for (int i = 3; i >= 0; i--) { - mask = (mask << 8) | _maskingBytes[(_unmaskingIndex + i) & 3]; - } - Int32x4 blockMask = new Int32x4(mask, mask, mask, mask); - Int32x4List blockBuffer = new Int32x4List.view( - buffer.buffer, buffer.offsetInBytes + index, blockCount); - for (int i = 0; i < blockBuffer.length; i++) { - blockBuffer[i] ^= blockMask; - } - final int bytes = blockCount * BLOCK_SIZE; - index += bytes; - length -= bytes; - } - } - // Handle end. - final int end = index + length; - for (int i = index; i < end; i++) { - buffer[i] ^= _maskingBytes[_unmaskingIndex++ & 3]; - } - } - - void _lengthDone() { - if (_masked) { - if (!_serverSide) { - throw new WebSocketException("Received masked frame from server"); - } - _state = MASK; - } else { - if (_serverSide) { - throw new WebSocketException("Received unmasked frame from client"); - } - _remainingPayloadBytes = _len; - _startPayload(); - } - } - - void _maskDone() { - _remainingPayloadBytes = _len; - _startPayload(); - } - - void _startPayload() { - // If there is no actual payload perform perform callbacks without - // going through the PAYLOAD state. - if (_remainingPayloadBytes == 0) { - if (_isControlFrame()) { - switch (_opcode) { - case _WebSocketOpcode.CLOSE: - _state = CLOSED; - _eventSink!.close(); - break; - case _WebSocketOpcode.PING: - _eventSink!.add(new _WebSocketPing()); - break; - case _WebSocketOpcode.PONG: - _eventSink!.add(new _WebSocketPong()); - break; - } - _prepareForNextFrame(); - } else { - _messageFrameEnd(); - } - } else { - _state = PAYLOAD; - } - } - - void _messageFrameEnd() { - if (_fin) { - var bytes = _payload.takeBytes(); - var deflate = _deflate; - if (deflate != null && _compressed) { - bytes = deflate.processIncomingMessage(bytes); - } - - switch (_currentMessageType) { - case _WebSocketMessageType.TEXT: - _eventSink!.add(utf8.decode(bytes)); - break; - case _WebSocketMessageType.BINARY: - _eventSink!.add(bytes); - break; - } - _currentMessageType = _WebSocketMessageType.NONE; - } - _prepareForNextFrame(); - } - - void _controlFrameEnd() { - switch (_opcode) { - case _WebSocketOpcode.CLOSE: - closeCode = WebSocketStatus.noStatusReceived; - var payload = _payload.takeBytes(); - if (payload.length > 0) { - if (payload.length == 1) { - throw new WebSocketException("Protocol error"); - } - closeCode = payload[0] << 8 | payload[1]; - if (closeCode == WebSocketStatus.noStatusReceived) { - throw new WebSocketException("Protocol error"); - } - if (payload.length > 2) { - closeReason = utf8.decode(payload.sublist(2)); - } - } - _state = CLOSED; - _eventSink!.close(); - break; - - case _WebSocketOpcode.PING: - _eventSink!.add(new _WebSocketPing(_payload.takeBytes())); - break; - - case _WebSocketOpcode.PONG: - _eventSink!.add(new _WebSocketPong(_payload.takeBytes())); - break; - } - _prepareForNextFrame(); - } - - bool _isControlFrame() { - return _opcode == _WebSocketOpcode.CLOSE || - _opcode == _WebSocketOpcode.PING || - _opcode == _WebSocketOpcode.PONG; - } - - void _prepareForNextFrame() { - if (_state != CLOSED && _state != FAILURE) _state = START; - _fin = false; - _opcode = -1; - _len = -1; - _remainingLenBytes = -1; - _remainingMaskingKeyBytes = 4; - _remainingPayloadBytes = -1; - _unmaskingIndex = 0; - } -} - -class _WebSocketPing { - final List? payload; - _WebSocketPing([this.payload = null]); -} - -class _WebSocketPong { - final List? payload; - _WebSocketPong([this.payload = null]); -} - -typedef /*String|Future*/ _ProtocolSelector(List protocols); - -class _WebSocketTransformerImpl - extends StreamTransformerBase - implements WebSocketTransformer { - final StreamController _controller = - new StreamController(sync: true); - final _ProtocolSelector? _protocolSelector; - final CompressionOptions _compression; - - _WebSocketTransformerImpl(this._protocolSelector, this._compression); - - Stream bind(Stream stream) { - stream.listen((request) { - _upgrade(request, _protocolSelector, _compression) - .then((WebSocket webSocket) => _controller.add(webSocket)) - .catchError(_controller.addError); - }, onDone: () { - _controller.close(); - }); - - return _controller.stream; - } - - static List _tokenizeFieldValue(String headerValue) { - List tokens = []; - int start = 0; - int index = 0; - while (index < headerValue.length) { - if (headerValue[index] == ",") { - tokens.add(headerValue.substring(start, index)); - start = index + 1; - } else if (headerValue[index] == " " || headerValue[index] == "\t") { - start++; - } - index++; - } - tokens.add(headerValue.substring(start, index)); - return tokens; - } - - static Future _upgrade(HttpRequest request, - _ProtocolSelector? protocolSelector, CompressionOptions compression) { - var response = request.response; - if (!_isUpgradeRequest(request)) { - // Send error response. - response - ..statusCode = HttpStatus.badRequest - ..close(); - return new Future.error( - new WebSocketException("Invalid WebSocket upgrade request")); - } - - Future upgrade(String? protocol) { - // Send the upgrade response. - response - ..statusCode = HttpStatus.switchingProtocols - ..headers.add(HttpHeaders.connectionHeader, "Upgrade") - ..headers.add(HttpHeaders.upgradeHeader, "websocket"); - String key = request.headers.value("Sec-WebSocket-Key")!; - _SHA1 sha1 = new _SHA1(); - sha1.add("$key$_webSocketGUID".codeUnits); - String accept = _CryptoUtils.bytesToBase64(sha1.close()); - response.headers.add("Sec-WebSocket-Accept", accept); - if (protocol != null) { - response.headers.add("Sec-WebSocket-Protocol", protocol); - } - - var deflate = _negotiateCompression(request, response, compression); - - response.headers.contentLength = 0; - return response.detachSocket().then((socket) => - new _WebSocketImpl._fromSocket( - socket, protocol, compression, true, deflate)); - } - - var protocols = request.headers['Sec-WebSocket-Protocol']; - if (protocols != null && protocolSelector != null) { - // The suggested protocols can be spread over multiple lines, each - // consisting of multiple protocols. To unify all of them, first join - // the lists with ', ' and then tokenize. - var tokenizedProtocols = _tokenizeFieldValue(protocols.join(', ')); - return new Future(() => protocolSelector(tokenizedProtocols)) - .then((protocol) { - if (tokenizedProtocols.indexOf(protocol) < 0) { - throw new WebSocketException( - "Selected protocol is not in the list of available protocols"); - } - return protocol; - }).catchError((error) { - response - ..statusCode = HttpStatus.internalServerError - ..close(); - throw error; - }).then(upgrade); - } else { - return upgrade(null); - } - } - - static _WebSocketPerMessageDeflate? _negotiateCompression(HttpRequest request, - HttpResponse response, CompressionOptions compression) { - var extensionHeader = request.headers.value("Sec-WebSocket-Extensions"); - - extensionHeader ??= ""; - - var hv = HeaderValue.parse(extensionHeader, valueSeparator: ','); - if (compression.enabled && hv.value == _WebSocketImpl.PER_MESSAGE_DEFLATE) { - var info = compression._createHeader(hv); - - response.headers.add("Sec-WebSocket-Extensions", info.headerValue); - var serverNoContextTakeover = - (hv.parameters.containsKey(_serverNoContextTakeover) && - compression.serverNoContextTakeover); - var clientNoContextTakeover = - (hv.parameters.containsKey(_clientNoContextTakeover) && - compression.clientNoContextTakeover); - var deflate = new _WebSocketPerMessageDeflate( - serverNoContextTakeover: serverNoContextTakeover, - clientNoContextTakeover: clientNoContextTakeover, - serverMaxWindowBits: info.maxWindowBits, - clientMaxWindowBits: info.maxWindowBits, - serverSide: true); - - return deflate; - } - - return null; - } - - static bool _isUpgradeRequest(HttpRequest request) { - if (request.method != "GET") { - return false; - } - var connectionHeader = request.headers[HttpHeaders.connectionHeader]; - if (connectionHeader == null) { - return false; - } - bool isUpgrade = false; - for (var value in connectionHeader) { - if (value.toLowerCase() == "upgrade") { - isUpgrade = true; - break; - } - } - if (!isUpgrade) return false; - String? upgrade = request.headers.value(HttpHeaders.upgradeHeader); - if (upgrade == null || upgrade.toLowerCase() != "websocket") { - return false; - } - String? version = request.headers.value("Sec-WebSocket-Version"); - if (version == null || version != "13") { - return false; - } - String? key = request.headers.value("Sec-WebSocket-Key"); - if (key == null) { - return false; - } - return true; - } -} - -class _WebSocketPerMessageDeflate { - bool serverNoContextTakeover; - bool clientNoContextTakeover; - int clientMaxWindowBits; - int serverMaxWindowBits; - bool serverSide; - - RawZLibFilter? decoder; - RawZLibFilter? encoder; - - _WebSocketPerMessageDeflate( - {this.clientMaxWindowBits = _WebSocketImpl.DEFAULT_WINDOW_BITS, - this.serverMaxWindowBits = _WebSocketImpl.DEFAULT_WINDOW_BITS, - this.serverNoContextTakeover = false, - this.clientNoContextTakeover = false, - this.serverSide = false}); - - RawZLibFilter _ensureDecoder() => decoder ??= new RawZLibFilter.inflateFilter( - windowBits: serverSide ? clientMaxWindowBits : serverMaxWindowBits, - raw: true); - - RawZLibFilter _ensureEncoder() => encoder ??= new RawZLibFilter.deflateFilter( - windowBits: serverSide ? serverMaxWindowBits : clientMaxWindowBits, - raw: true); - - Uint8List processIncomingMessage(List msg) { - var decoder = _ensureDecoder(); - - var data = []; - data.addAll(msg); - data.addAll(const [0x00, 0x00, 0xff, 0xff]); - - decoder.process(data, 0, data.length); - final result = new BytesBuilder(); - List out; - - while (true) { - final out = decoder.processed(); - if (out == null) break; - result.add(out); - } - - if ((serverSide && clientNoContextTakeover) || - (!serverSide && serverNoContextTakeover)) { - this.decoder = null; - } - - return result.takeBytes(); - } - - List processOutgoingMessage(List msg) { - var encoder = _ensureEncoder(); - var result = []; - Uint8List buffer; - - if (msg is! Uint8List) { - for (var i = 0; i < msg.length; i++) { - if (msg[i] < 0 || 255 < msg[i]) { - throw new ArgumentError("List element is not a byte value " - "(value ${msg[i]} at index $i)"); - } - } - buffer = new Uint8List.fromList(msg); - } else { - buffer = msg; - } - - encoder.process(buffer, 0, buffer.length); - - while (true) { - final out = encoder.processed(); - if (out == null) break; - result.addAll(out); - } - - if ((!serverSide && clientNoContextTakeover) || - (serverSide && serverNoContextTakeover)) { - this.encoder = null; - } - - if (result.length > 4) { - result = result.sublist(0, result.length - 4); - } - - // RFC 7692 7.2.3.6. "Generating an Empty Fragment" says that if the - // compression library doesn't generate any data when the bufer is empty, - // then an empty uncompressed deflate block is used for this purpose. The - // 0x00 block has the BFINAL header bit set to 0 and the BTYPE header set to - // 00 along with 5 bits of padding. This block decodes to zero bytes. - if (result.length == 0) { - return [0x00]; - } - - return result; - } -} - -// TODO(ajohnsen): Make this transformer reusable. -class _WebSocketOutgoingTransformer - extends StreamTransformerBase> implements EventSink { - final _WebSocketImpl webSocket; - EventSink>? _eventSink; - - _WebSocketPerMessageDeflate? _deflateHelper; - - _WebSocketOutgoingTransformer(this.webSocket) - : _deflateHelper = webSocket._deflate; - - Stream> bind(Stream stream) { - return new Stream>.eventTransformed(stream, - (EventSink> eventSink) { - if (_eventSink != null) { - throw new StateError("WebSocket transformer already used"); - } - _eventSink = eventSink; - return this; - }); - } - - void add(message) { - if (message is _WebSocketPong) { - addFrame(_WebSocketOpcode.PONG, message.payload); - return; - } - if (message is _WebSocketPing) { - addFrame(_WebSocketOpcode.PING, message.payload); - return; - } - List? data; - int opcode; - if (message != null) { - List messageData; - if (message is String) { - opcode = _WebSocketOpcode.TEXT; - messageData = utf8.encode(message); - } else if (message is List) { - opcode = _WebSocketOpcode.BINARY; - messageData = message; - } else if (message is _EncodedString) { - opcode = _WebSocketOpcode.TEXT; - messageData = message.bytes; - } else { - throw new ArgumentError(message); - } - var deflateHelper = _deflateHelper; - if (deflateHelper != null) { - messageData = deflateHelper.processOutgoingMessage(messageData); - } - data = messageData; - } else { - opcode = _WebSocketOpcode.TEXT; - } - addFrame(opcode, data); - } - - void addError(Object error, [StackTrace? stackTrace]) { - // TODO(40614): Remove once non-nullability is sound. - ArgumentError.checkNotNull(error, "error"); - _eventSink!.addError(error, stackTrace); - } - - void close() { - int? code = webSocket._outCloseCode; - String? reason = webSocket._outCloseReason; - List? data; - if (code != null) { - data = [ - (code >> 8) & 0xFF, - code & 0xFF, - if (reason != null) ...utf8.encode(reason) - ]; - } - addFrame(_WebSocketOpcode.CLOSE, data); - _eventSink!.close(); - } - - void addFrame(int opcode, List? data) { - createFrame( - opcode, - data, - webSocket._serverSide, - _deflateHelper != null && - (opcode == _WebSocketOpcode.TEXT || - opcode == _WebSocketOpcode.BINARY)) - .forEach((e) { - _eventSink!.add(e); - }); - } - - static Iterable> createFrame( - int opcode, List? data, bool serverSide, bool compressed) { - bool mask = !serverSide; // Masking not implemented for server. - int dataLength = data == null ? 0 : data.length; - // Determine the header size. - int headerSize = (mask) ? 6 : 2; - if (dataLength > 65535) { - headerSize += 8; - } else if (dataLength > 125) { - headerSize += 2; - } - Uint8List header = new Uint8List(headerSize); - int index = 0; - - // Set FIN and opcode. - var hoc = _WebSocketProtocolTransformer.FIN | - (compressed ? _WebSocketProtocolTransformer.RSV1 : 0) | - (opcode & _WebSocketProtocolTransformer.OPCODE); - - header[index++] = hoc; - // Determine size and position of length field. - int lengthBytes = 1; - if (dataLength > 65535) { - header[index++] = 127; - lengthBytes = 8; - } else if (dataLength > 125) { - header[index++] = 126; - lengthBytes = 2; - } - // Write the length in network byte order into the header. - for (int i = 0; i < lengthBytes; i++) { - header[index++] = dataLength >> (((lengthBytes - 1) - i) * 8) & 0xFF; - } - if (mask) { - header[1] |= 1 << 7; - var maskBytes = _CryptoUtils.getRandomBytes(4); - header.setRange(index, index + 4, maskBytes); - index += 4; - if (data != null) { - Uint8List list; - // If this is a text message just do the masking inside the - // encoded data. - if (opcode == _WebSocketOpcode.TEXT && data is Uint8List) { - list = data; - } else { - if (data is Uint8List) { - list = new Uint8List.fromList(data); - } else { - list = new Uint8List(data.length); - for (int i = 0; i < data.length; i++) { - if (data[i] < 0 || 255 < data[i]) { - throw new ArgumentError("List element is not a byte value " - "(value ${data[i]} at index $i)"); - } - list[i] = data[i]; - } - } - } - const int BLOCK_SIZE = 16; - int blockCount = list.length ~/ BLOCK_SIZE; - if (blockCount > 0) { - // Create mask block. - int mask = 0; - for (int i = 3; i >= 0; i--) { - mask = (mask << 8) | maskBytes[i]; - } - Int32x4 blockMask = new Int32x4(mask, mask, mask, mask); - Int32x4List blockBuffer = - new Int32x4List.view(list.buffer, list.offsetInBytes, blockCount); - for (int i = 0; i < blockBuffer.length; i++) { - blockBuffer[i] ^= blockMask; - } - } - // Handle end. - for (int i = blockCount * BLOCK_SIZE; i < list.length; i++) { - list[i] ^= maskBytes[i & 3]; - } - data = list; - } - } - assert(index == headerSize); - if (data == null) { - return [header]; - } else { - return [header, data]; - } - } -} - -class _WebSocketConsumer implements StreamConsumer { - final _WebSocketImpl webSocket; - final Socket socket; - StreamController? _controller; - StreamSubscription? _subscription; - bool _issuedPause = false; - bool _closed = false; - Completer _closeCompleter = new Completer(); - Completer? _completer; - - _WebSocketConsumer(this.webSocket, this.socket); - - void _onListen() { - _subscription?.cancel(); - } - - void _onPause() { - var subscription = _subscription; - if (subscription != null) { - subscription.pause(); - } else { - _issuedPause = true; - } - } - - void _onResume() { - var subscription = _subscription; - if (subscription != null) { - subscription.resume(); - } else { - _issuedPause = false; - } - } - - void _cancel() { - var subscription = _subscription; - if (subscription != null) { - _subscription = null; - subscription.cancel(); - } - } - - StreamController _ensureController() { - var controller = _controller; - if (controller != null) return controller; - controller = _controller = new StreamController( - sync: true, - onPause: _onPause, - onResume: _onResume, - onCancel: _onListen); - var stream = controller.stream - .transform(new _WebSocketOutgoingTransformer(webSocket)); - socket.addStream(stream).then((_) { - _done(); - _closeCompleter.complete(webSocket); - }, onError: (Object error, StackTrace stackTrace) { - _closed = true; - _cancel(); - if (error is ArgumentError) { - if (!_done(error, stackTrace)) { - _closeCompleter.completeError(error, stackTrace); - } - } else { - _done(); - _closeCompleter.complete(webSocket); - } - }); - return controller; - } - - bool _done([Object? error, StackTrace? stackTrace]) { - var completer = _completer; - if (completer == null) return false; - if (error != null) { - completer.completeError(error, stackTrace); - } else { - completer.complete(webSocket); - } - _completer = null; - return true; - } - - Future addStream(Stream stream) { - if (_closed) { - stream.listen(null).cancel(); - return new Future.value(webSocket); - } - _ensureController(); - var completer = _completer = new Completer(); - var subscription = _subscription = stream.listen((data) { - _controller!.add(data); - }, onDone: _done, onError: _done, cancelOnError: true); - if (_issuedPause) { - subscription.pause(); - _issuedPause = false; - } - return completer.future; - } - - Future close() { - _ensureController().close(); - - return _closeCompleter.future - .then((_) => socket.close().catchError((_) {}).then((_) => webSocket)); - } - - void add(data) { - if (_closed) return; - var controller = _ensureController(); - // Stop sending message if _controller has been closed. - // https://github.com/dart-lang/sdk/issues/37441 - if (controller.isClosed) return; - controller.add(data); - } - - void closeSocket() { - _closed = true; - _cancel(); - close(); - } -} - -class _WebSocketImpl extends Stream with _ServiceObject implements WebSocket { - // Use default Map so we keep order. - static Map _webSockets = new Map(); - static const int DEFAULT_WINDOW_BITS = 15; - static const String PER_MESSAGE_DEFLATE = "permessage-deflate"; - - final String? protocol; - - final StreamController _controller; - StreamSubscription? _subscription; - late StreamSink _sink; - - final Socket _socket; - final bool _serverSide; - int _readyState = WebSocket.connecting; - bool _writeClosed = false; - int? _closeCode; - String? _closeReason; - Duration? _pingInterval; - Timer? _pingTimer; - late _WebSocketConsumer _consumer; - - int? _outCloseCode; - String? _outCloseReason; - Timer? _closeTimer; - _WebSocketPerMessageDeflate? _deflate; - - static final HttpClient _httpClient = new HttpClient(); - - static Future connect( - String url, Iterable? protocols, Map? headers, - {CompressionOptions compression = - CompressionOptions.compressionDefault}) { - Uri uri = Uri.parse(url); - if (uri.scheme != "ws" && uri.scheme != "wss") { - throw new WebSocketException("Unsupported URL scheme '${uri.scheme}'"); - } - - Random random = new Random(); - // Generate 16 random bytes. - Uint8List nonceData = new Uint8List(16); - for (int i = 0; i < 16; i++) { - nonceData[i] = random.nextInt(256); - } - String nonce = _CryptoUtils.bytesToBase64(nonceData); - - uri = new Uri( - scheme: uri.scheme == "wss" ? "https" : "http", - userInfo: uri.userInfo, - host: uri.host, - port: uri.port, - path: uri.path, - query: uri.query, - fragment: uri.fragment); - return _httpClient.openUrl("GET", uri).then((request) { - if (uri.userInfo != null && !uri.userInfo.isEmpty) { - // If the URL contains user information use that for basic - // authorization. - String auth = _CryptoUtils.bytesToBase64(utf8.encode(uri.userInfo)); - request.headers.set(HttpHeaders.authorizationHeader, "Basic $auth"); - } - if (headers != null) { - headers.forEach((field, value) => request.headers.add(field, value)); - } - // Setup the initial handshake. - request.headers - ..set(HttpHeaders.connectionHeader, "Upgrade") - ..set(HttpHeaders.upgradeHeader, "websocket") - ..set("Sec-WebSocket-Key", nonce) - ..set("Cache-Control", "no-cache") - ..set("Sec-WebSocket-Version", "13"); - if (protocols != null) { - request.headers.add("Sec-WebSocket-Protocol", protocols.toList()); - } - - if (compression.enabled) { - request.headers - .add("Sec-WebSocket-Extensions", compression._createHeader()); - } - - return request.close(); - }).then((response) { - Never error(String message) { - // Flush data. - response.detachSocket().then((socket) { - socket.destroy(); - }); - throw new WebSocketException(message); - } - - var connectionHeader = response.headers[HttpHeaders.connectionHeader]; - if (response.statusCode != HttpStatus.switchingProtocols || - connectionHeader == null || - !connectionHeader.any((value) => value.toLowerCase() == "upgrade") || - response.headers.value(HttpHeaders.upgradeHeader)!.toLowerCase() != - "websocket") { - error("Connection to '$uri' was not upgraded to websocket"); - } - String? accept = response.headers.value("Sec-WebSocket-Accept"); - if (accept == null) { - error("Response did not contain a 'Sec-WebSocket-Accept' header"); - } - _SHA1 sha1 = new _SHA1(); - sha1.add("$nonce$_webSocketGUID".codeUnits); - List expectedAccept = sha1.close(); - List receivedAccept = _CryptoUtils.base64StringToBytes(accept); - if (expectedAccept.length != receivedAccept.length) { - error("Response header 'Sec-WebSocket-Accept' is the wrong length"); - } - for (int i = 0; i < expectedAccept.length; i++) { - if (expectedAccept[i] != receivedAccept[i]) { - error("Bad response 'Sec-WebSocket-Accept' header"); - } - } - var protocol = response.headers.value('Sec-WebSocket-Protocol'); - - _WebSocketPerMessageDeflate? deflate = - negotiateClientCompression(response, compression); - - return response.detachSocket().then((socket) => - new _WebSocketImpl._fromSocket( - socket, protocol, compression, false, deflate)); - }); - } - - static _WebSocketPerMessageDeflate? negotiateClientCompression( - HttpClientResponse response, CompressionOptions compression) { - String extensionHeader = - response.headers.value('Sec-WebSocket-Extensions') ?? ""; - - var hv = HeaderValue.parse(extensionHeader, valueSeparator: ','); - - if (compression.enabled && hv.value == PER_MESSAGE_DEFLATE) { - var serverNoContextTakeover = - hv.parameters.containsKey(_serverNoContextTakeover); - var clientNoContextTakeover = - hv.parameters.containsKey(_clientNoContextTakeover); - - int getWindowBits(String type) { - var o = hv.parameters[type]; - if (o == null) { - return DEFAULT_WINDOW_BITS; - } - - return int.tryParse(o) ?? DEFAULT_WINDOW_BITS; - } - - return new _WebSocketPerMessageDeflate( - clientMaxWindowBits: getWindowBits(_clientMaxWindowBits), - serverMaxWindowBits: getWindowBits(_serverMaxWindowBits), - clientNoContextTakeover: clientNoContextTakeover, - serverNoContextTakeover: serverNoContextTakeover); - } - - return null; - } - - _WebSocketImpl._fromSocket( - this._socket, this.protocol, CompressionOptions compression, - [this._serverSide = false, _WebSocketPerMessageDeflate? deflate]) - : _controller = new StreamController(sync: true) { - _consumer = new _WebSocketConsumer(this, _socket); - _sink = new _StreamSinkImpl(_consumer); - _readyState = WebSocket.open; - _deflate = deflate; - - var transformer = new _WebSocketProtocolTransformer(_serverSide, deflate); - var subscription = _subscription = transformer.bind(_socket).listen((data) { - if (data is _WebSocketPing) { - if (!_writeClosed) _consumer.add(new _WebSocketPong(data.payload)); - } else if (data is _WebSocketPong) { - // Simply set pingInterval, as it'll cancel any timers. - pingInterval = _pingInterval; - } else { - _controller.add(data); - } - }, onError: (Object error, StackTrace stackTrace) { - _closeTimer?.cancel(); - if (error is FormatException) { - _close(WebSocketStatus.invalidFramePayloadData); - } else { - _close(WebSocketStatus.protocolError); - } - // An error happened, set the close code set above. - _closeCode = _outCloseCode; - _closeReason = _outCloseReason; - _controller.close(); - }, onDone: () { - _closeTimer?.cancel(); - if (_readyState == WebSocket.open) { - _readyState = WebSocket.closing; - if (!_isReservedStatusCode(transformer.closeCode)) { - _close(transformer.closeCode, transformer.closeReason); - } else { - _close(); - } - _readyState = WebSocket.closed; - } - // Protocol close, use close code from transformer. - _closeCode = transformer.closeCode; - _closeReason = transformer.closeReason; - _controller.close(); - }, cancelOnError: true); - subscription.pause(); - _controller - ..onListen = subscription.resume - ..onCancel = () { - _subscription!.cancel(); - _subscription = null; - } - ..onPause = subscription.pause - ..onResume = subscription.resume; - - _webSockets[_serviceId] = this; - } - - StreamSubscription listen(void onData(message)?, - {Function? onError, void onDone()?, bool? cancelOnError}) { - return _controller.stream.listen(onData, - onError: onError, onDone: onDone, cancelOnError: cancelOnError); - } - - Duration? get pingInterval => _pingInterval; - - void set pingInterval(Duration? interval) { - if (_writeClosed) return; - _pingTimer?.cancel(); - _pingInterval = interval; - - if (interval == null) return; - - _pingTimer = new Timer(interval, () { - if (_writeClosed) return; - _consumer.add(new _WebSocketPing()); - _pingTimer = new Timer(interval, () { - _closeTimer?.cancel(); - // No pong received. - _close(WebSocketStatus.goingAway); - _closeCode = _outCloseCode; - _closeReason = _outCloseReason; - _controller.close(); - }); - }); - } - - int get readyState => _readyState; - - String get extensions => ""; - int? get closeCode => _closeCode; - String? get closeReason => _closeReason; - - void add(data) { - _sink.add(data); - } - - void addUtf8Text(List bytes) { - // TODO(40614): Remove once non-nullability is sound. - ArgumentError.checkNotNull(bytes, "bytes"); - _sink.add(new _EncodedString(bytes)); - } - - void addError(Object error, [StackTrace? stackTrace]) { - _sink.addError(error, stackTrace); - } - - Future addStream(Stream stream) => _sink.addStream(stream); - Future get done => _sink.done; - - Future close([int? code, String? reason]) { - if (_isReservedStatusCode(code)) { - throw new WebSocketException("Reserved status code $code"); - } - if (_outCloseCode == null) { - _outCloseCode = code; - _outCloseReason = reason; - } - if (!_controller.isClosed) { - // If a close has not yet been received from the other end then - // 1) make sure to listen on the stream so the close frame will be - // processed if received. - // 2) set a timer terminate the connection if a close frame is - // not received. - if (!_controller.hasListener && _subscription != null) { - _controller.stream.drain().catchError((_) => {}); - } - if (_closeTimer == null) { - // When closing the web-socket, we no longer accept data. - _closeTimer = new Timer(const Duration(seconds: 5), () { - // Reuse code and reason from the local close. - _closeCode = _outCloseCode; - _closeReason = _outCloseReason; - _subscription?.cancel(); - _controller.close(); - _webSockets.remove(_serviceId); - }); - } - } - return _sink.close(); - } - - static String? get userAgent => _httpClient.userAgent; - - static set userAgent(String? userAgent) { - _httpClient.userAgent = userAgent; - } - - void _close([int? code, String? reason]) { - if (_writeClosed) return; - if (_outCloseCode == null) { - _outCloseCode = code; - _outCloseReason = reason; - } - _writeClosed = true; - _consumer.closeSocket(); - _webSockets.remove(_serviceId); - } - - String get _serviceTypePath => 'io/websockets'; - String get _serviceTypeName => 'WebSocket'; - - Map _toJSON(bool ref) { - var name = '${_socket.address.host}:${_socket.port}'; - var r = { - 'id': _servicePath, - 'type': _serviceType(ref), - 'name': name, - 'user_name': name, - }; - if (ref) { - return r; - } - try { - r['socket'] = (_socket as dynamic)._toJSON(true); - } catch (_) { - r['socket'] = { - 'id': _servicePath, - 'type': '@Socket', - 'name': 'UserSocket', - 'user_name': 'UserSocket', - }; - } - return r; - } - - static bool _isReservedStatusCode(int? code) { - return code != null && - (code < WebSocketStatus.normalClosure || - code == WebSocketStatus.reserved1004 || - code == WebSocketStatus.noStatusReceived || - code == WebSocketStatus.abnormalClosure || - (code > WebSocketStatus.internalServerError && - code < WebSocketStatus.reserved1015) || - (code >= WebSocketStatus.reserved1015 && code < 3000)); - } -} diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/async_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/async_patch.dart deleted file mode 100644 index b80c74e8975..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/async_patch.dart +++ /dev/null @@ -1,472 +0,0 @@ -// Copyright (c) 2012, 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. - -// Patch file for the dart:async library. - -import 'dart:_js_helper' show notNull, patch, ReifyFunctionTypes; -import 'dart:_isolate_helper' show TimerImpl; -import 'dart:_foreign_helper' show JS, JSExportName; -import 'dart:_runtime' as dart; - -/// This function adapts ES6 generators to implement Dart's async/await. -/// -/// It's designed to interact with Dart's Future and follow Dart async/await -/// semantics. -/// -/// See https://github.com/dart-lang/sdk/issues/27315 for ideas on reconciling -/// Dart's Future and ES6 Promise. At that point we should use native JS -/// async/await. -/// -/// Inspired by `co`: https://github.com/tj/co/blob/master/index.js, which is a -/// stepping stone for ES async/await. -@JSExportName('async') -@ReifyFunctionTypes(false) -_async(Function() initGenerator) { - var iter; - late Object? Function(Object?) onValue; - late Object Function(Object, StackTrace?) onError; - - onAwait(Object? value) { - _Future f; - if (value is _Future) { - f = value; - } else if (value is Future) { - f = _Future(); - _Future._chainForeignFuture(value, f); - } else { - f = _Future.value(value); - } - f = JS('', '#', f._thenAwait(onValue, onError)); - return f; - } - - onValue = (value) { - var iteratorResult = JS('', '#.next(#)', iter, value); - value = JS('', '#.value', iteratorResult); - return JS('!', '#.done', iteratorResult) ? value : onAwait(value); - }; - - // If the awaited Future throws, we want to convert this to an exception - // thrown from the `yield` point, as if it was thrown there. - // - // If the exception is not caught inside `gen`, it will emerge here, which - // will send it to anyone listening on this async function's Future. - // - // In essence, we are giving the code inside the generator a chance to - // use try-catch-finally. - onError = (value, stackTrace) { - var iteratorResult = JS( - '', '#.throw(#)', iter, dart.createErrorWithStack(value, stackTrace)); - value = JS('', '#.value', iteratorResult); - return JS('!', '#.done', iteratorResult) ? value : onAwait(value); - }; - - var zone = Zone.current; - if (!identical(zone, _rootZone)) { - onValue = zone.registerUnaryCallback(onValue); - onError = zone.registerBinaryCallback(onError); - } - - var asyncFuture = _Future(); - - // This will be set to true once we've yielded to the event loop. - // - // Before we've done that, we need to complete the future asynchronously to - // match dart2js/VM. See https://github.com/dart-lang/sdk/issues/33330 - // - // Once we've yielded to the event loop we can complete synchronously. - // Other implementations call this `isSync` to indicate that. - bool isRunningAsEvent = false; - runBody() { - try { - iter = JS('', '#[Symbol.iterator]()', initGenerator()); - var iteratorValue = JS('', '#.next(null)', iter); - var value = JS('', '#.value', iteratorValue); - if (JS('!', '#.done', iteratorValue)) { - // TODO(jmesserly): this is a workaround for ignored cast failures. - // Remove it once we've fixed those. We should be able to call: - // - // if (isRunningAsEvent) { - // asyncFuture._complete(value); - // } else { - // asyncFuture._asyncComplete(value); - // } - // - // But if the user code returns `Future` instead of - // `Future`, that function won't recognize it as a future and will - // instead treat it as a completed value. - if (value is Future) { - if (value is _Future) { - _Future._chainCoreFuture(value, asyncFuture); - } else { - _Future._chainForeignFuture(value, asyncFuture); - } - } else if (isRunningAsEvent) { - asyncFuture._completeWithValue(JS('', '#', value)); - } else { - asyncFuture._asyncComplete(JS('', '#', value)); - } - } else { - _Future._chainCoreFuture(onAwait(value), asyncFuture); - } - } catch (e, s) { - if (isRunningAsEvent) { - _completeWithErrorCallback(asyncFuture, e, s); - } else { - _asyncCompleteWithErrorCallback(asyncFuture, e, s); - } - } - } - - if (dart.startAsyncSynchronously) { - runBody(); - isRunningAsEvent = true; - } else { - isRunningAsEvent = true; - scheduleMicrotask(runBody); - } - return asyncFuture; -} - -@patch -class _AsyncRun { - @patch - static void _scheduleImmediate(void Function() callback) { - _scheduleImmediateClosure(callback); - } - - // Lazily initialized. - static final _scheduleImmediateClosure = _initializeScheduleImmediate(); - - static void Function(void Function()) _initializeScheduleImmediate() { - // d8 support, see preambles/d8.js for the definiton of `scheduleImmediate`. - // - // TODO(jmesserly): do we need this? It's only for our d8 stack trace test. - if (JS('', '#.scheduleImmediate', dart.global_) != null) { - return _scheduleImmediateJSOverride; - } - return _scheduleImmediateWithPromise; - } - - @ReifyFunctionTypes(false) - static void _scheduleImmediateJSOverride(void Function() callback) { - dart.addAsyncCallback(); - JS('void', '#.scheduleImmediate(#)', dart.global_, () { - dart.removeAsyncCallback(); - callback(); - }); - } - - @ReifyFunctionTypes(false) - static void _scheduleImmediateWithPromise(void Function() callback) { - dart.addAsyncCallback(); - JS('', '#.Promise.resolve(null).then(#)', dart.global_, () { - dart.removeAsyncCallback(); - callback(); - }); - } -} - -@patch -class DeferredLibrary { - @patch - Future load() { - throw 'DeferredLibrary not supported. ' - 'please use the `import "lib.dart" deferred as lib` syntax.'; - } -} - -@patch -class Timer { - @patch - static Timer _createTimer(Duration duration, void Function() callback) { - int milliseconds = duration.inMilliseconds; - if (milliseconds < 0) milliseconds = 0; - return TimerImpl(milliseconds, callback); - } - - @patch - static Timer _createPeriodicTimer( - Duration duration, void callback(Timer timer)) { - int milliseconds = duration.inMilliseconds; - if (milliseconds < 0) milliseconds = 0; - return TimerImpl.periodic(milliseconds, callback); - } -} - -@patch -void _rethrow(Object error, StackTrace stackTrace) { - JS('', 'throw #', dart.createErrorWithStack(error, stackTrace)); -} - -/// Used by the compiler to implement `async*` functions. -/// -/// This is inspired by _AsyncStarStreamController in dart-lang/sdk's -/// runtime/lib/core_patch.dart -/// -/// Given input like: -/// -/// foo() async* { -/// yield 1; -/// yield* bar(); -/// print(await baz()); -/// } -/// -/// This compiles to: -/// -/// function foo() { -/// return new (AsyncStarImplOfT()).new(function*(stream) { -/// if (stream.add(1)) return; -/// yield; -/// if (stream.addStream(bar()) return; -/// yield; -/// print(yield baz()); -/// }); -/// } -/// -class _AsyncStarImpl { - late StreamController controller; - Object Function(_AsyncStarImpl) initGenerator; - @notNull - bool isSuspendedAtYieldStar = false; - @notNull - bool onListenReceived = false; - @notNull - bool isScheduled = false; - @notNull - bool isSuspendedAtYield = false; - - /// Whether we're suspended at an `await`. - @notNull - bool isSuspendedAtAwait = false; - - Completer? cancellationCompleter; - late Object jsIterator; - - Null Function(Object, StackTrace)? _handleErrorCallback; - void Function([Object?])? _runBodyCallback; - - _AsyncStarImpl(this.initGenerator) { - controller = StreamController( - onListen: JS('!', 'this.onListen.bind(this)'), - onResume: JS('!', 'this.onResume.bind(this)'), - onCancel: JS('!', 'this.onCancel.bind(this)')); - jsIterator = JS('!', '#[Symbol.iterator]()', initGenerator(this)); - } - - /// The stream produced by this `async*` function. - Stream get stream => controller.stream; - - /// Returns the callback used for error handling. - /// - /// This callback throws the error back into the user code, at the appropriate - /// location (e.g. `await` `yield` or `yield*`). This gives user code a chance - /// to handle it try-catch. If they do not handle, the error gets routed to - /// the [stream] as an error via [addError]. - /// - /// As a performance optimization, this callback is only bound once to the - /// current [Zone]. This works because a single subscription stream should - /// always be running in its original zone. An `async*` method will always - /// save/restore the zone that was active when `listen()` was first called, - /// similar to a stream. This follows from section 16.14 of the Dart 4th - /// edition spec: - /// - /// > If `f` is marked `async*` (9), then a fresh instance `s` implementing - /// > the built-in class `Stream` is associated with the invocation and - /// > immediately returned. When `s` is listened to, execution of the body of - /// > `f` will begin. - /// - Null Function(Object, StackTrace) get handleError { - if (_handleErrorCallback == null) { - _handleErrorCallback = (error, StackTrace stackTrace) { - try { - JS('', '#.throw(#)', jsIterator, - dart.createErrorWithStack(error, stackTrace)); - } catch (e, newStack) { - // The generator didn't catch the error, or it threw a new one. - // Make sure to propagate the new error. - addError(e, newStack); - } - }; - var zone = Zone.current; - if (!identical(zone, Zone.root)) { - _handleErrorCallback = zone.bindBinaryCallback(_handleErrorCallback!); - } - } - return _handleErrorCallback!; - } - - void scheduleGenerator() { - // TODO(jmesserly): is this isPaused check in the right place? Assuming the - // async* Stream yields, then is paused (by other code), the body will - // already be scheduled. This will cause at least one more iteration to - // run (adding another data item to the Stream) before actually pausing. - // It could be fixed by moving the `isPaused` check inside `runBody`. - if (isScheduled || controller.isPaused || isSuspendedAtYieldStar) { - return; - } - isScheduled = true; - // Capture the current zone. See comment on [handleError] for more - // information about this optimization. - var zone = Zone.current; - if (_runBodyCallback == null) { - _runBodyCallback = JS('!', '#.bind(this)', runBody); - if (!identical(zone, Zone.root)) { - var registered = zone.registerUnaryCallback(_runBodyCallback!); - _runBodyCallback = ([arg]) => zone.runUnaryGuarded(registered, arg); - } - } - zone.scheduleMicrotask(_runBodyCallback!); - } - - void runBody(awaitValue) { - isScheduled = false; - isSuspendedAtYield = false; - isSuspendedAtAwait = false; - - Object iterResult; - try { - iterResult = JS('', '#.next(#)', jsIterator, awaitValue); - } catch (e, s) { - addError(e, s); - return; - } - - if (JS('!', '#.done', iterResult)) { - close(); - return; - } - - // If we're suspended at a yield/yield*, we're done for now. - if (isSuspendedAtYield || isSuspendedAtYieldStar) return; - - // Handle `await`: if we get a value passed to `yield` it means we are - // waiting on this Future. Make sure to prevent scheduling, and pass the - // value back as the result of the `yield`. - // - // TODO(jmesserly): is the timing here correct? The assumption here is - // that we should schedule `await` in `async*` the same as in `async`. - isSuspendedAtAwait = true; - FutureOr value = JS('', '#.value', iterResult); - - // TODO(jmesserly): this logic was copied from `async` function impl. - _Future f; - if (value is _Future) { - f = value; - } else if (value is Future) { - f = _Future(); - _Future._chainForeignFuture(value, f); - } else { - f = _Future.value(value); - } - f._thenAwait(_runBodyCallback!, handleError); - } - - /// Adds element to [stream] and returns true if the caller should terminate - /// execution of the generator. - /// - /// This is called from generated code like this: - /// - /// if (controller.add(1)) return; - /// yield; - // - // TODO(hausner): Per spec, the generator should be suspended before exiting - // when the stream is closed. We could add a getter like this: - // - // get isCancelled => controller.hasListener; - // - // The generator would translate a 'yield e' statement to - // - // controller.add(1); - // suspend; // this is `yield` in JS. - // if (controller.isCancelled) return; - bool add(T event) { - if (!onListenReceived) _fatal("yield before stream is listened to"); - if (isSuspendedAtYield) _fatal("unexpected yield"); - // If stream is cancelled, tell caller to exit the async generator. - if (!controller.hasListener) { - return true; - } - controller.add(event); - scheduleGenerator(); - isSuspendedAtYield = true; - return false; - } - - /// Adds the elements of [stream] into this [controller]'s stream, and returns - /// true if the caller should terminate execution of the generator. - /// - /// The generator will be scheduled again when all of the elements of the - /// added stream have been consumed. - bool addStream(Stream stream) { - if (!onListenReceived) _fatal("yield* before stream is listened to"); - // If stream is cancelled, tell caller to exit the async generator. - if (!controller.hasListener) return true; - isSuspendedAtYieldStar = true; - var whenDoneAdding = controller.addStream(stream, cancelOnError: false); - whenDoneAdding.then((_) { - isSuspendedAtYieldStar = false; - scheduleGenerator(); - if (!isScheduled) isSuspendedAtYield = true; - }, onError: handleError); - return false; - } - - void addError(Object error, StackTrace stackTrace) { - ArgumentError.checkNotNull(error, "error"); - var completer = cancellationCompleter; - if (completer != null && !completer.isCompleted) { - // If the stream has been cancelled, complete the cancellation future - // with the error. - completer.completeError(error, stackTrace); - } else if (controller.hasListener) { - controller.addError(error, stackTrace); - } - // No need to schedule the generator body here. This code is only - // called from the catch clause of the implicit try-catch-finally - // around the generator body. That is, we are on the error path out - // of the generator and do not need to run the generator again. - close(); - } - - void close() { - var completer = cancellationCompleter; - if (completer != null && !completer.isCompleted) { - // If the stream has been cancelled, complete the cancellation future - // with the error. - completer.complete(); - } - controller.close(); - } - - onListen() { - assert(!onListenReceived); - onListenReceived = true; - scheduleGenerator(); - } - - onResume() { - if (isSuspendedAtYield) { - scheduleGenerator(); - } - } - - onCancel() { - if (controller.isClosed) { - return null; - } - if (cancellationCompleter == null) { - cancellationCompleter = Completer(); - // Only resume the generator if it is suspended at a yield. - // Cancellation does not affect an async generator that is - // suspended at an await. - if (isSuspendedAtYield) { - scheduleGenerator(); - } - } - return cancellationCompleter!.future; - } - - _fatal(String message) => throw StateError(message); -} diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/collection_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/collection_patch.dart deleted file mode 100644 index d9709b9ee59..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/collection_patch.dart +++ /dev/null @@ -1,580 +0,0 @@ -// Copyright (c) 2013, 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. - -// Patch file for dart:collection classes. -import 'dart:_foreign_helper' show JS, JSExportName; -import 'dart:_runtime' as dart; -import 'dart:_interceptors' show JSArray; -import 'dart:_js_helper' - show - NoInline, - NoSideEffects, - NoThrows, - patch, - LinkedMap, - IdentityMap, - CustomHashMap, - CustomKeyHashMap, - DartIterator, - notNull, - putLinkedMapKey; - -@patch -class HashMap { - @patch - factory HashMap( - {bool Function(K, K)? equals, - int Function(K)? hashCode, - bool Function(dynamic)? isValidKey}) { - if (isValidKey == null) { - if (hashCode == null) { - if (equals == null) { - if (identical(K, String) || identical(K, int)) { - return IdentityMap(); - } - return LinkedMap(); - } - hashCode = dart.hashCode; - } else if (identical(identityHashCode, hashCode) && - identical(identical, equals)) { - return IdentityMap(); - } - return CustomHashMap(equals ?? dart.equals, hashCode); - } - return CustomKeyHashMap( - equals ?? dart.equals, hashCode ?? dart.hashCode, isValidKey); - } - - @patch - factory HashMap.identity() = IdentityMap; -} - -@patch -class LinkedHashMap { - @patch - factory LinkedHashMap( - {bool Function(K, K)? equals, - int Function(K)? hashCode, - bool Function(dynamic)? isValidKey}) { - if (isValidKey == null) { - if (hashCode == null) { - if (equals == null) { - if (identical(K, String) || identical(K, int)) { - return IdentityMap(); - } - return LinkedMap(); - } - hashCode = dart.hashCode; - } else if (identical(identityHashCode, hashCode) && - identical(identical, equals)) { - return IdentityMap(); - } - return CustomHashMap(equals ?? dart.equals, hashCode); - } - return CustomKeyHashMap( - equals ?? dart.equals, hashCode ?? dart.hashCode, isValidKey); - } - - @patch - factory LinkedHashMap.identity() = IdentityMap; -} - -@patch -class HashSet { - @patch - factory HashSet( - {bool Function(E, E)? equals, - int Function(E)? hashCode, - bool Function(dynamic)? isValidKey}) { - if (isValidKey == null) { - if (hashCode == null) { - if (equals == null) { - if (identical(E, String) || identical(E, int)) { - return _IdentityHashSet(); - } - return _HashSet(); - } - } else if (identical(identityHashCode, hashCode) && - identical(identical, equals)) { - return _IdentityHashSet(); - } - return _CustomHashSet( - equals ?? dart.equals, hashCode ?? dart.hashCode); - } - return _CustomKeyHashSet( - equals ?? dart.equals, hashCode ?? dart.hashCode, isValidKey); - } - - @patch - factory HashSet.identity() = _IdentityHashSet; -} - -@patch -class LinkedHashSet { - @patch - factory LinkedHashSet( - {bool Function(E, E)? equals, - int Function(E)? hashCode, - bool Function(dynamic)? isValidKey}) { - if (isValidKey == null) { - if (hashCode == null) { - if (equals == null) { - if (identical(E, String) || identical(E, int)) { - return _IdentityHashSet(); - } - return _HashSet(); - } - hashCode = dart.hashCode; - } else if (identical(identityHashCode, hashCode) && - identical(identical, equals)) { - return _IdentityHashSet(); - } - return _CustomHashSet(equals ?? dart.equals, hashCode); - } - return _CustomKeyHashSet( - equals ?? dart.equals, hashCode ?? dart.hashCode, isValidKey); - } - - @patch - factory LinkedHashSet.identity() = _IdentityHashSet; -} - -class _HashSet extends _InternalSet - implements HashSet, LinkedHashSet { - /// The backing store for this set. - /// - /// Keys that use identity equality are stored directly. For other types of - /// keys, we first look them up (by hashCode) in the [_keyMap] map, then - /// we lookup the key in this map. - @notNull - final _map = JS('', 'new Set()'); - - /// Items that use custom equality semantics. - /// - /// This maps from the item's hashCode to the canonical key, which is then - /// used to lookup the item in [_map]. Keeping the data in our primary backing - /// map gives us the ordering semantics requred by [LinkedHashMap], while - /// also providing convenient access to keys/values. - @notNull - final _keyMap = JS('', 'new Map()'); - - // We track the number of modifications done to the key set of the - // hash map to be able to throw when the map is modified while being - // iterated over. - // - // Value cycles after 2^30 modifications so that modification counts are - // always unboxed (Smi) values. Modification detection will be missed if you - // make exactly some multiple of 2^30 modifications between advances of an - // iterator. - @notNull - int _modifications = 0; - - _HashSet(); - - Set _newSet() => _HashSet(); - - Set _newSimilarSet() => _HashSet(); - - bool contains(Object? key) { - if (key == null) { - // Convert undefined to null, if needed. - key = null; - } else if (JS('!', '#[#] !== #', key, dart.extensionSymbol('_equals'), - dart.identityEquals)) { - @notNull - Object? k = key; - var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, k.hashCode); - if (buckets != null) { - for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) { - k = JS('', '#[#]', buckets, i); - if (k == key) return true; - } - } - return false; - } - return JS('!', '#.has(#)', _map, key); - } - - E? lookup(Object? key) { - if (key == null) return null; - if (JS('!', '#[#] !== #', key, dart.extensionSymbol('_equals'), - dart.identityEquals)) { - @notNull - Object? k = key; - var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, k.hashCode); - if (buckets != null) { - for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) { - k = JS('', '#[#]', buckets, i); - if (k == key) return JS('', '#', k); - } - } - return null; - } - return JS('', '#.has(#) ? # : null', _map, key, key); - } - - bool add(E key) { - var map = _map; - if (key == null) { - if (JS('', '#.has(null)', map)) return false; - // Convert undefined to null, if needed. - JS('', '# = null', key); - } else if (JS('!', '#[#] !== #', key, dart.extensionSymbol('_equals'), - dart.identityEquals)) { - var keyMap = _keyMap; - @notNull - var k = key; - int hash = JS('!', '# & 0x3ffffff', k.hashCode); - var buckets = JS('', '#.get(#)', keyMap, hash); - if (buckets == null) { - JS('', '#.set(#, [#])', keyMap, hash, key); - } else { - for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) { - k = JS('', '#[#]', buckets, i); - if (k == key) return false; - } - JS('', '#.push(#)', buckets, key); - } - } else if (JS('', '#.has(#)', map, key)) { - return false; - } - JS('', '#.add(#)', map, key); - _modifications = (_modifications + 1) & 0x3ffffff; - return true; - } - - void addAll(Iterable objects) { - var map = _map; - int length = JS('', '#.size', map); - for (E key in objects) { - if (key == null) { - // Convert undefined to null, if needed. - JS('', '# = null', key); - } else if (JS('!', '#[#] !== #', key, - dart.extensionSymbol('_equals'), dart.identityEquals)) { - key = putLinkedMapKey(key, _keyMap); - } - JS('', '#.add(#)', map, key); - } - if (length != JS('!', '#.size', map)) { - _modifications = (_modifications + 1) & 0x3ffffff; - } - } - - bool remove(Object? key) { - if (key == null) { - // Convert undefined to null, if needed. - key = null; - } else if (JS('!', '#[#] !== #', key, dart.extensionSymbol('_equals'), - dart.identityEquals)) { - @notNull - Object? k = key; - int hash = JS('!', '# & 0x3ffffff', k.hashCode); - var buckets = JS('', '#.get(#)', _keyMap, hash); - if (buckets == null) return false; // not found - for (int i = 0, n = JS('!', '#.length', buckets);;) { - k = JS('', '#[#]', buckets, i); - if (k == key) { - key = k; - if (n == 1) { - JS('', '#.delete(#)', _keyMap, hash); - } else { - JS('', '#.splice(#, 1)', buckets, i); - } - break; - } - if (++i >= n) return false; // not found - } - } - var map = _map; - if (JS('!', '#.delete(#)', map, key)) { - _modifications = (_modifications + 1) & 0x3ffffff; - return true; - } - return false; - } - - void clear() { - var map = _map; - if (JS('!', '#.size', map) > 0) { - JS('', '#.clear()', map); - JS('', '#.clear()', _keyMap); - _modifications = (_modifications + 1) & 0x3ffffff; - } - } -} - -// Used for DDC const sets. -class _ImmutableSet extends _HashSet { - _ImmutableSet.from(JSArray entries) { - var map = _map; - for (Object key in entries) { - if (key == null) { - // Convert undefined to null, if needed. - JS('', '# = null', key); - } else if (JS('!', '#[#] !== #', key, - dart.extensionSymbol('_equals'), dart.identityEquals)) { - key = putLinkedMapKey(key, _keyMap); - } - JS('', '#.add(#)', map, key); - } - } - - bool add(E value) => throw _unsupported(); - void addAll(Iterable elements) => throw _unsupported(); - void clear() => throw _unsupported(); - bool remove(Object? value) => throw _unsupported(); - - static Error _unsupported() => - UnsupportedError("Cannot modify unmodifiable set"); -} - -class _IdentityHashSet extends _InternalSet - implements HashSet, LinkedHashSet { - /// The backing store for this set. - @notNull - final _map = JS('', 'new Set()'); - - @notNull - int _modifications = 0; - - _IdentityHashSet(); - - Set _newSet() => _IdentityHashSet(); - - Set _newSimilarSet() => _IdentityHashSet(); - - bool contains(Object? element) { - return JS('!', '#.has(#)', _map, element); - } - - E? lookup(Object? element) { - return element is E && JS('!', '#.has(#)', _map, element) - ? element - : null; - } - - bool add(E element) { - var map = _map; - if (JS('!', '#.has(#)', map, element)) return false; - JS('', '#.add(#)', map, element); - _modifications = (_modifications + 1) & 0x3ffffff; - return true; - } - - void addAll(Iterable objects) { - var map = _map; - int length = JS('', '#.size', map); - for (E key in objects) { - JS('', '#.add(#)', map, key); - } - if (length != JS('!', '#.size', map)) { - _modifications = (_modifications + 1) & 0x3ffffff; - } - } - - bool remove(Object? element) { - if (JS('!', '#.delete(#)', _map, element)) { - _modifications = (_modifications + 1) & 0x3ffffff; - return true; - } - return false; - } - - void clear() { - var map = _map; - if (JS('!', '#.size', map) > 0) { - JS('', '#.clear()', map); - _modifications = (_modifications + 1) & 0x3ffffff; - } - } -} - -class _CustomKeyHashSet extends _CustomHashSet { - _Predicate _validKey; - _CustomKeyHashSet(_Equality equals, _Hasher hashCode, this._validKey) - : super(equals, hashCode); - - Set _newSet() => _CustomKeyHashSet(_equals, _hashCode, _validKey); - - Set _newSimilarSet() => _HashSet(); - - bool contains(Object? element) { - // TODO(jmesserly): there is a subtle difference here compared to Dart 1. - // See the comment on CustomKeyHashMap.containsKey for more information. - // Treatment of `null` is different due to strong mode's requirement to - // perform an `element is E` check before calling equals/hashCode. - if (!_validKey(element)) return false; - return super.contains(element); - } - - E? lookup(Object? element) { - if (!_validKey(element)) return null; - return super.lookup(element); - } - - bool remove(Object? element) { - if (!_validKey(element)) return false; - return super.remove(element); - } -} - -class _CustomHashSet extends _InternalSet - implements HashSet, LinkedHashSet { - _Equality _equals; - _Hasher _hashCode; - - // We track the number of modifications done to the key set of the - // hash map to be able to throw when the map is modified while being - // iterated over. - // - // Value cycles after 2^30 modifications so that modification counts are - // always unboxed (Smi) values. Modification detection will be missed if you - // make exactly some multiple of 2^30 modifications between advances of an - // iterator. - @notNull - int _modifications = 0; - - /// The backing store for this set, used to handle ordering. - // TODO(jmesserly): a non-linked custom hash set could skip this. - @notNull - final _map = JS('', 'new Set()'); - - /// Our map used to map keys onto the canonical key that is stored in [_map]. - @notNull - final _keyMap = JS('', 'new Map()'); - - _CustomHashSet(this._equals, this._hashCode); - - Set _newSet() => _CustomHashSet(_equals, _hashCode); - Set _newSimilarSet() => _HashSet(); - - bool contains(Object? key) { - if (key is E) { - var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, _hashCode(key)); - if (buckets != null) { - var equals = _equals; - for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) { - E k = JS('', '#[#]', buckets, i); - if (equals(k, key)) return true; - } - } - } - return false; - } - - E? lookup(Object? key) { - if (key is E) { - var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, _hashCode(key)); - if (buckets != null) { - var equals = _equals; - for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) { - E k = JS('', '#[#]', buckets, i); - if (equals(k, key)) return k; - } - } - } - return null; - } - - bool add(E key) { - var keyMap = _keyMap; - var hash = JS('!', '# & 0x3ffffff', _hashCode(key)); - var buckets = JS('', '#.get(#)', keyMap, hash); - if (buckets == null) { - JS('', '#.set(#, [#])', keyMap, hash, key); - } else { - var equals = _equals; - for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) { - E k = JS('', '#[#]', buckets, i); - if (equals(k, key)) return false; - } - JS('', '#.push(#)', buckets, key); - } - JS('', '#.add(#)', _map, key); - _modifications = (_modifications + 1) & 0x3ffffff; - return true; - } - - void addAll(Iterable objects) { - // TODO(jmesserly): it'd be nice to skip the covariance check here. - for (E element in objects) add(element); - } - - bool remove(Object? key) { - if (key is E) { - var hash = JS('!', '# & 0x3ffffff', _hashCode(key)); - var keyMap = _keyMap; - var buckets = JS('', '#.get(#)', keyMap, hash); - if (buckets == null) return false; // not found - var equals = _equals; - for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) { - E k = JS('', '#[#]', buckets, i); - if (equals(k, key)) { - if (n == 1) { - JS('', '#.delete(#)', keyMap, hash); - } else { - JS('', '#.splice(#, 1)', buckets, i); - } - JS('', '#.delete(#)', _map, k); - _modifications = (_modifications + 1) & 0x3ffffff; - return true; - } - } - } - return false; - } - - void clear() { - var map = _map; - if (JS('!', '#.size', map) > 0) { - JS('', '#.clear()', map); - JS('', '#.clear()', _keyMap); - _modifications = (_modifications + 1) & 0x3ffffff; - } - } -} - -/// Base class for our internal [LinkedHashSet]/[HashSet] implementations. -/// -/// This implements the common functionality. -abstract class _InternalSet extends _SetBase { - @notNull - get _map; - - @notNull - int get _modifications; - - @notNull - int get length => JS('!', '#.size', _map); - - @notNull - bool get isEmpty => JS('!', '#.size == 0', _map); - - @notNull - bool get isNotEmpty => JS('!', '#.size != 0', _map); - - Iterator get iterator => DartIterator(_jsIterator()); - - @JSExportName('Symbol.iterator') - _jsIterator() { - var self = this; - var iterator = JS('', '#.values()', self._map); - int modifications = self._modifications; - return JS( - '', - '''{ - next() { - if (# != #) { - throw #; - } - return #.next(); - } - }''', - modifications, - self._modifications, - ConcurrentModificationError(self), - iterator); - } -} diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/convert_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/convert_patch.dart deleted file mode 100644 index c86dab00de1..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/convert_patch.dart +++ /dev/null @@ -1,487 +0,0 @@ -// Copyright (c) 2013, 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. - -// Patch file for dart:convert library. - -import 'dart:_js_helper' show argumentErrorValue, patch; -import 'dart:_foreign_helper' show JS; -import 'dart:_interceptors' show JSExtendableArray; -import 'dart:_internal' show MappedIterable, ListIterable; -import 'dart:collection' show LinkedHashMap, MapBase; -import 'dart:_native_typed_data' show NativeUint8List; - -/** - * Parses [json] and builds the corresponding parsed JSON value. - * - * Parsed JSON values Nare of the types [num], [String], [bool], [Null], - * [List]s of parsed JSON values or [Map]s from [String] to parsed - * JSON values. - * - * The optional [reviver] function, if provided, is called once for each object - * or list property parsed. The arguments are the property name ([String]) or - * list index ([int]), and the value is the parsed value. The return value of - * the reviver will be used as the value of that property instead of the parsed - * value. The top level value is passed to the reviver with the empty string as - * a key. - * - * Throws [FormatException] if the input is not valid JSON text. - */ -@patch -_parseJson(String source, reviver(key, value)?) { - if (source is! String) throw argumentErrorValue(source); - - var parsed; - try { - parsed = JS('=Object|JSExtendableArray|Null|bool|num|String', - 'JSON.parse(#)', source); - } catch (e) { - throw FormatException(JS('!', 'String(#)', e)); - } - - if (reviver == null) { - return _convertJsonToDartLazy(parsed); - } else { - return _convertJsonToDart(parsed, reviver); - } -} - -/** - * Walks the raw JavaScript value [json], replacing JavaScript Objects with - * Maps. [json] is expected to be freshly allocated so elements can be replaced - * in-place. - */ -_convertJsonToDart(json, reviver(Object? key, Object? value)) { - walk(e) { - // JavaScript null, string, number, bool are in the correct representation. - if (JS('!', '# == null', e) || - JS('!', 'typeof # != "object"', e)) { - return e; - } - - // This test is needed to avoid identifying '{"__proto__":[]}' as an Array. - // TODO(sra): Replace this test with cheaper '#.constructor === Array' when - // bug 621 below is fixed. - if (JS('!', 'Object.getPrototypeOf(#) === Array.prototype', e)) { - // In-place update of the elements since JS Array is a Dart List. - for (int i = 0; i < JS('!', '#.length', e); i++) { - // Use JS indexing to avoid range checks. We know this is the only - // reference to the list, but the compiler will likely never be able to - // tell that this instance of the list cannot have its length changed by - // the reviver even though it later will be passed to the reviver at the - // outer level. - var item = JS('', '#[#]', e, i); - JS('', '#[#]=#', e, i, reviver(i, walk(item))); - } - return e; - } - - // Otherwise it is a plain object, so copy to a JSON map, so we process - // and revive all entries recursively. - _JsonMap map = _JsonMap(e); - var processed = map._processed; - List keys = map._computeKeys(); - for (int i = 0; i < keys.length; i++) { - String key = keys[i]; - var revived = reviver(key, walk(JS('', '#[#]', e, key))); - JS('', '#[#]=#', processed, key, revived); - } - - // Update the JSON map structure so future access is cheaper. - map._original = processed; // Don't keep two objects around. - return map; - } - - return reviver(null, walk(json)); -} - -_convertJsonToDartLazy(object) { - // JavaScript null and undefined are represented as null. - if (object == null) return null; - - // JavaScript string, number, bool already has the correct representation. - if (JS('!', 'typeof # != "object"', object)) { - return object; - } - - // This test is needed to avoid identifying '{"__proto__":[]}' as an array. - // TODO(sra): Replace this test with cheaper '#.constructor === Array' when - // bug https://code.google.com/p/v8/issues/detail?id=621 is fixed. - if (JS('!', 'Object.getPrototypeOf(#) !== Array.prototype', object)) { - return _JsonMap(object); - } - - // Update the elements in place since JS arrays are Dart lists. - for (int i = 0; i < JS('!', '#.length', object); i++) { - // Use JS indexing to avoid range checks. We know this is the only - // reference to the list, but the compiler will likely never be able to - // tell that this instance of the list cannot have its length changed by - // the reviver even though it later will be passed to the reviver at the - // outer level. - var item = JS('', '#[#]', object, i); - JS('', '#[#]=#', object, i, _convertJsonToDartLazy(item)); - } - return object; -} - -class _JsonMap extends MapBase { - // The original JavaScript object remains unchanged until - // the map is eventually upgraded, in which case we null it - // out to reclaim the memory used by it. - var _original; - - // We keep track of the map entries that we have already - // processed by adding them to a separate JavaScript object. - var _processed = _newJavaScriptObject(); - - // If the data slot isn't null, it represents either the list - // of keys (for non-upgraded JSON maps) or the upgraded map. - var _data = null; - - _JsonMap(this._original); - - operator [](key) { - if (_isUpgraded) { - return _upgradedMap[key]; - } else if (key is! String) { - return null; - } else { - var result = _getProperty(_processed, key); - if (_isUnprocessed(result)) result = _process(key); - return result; - } - } - - int get length => _isUpgraded ? _upgradedMap.length : _computeKeys().length; - - bool get isEmpty => length == 0; - bool get isNotEmpty => length > 0; - - Iterable get keys { - if (_isUpgraded) return _upgradedMap.keys; - return _JsonMapKeyIterable(this); - } - - Iterable get values { - if (_isUpgraded) return _upgradedMap.values; - return MappedIterable(_computeKeys(), (each) => this[each]); - } - - operator []=(key, value) { - if (_isUpgraded) { - _upgradedMap[key] = value; - } else if (containsKey(key)) { - var processed = _processed; - _setProperty(processed, key, value); - var original = _original; - if (!identical(original, processed)) { - _setProperty(original, key, null); // Reclaim memory. - } - } else { - _upgrade()[key] = value; - } - } - - void addAll(Map other) { - other.forEach((key, value) { - this[key] = value; - }); - } - - bool containsValue(value) { - if (_isUpgraded) return _upgradedMap.containsValue(value); - List keys = _computeKeys(); - for (int i = 0; i < keys.length; i++) { - String key = keys[i]; - if (this[key] == value) return true; - } - return false; - } - - bool containsKey(key) { - if (_isUpgraded) return _upgradedMap.containsKey(key); - if (key is! String) return false; - return _hasProperty(_original, key); - } - - putIfAbsent(key, ifAbsent()) { - if (containsKey(key)) return this[key]; - var value = ifAbsent(); - this[key] = value; - return value; - } - - remove(Object? key) { - if (!_isUpgraded && !containsKey(key)) return null; - return _upgrade().remove(key); - } - - void clear() { - if (_isUpgraded) { - _upgradedMap.clear(); - } else { - if (_data != null) { - // Clear the list of keys to make sure we force - // a concurrent modification error if anyone is - // currently iterating over it. - _data.clear(); - } - _original = _processed = null; - _data = {}; - } - } - - void forEach(void f(String key, value)) { - if (_isUpgraded) return _upgradedMap.forEach(f); - List keys = _computeKeys(); - for (int i = 0; i < keys.length; i++) { - String key = keys[i]; - - // Compute the value under the assumption that the property - // is present but potentially not processed. - var value = _getProperty(_processed, key); - if (_isUnprocessed(value)) { - value = _convertJsonToDartLazy(_getProperty(_original, key)); - _setProperty(_processed, key, value); - } - - // Do the callback. - f(key, value); - - // Check if invoking the callback function changed - // the key set. If so, throw an exception. - if (!identical(keys, _data)) { - throw ConcurrentModificationError(this); - } - } - } - - // ------------------------------------------ - // Private helper methods. - // ------------------------------------------ - - bool get _isUpgraded => _processed == null; - - Map get _upgradedMap { - assert(_isUpgraded); - // 'cast' the union type to LinkedHashMap. It would be even better if we - // could 'cast' to the implementation type, since LinkedHashMap includes - // _JsonMap. - return JS('LinkedHashMap', '#', _data); - } - - List _computeKeys() { - assert(!_isUpgraded); - List? keys = _data; - if (keys == null) { - keys = _data = _getPropertyNames(_original); - } - return JS('JSExtendableArray', '#', keys); - } - - Map _upgrade() { - if (_isUpgraded) return _upgradedMap; - - // Copy all the (key, value) pairs to a freshly allocated - // linked hash map thus preserving the ordering. - var result = {}; - List keys = _computeKeys(); - for (int i = 0; i < keys.length; i++) { - String key = keys[i]; - result[key] = this[key]; - } - - // We only upgrade when we need to extend the map, so we can - // safely force a concurrent modification error in case - // someone is iterating over the map here. - if (keys.isEmpty) { - keys.add(""); - } else { - keys.clear(); - } - - // Clear out the associated JavaScript objects and mark the - // map as having been upgraded. - _original = _processed = null; - _data = result; - assert(_isUpgraded); - return result; - } - - _process(String key) { - if (!_hasProperty(_original, key)) return null; - var result = _convertJsonToDartLazy(_getProperty(_original, key)); - return _setProperty(_processed, key, result); - } - - // ------------------------------------------ - // Private JavaScript helper methods. - // ------------------------------------------ - - static bool _hasProperty(object, String key) => - JS('!', 'Object.prototype.hasOwnProperty.call(#,#)', object, key); - static _getProperty(object, String key) => JS('', '#[#]', object, key); - static _setProperty(object, String key, value) => - JS('', '#[#]=#', object, key, value); - static List _getPropertyNames(object) => - JS('JSExtendableArray', 'Object.keys(#)', object); - static bool _isUnprocessed(object) => - JS('!', 'typeof(#)=="undefined"', object); - static _newJavaScriptObject() => JS('=Object', 'Object.create(null)'); -} - -class _JsonMapKeyIterable extends ListIterable { - final _JsonMap _parent; - - _JsonMapKeyIterable(this._parent); - - int get length => _parent.length; - - String elementAt(int index) { - return _parent._isUpgraded - ? _parent.keys.elementAt(index) - : _parent._computeKeys()[index]; - } - - /// Although [ListIterable] defines its own iterator, we return the iterator - /// of the underlying list [_keys] in order to propagate - /// [ConcurrentModificationError]s. - Iterator get iterator { - return _parent._isUpgraded - ? _parent.keys.iterator - : _parent._computeKeys().iterator; - } - - /// Delegate to [parent.containsKey] to ensure the performance expected - /// from [Map.keys.containsKey]. - bool contains(Object? key) => _parent.containsKey(key); -} - -@patch -class JsonDecoder { - @patch - StringConversionSink startChunkedConversion(Sink sink) { - return _JsonDecoderSink(_reviver, sink); - } -} - -/** - * Implements the chunked conversion from a JSON string to its corresponding - * object. - * - * The sink only creates one object, but its input can be chunked. - */ -// TODO(floitsch): don't accumulate everything before starting to decode. -class _JsonDecoderSink extends _StringSinkConversionSink { - final Object? Function(Object? key, Object? value)? _reviver; - final Sink _sink; - - _JsonDecoderSink(this._reviver, this._sink) : super(StringBuffer('')); - - void close() { - super.close(); - String accumulated = _stringSink.toString(); - _stringSink.clear(); - Object? decoded = _parseJson(accumulated, _reviver); - _sink.add(decoded); - _sink.close(); - } -} - -@patch -class Utf8Decoder { - // Always fall back to the Dart implementation for strings shorter than this - // threshold, as there is a large, constant overhead for using TextDecoder. - static const int _shortInputThreshold = 15; - - @patch - Converter, T> fuse(Converter next) { - return super.fuse(next); - } - - // Currently not intercepting UTF8 decoding. - @patch - static String? _convertIntercepted( - bool allowMalformed, List codeUnits, int start, int? end) { - // Test `codeUnits is NativeUint8List`. Dart's NativeUint8List is - // implemented by JavaScript's Uint8Array. - if (JS('!', '# instanceof Uint8Array', codeUnits)) { - // JS 'cast' to avoid a downcast equivalent to the is-check we hand-coded. - NativeUint8List casted = JS('!', '#', codeUnits); - // Always use Dart implementation for short strings. - end ??= casted.length; - if (end - start < _shortInputThreshold) { - return null; - } - String? result = - _convertInterceptedUint8List(allowMalformed, casted, start, end); - if (result != null && allowMalformed) { - // In principle, TextDecoder should have provided the correct result - // here, but some browsers deviate from the standard as to how many - // replacement characters they produce. Thus, we fall back to the Dart - // implementation if the result contains any replacement characters. - if (JS('int', r'#.indexOf(#)', result, '\uFFFD') >= 0) { - return null; - } - } - return result; - } - return null; // This call was not intercepted. - } - - static String? _convertInterceptedUint8List( - bool allowMalformed, NativeUint8List codeUnits, int start, int end) { - final decoder = allowMalformed ? _decoderNonfatal : _decoder; - if (decoder == null) return null; - if (0 == start && end == codeUnits.length) { - return _useTextDecoder(decoder, codeUnits); - } - - int length = codeUnits.length; - end = RangeError.checkValidRange(start, end, length); - - return _useTextDecoder(decoder, - JS('!', '#.subarray(#, #)', codeUnits, start, end)); - } - - static String? _useTextDecoder(decoder, NativeUint8List codeUnits) { - // If the input is malformed, catch the exception and return `null` to fall - // back on unintercepted decoder. The fallback will either succeed in - // decoding, or report the problem better than TextDecoder. - try { - return JS('!', '#.decode(#)', decoder, codeUnits); - } catch (e) {} - return null; - } - - // TextDecoder is not defined on some browsers and on the stand-alone d8 and - // jsshell engines. Use a lazy initializer to do feature detection once. - static final _decoder = () { - try { - return JS('', 'new TextDecoder("utf-8", {fatal: true})'); - } catch (e) {} - return null; - }(); - static final _decoderNonfatal = () { - try { - return JS('', 'new TextDecoder("utf-8", {fatal: false})'); - } catch (e) {} - return null; - }(); -} - -@patch -class _Utf8Decoder { - @patch - _Utf8Decoder(this.allowMalformed) : _state = beforeBom; - - @patch - String convertSingle(List codeUnits, int start, int? maybeEnd) { - return convertGeneral(codeUnits, start, maybeEnd, true); - } - - @patch - String convertChunked(List codeUnits, int start, int? maybeEnd) { - return convertGeneral(codeUnits, start, maybeEnd, false); - } -} diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/core_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/core_patch.dart deleted file mode 100644 index 2171a9f1e7e..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/core_patch.dart +++ /dev/null @@ -1,3015 +0,0 @@ -// Copyright (c) 2012, 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. - -// Patch file for dart:core classes. -import "dart:_internal" as _symbol_dev; -import 'dart:_interceptors'; -import 'dart:_js_helper' - show - patch, - checkInt, - getRuntimeType, - LinkedMap, - JSSyntaxRegExp, - NoInline, - notNull, - nullCheck, - Primitives, - PrivateSymbol, - quoteStringForRegExp, - undefined; -import 'dart:_runtime' as dart; -import 'dart:_foreign_helper' show JS, JSExportName; -import 'dart:_native_typed_data' show NativeUint8List; -import 'dart:collection' show UnmodifiableMapView; -import 'dart:convert' show Encoding, utf8; -import 'dart:typed_data' show Endian, Uint8List, Uint16List; - -String _symbolToString(Symbol symbol) => symbol is PrivateSymbol - ? PrivateSymbol.getName(symbol) - : _symbol_dev.Symbol.getName(symbol as _symbol_dev.Symbol); - -@patch -int identityHashCode(Object? object) { - if (object == null) return 0; - // Note: this works for primitives because we define the `identityHashCode` - // for them to be equivalent to their computed hashCode function. - int? hash = JS('int|Null', r'#[#]', object, dart.identityHashCode_); - if (hash == null) { - hash = JS('!', '(Math.random() * 0x3fffffff) | 0'); - JS('void', r'#[#] = #', object, dart.identityHashCode_, hash); - } - return JS('!', '#', hash); -} - -// Patch for Object implementation. -@patch -class Object { - @patch - bool operator ==(Object other) => identical(this, other); - - @patch - int get hashCode => identityHashCode(this); - - @patch - String toString() => - "Instance of '${dart.typeName(dart.getReifiedType(this))}'"; - - @patch - dynamic noSuchMethod(Invocation invocation) { - return dart.defaultNoSuchMethod(this, invocation); - } - - @patch - Type get runtimeType => dart.wrapType(dart.getReifiedType(this)); - - // Everything is an Object. - @JSExportName('is') - static bool _is_Object(Object? o) => o != null; - - @JSExportName('as') - static Object? _as_Object(Object? o) => - o == null ? dart.cast(o, dart.unwrapType(Object)) : o; -} - -@patch -class Null { - @patch - int get hashCode => super.hashCode; - - @JSExportName('is') - static bool _is_Null(Object? o) => o == null; - - @JSExportName('as') - static Object? _as_Null(Object? o) { - // Avoid extra function call to core.Null.is() by manually inlining. - if (o == null) return o; - return dart.cast(o, dart.unwrapType(Null)); - } -} - -// Patch for Function implementation. -@patch -class Function { - @patch - static apply(Function function, List? positionalArguments, - [Map? namedArguments]) { - positionalArguments ??= []; - // dcall expects the namedArguments as a JS map in the last slot. - if (namedArguments != null && namedArguments.isNotEmpty) { - var map = JS('', '{}'); - namedArguments.forEach((symbol, arg) { - JS('', '#[#] = #', map, _symbolToString(symbol), arg); - }); - return dart.dcall(function, positionalArguments, map); - } - return dart.dcall(function, positionalArguments); - } - - static Map _toMangledNames( - Map namedArguments) { - Map result = {}; - namedArguments.forEach((symbol, value) { - result[_symbolToString(symbol)] = value; - }); - return result; - } - - @JSExportName('is') - static bool _is_Function(Object? o) => - JS('!', 'typeof $o == "function"'); - - @JSExportName('as') - static Object? _as_Function(Object? o) { - // Avoid extra function call to core.Function.is() by manually inlining. - if (JS('!', 'typeof $o == "function"')) return o; - return dart.cast(o, dart.unwrapType(Function)); - } -} - -// TODO(jmesserly): switch to WeakMap -// Patch for Expando implementation. -@patch -class Expando { - @patch - Expando([String? name]) : this.name = name; - - @patch - T? operator [](Object object) { - var values = Primitives.getProperty(object, _EXPANDO_PROPERTY_NAME); - return (values == null) - ? null - : Primitives.getProperty(values, _getKey()) as T?; - } - - @patch - void operator []=(Object object, T? value) { - var values = Primitives.getProperty(object, _EXPANDO_PROPERTY_NAME); - if (values == null) { - values = Object(); - Primitives.setProperty(object, _EXPANDO_PROPERTY_NAME, values); - } - Primitives.setProperty(values, _getKey(), value); - } - - String _getKey() { - var key = Primitives.getProperty(this, _KEY_PROPERTY_NAME) as String?; - if (key == null) { - key = "expando\$key\$${_keyCount++}"; - Primitives.setProperty(this, _KEY_PROPERTY_NAME, key); - } - return key; - } - - static const String _KEY_PROPERTY_NAME = 'expando\$key'; - static const String _EXPANDO_PROPERTY_NAME = 'expando\$values'; - static int _keyCount = 0; -} - -@patch -class int { - @patch - static int parse(String source, - {int? radix, @deprecated int onError(String source)?}) { - var value = tryParse(source, radix: radix); - if (value != null) return value; - if (onError != null) return onError(source); - throw new FormatException(source); - } - - @patch - static int? tryParse(String source, {int? radix}) { - return Primitives.parseInt(source, radix); - } - - @patch - factory int.fromEnvironment(String name, {int defaultValue = 0}) { - // ignore: const_constructor_throws_exception - throw UnsupportedError( - 'int.fromEnvironment can only be used as a const constructor'); - } - - @JSExportName('is') - static bool _is_int(Object? o) { - return JS('!', 'typeof $o == "number" && Math.floor($o) == $o'); - } - - @JSExportName('as') - static Object? _as_int(Object? o) { - // Avoid extra function call to core.int.is() by manually inlining. - if (JS('!', '(typeof $o == "number" && Math.floor($o) == $o)')) { - return o; - } - return dart.cast(o, dart.unwrapType(int)); - } -} - -@patch -class double { - @patch - static double parse(String source, - [@deprecated double onError(String source)?]) { - var value = tryParse(source); - if (value != null) return value; - if (onError != null) return onError(source); - throw new FormatException('Invalid double', source); - } - - @patch - static double? tryParse(String source) { - return Primitives.parseDouble(source); - } - - @JSExportName('is') - static bool _is_double(Object? o) { - return JS('!', 'typeof $o == "number"'); - } - - @JSExportName('as') - static Object? _as_double(Object? o) { - // Avoid extra function call to core.double.is() by manually inlining. - if (JS('!', 'typeof $o == "number"')) return o; - return dart.cast(o, dart.unwrapType(double)); - } -} - -@patch -abstract class num implements Comparable { - @JSExportName('is') - static bool _is_num(Object? o) { - return JS('!', 'typeof $o == "number"'); - } - - @JSExportName('as') - static Object? _as_num(Object? o) { - // Avoid extra function call to core.num.is() by manually inlining. - if (JS('!', 'typeof $o == "number"')) return o; - return dart.cast(o, dart.unwrapType(num)); - } -} - -@patch -class BigInt implements Comparable { - @patch - static BigInt get zero => _BigIntImpl.zero; - @patch - static BigInt get one => _BigIntImpl.one; - @patch - static BigInt get two => _BigIntImpl.two; - - @patch - static BigInt parse(String source, {int? radix}) => - _BigIntImpl.parse(source, radix: radix); - - @patch - static BigInt? tryParse(String source, {int? radix}) => - _BigIntImpl._tryParse(source, radix: radix); - - @patch - factory BigInt.from(num value) = _BigIntImpl.from; -} - -@patch -class Error { - @patch - static String _objectToString(Object object) { - return "Instance of '${dart.typeName(dart.getReifiedType(object))}'"; - } - - @patch - static String _stringToSafeString(String string) { - return JS("String", "JSON.stringify(#)", string); - } - - @patch - StackTrace? get stackTrace => dart.stackTraceForError(this); -} - -@patch -class FallThroughError { - @patch - FallThroughError._create(String url, int line); - - @patch - String toString() => super.toString(); -} - -@patch -class AbstractClassInstantiationError { - @patch - String toString() => "Cannot instantiate abstract class: '$_className'"; -} - -// Patch for DateTime implementation. -@patch -class DateTime { - @patch - DateTime.fromMillisecondsSinceEpoch(int millisecondsSinceEpoch, - {bool isUtc = false}) - : this._withValue(millisecondsSinceEpoch, isUtc: isUtc); - - @patch - DateTime.fromMicrosecondsSinceEpoch(int microsecondsSinceEpoch, - {bool isUtc = false}) - : this._withValue( - _microsecondInRoundedMilliseconds(microsecondsSinceEpoch), - isUtc: isUtc); - - @patch - DateTime._internal(int year, int month, int day, int hour, int minute, - int second, int millisecond, int microsecond, bool isUtc) - : isUtc = isUtc, - _value = checkInt(Primitives.valueFromDecomposedDate( - year, - month, - day, - hour, - minute, - second, - millisecond + _microsecondInRoundedMilliseconds(microsecond), - isUtc)); - - @patch - DateTime._now() - : isUtc = false, - _value = Primitives.dateNow(); - - /// Rounds the given [microsecond] to the nearest milliseconds value. - /// - /// For example, invoked with argument `2600` returns `3`. - static int _microsecondInRoundedMilliseconds(int microsecond) { - return (microsecond / 1000).round(); - } - - @patch - static int? _brokenDownDateToValue(int year, int month, int day, int hour, - int minute, int second, int millisecond, int microsecond, bool isUtc) { - return Primitives.valueFromDecomposedDate( - year, - month, - day, - hour, - minute, - second, - millisecond + _microsecondInRoundedMilliseconds(microsecond), - isUtc); - } - - @patch - String get timeZoneName { - if (isUtc) return "UTC"; - return Primitives.getTimeZoneName(this); - } - - @patch - Duration get timeZoneOffset { - if (isUtc) return Duration.zero; - return Duration(minutes: Primitives.getTimeZoneOffsetInMinutes(this)); - } - - @patch - DateTime add(Duration duration) { - return DateTime._withValue(_value + duration.inMilliseconds, isUtc: isUtc); - } - - @patch - DateTime subtract(Duration duration) { - return DateTime._withValue(_value - duration.inMilliseconds, isUtc: isUtc); - } - - @patch - Duration difference(DateTime other) { - return Duration(milliseconds: _value - other._value); - } - - @patch - int get millisecondsSinceEpoch => _value; - - @patch - int get microsecondsSinceEpoch => _value * 1000; - - @patch - int get year => Primitives.getYear(this); - - @patch - int get month => Primitives.getMonth(this); - - @patch - int get day => Primitives.getDay(this); - - @patch - int get hour => Primitives.getHours(this); - - @patch - int get minute => Primitives.getMinutes(this); - - @patch - int get second => Primitives.getSeconds(this); - - @patch - int get millisecond => Primitives.getMilliseconds(this); - - @patch - int get microsecond => 0; - - @patch - int get weekday => Primitives.getWeekday(this); - - @patch - bool operator ==(Object other) => - other is DateTime && - _value == other.millisecondsSinceEpoch && - isUtc == other.isUtc; - - @patch - bool isBefore(DateTime other) => _value < other.millisecondsSinceEpoch; - - @patch - bool isAfter(DateTime other) => _value > other.millisecondsSinceEpoch; - - @patch - bool isAtSameMomentAs(DateTime other) => - _value == other.millisecondsSinceEpoch; - - @patch - int compareTo(DateTime other) => - _value.compareTo(other.millisecondsSinceEpoch); -} - -// Patch for Stopwatch implementation. -@patch -class Stopwatch { - @patch - static int _initTicker() { - Primitives.initTicker(); - return Primitives.timerFrequency; - } - - @patch - static int _now() => Primitives.timerTicks(); - - @patch - int get elapsedMicroseconds { - int ticks = elapsedTicks; - if (_frequency == 1000000) return ticks; - assert(_frequency == 1000); - return ticks * 1000; - } - - @patch - int get elapsedMilliseconds { - int ticks = elapsedTicks; - if (_frequency == 1000) return ticks; - assert(_frequency == 1000000); - return ticks ~/ 1000; - } -} - -// Patch for List implementation. -@patch -class List { - @patch - factory List([@undefined int? length]) { - dynamic list; - if (JS('!', '# === void 0', length)) { - list = JS('', '[]'); - } else { - int _length = JS('!', '#', length); - if (length == null || _length < 0) { - throw ArgumentError("Length must be a non-negative integer: $_length"); - } - list = JS('', 'new Array(#)', _length); - JS('', '#.fill(null)', list); - JSArray.markFixedList(list); - } - return JSArray.of(list); - } - - @patch - factory List.empty({bool growable = false}) { - var list = JSArray.of(JS('', 'new Array()')); - if (!growable) JSArray.markFixedList(list); - return list; - } - - @patch - factory List.filled(@nullCheck int length, E fill, {bool growable = false}) { - var list = JSArray.of(JS('', 'new Array(#)', length)); - JS('', '#.fill(#)', list, fill); - if (!growable) JSArray.markFixedList(list); - return list; - } - - @patch - factory List.from(Iterable elements, {bool growable = true}) { - var list = JSArray.of(JS('', '[]')); - // Specialize the copy loop for the case that doesn't need a - // runtime check. - if (elements is Iterable) { - for (var e in elements) { - list.add(e); - } - } else { - for (var e in elements) { - list.add(e as E); - } - } - if (!growable) JSArray.markFixedList(list); - return list; - } - - @patch - factory List.of(Iterable elements, {bool growable = true}) { - // TODO(32937): Specialize to benefit from known element type. - return List.from(elements, growable: growable); - } - - @patch - factory List.generate(int length, E generator(int index), - {bool growable = true}) { - final result = JSArray.of(JS('', 'new Array(#)', length)); - if (!growable) JSArray.markFixedList(result); - for (int i = 0; i < length; i++) { - result[i] = generator(i); - } - return result; - } - - @patch - factory List.unmodifiable(Iterable elements) { - var list = List.from(elements); - JSArray.markUnmodifiableList(list); - return list; - } -} - -@patch -class Map { - @patch - factory Map.unmodifiable(Map other) { - return UnmodifiableMapView(Map.from(other)); - } - - @patch - factory Map() = LinkedMap; -} - -@patch -class String { - @patch - factory String.fromCharCodes(Iterable charCodes, - [int start = 0, int? end]) { - if (charCodes is JSArray) { - return _stringFromJSArray(charCodes, start, end); - } - if (charCodes is NativeUint8List) { - return _stringFromUint8List(charCodes, start, end); - } - return _stringFromIterable(charCodes, start, end); - } - - @patch - factory String.fromCharCode(int charCode) { - return Primitives.stringFromCharCode(charCode); - } - - @patch - factory String.fromEnvironment(String name, {String defaultValue = ""}) { - // ignore: const_constructor_throws_exception - throw UnsupportedError( - 'String.fromEnvironment can only be used as a const constructor'); - } - - static String _stringFromJSArray( - /*=JSArray*/ list, - int start, - int? endOrNull) { - int len = list.length; - int end = RangeError.checkValidRange(start, endOrNull, len); - if (start > 0 || end < len) { - list = list.sublist(start, end); - } - return Primitives.stringFromCharCodes(list); - } - - static String _stringFromUint8List( - NativeUint8List charCodes, int start, int? endOrNull) { - int len = charCodes.length; - int end = RangeError.checkValidRange(start, endOrNull, len); - return Primitives.stringFromNativeUint8List(charCodes, start, end); - } - - static String _stringFromIterable( - Iterable charCodes, int start, int? end) { - if (start < 0) throw RangeError.range(start, 0, charCodes.length); - if (end != null && end < start) { - throw RangeError.range(end, start, charCodes.length); - } - var it = charCodes.iterator; - for (int i = 0; i < start; i++) { - if (!it.moveNext()) { - throw RangeError.range(start, 0, i); - } - } - var list = JSArray.of(JS('', 'new Array()')); - if (end == null) { - while (it.moveNext()) list.add(it.current); - } else { - for (int i = start; i < end; i++) { - if (!it.moveNext()) { - throw RangeError.range(end, start, i); - } - list.add(it.current); - } - } - return Primitives.stringFromCharCodes(list); - } - - @JSExportName('is') - static bool _is_String(Object? o) { - return JS('!', 'typeof $o == "string"'); - } - - @JSExportName('as') - static Object? _as_String(Object? o) { - // Avoid extra function call to core.String.is() by manually inlining. - if (JS('!', 'typeof $o == "string"')) return o; - return dart.cast(o, dart.unwrapType(String)); - } -} - -@patch -class bool { - @patch - factory bool.fromEnvironment(String name, {bool defaultValue = false}) { - // ignore: const_constructor_throws_exception - throw UnsupportedError( - 'bool.fromEnvironment can only be used as a const constructor'); - } - - @patch - factory bool.hasEnvironment(String name) { - // ignore: const_constructor_throws_exception - throw UnsupportedError( - 'bool.hasEnvironment can only be used as a const constructor'); - } - - @patch - int get hashCode => super.hashCode; - - @JSExportName('is') - static bool _is_bool(Object? o) => - JS('!', '$o === true || $o === false'); - - @JSExportName('as') - static Object? _as_bool(Object? o) { - // Avoid extra function call to core.bool.is() by manually inlining. - if (JS("!", '$o === true || $o === false')) return o; - return dart.cast(o, dart.unwrapType(bool)); - } -} - -@patch -class RegExp { - @patch - factory RegExp(String source, - {bool multiLine = false, - bool caseSensitive = true, - bool unicode = false, - bool dotAll = false}) => - JSSyntaxRegExp(source, - multiLine: multiLine, - caseSensitive: caseSensitive, - unicode: unicode, - dotAll: dotAll); - - @patch - static String escape(String text) => quoteStringForRegExp(text); -} - -// Patch for 'identical' function. -@patch -bool identical(Object? a, Object? b) { - return JS('!', '(# == null ? # == null : # === #)', a, b, a, b); -} - -@patch -class StringBuffer { - String _contents; - - @patch - StringBuffer([Object content = ""]) : _contents = '$content'; - - @patch - int get length => _contents.length; - - @patch - void write(Object? obj) { - _writeString('$obj'); - } - - @patch - void writeCharCode(int charCode) { - _writeString(String.fromCharCode(charCode)); - } - - @patch - void writeAll(Iterable objects, [String separator = ""]) { - _contents = _writeAll(_contents, objects, separator); - } - - @patch - void writeln([Object? obj = ""]) { - _writeString('$obj\n'); - } - - @patch - void clear() { - _contents = ""; - } - - @patch - String toString() => Primitives.flattenString(_contents); - - void _writeString(String str) { - _contents = Primitives.stringConcatUnchecked(_contents, str); - } - - static String _writeAll(String string, Iterable objects, String separator) { - Iterator iterator = objects.iterator; - if (!iterator.moveNext()) return string; - if (separator.isEmpty) { - do { - string = _writeOne(string, iterator.current); - } while (iterator.moveNext()); - } else { - string = _writeOne(string, iterator.current); - while (iterator.moveNext()) { - string = _writeOne(string, separator); - string = _writeOne(string, iterator.current); - } - } - return string; - } - - static String _writeOne(String string, Object? obj) { - return Primitives.stringConcatUnchecked(string, '$obj'); - } -} - -// TODO(jmesserly): kernel expects to find this in our SDK. -class _CompileTimeError extends Error { - final String _errorMsg; - _CompileTimeError(this._errorMsg); - String toString() => _errorMsg; -} - -@patch -class NoSuchMethodError { - final Object? _receiver; - final Symbol _memberName; - final List? _arguments; - final Map? _namedArguments; - final Invocation? _invocation; - - @patch - NoSuchMethodError(Object? receiver, Symbol memberName, - List? positionalArguments, Map? namedArguments) - : _receiver = receiver, - _memberName = memberName, - _arguments = positionalArguments, - _namedArguments = namedArguments, - _invocation = null; - - @patch - NoSuchMethodError.withInvocation(Object? receiver, Invocation invocation) - : _receiver = receiver, - _memberName = invocation.memberName, - _arguments = invocation.positionalArguments, - _namedArguments = invocation.namedArguments, - _invocation = invocation; - - @patch - String toString() { - StringBuffer sb = StringBuffer(''); - String comma = ''; - var arguments = _arguments; - if (arguments != null) { - for (var argument in arguments) { - sb.write(comma); - sb.write(Error.safeToString(argument)); - comma = ', '; - } - } - var namedArguments = _namedArguments; - if (namedArguments != null) { - namedArguments.forEach((Symbol key, var value) { - sb.write(comma); - sb.write(_symbolToString(key)); - sb.write(": "); - sb.write(Error.safeToString(value)); - comma = ', '; - }); - } - String memberName = _symbolToString(_memberName); - String receiverText = Error.safeToString(_receiver); - String actualParameters = '$sb'; - var invocation = _invocation; - var failureMessage = (invocation is dart.InvocationImpl) - ? invocation.failureMessage - : 'method not found'; - return "NoSuchMethodError: '$memberName'\n" - "$failureMessage\n" - "Receiver: ${receiverText}\n" - "Arguments: [$actualParameters]"; - } -} - -@patch -class Uri { - @patch - static Uri get base { - String uri = Primitives.currentUri(); - if (uri != null) return Uri.parse(uri); - throw UnsupportedError("'Uri.base' is not supported"); - } -} - -@patch -class _Uri { - @patch - static bool get _isWindows => _isWindowsCached; - - static final bool _isWindowsCached = JS( - 'bool', - 'typeof process != "undefined" && ' - 'Object.prototype.toString.call(process) == "[object process]" && ' - 'process.platform == "win32"'); - - // Matches a String that _uriEncodes to itself regardless of the kind of - // component. This corresponds to [_unreservedTable], i.e. characters that - // are not encoded by any encoding table. - static final RegExp _needsNoEncoding = RegExp(r'^[\-\.0-9A-Z_a-z~]*$'); - - /** - * This is the internal implementation of JavaScript's encodeURI function. - * It encodes all characters in the string [text] except for those - * that appear in [canonicalTable], and returns the escaped string. - */ - @patch - static String _uriEncode(List canonicalTable, String text, - Encoding encoding, bool spaceToPlus) { - if (identical(encoding, utf8) && _needsNoEncoding.hasMatch(text)) { - return text; - } - - // Encode the string into bytes then generate an ASCII only string - // by percent encoding selected bytes. - StringBuffer result = StringBuffer(''); - var bytes = encoding.encode(text); - for (int i = 0; i < bytes.length; i++) { - int byte = bytes[i]; - if (byte < 128 && - ((canonicalTable[byte >> 4] & (1 << (byte & 0x0f))) != 0)) { - result.writeCharCode(byte); - } else if (spaceToPlus && byte == _SPACE) { - result.write('+'); - } else { - const String hexDigits = '0123456789ABCDEF'; - result.write('%'); - result.write(hexDigits[(byte >> 4) & 0x0f]); - result.write(hexDigits[byte & 0x0f]); - } - } - return result.toString(); - } -} - -@patch -class StackTrace { - @patch - @NoInline() - static StackTrace get current { - return dart.stackTrace(JS('', 'Error()')); - } -} - -// TODO(jmesserly): this class is supposed to be obsolete in Strong Mode, but -// the front-end crashes without it -class _DuplicatedFieldInitializerError { - final String _name; - - _DuplicatedFieldInitializerError(this._name); - - toString() => "Error: field '$_name' is already initialized."; -} - -// TODO(jmesserly): The rest of this core_patch.dart source should reside in an -// included part file instead of being inlined. However, part files are not -// properly supported here. - -// Copyright (c) 2017, 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. - -// part of dart.core; - -int _max(int a, int b) => a > b ? a : b; -int _min(int a, int b) => a < b ? a : b; - -/// Empty list used as an initializer for local variables in the `_BigIntImpl`. -final _dummyList = new Uint16List(0); - -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -/* - * Copyright (c) 2003-2005 Tom Wu - * Copyright (c) 2012 Adam Singer (adam@solvr.io) - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL, - * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER - * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF - * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * In addition, the following condition applies: - * - * All redistributions must retain an intact copy of this copyright notice - * and disclaimer. - */ - -/** - * An implementation for the arbitrarily large integer. - * - * The integer number is represented by a sign, an array of 16-bit unsigned - * integers in little endian format, and a number of used digits in that array. - */ -class _BigIntImpl implements BigInt { - // Bits per digit. - static const int _digitBits = 16; - static const int _digitBase = 1 << _digitBits; - static const int _digitMask = (1 << _digitBits) - 1; - - static final _BigIntImpl zero = _BigIntImpl._fromInt(0); - static final _BigIntImpl one = _BigIntImpl._fromInt(1); - static final _BigIntImpl two = _BigIntImpl._fromInt(2); - - static final _BigIntImpl _minusOne = -one; - static final _BigIntImpl _bigInt10000 = _BigIntImpl._fromInt(10000); - - // Result cache for last _divRem call. - // Result cache for last _divRem call. - static Uint16List? _lastDividendDigits; - static int? _lastDividendUsed; - static Uint16List? _lastDivisorDigits; - static int? _lastDivisorUsed; - static Uint16List? _lastQuoRemDigits; - static int? _lastQuoRemUsed; - static int? _lastRemUsed; - static int? _lastRem_nsh; - - /// Whether this bigint is negative. - final bool _isNegative; - - /// The unsigned digits of this bigint. - /// - /// The least significant digit is in slot 0. - /// The list may have more digits than needed. That is, `_digits.length` may - /// be strictly greater than `_used`. - final Uint16List _digits; - - /// The number of used entries in [_digits]. - /// - /// To avoid reallocating [Uint16List]s, lists that are too big are not - /// replaced. - final int _used; - - /** - * Parses [source] as a, possibly signed, integer literal and returns its - * value. - * - * The [source] must be a non-empty sequence of base-[radix] digits, - * optionally prefixed with a minus or plus sign ('-' or '+'). - * - * The [radix] must be in the range 2..36. The digits used are - * first the decimal digits 0..9, and then the letters 'a'..'z' with - * values 10 through 35. Also accepts upper-case letters with the same - * values as the lower-case ones. - * - * If no [radix] is given then it defaults to 10. In this case, the [source] - * digits may also start with `0x`, in which case the number is interpreted - * as a hexadecimal literal, which effectively means that the `0x` is ignored - * and the radix is instead set to 16. - * - * For any int `n` and radix `r`, it is guaranteed that - * `n == int.parse(n.toRadixString(r), radix: r)`. - * - * Throws a [FormatException] if the [source] is not a valid integer literal, - * optionally prefixed by a sign. - */ - static _BigIntImpl parse(String source, {int? radix}) { - var result = _tryParse(source, radix: radix); - if (result == null) { - throw FormatException("Could not parse BigInt", source); - } - return result; - } - - /// Parses a decimal bigint literal. - /// - /// The [source] must not contain leading or trailing whitespace. - static _BigIntImpl _parseDecimal(String source, bool isNegative) { - const _0 = 48; - - int part = 0; - _BigIntImpl result = zero; - // Read in the source 4 digits at a time. - // The first part may have a few leading virtual '0's to make the remaining - // parts all have exactly 4 digits. - var digitInPartCount = 4 - source.length.remainder(4); - if (digitInPartCount == 4) digitInPartCount = 0; - for (int i = 0; i < source.length; i++) { - part = part * 10 + source.codeUnitAt(i) - _0; - if (++digitInPartCount == 4) { - result = result * _bigInt10000 + _BigIntImpl._fromInt(part); - part = 0; - digitInPartCount = 0; - } - } - if (isNegative) return -result; - return result; - } - - /// Returns the value of a given source digit. - /// - /// Source digits between "0" and "9" (inclusive) return their decimal value. - /// - /// Source digits between "a" and "z", or "A" and "Z" (inclusive) return - /// 10 + their position in the ASCII alphabet. - /// - /// The incoming [codeUnit] must be an ASCII code-unit. - static int _codeUnitToRadixValue(int codeUnit) { - // We know that the characters must be ASCII as otherwise the - // regexp wouldn't have matched. Lowercasing by doing `| 0x20` is thus - // guaranteed to be a safe operation, since it preserves digits - // and lower-cases ASCII letters. - const int _0 = 48; - const int _9 = 57; - const int _a = 97; - if (_0 <= codeUnit && codeUnit <= _9) return codeUnit - _0; - codeUnit |= 0x20; - var result = codeUnit - _a + 10; - return result; - } - - /// Parses the given [source] string, starting at [startPos], as a hex - /// literal. - /// - /// If [isNegative] is true, negates the result before returning it. - /// - /// The [source] (substring) must be a valid hex literal. - static _BigIntImpl? _parseHex(String source, int startPos, bool isNegative) { - int hexDigitsPerChunk = _digitBits ~/ 4; - int sourceLength = source.length - startPos; - int chunkCount = (sourceLength / hexDigitsPerChunk).ceil(); - var digits = Uint16List(chunkCount); - - int lastDigitLength = sourceLength - (chunkCount - 1) * hexDigitsPerChunk; - int digitIndex = digits.length - 1; - int i = startPos; - int chunk = 0; - for (int j = 0; j < lastDigitLength; j++) { - var digitValue = _codeUnitToRadixValue(source.codeUnitAt(i++)); - if (digitValue >= 16) return null; - chunk = chunk * 16 + digitValue; - } - digits[digitIndex--] = chunk; - - while (i < source.length) { - chunk = 0; - for (int j = 0; j < hexDigitsPerChunk; j++) { - var digitValue = _codeUnitToRadixValue(source.codeUnitAt(i++)); - if (digitValue >= 16) return null; - chunk = chunk * 16 + digitValue; - } - digits[digitIndex--] = chunk; - } - if (digits.length == 1 && digits[0] == 0) return zero; - return _BigIntImpl._(isNegative, digits.length, digits); - } - - /// Parses the given [source] as a [radix] literal. - /// - /// The [source] will be checked for invalid characters. If it is invalid, - /// this function returns `null`. - static _BigIntImpl? _parseRadix(String source, int radix, bool isNegative) { - var result = zero; - var base = _BigIntImpl._fromInt(radix); - for (int i = 0; i < source.length; i++) { - var digitValue = _codeUnitToRadixValue(source.codeUnitAt(i)); - if (digitValue >= radix) return null; - result = result * base + _BigIntImpl._fromInt(digitValue); - } - if (isNegative) return -result; - return result; - } - - /// Tries to parse the given [source] as a [radix] literal. - /// - /// Returns the parsed big integer, or `null` if it failed. - /// - /// If the [radix] is `null` accepts decimal literals or `0x` hex literals. - static _BigIntImpl? _tryParse(String source, {int? radix}) { - if (source == "") return null; - - var match = _parseRE.firstMatch(source); - int signIndex = 1; - int hexIndex = 3; - int decimalIndex = 4; - int nonDecimalHexIndex = 5; - if (match == null) return null; - - bool isNegative = match[signIndex] == "-"; - - String? decimalMatch = match[decimalIndex]; - String? hexMatch = match[hexIndex]; - String? nonDecimalMatch = match[nonDecimalHexIndex]; - - if (radix == null) { - if (decimalMatch != null) { - // Cannot fail because we know that the digits are all decimal. - return _parseDecimal(decimalMatch, isNegative); - } - if (hexMatch != null) { - // Cannot fail because we know that the digits are all hex. - return _parseHex(hexMatch, 2, isNegative); - } - return null; - } - - if (radix < 2 || radix > 36) { - throw RangeError.range(radix, 2, 36, 'radix'); - } - if (radix == 10 && decimalMatch != null) { - return _parseDecimal(decimalMatch, isNegative); - } - if (radix == 16 && (decimalMatch != null || nonDecimalMatch != null)) { - return _parseHex(decimalMatch ?? nonDecimalMatch!, 0, isNegative); - } - - return _parseRadix( - decimalMatch ?? nonDecimalMatch ?? hexMatch!, radix, isNegative); - } - - static RegExp _parseRE = RegExp( - r'^\s*([+-]?)((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$', - caseSensitive: false); - - /// Finds the amount significant digits in the provided [digits] array. - static int _normalize(int used, Uint16List digits) { - while (used > 0 && digits[used - 1] == 0) used--; - return used; - } - - /// Factory returning an instance initialized with the given field values. - /// If the [digits] array contains leading 0s, the [used] value is adjusted - /// accordingly. The [digits] array is not modified. - _BigIntImpl._(bool isNegative, int used, Uint16List digits) - : this._normalized(isNegative, _normalize(used, digits), digits); - - _BigIntImpl._normalized(bool isNegative, this._used, this._digits) - : _isNegative = _used == 0 ? false : isNegative; - - /// Whether this big integer is zero. - bool get _isZero => _used == 0; - - /// Allocates an array of the given [length] and copies the [digits] in the - /// range [from] to [to-1], starting at index 0, followed by leading zero - /// digits. - static Uint16List _cloneDigits( - Uint16List digits, int from, int to, int length) { - var resultDigits = Uint16List(length); - var n = to - from; - for (var i = 0; i < n; i++) { - resultDigits[i] = digits[from + i]; - } - return resultDigits; - } - - /// Allocates a big integer from the provided [value] number. - factory _BigIntImpl.from(num value) { - if (value == 0) return zero; - if (value == 1) return one; - if (value == 2) return two; - - // Given this order dart2js will use the `_fromInt` for smaller value and - // then use the bit-manipulating `_fromDouble` for all other values. - if (value.abs() < 0x100000000) return _BigIntImpl._fromInt(value.toInt()); - if (value is double) return _BigIntImpl._fromDouble(value); - return _BigIntImpl._fromInt(value as int); - } - - factory _BigIntImpl._fromInt(int value) { - bool isNegative = value < 0; - assert(_digitBits == 16); - if (isNegative) { - // Handle the min 64-bit value differently, since its negation is not - // positive. - const int minInt64 = -0x80000000 * 0x100000000; - if (value == minInt64) { - var digits = Uint16List(4); - digits[3] = 0x8000; - return _BigIntImpl._(true, 4, digits); - } - value = -value; - } - if (value < _digitBase) { - var digits = Uint16List(1); - digits[0] = value; - return _BigIntImpl._(isNegative, 1, digits); - } - if (value <= 0xFFFFFFFF) { - var digits = Uint16List(2); - digits[0] = value & _digitMask; - digits[1] = value >> _digitBits; - return _BigIntImpl._(isNegative, 2, digits); - } - - var bits = value.bitLength; - var digits = Uint16List((bits - 1) ~/ _digitBits + 1); - var i = 0; - while (value != 0) { - digits[i++] = value & _digitMask; - value = value ~/ _digitBase; - } - return _BigIntImpl._(isNegative, digits.length, digits); - } - - /// An 8-byte Uint8List we can reuse for [_fromDouble] to avoid generating - /// garbage. - static final Uint8List _bitsForFromDouble = Uint8List(8); - - factory _BigIntImpl._fromDouble(double value) { - const int exponentBias = 1075; - - if (value.isNaN || value.isInfinite) { - throw ArgumentError("Value must be finite: $value"); - } - bool isNegative = value < 0; - if (isNegative) value = -value; - - value = value.floorToDouble(); - if (value == 0) return zero; - - var bits = _bitsForFromDouble; - for (int i = 0; i < 8; i++) { - bits[i] = 0; - } - bits.buffer.asByteData().setFloat64(0, value, Endian.little); - // The exponent is in bits 53..63. - var biasedExponent = (bits[7] << 4) + (bits[6] >> 4); - var exponent = biasedExponent - exponentBias; - - assert(_digitBits == 16); - // The significant bits are in 0 .. 52. - var unshiftedDigits = Uint16List(4); - unshiftedDigits[0] = (bits[1] << 8) + bits[0]; - unshiftedDigits[1] = (bits[3] << 8) + bits[2]; - unshiftedDigits[2] = (bits[5] << 8) + bits[4]; - // Don't forget to add the hidden bit. - unshiftedDigits[3] = 0x10 | (bits[6] & 0xF); - - var unshiftedBig = _BigIntImpl._normalized(false, 4, unshiftedDigits); - _BigIntImpl absResult = unshiftedBig; - if (exponent < 0) { - absResult = unshiftedBig >> -exponent; - } else if (exponent > 0) { - absResult = unshiftedBig << exponent; - } - if (isNegative) return -absResult; - return absResult; - } - - /** - * Return the negative value of this integer. - * - * The result of negating an integer always has the opposite sign, except - * for zero, which is its own negation. - */ - _BigIntImpl operator -() { - if (_used == 0) return this; - return _BigIntImpl._(!_isNegative, _used, _digits); - } - - /** - * Returns the absolute value of this integer. - * - * For any integer `x`, the result is the same as `x < 0 ? -x : x`. - */ - _BigIntImpl abs() => _isNegative ? -this : this; - - /// Returns this << n *_DIGIT_BITS. - _BigIntImpl _dlShift(int n) { - final used = _used; - if (used == 0) { - return zero; - } - final resultUsed = used + n; - final digits = _digits; - final resultDigits = Uint16List(resultUsed); - for (int i = used - 1; i >= 0; i--) { - resultDigits[i + n] = digits[i]; - } - return _BigIntImpl._(_isNegative, resultUsed, resultDigits); - } - - /// Same as [_dlShift] but works on the decomposed big integers. - /// - /// Returns `resultUsed`. - /// - /// `resultDigits[0..resultUsed-1] = xDigits[0..xUsed-1] << n*_DIGIT_BITS`. - static int _dlShiftDigits( - Uint16List xDigits, int xUsed, int n, Uint16List resultDigits) { - if (xUsed == 0) { - return 0; - } - if (n == 0 && identical(resultDigits, xDigits)) { - return xUsed; - } - final resultUsed = xUsed + n; - for (int i = xUsed - 1; i >= 0; i--) { - resultDigits[i + n] = xDigits[i]; - } - for (int i = n - 1; i >= 0; i--) { - resultDigits[i] = 0; - } - return resultUsed; - } - - /// Returns `this >> n*_DIGIT_BITS`. - _BigIntImpl _drShift(int n) { - final used = _used; - if (used == 0) { - return zero; - } - final resultUsed = used - n; - if (resultUsed <= 0) { - return _isNegative ? _minusOne : zero; - } - final digits = _digits; - final resultDigits = Uint16List(resultUsed); - for (var i = n; i < used; i++) { - resultDigits[i - n] = digits[i]; - } - final result = _BigIntImpl._(_isNegative, resultUsed, resultDigits); - if (_isNegative) { - // Round down if any bit was shifted out. - for (var i = 0; i < n; i++) { - if (digits[i] != 0) { - return result - one; - } - } - } - return result; - } - - /// Shifts the digits of [xDigits] into the right place in [resultDigits]. - /// - /// `resultDigits[ds..xUsed+ds] = xDigits[0..xUsed-1] << (n % _DIGIT_BITS)` - /// where `ds = n ~/ _DIGIT_BITS` - /// - /// Does *not* clear digits below ds. - static void _lsh( - Uint16List xDigits, int xUsed, int n, Uint16List resultDigits) { - assert(xUsed > 0); - final digitShift = n ~/ _digitBits; - final bitShift = n % _digitBits; - final carryBitShift = _digitBits - bitShift; - final bitMask = (1 << carryBitShift) - 1; - var carry = 0; - for (int i = xUsed - 1; i >= 0; i--) { - final digit = xDigits[i]; - resultDigits[i + digitShift + 1] = (digit >> carryBitShift) | carry; - carry = (digit & bitMask) << bitShift; - } - resultDigits[digitShift] = carry; - } - - /** - * Shift the bits of this integer to the left by [shiftAmount]. - * - * Shifting to the left makes the number larger, effectively multiplying - * the number by `pow(2, shiftIndex)`. - * - * There is no limit on the size of the result. It may be relevant to - * limit intermediate values by using the "and" operator with a suitable - * mask. - * - * It is an error if [shiftAmount] is negative. - */ - _BigIntImpl operator <<(int shiftAmount) { - if (shiftAmount < 0) { - throw ArgumentError("shift-amount must be posititve $shiftAmount"); - } - if (_isZero) return this; - final digitShift = shiftAmount ~/ _digitBits; - final bitShift = shiftAmount % _digitBits; - if (bitShift == 0) { - return _dlShift(digitShift); - } - var resultUsed = _used + digitShift + 1; - var resultDigits = Uint16List(resultUsed); - _lsh(_digits, _used, shiftAmount, resultDigits); - return _BigIntImpl._(_isNegative, resultUsed, resultDigits); - } - - // resultDigits[0..resultUsed-1] = xDigits[0..xUsed-1] << n. - // Returns resultUsed. - static int _lShiftDigits( - Uint16List xDigits, int xUsed, int n, Uint16List resultDigits) { - final digitsShift = n ~/ _digitBits; - final bitShift = n % _digitBits; - if (bitShift == 0) { - return _dlShiftDigits(xDigits, xUsed, digitsShift, resultDigits); - } - var resultUsed = xUsed + digitsShift + 1; - _lsh(xDigits, xUsed, n, resultDigits); - var i = digitsShift; - while (--i >= 0) { - resultDigits[i] = 0; - } - if (resultDigits[resultUsed - 1] == 0) { - resultUsed--; // Clamp result. - } - return resultUsed; - } - - // resultDigits[0..resultUsed-1] = xDigits[0..xUsed-1] >> n. - static void _rsh( - Uint16List xDigits, int xUsed, int n, Uint16List resultDigits) { - assert(xUsed > 0); - final digitsShift = n ~/ _digitBits; - final bitShift = n % _digitBits; - final carryBitShift = _digitBits - bitShift; - final bitMask = (1 << bitShift) - 1; - var carry = xDigits[digitsShift] >> bitShift; - final last = xUsed - digitsShift - 1; - for (var i = 0; i < last; i++) { - final digit = xDigits[i + digitsShift + 1]; - resultDigits[i] = ((digit & bitMask) << carryBitShift) | carry; - carry = digit >> bitShift; - } - resultDigits[last] = carry; - } - - /** - * Shift the bits of this integer to the right by [shiftAmount]. - * - * Shifting to the right makes the number smaller and drops the least - * significant bits, effectively doing an integer division by - *`pow(2, shiftIndex)`. - * - * It is an error if [shiftAmount] is negative. - */ - _BigIntImpl operator >>(int shiftAmount) { - if (shiftAmount < 0) { - throw ArgumentError("shift-amount must be posititve $shiftAmount"); - } - if (_isZero) return this; - final digitShift = shiftAmount ~/ _digitBits; - final bitShift = shiftAmount % _digitBits; - if (bitShift == 0) { - return _drShift(digitShift); - } - final used = _used; - final resultUsed = used - digitShift; - if (resultUsed <= 0) { - return _isNegative ? _minusOne : zero; - } - final digits = _digits; - final resultDigits = Uint16List(resultUsed); - _rsh(digits, used, shiftAmount, resultDigits); - final result = _BigIntImpl._(_isNegative, resultUsed, resultDigits); - if (_isNegative) { - // Round down if any bit was shifted out. - if ((digits[digitShift] & ((1 << bitShift) - 1)) != 0) { - return result - one; - } - for (var i = 0; i < digitShift; i++) { - if (digits[i] != 0) { - return result - one; - } - } - } - return result; - } - - /// Compares this to [other] taking the absolute value of both operands. - /// - /// Returns 0 if abs(this) == abs(other); a positive number if - /// abs(this) > abs(other); and a negative number if abs(this) < abs(other). - int _absCompare(_BigIntImpl other) { - return _compareDigits(_digits, _used, other._digits, other._used); - } - - /** - * Compares this to `other`. - * - * Returns a negative number if `this` is less than `other`, zero if they are - * equal, and a positive number if `this` is greater than `other`. - */ - int compareTo(covariant _BigIntImpl other) { - if (_isNegative == other._isNegative) { - var result = _absCompare(other); - // Use 0 - result to avoid negative zero in JavaScript. - return _isNegative ? 0 - result : result; - } - return _isNegative ? -1 : 1; - } - - /// Compares `digits[0..used-1]` with `otherDigits[0..otherUsed-1]`. - /// - /// Returns 0 if equal; a positive number if larger; - /// and a negative number if smaller. - static int _compareDigits( - Uint16List digits, int used, Uint16List otherDigits, int otherUsed) { - var result = used - otherUsed; - if (result == 0) { - for (int i = used - 1; i >= 0; i--) { - result = digits[i] - otherDigits[i]; - if (result != 0) return result; - } - } - return result; - } - - // resultDigits[0..used] = digits[0..used-1] + otherDigits[0..otherUsed-1]. - // used >= otherUsed > 0. - static void _absAdd(Uint16List digits, int used, Uint16List otherDigits, - int otherUsed, Uint16List resultDigits) { - assert(used >= otherUsed && otherUsed > 0); - var carry = 0; - for (var i = 0; i < otherUsed; i++) { - carry += digits[i] + otherDigits[i]; - resultDigits[i] = carry & _digitMask; - carry >>= _digitBits; - } - for (var i = otherUsed; i < used; i++) { - carry += digits[i]; - resultDigits[i] = carry & _digitMask; - carry >>= _digitBits; - } - resultDigits[used] = carry; - } - - // resultDigits[0..used-1] = digits[0..used-1] - otherDigits[0..otherUsed-1]. - // used >= otherUsed > 0. - static void _absSub(Uint16List digits, int used, Uint16List otherDigits, - int otherUsed, Uint16List resultDigits) { - assert(used >= otherUsed && otherUsed > 0); - - var carry = 0; - for (var i = 0; i < otherUsed; i++) { - carry += digits[i] - otherDigits[i]; - resultDigits[i] = carry & _digitMask; - // Dart2js only supports unsigned shifts. - // Since the carry can only be -1 or 0 use this hack. - carry = 0 - ((carry >> _digitBits) & 1); - } - for (var i = otherUsed; i < used; i++) { - carry += digits[i]; - resultDigits[i] = carry & _digitMask; - // Dart2js only supports unsigned shifts. - // Since the carry can only be -1 or 0 use this hack. - carry = 0 - ((carry >> _digitBits) & 1); - } - } - - /// Returns `abs(this) + abs(other)` with sign set according to [isNegative]. - _BigIntImpl _absAddSetSign(_BigIntImpl other, bool isNegative) { - var used = _used; - var otherUsed = other._used; - if (used < otherUsed) { - return other._absAddSetSign(this, isNegative); - } - if (used == 0) { - assert(!isNegative); - return zero; - } - if (otherUsed == 0) { - return _isNegative == isNegative ? this : -this; - } - var resultUsed = used + 1; - var resultDigits = Uint16List(resultUsed); - _absAdd(_digits, used, other._digits, otherUsed, resultDigits); - return _BigIntImpl._(isNegative, resultUsed, resultDigits); - } - - /// Returns `abs(this) - abs(other)` with sign set according to [isNegative]. - /// - /// Requirement: `abs(this) >= abs(other)`. - _BigIntImpl _absSubSetSign(_BigIntImpl other, bool isNegative) { - assert(_absCompare(other) >= 0); - var used = _used; - if (used == 0) { - assert(!isNegative); - return zero; - } - var otherUsed = other._used; - if (otherUsed == 0) { - return _isNegative == isNegative ? this : -this; - } - var resultDigits = Uint16List(used); - _absSub(_digits, used, other._digits, otherUsed, resultDigits); - return _BigIntImpl._(isNegative, used, resultDigits); - } - - /// Returns `abs(this) & abs(other)` with sign set according to [isNegative]. - _BigIntImpl _absAndSetSign(_BigIntImpl other, bool isNegative) { - var resultUsed = _min(_used, other._used); - var digits = _digits; - var otherDigits = other._digits; - var resultDigits = Uint16List(resultUsed); - for (var i = 0; i < resultUsed; i++) { - resultDigits[i] = digits[i] & otherDigits[i]; - } - return _BigIntImpl._(isNegative, resultUsed, resultDigits); - } - - /// Returns `abs(this) &~ abs(other)` with sign set according to [isNegative]. - _BigIntImpl _absAndNotSetSign(_BigIntImpl other, bool isNegative) { - var resultUsed = _used; - var digits = _digits; - var otherDigits = other._digits; - var resultDigits = Uint16List(resultUsed); - var m = _min(resultUsed, other._used); - for (var i = 0; i < m; i++) { - resultDigits[i] = digits[i] & ~otherDigits[i]; - } - for (var i = m; i < resultUsed; i++) { - resultDigits[i] = digits[i]; - } - return _BigIntImpl._(isNegative, resultUsed, resultDigits); - } - - /// Returns `abs(this) | abs(other)` with sign set according to [isNegative]. - _BigIntImpl _absOrSetSign(_BigIntImpl other, bool isNegative) { - var used = _used; - var otherUsed = other._used; - var resultUsed = _max(used, otherUsed); - var digits = _digits; - var otherDigits = other._digits; - var resultDigits = Uint16List(resultUsed); - _BigIntImpl l; - int m; - if (used < otherUsed) { - l = other; - m = used; - } else { - l = this; - m = otherUsed; - } - for (var i = 0; i < m; i++) { - resultDigits[i] = digits[i] | otherDigits[i]; - } - var lDigits = l._digits; - for (var i = m; i < resultUsed; i++) { - resultDigits[i] = lDigits[i]; - } - return _BigIntImpl._(isNegative, resultUsed, resultDigits); - } - - /// Returns `abs(this) ^ abs(other)` with sign set according to [isNegative]. - _BigIntImpl _absXorSetSign(_BigIntImpl other, bool isNegative) { - var used = _used; - var otherUsed = other._used; - var resultUsed = _max(used, otherUsed); - var digits = _digits; - var otherDigits = other._digits; - var resultDigits = Uint16List(resultUsed); - _BigIntImpl l; - int m; - if (used < otherUsed) { - l = other; - m = used; - } else { - l = this; - m = otherUsed; - } - for (var i = 0; i < m; i++) { - resultDigits[i] = digits[i] ^ otherDigits[i]; - } - var lDigits = l._digits; - for (var i = m; i < resultUsed; i++) { - resultDigits[i] = lDigits[i]; - } - return _BigIntImpl._(isNegative, resultUsed, resultDigits); - } - - /** - * Bit-wise and operator. - * - * Treating both `this` and [other] as sufficiently large two's component - * integers, the result is a number with only the bits set that are set in - * both `this` and [other] - * - * Of both operands are negative, the result is negative, otherwise - * the result is non-negative. - */ - _BigIntImpl operator &(covariant _BigIntImpl other) { - if (_isZero || other._isZero) return zero; - if (_isNegative == other._isNegative) { - if (_isNegative) { - // (-this) & (-other) == ~(this-1) & ~(other-1) - // == ~((this-1) | (other-1)) - // == -(((this-1) | (other-1)) + 1) - _BigIntImpl this1 = _absSubSetSign(one, true); - _BigIntImpl other1 = other._absSubSetSign(one, true); - // Result cannot be zero if this and other are negative. - return this1._absOrSetSign(other1, true)._absAddSetSign(one, true); - } - return _absAndSetSign(other, false); - } - // _isNegative != other._isNegative - _BigIntImpl p, n; - if (_isNegative) { - p = other; - n = this; - } else { - // & is symmetric. - p = this; - n = other; - } - // p & (-n) == p & ~(n-1) == p &~ (n-1) - var n1 = n._absSubSetSign(one, false); - return p._absAndNotSetSign(n1, false); - } - - /** - * Bit-wise or operator. - * - * Treating both `this` and [other] as sufficiently large two's component - * integers, the result is a number with the bits set that are set in either - * of `this` and [other] - * - * If both operands are non-negative, the result is non-negative, - * otherwise the result us negative. - */ - _BigIntImpl operator |(covariant _BigIntImpl other) { - if (_isZero) return other; - if (other._isZero) return this; - if (_isNegative == other._isNegative) { - if (_isNegative) { - // (-this) | (-other) == ~(this-1) | ~(other-1) - // == ~((this-1) & (other-1)) - // == -(((this-1) & (other-1)) + 1) - var this1 = _absSubSetSign(one, true); - var other1 = other._absSubSetSign(one, true); - // Result cannot be zero if this and a are negative. - return this1._absAndSetSign(other1, true)._absAddSetSign(one, true); - } - return _absOrSetSign(other, false); - } - // _neg != a._neg - _BigIntImpl p, n; - if (_isNegative) { - p = other; - n = this; - } else { - // | is symmetric. - p = this; - n = other; - } - // p | (-n) == p | ~(n-1) == ~((n-1) &~ p) == -(~((n-1) &~ p) + 1) - var n1 = n._absSubSetSign(one, true); - // Result cannot be zero if only one of this or a is negative. - return n1._absAndNotSetSign(p, true)._absAddSetSign(one, true); - } - - /** - * Bit-wise exclusive-or operator. - * - * Treating both `this` and [other] as sufficiently large two's component - * integers, the result is a number with the bits set that are set in one, - * but not both, of `this` and [other] - * - * If the operands have the same sign, the result is non-negative, - * otherwise the result is negative. - */ - _BigIntImpl operator ^(covariant _BigIntImpl other) { - if (_isZero) return other; - if (other._isZero) return this; - if (_isNegative == other._isNegative) { - if (_isNegative) { - // (-this) ^ (-other) == ~(this-1) ^ ~(other-1) == (this-1) ^ (other-1) - var this1 = _absSubSetSign(one, true); - var other1 = other._absSubSetSign(one, true); - return this1._absXorSetSign(other1, false); - } - return _absXorSetSign(other, false); - } - // _isNegative != a._isNegative - _BigIntImpl p, n; - if (_isNegative) { - p = other; - n = this; - } else { - // ^ is symmetric. - p = this; - n = other; - } - // p ^ (-n) == p ^ ~(n-1) == ~(p ^ (n-1)) == -((p ^ (n-1)) + 1) - var n1 = n._absSubSetSign(one, true); - // Result cannot be zero if only one of this or a is negative. - return p._absXorSetSign(n1, true)._absAddSetSign(one, true); - } - - /** - * The bit-wise negate operator. - * - * Treating `this` as a sufficiently large two's component integer, - * the result is a number with the opposite bits set. - * - * This maps any integer `x` to `-x - 1`. - */ - _BigIntImpl operator ~() { - if (_isZero) return _minusOne; - if (_isNegative) { - // ~(-this) == ~(~(this-1)) == this-1 - return _absSubSetSign(one, false); - } - // ~this == -this-1 == -(this+1) - // Result cannot be zero if this is positive. - return _absAddSetSign(one, true); - } - - /// Addition operator. - _BigIntImpl operator +(covariant _BigIntImpl other) { - if (_isZero) return other; - if (other._isZero) return this; - var isNegative = _isNegative; - if (isNegative == other._isNegative) { - // this + other == this + other - // (-this) + (-other) == -(this + other) - return _absAddSetSign(other, isNegative); - } - // this + (-other) == this - other == -(this - other) - // (-this) + other == other - this == -(this - other) - if (_absCompare(other) >= 0) { - return _absSubSetSign(other, isNegative); - } - return other._absSubSetSign(this, !isNegative); - } - - /// Subtraction operator. - _BigIntImpl operator -(covariant _BigIntImpl other) { - if (_isZero) return -other; - if (other._isZero) return this; - var isNegative = _isNegative; - if (isNegative != other._isNegative) { - // this - (-other) == this + other - // (-this) - other == -(this + other) - return _absAddSetSign(other, isNegative); - } - // this - other == this - a == -(this - other) - // (-this) - (-other) == other - this == -(this - other) - if (_absCompare(other) >= 0) { - return _absSubSetSign(other, isNegative); - } - return other._absSubSetSign(this, !isNegative); - } - - /// Multiplies [x] with [multiplicandDigits] and adds the result to - /// [accumulatorDigits]. - /// - /// The [multiplicandDigits] in the range [i] to [i]+[n]-1 are the - /// multiplicand digits. - /// - /// The [acculumatorDigits] in the range [j] to [j]+[n]-1 are the accumulator - /// digits. - /// - /// Adds the result of the multiplicand-digits * [x] to the accumulator. - /// - /// Concretely: `accumulatorDigits[j..j+n] += x * m_digits[i..i+n-1]`. - static void _mulAdd(int x, Uint16List multiplicandDigits, int i, - Uint16List accumulatorDigits, int j, int n) { - if (x == 0) { - // No-op if x is 0. - return; - } - int c = 0; - while (--n >= 0) { - int product = x * multiplicandDigits[i++]; - int combined = product + accumulatorDigits[j] + c; - accumulatorDigits[j++] = combined & _digitMask; - // Note that this works with 53 bits, as the division will not lose - // bits. - c = combined ~/ _digitBase; - } - while (c != 0) { - int l = accumulatorDigits[j] + c; - accumulatorDigits[j++] = l & _digitMask; - c = l ~/ _digitBase; - } - } - - /// Multiplication operator. - _BigIntImpl operator *(covariant _BigIntImpl other) { - var used = _used; - var otherUsed = other._used; - if (used == 0 || otherUsed == 0) { - return zero; - } - var resultUsed = used + otherUsed; - var digits = _digits; - var otherDigits = other._digits; - var resultDigits = Uint16List(resultUsed); - var i = 0; - while (i < otherUsed) { - _mulAdd(otherDigits[i], digits, 0, resultDigits, i, used); - i++; - } - return _BigIntImpl._( - _isNegative != other._isNegative, resultUsed, resultDigits); - } - - // r_digits[0..rUsed-1] = xDigits[0..xUsed-1]*otherDigits[0..otherUsed-1]. - // Return resultUsed = xUsed + otherUsed. - static int _mulDigits(Uint16List xDigits, int xUsed, Uint16List otherDigits, - int otherUsed, Uint16List resultDigits) { - var resultUsed = xUsed + otherUsed; - var i = resultUsed; - assert(resultDigits.length >= i); - while (--i >= 0) { - resultDigits[i] = 0; - } - i = 0; - while (i < otherUsed) { - _mulAdd(otherDigits[i], xDigits, 0, resultDigits, i, xUsed); - i++; - } - return resultUsed; - } - - /// Returns an estimate of `digits[i-1..i] ~/ topDigitDivisor`. - static int _estimateQuotientDigit( - int topDigitDivisor, Uint16List digits, int i) { - if (digits[i] == topDigitDivisor) return _digitMask; - var quotientDigit = - (digits[i] << _digitBits | digits[i - 1]) ~/ topDigitDivisor; - if (quotientDigit > _digitMask) return _digitMask; - return quotientDigit; - } - - /// Returns `trunc(this / other)`, with `other != 0`. - _BigIntImpl _div(_BigIntImpl other) { - assert(other._used > 0); - if (_used < other._used) { - return zero; - } - _divRem(other); - // Return quotient, i.e. - // _lastQuoRem_digits[_lastRem_used.._lastQuoRem_used-1] with proper sign. - var lastQuo_used = _lastQuoRemUsed! - _lastRemUsed!; - var quo_digits = _cloneDigits( - _lastQuoRemDigits!, _lastRemUsed!, _lastQuoRemUsed!, lastQuo_used); - var quo = _BigIntImpl._(false, lastQuo_used, quo_digits); - if ((_isNegative != other._isNegative) && (quo._used > 0)) { - quo = -quo; - } - return quo; - } - - /// Returns `this - other * trunc(this / other)`, with `other != 0`. - _BigIntImpl _rem(_BigIntImpl other) { - assert(other._used > 0); - if (_used < other._used) { - return this; - } - _divRem(other); - // Return remainder, i.e. - // denormalized _lastQuoRem_digits[0.._lastRem_used-1] with proper sign. - var remDigits = - _cloneDigits(_lastQuoRemDigits!, 0, _lastRemUsed!, _lastRemUsed!); - var rem = _BigIntImpl._(false, _lastRemUsed!, remDigits); - if (_lastRem_nsh! > 0) { - rem = rem >> _lastRem_nsh!; // Denormalize remainder. - } - if (_isNegative && (rem._used > 0)) { - rem = -rem; - } - return rem; - } - - /// Computes this ~/ other and this.remainder(other). - /// - /// Stores the result in [_lastQuoRemDigits], [_lastQuoRemUsed] and - /// [_lastRemUsed]. The [_lastQuoRemDigits] contains the digits of *both*, the - /// quotient and the remainder. - /// - /// Caches the input to avoid doing the work again when users write - /// `a ~/ b` followed by a `a % b`. - void _divRem(_BigIntImpl other) { - // Check if result is already cached. - if ((this._used == _lastDividendUsed) && - (other._used == _lastDivisorUsed) && - identical(this._digits, _lastDividendDigits) && - identical(other._digits, _lastDivisorDigits)) { - return; - } - assert(_used >= other._used); - - var nsh = _digitBits - other._digits[other._used - 1].bitLength; - // Concatenated positive quotient and normalized positive remainder. - // The resultDigits can have at most one more digit than the dividend. - Uint16List resultDigits; - int resultUsed; - // Normalized positive divisor. - // The normalized divisor has the most-significant bit of its most - // significant digit set. - // This makes estimating the quotient easier. - Uint16List yDigits; - int yUsed; - if (nsh > 0) { - yDigits = Uint16List(other._used + 5); - yUsed = _lShiftDigits(other._digits, other._used, nsh, yDigits); - resultDigits = Uint16List(_used + 5); - resultUsed = _lShiftDigits(_digits, _used, nsh, resultDigits); - } else { - yDigits = other._digits; - yUsed = other._used; - resultDigits = _cloneDigits(_digits, 0, _used, _used + 2); - resultUsed = _used; - } - var topDigitDivisor = yDigits[yUsed - 1]; - var i = resultUsed; - var j = i - yUsed; - // tmpDigits is a temporary array of i (resultUsed) digits. - var tmpDigits = Uint16List(i); - var tmpUsed = _dlShiftDigits(yDigits, yUsed, j, tmpDigits); - // Explicit first division step in case normalized dividend is larger or - // equal to shifted normalized divisor. - if (_compareDigits(resultDigits, resultUsed, tmpDigits, tmpUsed) >= 0) { - assert(i == resultUsed); - resultDigits[resultUsed++] = 1; // Quotient = 1. - // Subtract divisor from remainder. - _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits); - } else { - // Account for possible carry in _mulAdd step. - resultDigits[resultUsed++] = 0; - } - - // Negate y so we can later use _mulAdd instead of non-existent _mulSub. - var nyDigits = Uint16List(yUsed + 2); - nyDigits[yUsed] = 1; - _absSub(nyDigits, yUsed + 1, yDigits, yUsed, nyDigits); - // nyDigits is read-only and has yUsed digits (possibly including several - // leading zeros). - // resultDigits is modified during iteration. - // resultDigits[0..yUsed-1] is the current remainder. - // resultDigits[yUsed..resultUsed-1] is the current quotient. - --i; - - while (j > 0) { - var estimatedQuotientDigit = - _estimateQuotientDigit(topDigitDivisor, resultDigits, i); - j--; - _mulAdd(estimatedQuotientDigit, nyDigits, 0, resultDigits, j, yUsed); - if (resultDigits[i] < estimatedQuotientDigit) { - // Reusing the already existing tmpDigits array. - var tmpUsed = _dlShiftDigits(nyDigits, yUsed, j, tmpDigits); - _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits); - while (resultDigits[i] < --estimatedQuotientDigit) { - _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits); - } - } - i--; - } - // Cache result. - _lastDividendDigits = _digits; - _lastDividendUsed = _used; - _lastDivisorDigits = other._digits; - _lastDivisorUsed = other._used; - _lastQuoRemDigits = resultDigits; - _lastQuoRemUsed = resultUsed; - _lastRemUsed = yUsed; - _lastRem_nsh = nsh; - } - - int get hashCode { - // This is the [Jenkins hash function][1] but using masking to keep - // values in SMI range. - // - // [1]: http://en.wikipedia.org/wiki/Jenkins_hash_function - - int combine(int hash, int value) { - hash = 0x1fffffff & (hash + value); - hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10)); - return hash ^ (hash >> 6); - } - - int finish(int hash) { - hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3)); - hash = hash ^ (hash >> 11); - return 0x1fffffff & (hash + ((0x00003fff & hash) << 15)); - } - - if (_isZero) return 6707; // Just a random number. - var hash = _isNegative ? 83585 : 429689; // Also random. - for (int i = 0; i < _used; i++) { - hash = combine(hash, _digits[i]); - } - return finish(hash); - } - - /** - * Test whether this value is numerically equal to `other`. - * - * If [other] is a [_BigIntImpl] returns whether the two operands have the same - * value. - * - * Returns false if `other` is not a [_BigIntImpl]. - */ - bool operator ==(Object other) => - other is _BigIntImpl && compareTo(other) == 0; - - /** - * Returns the minimum number of bits required to store this big integer. - * - * The number of bits excludes the sign bit, which gives the natural length - * for non-negative (unsigned) values. Negative values are complemented to - * return the bit position of the first bit that differs from the sign bit. - * - * To find the number of bits needed to store the value as a signed value, - * add one, i.e. use `x.bitLength + 1`. - * - * ``` - * x.bitLength == (-x-1).bitLength - * - * new BigInt.from(3).bitLength == 2; // 00000011 - * new BigInt.from(2).bitLength == 2; // 00000010 - * new BigInt.from(1).bitLength == 1; // 00000001 - * new BigInt.from(0).bitLength == 0; // 00000000 - * new BigInt.from(-1).bitLength == 0; // 11111111 - * new BigInt.from(-2).bitLength == 1; // 11111110 - * new BigInt.from(-3).bitLength == 2; // 11111101 - * new BigInt.from(-4).bitLength == 2; // 11111100 - * ``` - */ - int get bitLength { - if (_used == 0) return 0; - if (_isNegative) return (~this).bitLength; - return _digitBits * (_used - 1) + _digits[_used - 1].bitLength; - } - - /** - * Truncating division operator. - * - * Performs a truncating integer division, where the remainder is discarded. - * - * The remainder can be computed using the [remainder] method. - * - * Examples: - * ``` - * var seven = new BigInt.from(7); - * var three = new BigInt.from(3); - * seven ~/ three; // => 2 - * (-seven) ~/ three; // => -2 - * seven ~/ -three; // => -2 - * seven.remainder(three); // => 1 - * (-seven).remainder(three); // => -1 - * seven.remainder(-three); // => 1 - * ``` - */ - _BigIntImpl operator ~/(covariant _BigIntImpl other) { - if (other._used == 0) { - throw const IntegerDivisionByZeroException(); - } - return _div(other); - } - - /** - * Returns the remainder of the truncating division of `this` by [other]. - * - * The result `r` of this operation satisfies: - * `this == (this ~/ other) * other + r`. - * As a consequence the remainder `r` has the same sign as the divider `this`. - */ - _BigIntImpl remainder(covariant _BigIntImpl other) { - if (other._used == 0) { - throw const IntegerDivisionByZeroException(); - } - return _rem(other); - } - - /// Division operator. - double operator /(BigInt other) => this.toDouble() / other.toDouble(); - - /** Relational less than operator. */ - bool operator <(covariant _BigIntImpl other) => compareTo(other) < 0; - - /** Relational less than or equal operator. */ - bool operator <=(covariant _BigIntImpl other) => compareTo(other) <= 0; - - /** Relational greater than operator. */ - bool operator >(covariant _BigIntImpl other) => compareTo(other) > 0; - - /** Relational greater than or equal operator. */ - bool operator >=(covariant _BigIntImpl other) => compareTo(other) >= 0; - - /** - * Euclidean modulo operator. - * - * Returns the remainder of the Euclidean division. The Euclidean division of - * two integers `a` and `b` yields two integers `q` and `r` such that - * `a == b * q + r` and `0 <= r < b.abs()`. - * - * The sign of the returned value `r` is always positive. - * - * See [remainder] for the remainder of the truncating division. - */ - _BigIntImpl operator %(covariant _BigIntImpl other) { - if (other._used == 0) { - throw const IntegerDivisionByZeroException(); - } - var result = _rem(other); - if (result._isNegative) { - if (other._isNegative) { - result = result - other; - } else { - result = result + other; - } - } - return result; - } - - /** - * Returns the sign of this big integer. - * - * Returns 0 for zero, -1 for values less than zero and - * +1 for values greater than zero. - */ - int get sign { - if (_used == 0) return 0; - return _isNegative ? -1 : 1; - } - - /// Whether this big integer is even. - bool get isEven => _used == 0 || (_digits[0] & 1) == 0; - - /// Whether this big integer is odd. - bool get isOdd => !isEven; - - /// Whether this number is negative. - bool get isNegative => _isNegative; - - _BigIntImpl pow(int exponent) { - if (exponent < 0) { - throw ArgumentError("Exponent must not be negative: $exponent"); - } - if (exponent == 0) return one; - - // Exponentiation by squaring. - var result = one; - var base = this; - while (exponent != 0) { - if ((exponent & 1) == 1) { - result *= base; - } - exponent >>= 1; - // Skip unnecessary operation. - if (exponent != 0) { - base *= base; - } - } - return result; - } - - /** - * Returns this integer to the power of [exponent] modulo [modulus]. - * - * The [exponent] must be non-negative and [modulus] must be - * positive. - */ - _BigIntImpl modPow( - covariant _BigIntImpl exponent, covariant _BigIntImpl modulus) { - if (exponent._isNegative) { - throw ArgumentError("exponent must be positive: $exponent"); - } - if (modulus <= zero) { - throw ArgumentError("modulus must be strictly positive: $modulus"); - } - if (exponent._isZero) return one; - - final modulusUsed = modulus._used; - final modulusUsed2p4 = 2 * modulusUsed + 4; - final exponentBitlen = exponent.bitLength; - if (exponentBitlen <= 0) return one; - _BigIntReduction z = _BigIntClassic(modulus); - var resultDigits = Uint16List(modulusUsed2p4); - var result2Digits = Uint16List(modulusUsed2p4); - var gDigits = Uint16List(modulusUsed); - var gUsed = z.convert(this, gDigits); - // Initialize result with g. - // Copy leading zero if any. - for (int j = gUsed - 1; j >= 0; j--) { - resultDigits[j] = gDigits[j]; - } - var resultUsed = gUsed; - int result2Used; - for (int i = exponentBitlen - 2; i >= 0; i--) { - result2Used = z.sqr(resultDigits, resultUsed, result2Digits); - if (!(exponent & (one << i))._isZero) { - resultUsed = - z.mul(result2Digits, result2Used, gDigits, gUsed, resultDigits); - } else { - // Swap result and result2. - var tmpDigits = resultDigits; - var tmpUsed = resultUsed; - resultDigits = result2Digits; - resultUsed = result2Used; - result2Digits = tmpDigits; - result2Used = tmpUsed; - } - } - return z.revert(resultDigits, resultUsed); - } - - // If inv is false, returns gcd(x, y). - // If inv is true and gcd(x, y) = 1, returns d, so that c*x + d*y = 1. - // If inv is true and gcd(x, y) != 1, throws Exception("Not coprime"). - static _BigIntImpl _binaryGcd(_BigIntImpl x, _BigIntImpl y, bool inv) { - var xDigits = x._digits; - var yDigits = y._digits; - var xUsed = x._used; - var yUsed = y._used; - var maxUsed = xUsed > yUsed ? xUsed : yUsed; - var unshiftedMaxUsed = maxUsed; // Keep - xDigits = _cloneDigits(xDigits, 0, xUsed, maxUsed); - yDigits = _cloneDigits(yDigits, 0, yUsed, maxUsed); - int shiftAmount = 0; - if (inv) { - if ((yUsed == 1) && (yDigits[0] == 1)) return one; - if ((yUsed == 0) || (yDigits[0].isEven && xDigits[0].isEven)) { - throw Exception("Not coprime"); - } - } else { - if (x._isZero) { - throw ArgumentError.value(0, "this", "must not be zero"); - } - if (y._isZero) { - throw ArgumentError.value(0, "other", "must not be zero"); - } - if (((xUsed == 1) && (xDigits[0] == 1)) || - ((yUsed == 1) && (yDigits[0] == 1))) return one; - while (((xDigits[0] & 1) == 0) && ((yDigits[0] & 1) == 0)) { - _rsh(xDigits, xUsed, 1, xDigits); - _rsh(yDigits, yUsed, 1, yDigits); - shiftAmount++; - } - if (shiftAmount >= _digitBits) { - var digitShiftAmount = shiftAmount ~/ _digitBits; - xUsed -= digitShiftAmount; - yUsed -= digitShiftAmount; - maxUsed -= digitShiftAmount; - } - if ((yDigits[0] & 1) == 1) { - // Swap x and y. - var tmpDigits = xDigits; - var tmpUsed = xUsed; - xDigits = yDigits; - xUsed = yUsed; - yDigits = tmpDigits; - yUsed = tmpUsed; - } - } - var uDigits = _cloneDigits(xDigits, 0, xUsed, unshiftedMaxUsed); - var vDigits = - _cloneDigits(yDigits, 0, yUsed, unshiftedMaxUsed + 2); // +2 for lsh. - final bool ac = (xDigits[0] & 1) == 0; - - // Variables a, b, c, and d require one more digit. - final abcdUsed = maxUsed + 1; - final abcdLen = abcdUsed + 2; // +2 to satisfy _absAdd. - var aDigits = _dummyList; - var aIsNegative = false; - var cDigits = _dummyList; - var cIsNegative = false; - if (ac) { - aDigits = Uint16List(abcdLen); - aDigits[0] = 1; - cDigits = Uint16List(abcdLen); - } - var bDigits = Uint16List(abcdLen); - var bIsNegative = false; - var dDigits = Uint16List(abcdLen); - var dIsNegative = false; - dDigits[0] = 1; - - while (true) { - while ((uDigits[0] & 1) == 0) { - _rsh(uDigits, maxUsed, 1, uDigits); - if (ac) { - if (((aDigits[0] & 1) == 1) || ((bDigits[0] & 1) == 1)) { - // a += y - if (aIsNegative) { - if ((aDigits[maxUsed] != 0) || - (_compareDigits(aDigits, maxUsed, yDigits, maxUsed)) > 0) { - _absSub(aDigits, abcdUsed, yDigits, maxUsed, aDigits); - } else { - _absSub(yDigits, maxUsed, aDigits, maxUsed, aDigits); - aIsNegative = false; - } - } else { - _absAdd(aDigits, abcdUsed, yDigits, maxUsed, aDigits); - } - // b -= x - if (bIsNegative) { - _absAdd(bDigits, abcdUsed, xDigits, maxUsed, bDigits); - } else if ((bDigits[maxUsed] != 0) || - (_compareDigits(bDigits, maxUsed, xDigits, maxUsed) > 0)) { - _absSub(bDigits, abcdUsed, xDigits, maxUsed, bDigits); - } else { - _absSub(xDigits, maxUsed, bDigits, maxUsed, bDigits); - bIsNegative = true; - } - } - _rsh(aDigits, abcdUsed, 1, aDigits); - } else if ((bDigits[0] & 1) == 1) { - // b -= x - if (bIsNegative) { - _absAdd(bDigits, abcdUsed, xDigits, maxUsed, bDigits); - } else if ((bDigits[maxUsed] != 0) || - (_compareDigits(bDigits, maxUsed, xDigits, maxUsed) > 0)) { - _absSub(bDigits, abcdUsed, xDigits, maxUsed, bDigits); - } else { - _absSub(xDigits, maxUsed, bDigits, maxUsed, bDigits); - bIsNegative = true; - } - } - _rsh(bDigits, abcdUsed, 1, bDigits); - } - while ((vDigits[0] & 1) == 0) { - _rsh(vDigits, maxUsed, 1, vDigits); - if (ac) { - if (((cDigits[0] & 1) == 1) || ((dDigits[0] & 1) == 1)) { - // c += y - if (cIsNegative) { - if ((cDigits[maxUsed] != 0) || - (_compareDigits(cDigits, maxUsed, yDigits, maxUsed) > 0)) { - _absSub(cDigits, abcdUsed, yDigits, maxUsed, cDigits); - } else { - _absSub(yDigits, maxUsed, cDigits, maxUsed, cDigits); - cIsNegative = false; - } - } else { - _absAdd(cDigits, abcdUsed, yDigits, maxUsed, cDigits); - } - // d -= x - if (dIsNegative) { - _absAdd(dDigits, abcdUsed, xDigits, maxUsed, dDigits); - } else if ((dDigits[maxUsed] != 0) || - (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) { - _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits); - } else { - _absSub(xDigits, maxUsed, dDigits, maxUsed, dDigits); - dIsNegative = true; - } - } - _rsh(cDigits, abcdUsed, 1, cDigits); - } else if ((dDigits[0] & 1) == 1) { - // d -= x - if (dIsNegative) { - _absAdd(dDigits, abcdUsed, xDigits, maxUsed, dDigits); - } else if ((dDigits[maxUsed] != 0) || - (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) { - _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits); - } else { - _absSub(xDigits, maxUsed, dDigits, maxUsed, dDigits); - dIsNegative = true; - } - } - _rsh(dDigits, abcdUsed, 1, dDigits); - } - if (_compareDigits(uDigits, maxUsed, vDigits, maxUsed) >= 0) { - // u -= v - _absSub(uDigits, maxUsed, vDigits, maxUsed, uDigits); - if (ac) { - // a -= c - if (aIsNegative == cIsNegative) { - var a_cmp_c = _compareDigits(aDigits, abcdUsed, cDigits, abcdUsed); - if (a_cmp_c > 0) { - _absSub(aDigits, abcdUsed, cDigits, abcdUsed, aDigits); - } else { - _absSub(cDigits, abcdUsed, aDigits, abcdUsed, aDigits); - aIsNegative = !aIsNegative && (a_cmp_c != 0); - } - } else { - _absAdd(aDigits, abcdUsed, cDigits, abcdUsed, aDigits); - } - } - // b -= d - if (bIsNegative == dIsNegative) { - var b_cmp_d = _compareDigits(bDigits, abcdUsed, dDigits, abcdUsed); - if (b_cmp_d > 0) { - _absSub(bDigits, abcdUsed, dDigits, abcdUsed, bDigits); - } else { - _absSub(dDigits, abcdUsed, bDigits, abcdUsed, bDigits); - bIsNegative = !bIsNegative && (b_cmp_d != 0); - } - } else { - _absAdd(bDigits, abcdUsed, dDigits, abcdUsed, bDigits); - } - } else { - // v -= u - _absSub(vDigits, maxUsed, uDigits, maxUsed, vDigits); - if (ac) { - // c -= a - if (cIsNegative == aIsNegative) { - var c_cmp_a = _compareDigits(cDigits, abcdUsed, aDigits, abcdUsed); - if (c_cmp_a > 0) { - _absSub(cDigits, abcdUsed, aDigits, abcdUsed, cDigits); - } else { - _absSub(aDigits, abcdUsed, cDigits, abcdUsed, cDigits); - cIsNegative = !cIsNegative && (c_cmp_a != 0); - } - } else { - _absAdd(cDigits, abcdUsed, aDigits, abcdUsed, cDigits); - } - } - // d -= b - if (dIsNegative == bIsNegative) { - var d_cmp_b = _compareDigits(dDigits, abcdUsed, bDigits, abcdUsed); - if (d_cmp_b > 0) { - _absSub(dDigits, abcdUsed, bDigits, abcdUsed, dDigits); - } else { - _absSub(bDigits, abcdUsed, dDigits, abcdUsed, dDigits); - dIsNegative = !dIsNegative && (d_cmp_b != 0); - } - } else { - _absAdd(dDigits, abcdUsed, bDigits, abcdUsed, dDigits); - } - } - // Exit loop if u == 0. - var i = maxUsed; - while ((i > 0) && (uDigits[i - 1] == 0)) --i; - if (i == 0) break; - } - if (!inv) { - if (shiftAmount > 0) { - maxUsed = _lShiftDigits(vDigits, maxUsed, shiftAmount, vDigits); - } - return _BigIntImpl._(false, maxUsed, vDigits); - } - // No inverse if v != 1. - var i = maxUsed - 1; - while ((i > 0) && (vDigits[i] == 0)) --i; - if ((i != 0) || (vDigits[0] != 1)) { - throw Exception("Not coprime"); - } - - if (dIsNegative) { - while ((dDigits[maxUsed] != 0) || - (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) { - // d += x, d still negative - _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits); - } - // d += x - _absSub(xDigits, maxUsed, dDigits, maxUsed, dDigits); - dIsNegative = false; - } else { - while ((dDigits[maxUsed] != 0) || - (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) >= 0)) { - // d -= x - _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits); - } - } - return _BigIntImpl._(false, maxUsed, dDigits); - } - - /** - * Returns the modular multiplicative inverse of this big integer - * modulo [modulus]. - * - * The [modulus] must be positive. - * - * It is an error if no modular inverse exists. - */ - // Returns 1/this % modulus, with modulus > 0. - _BigIntImpl modInverse(covariant _BigIntImpl modulus) { - if (modulus <= zero) { - throw ArgumentError("Modulus must be strictly positive: $modulus"); - } - if (modulus == one) return zero; - var tmp = this; - if (tmp._isNegative || (tmp._absCompare(modulus) >= 0)) { - tmp %= modulus; - } - return _binaryGcd(modulus, tmp, true); - } - - /** - * Returns the greatest common divisor of this big integer and [other]. - * - * If either number is non-zero, the result is the numerically greatest - * integer dividing both `this` and `other`. - * - * The greatest common divisor is independent of the order, - * so `x.gcd(y)` is always the same as `y.gcd(x)`. - * - * For any integer `x`, `x.gcd(x)` is `x.abs()`. - * - * If both `this` and `other` is zero, the result is also zero. - */ - _BigIntImpl gcd(covariant _BigIntImpl other) { - if (_isZero) return other.abs(); - if (other._isZero) return this.abs(); - return _binaryGcd(this, other, false); - } - - /** - * Returns the least significant [width] bits of this big integer as a - * non-negative number (i.e. unsigned representation). The returned value has - * zeros in all bit positions higher than [width]. - * - * ``` - * new BigInt.from(-1).toUnsigned(5) == 31 // 11111111 -> 00011111 - * ``` - * - * This operation can be used to simulate arithmetic from low level languages. - * For example, to increment an 8 bit quantity: - * - * ``` - * q = (q + 1).toUnsigned(8); - * ``` - * - * `q` will count from `0` up to `255` and then wrap around to `0`. - * - * If the input fits in [width] bits without truncation, the result is the - * same as the input. The minimum width needed to avoid truncation of `x` is - * given by `x.bitLength`, i.e. - * - * ``` - * x == x.toUnsigned(x.bitLength); - * ``` - */ - _BigIntImpl toUnsigned(int width) { - return this & ((one << width) - one); - } - - /** - * Returns the least significant [width] bits of this integer, extending the - * highest retained bit to the sign. This is the same as truncating the value - * to fit in [width] bits using an signed 2-s complement representation. The - * returned value has the same bit value in all positions higher than [width]. - * - * ``` - * var big15 = new BigInt.from(15); - * var big16 = new BigInt.from(16); - * var big239 = new BigInt.from(239); - * V--sign bit-V - * big16.toSigned(5) == -big16 // 00010000 -> 11110000 - * big239.toSigned(5) == big15 // 11101111 -> 00001111 - * ^ ^ - * ``` - * - * This operation can be used to simulate arithmetic from low level languages. - * For example, to increment an 8 bit signed quantity: - * - * ``` - * q = (q + 1).toSigned(8); - * ``` - * - * `q` will count from `0` up to `127`, wrap to `-128` and count back up to - * `127`. - * - * If the input value fits in [width] bits without truncation, the result is - * the same as the input. The minimum width needed to avoid truncation of `x` - * is `x.bitLength + 1`, i.e. - * - * ``` - * x == x.toSigned(x.bitLength + 1); - * ``` - */ - _BigIntImpl toSigned(int width) { - // The value of binary number weights each bit by a power of two. The - // twos-complement value weights the sign bit negatively. We compute the - // value of the negative weighting by isolating the sign bit with the - // correct power of two weighting and subtracting it from the value of the - // lower bits. - var signMask = one << (width - 1); - return (this & (signMask - one)) - (this & signMask); - } - - // Maximum number of digits that always fit in mantissa. - static const _simpleValidIntDigits = 53 ~/ _digitBits; - - bool get isValidInt { - if (_used <= _simpleValidIntDigits) return true; - var asInt = toInt(); - if (!asInt.toDouble().isFinite) return false; - return this == _BigIntImpl._fromInt(asInt); - } - - int toInt() { - var result = 0; - for (int i = _used - 1; i >= 0; i--) { - result = result * _digitBase + _digits[i]; - } - return _isNegative ? -result : result; - } - - /** - * Returns this [_BigIntImpl] as a [double]. - * - * If the number is not representable as a [double], an - * approximation is returned. For numerically large integers, the - * approximation may be infinite. - */ - double toDouble() { - const int exponentBias = 1075; - // There are 11 bits for the exponent. - // 2047 (all bits set to 1) is reserved for infinity and NaN. - // When storing the exponent in the 11 bits, it is biased by exponentBias - // to support negative exponents. - const int maxDoubleExponent = 2046 - exponentBias; - if (_isZero) return 0.0; - - // We fill the 53 bits little-endian. - var resultBits = Uint8List(8); - - var length = _digitBits * (_used - 1) + _digits[_used - 1].bitLength; - if (length > maxDoubleExponent + 53) { - return _isNegative ? double.negativeInfinity : double.infinity; - } - - // The most significant bit is for the sign. - if (_isNegative) resultBits[7] = 0x80; - - // Write the exponent into bits 1..12: - var biasedExponent = length - 53 + exponentBias; - resultBits[6] = (biasedExponent & 0xF) << 4; - resultBits[7] |= biasedExponent >> 4; - - int cachedBits = 0; - int cachedBitsLength = 0; - int digitIndex = _used - 1; - int readBits(int n) { - // Ensure that we have enough bits in [cachedBits]. - while (cachedBitsLength < n) { - int nextDigit; - int nextDigitLength = _digitBits; // May get updated. - if (digitIndex < 0) { - nextDigit = 0; - digitIndex--; - } else { - nextDigit = _digits[digitIndex]; - if (digitIndex == _used - 1) nextDigitLength = nextDigit.bitLength; - digitIndex--; - } - cachedBits = (cachedBits << nextDigitLength) + nextDigit; - cachedBitsLength += nextDigitLength; - } - // Read the top [n] bits. - var result = cachedBits >> (cachedBitsLength - n); - // Remove the bits from the cache. - cachedBits -= result << (cachedBitsLength - n); - cachedBitsLength -= n; - return result; - } - - // The first leading 1 bit is implicit in the double-representation and can - // be discarded. - var leadingBits = readBits(5) & 0xF; - resultBits[6] |= leadingBits; - - for (int i = 5; i >= 0; i--) { - // Get the remaining 48 bits. - resultBits[i] = readBits(8); - } - - void roundUp() { - // Simply consists of adding 1 to the whole 64 bit "number". - // It will update the exponent, if necessary. - // It might even round up to infinity (which is what we want). - var carry = 1; - for (int i = 0; i < 8; i++) { - if (carry == 0) break; - var sum = resultBits[i] + carry; - resultBits[i] = sum & 0xFF; - carry = sum >> 8; - } - } - - if (readBits(1) == 1) { - if (resultBits[0].isOdd) { - // Rounds to even all the time. - roundUp(); - } else { - // Round up, if there is at least one other digit that is not 0. - if (cachedBits != 0) { - // There is already one in the cachedBits. - roundUp(); - } else { - for (int i = digitIndex; i >= 0; i--) { - if (_digits[i] != 0) { - roundUp(); - break; - } - } - } - } - } - return resultBits.buffer.asByteData().getFloat64(0, Endian.little); - } - - /** - * Returns a String-representation of this integer. - * - * The returned string is parsable by [parse]. - * For any `_BigIntImpl` `i`, it is guaranteed that - * `i == _BigIntImpl.parse(i.toString())`. - */ - String toString() { - if (_used == 0) return "0"; - if (_used == 1) { - if (_isNegative) return (-_digits[0]).toString(); - return _digits[0].toString(); - } - - // Generate in chunks of 4 digits. - // The chunks are in reversed order. - var decimalDigitChunks = []; - var rest = isNegative ? -this : this; - while (rest._used > 1) { - var digits4 = rest.remainder(_bigInt10000).toString(); - decimalDigitChunks.add(digits4); - if (digits4.length == 1) decimalDigitChunks.add("000"); - if (digits4.length == 2) decimalDigitChunks.add("00"); - if (digits4.length == 3) decimalDigitChunks.add("0"); - rest = rest ~/ _bigInt10000; - } - decimalDigitChunks.add(rest._digits[0].toString()); - if (_isNegative) decimalDigitChunks.add("-"); - return decimalDigitChunks.reversed.join(); - } - - int _toRadixCodeUnit(int digit) { - const int _0 = 48; - const int _a = 97; - if (digit < 10) return _0 + digit; - return _a + digit - 10; - } - - /** - * Converts [this] to a string representation in the given [radix]. - * - * In the string representation, lower-case letters are used for digits above - * '9', with 'a' being 10 an 'z' being 35. - * - * The [radix] argument must be an integer in the range 2 to 36. - */ - String toRadixString(int radix) { - if (radix > 36) throw RangeError.range(radix, 2, 36); - - if (_used == 0) return "0"; - - if (_used == 1) { - var digitString = _digits[0].toRadixString(radix); - if (_isNegative) return "-" + digitString; - return digitString; - } - - if (radix == 16) return _toHexString(); - - var base = _BigIntImpl._fromInt(radix); - var reversedDigitCodeUnits = []; - var rest = this.abs(); - while (!rest._isZero) { - var digit = rest.remainder(base).toInt(); - rest = rest ~/ base; - reversedDigitCodeUnits.add(_toRadixCodeUnit(digit)); - } - var digitString = String.fromCharCodes(reversedDigitCodeUnits.reversed); - if (_isNegative) return "-" + digitString; - return digitString; - } - - String _toHexString() { - var chars = []; - for (int i = 0; i < _used - 1; i++) { - int chunk = _digits[i]; - for (int j = 0; j < (_digitBits ~/ 4); j++) { - chars.add(_toRadixCodeUnit(chunk & 0xF)); - chunk >>= 4; - } - } - var msbChunk = _digits[_used - 1]; - while (msbChunk != 0) { - chars.add(_toRadixCodeUnit(msbChunk & 0xF)); - msbChunk >>= 4; - } - if (_isNegative) { - const _dash = 45; - chars.add(_dash); - } - return String.fromCharCodes(chars.reversed); - } -} - -// Interface for modular reduction. -abstract class _BigIntReduction { - // Return the number of digits used by r_digits. - int convert(_BigIntImpl x, Uint16List r_digits); - int mul(Uint16List xDigits, int xUsed, Uint16List yDigits, int yUsed, - Uint16List resultDigits); - int sqr(Uint16List xDigits, int xUsed, Uint16List resultDigits); - - // Return x reverted to _BigIntImpl. - _BigIntImpl revert(Uint16List xDigits, int xUsed); -} - -// Modular reduction using "classic" algorithm. -class _BigIntClassic implements _BigIntReduction { - final _BigIntImpl _modulus; // Modulus. - final _BigIntImpl _normalizedModulus; // Normalized _modulus. - - _BigIntClassic(this._modulus) - : _normalizedModulus = _modulus << - (_BigIntImpl._digitBits - - _modulus._digits[_modulus._used - 1].bitLength); - - int convert(_BigIntImpl x, Uint16List resultDigits) { - Uint16List digits; - int used; - if (x._isNegative || x._absCompare(_modulus) >= 0) { - var remainder = x._rem(_modulus); - if (x._isNegative && remainder._used > 0) { - assert(remainder._isNegative); - remainder += _modulus; - } - assert(!remainder._isNegative); - used = remainder._used; - digits = remainder._digits; - } else { - used = x._used; - digits = x._digits; - } - var i = used; // Copy leading zero if any. - while (--i >= 0) { - resultDigits[i] = digits[i]; - } - return used; - } - - _BigIntImpl revert(Uint16List xDigits, int xUsed) { - return _BigIntImpl._(false, xUsed, xDigits); - } - - int _reduce(Uint16List xDigits, int xUsed) { - if (xUsed < _modulus._used) { - return xUsed; - } - var reverted = revert(xDigits, xUsed); - var rem = reverted._rem(_normalizedModulus); - return convert(rem, xDigits); - } - - int sqr(Uint16List xDigits, int xUsed, Uint16List resultDigits) { - var b = _BigIntImpl._(false, xUsed, xDigits); - var b2 = b * b; - for (int i = 0; i < b2._used; i++) { - resultDigits[i] = b2._digits[i]; - } - for (int i = b2._used; i < 2 * xUsed; i++) { - resultDigits[i] = 0; - } - return _reduce(resultDigits, 2 * xUsed); - } - - int mul(Uint16List xDigits, int xUsed, Uint16List yDigits, int yUsed, - Uint16List resultDigits) { - var resultUsed = - _BigIntImpl._mulDigits(xDigits, xUsed, yDigits, yUsed, resultDigits); - return _reduce(resultDigits, resultUsed); - } -} diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/developer_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/developer_patch.dart deleted file mode 100644 index d67b6c8265a..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/developer_patch.dart +++ /dev/null @@ -1,201 +0,0 @@ -// 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. - -// Patch file for dart:developer library. - -import 'dart:_js_helper' show patch, ForceInline, ReifyFunctionTypes; -import 'dart:_foreign_helper' show JS, JSExportName; -import 'dart:_runtime' as dart; -import 'dart:async'; -import 'dart:convert' show json; -import 'dart:isolate'; - -@patch -@ForceInline() -bool debugger({bool when = true, String? message}) { - if (when) { - JS('', 'debugger'); - } - return when; -} - -@patch -Object? inspect(Object? object) { - // Note: this log level does not show up by default in Chrome. - // This is used for communication with the debugger service. - JS('', 'console.debug("dart.developer.inspect", #)', object); - return object; -} - -@patch -void log(String message, - {DateTime? time, - int? sequenceNumber, - int level = 0, - String name = '', - Zone? zone, - Object? error, - StackTrace? stackTrace}) { - Object items = - JS('!', '{ message: #, name: #, level: # }', message, name, level); - if (time != null) JS('', '#.time = #', items, time); - if (sequenceNumber != null) { - JS('', '#.sequenceNumber = #', items, sequenceNumber); - } - if (zone != null) JS('', '#.zone = #', items, zone); - if (error != null) JS('', '#.error = #', items, error); - if (stackTrace != null) JS('', '#.stackTrace = #', items, stackTrace); - - JS('', 'console.debug("dart.developer.log", #)', items); -} - -final _extensions = {}; - -@patch -ServiceExtensionHandler? _lookupExtension(String method) { - return _extensions[method]; -} - -@patch -_registerExtension(String method, ServiceExtensionHandler handler) { - _extensions[method] = handler; - JS('', 'console.debug("dart.developer.registerExtension", #)', method); -} - -/// Returns a JS `Promise` that resolves with the result of invoking -/// [methodName] with an [encodedJson] map as its parameters. -/// -/// This is used by the VM Service Prototcol to invoke extensions registered -/// with [registerExtension]. For example, in JS: -/// -/// await sdk.developer.invokeExtension( -/// . "ext.flutter.inspector.getRootWidget", '{"objectGroup":""}'); -/// -@JSExportName('invokeExtension') -@ReifyFunctionTypes(false) -_invokeExtension(String methodName, String encodedJson) { - // TODO(vsm): We should factor this out as future<->promise. - return JS('', 'new #.Promise(#)', dart.global_, - (Function(Object) resolve, Function(Object) reject) async { - try { - var method = _lookupExtension(methodName)!; - var parameters = (json.decode(encodedJson) as Map).cast(); - var result = await method(methodName, parameters); - resolve(result._toString()); - } catch (e) { - // TODO(vsm): Reject or encode in result? - reject('$e'); - } - }); -} - -@patch -void _postEvent(String eventKind, String eventData) { - JS('', 'console.debug("dart.developer.postEvent", #, #)', eventKind, - eventData); -} - -@patch -bool _isDartStreamEnabled() { - return false; -} - -@patch -int _getTraceClock() { - // TODO. - return _clockValue++; -} - -int _clockValue = 0; - -@patch -void _reportFlowEvent( - String category, String name, int type, int id, String argumentsAsJson) { - // TODO. -} - -@patch -void _reportInstantEvent(String category, String name, String argumentsAsJson) { - // TODO. -} - -@patch -int _getNextAsyncId() { - return 0; -} - -@patch -void _reportTaskEvent(int taskId, String phase, String category, String name, - String argumentsAsJson) { - // TODO. -} - -@patch -int _getServiceMajorVersion() { - return 0; -} - -@patch -int _getServiceMinorVersion() { - return 0; -} - -@patch -void _getServerInfo(SendPort sendPort) { - sendPort.send(null); -} - -@patch -void _webServerControl(SendPort sendPort, bool enable) { - sendPort.send(null); -} - -@patch -String? _getIsolateIDFromSendPort(SendPort sendPort) { - return null; -} - -@patch -class UserTag { - @patch - factory UserTag(String label) = _FakeUserTag; - - @patch - static UserTag get defaultTag => _FakeUserTag._defaultTag; -} - -class _FakeUserTag implements UserTag { - static final _instances = {}; - - _FakeUserTag.real(this.label); - - factory _FakeUserTag(String label) { - // Canonicalize by name. - var existingTag = _instances[label]; - if (existingTag != null) { - return existingTag; - } - // Throw an exception if we've reached the maximum number of user tags. - if (_instances.length == UserTag.MAX_USER_TAGS) { - throw UnsupportedError( - 'UserTag instance limit (${UserTag.MAX_USER_TAGS}) reached.'); - } - return _instances[label] = _FakeUserTag.real(label); - } - - final String label; - - UserTag makeCurrent() { - var old = _currentTag; - _currentTag = this; - return old; - } - - static final UserTag _defaultTag = _FakeUserTag('Default'); -} - -var _currentTag = _FakeUserTag._defaultTag; - -@patch -UserTag getCurrentTag() => _currentTag; diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/internal_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/internal_patch.dart deleted file mode 100644 index 2e605a291b8..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/internal_patch.dart +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) 2013, 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 'dart:core' hide Symbol; -import 'dart:core' as core show Symbol; -import 'dart:_js_primitives' show printString; -import 'dart:_js_helper' show patch; -import 'dart:_interceptors' show JSArray; -import 'dart:_foreign_helper' show JS; -import 'dart:_runtime' as dart; - -@patch -bool typeAcceptsNull() => !dart.strictNullSafety || null is T; - -@patch -class Symbol implements core.Symbol { - @patch - const Symbol(String name) : this._name = name; - - @patch - int get hashCode { - int? hash = JS('int|Null', '#._hashCode', this); - if (hash != null) return hash; - const arbitraryPrime = 664597; - hash = 0x1fffffff & (arbitraryPrime * _name.hashCode); - JS('', '#._hashCode = #', this, hash); - return hash; - } - - @patch - toString() => 'Symbol("$_name")'; - - @patch - static String computeUnmangledName(Symbol symbol) => symbol._name; -} - -@patch -void printToConsole(String line) { - printString('$line'); -} - -@patch -List makeListFixedLength(List growableList) { - JSArray.markFixedList(growableList); - return growableList; -} - -@patch -List makeFixedListUnmodifiable(List fixedLengthList) { - JSArray.markUnmodifiableList(fixedLengthList); - return fixedLengthList; -} - -@patch -Object? extractTypeArguments(T instance, Function extract) => - dart.extractTypeArguments(instance, extract); diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/io_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/io_patch.dart deleted file mode 100644 index 041dfd54c18..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/io_patch.dart +++ /dev/null @@ -1,707 +0,0 @@ -// Copyright (c) 2013, 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 'dart:_js_helper' show patch; -import 'dart:async'; -import 'dart:convert'; -import 'dart:isolate' show SendPort; -import 'dart:typed_data'; - -@patch -class _Directory { - @patch - static _current(_Namespace namespace) { - throw UnsupportedError("Directory._current"); - } - - @patch - static _setCurrent(_Namespace namespace, Uint8List rawPath) { - throw UnsupportedError("Directory_SetCurrent"); - } - - @patch - static _createTemp(_Namespace namespace, Uint8List rawPath) { - throw UnsupportedError("Directory._createTemp"); - } - - @patch - static String _systemTemp(_Namespace namespace) { - throw UnsupportedError("Directory._systemTemp"); - } - - @patch - static _exists(_Namespace namespace, Uint8List rawPath) { - throw UnsupportedError("Directory._exists"); - } - - @patch - static _create(_Namespace namespace, Uint8List rawPath) { - throw UnsupportedError("Directory._create"); - } - - @patch - static _deleteNative( - _Namespace namespace, Uint8List rawPath, bool recursive) { - throw UnsupportedError("Directory._deleteNative"); - } - - @patch - static _rename(_Namespace namespace, Uint8List rawPath, String newPath) { - throw UnsupportedError("Directory._rename"); - } - - @patch - static void _fillWithDirectoryListing( - _Namespace namespace, - List list, - Uint8List rawPath, - bool recursive, - bool followLinks) { - throw UnsupportedError("Directory._fillWithDirectoryListing"); - } -} - -@patch -class _AsyncDirectoryListerOps { - @patch - factory _AsyncDirectoryListerOps(int pointer) { - throw UnsupportedError("Directory._list"); - } -} - -@patch -class _EventHandler { - @patch - static void _sendData(Object? sender, SendPort sendPort, int data) { - throw UnsupportedError("EventHandler._sendData"); - } -} - -@patch -class FileStat { - @patch - static _statSync(_Namespace namespace, String path) { - throw UnsupportedError("FileStat.stat"); - } -} - -@patch -class FileSystemEntity { - @patch - static _getTypeNative( - _Namespace namespace, Uint8List rawPath, bool followLinks) { - throw UnsupportedError("FileSystemEntity._getType"); - } - - @patch - static _identicalNative(_Namespace namespace, String path1, String path2) { - throw UnsupportedError("FileSystemEntity._identical"); - } - - @patch - static _resolveSymbolicLinks(_Namespace namespace, Uint8List rawPath) { - throw UnsupportedError("FileSystemEntity._resolveSymbolicLinks"); - } -} - -@patch -class _File { - @patch - static _exists(_Namespace namespace, Uint8List rawPath) { - throw UnsupportedError("File._exists"); - } - - @patch - static _create(_Namespace namespace, Uint8List rawPath) { - throw UnsupportedError("File._create"); - } - - @patch - static _createLink(_Namespace namespace, Uint8List rawPath, String target) { - throw UnsupportedError("File._createLink"); - } - - @patch - static _linkTarget(_Namespace namespace, Uint8List rawPath) { - throw UnsupportedError("File._linkTarget"); - } - - @patch - static _deleteNative(_Namespace namespace, Uint8List rawPath) { - throw UnsupportedError("File._deleteNative"); - } - - @patch - static _deleteLinkNative(_Namespace namespace, Uint8List rawPath) { - throw UnsupportedError("File._deleteLinkNative"); - } - - @patch - static _rename(_Namespace namespace, Uint8List oldPath, String newPath) { - throw UnsupportedError("File._rename"); - } - - @patch - static _renameLink(_Namespace namespace, Uint8List oldPath, String newPath) { - throw UnsupportedError("File._renameLink"); - } - - @patch - static _copy(_Namespace namespace, Uint8List oldPath, String newPath) { - throw UnsupportedError("File._copy"); - } - - @patch - static _lengthFromPath(_Namespace namespace, Uint8List rawPath) { - throw UnsupportedError("File._lengthFromPath"); - } - - @patch - static _lastModified(_Namespace namespace, Uint8List rawPath) { - throw UnsupportedError("File._lastModified"); - } - - @patch - static _lastAccessed(_Namespace namespace, Uint8List rawPath) { - throw UnsupportedError("File._lastAccessed"); - } - - @patch - static _setLastModified(_Namespace namespace, Uint8List rawPath, int millis) { - throw UnsupportedError("File._setLastModified"); - } - - @patch - static _setLastAccessed(_Namespace namespace, Uint8List rawPath, int millis) { - throw UnsupportedError("File._setLastAccessed"); - } - - @patch - static _open(_Namespace namespace, Uint8List rawPath, int mode) { - throw UnsupportedError("File._open"); - } - - @patch - static int _openStdio(int fd) { - throw UnsupportedError("File._openStdio"); - } -} - -@patch -class _Namespace { - @patch - static void _setupNamespace(var namespace) { - throw UnsupportedError("_Namespace"); - } - - @patch - static _Namespace get _namespace { - throw UnsupportedError("_Namespace"); - } - - @patch - static int get _namespacePointer { - throw UnsupportedError("_Namespace"); - } -} - -@patch -class _RandomAccessFileOps { - @patch - factory _RandomAccessFileOps(int pointer) { - throw UnsupportedError("RandomAccessFile"); - } -} - -@patch -bool _isDirectIOCapableTypedList(List buffer) { - throw UnsupportedError("_isDirectIOCapableTypedList"); -} - -@patch -class _IOCrypto { - @patch - static Uint8List getRandomBytes(int count) { - throw UnsupportedError("_IOCrypto.getRandomBytes"); - } -} - -@patch -class _Platform { - @patch - static int _numberOfProcessors() { - throw UnsupportedError("Platform._numberOfProcessors"); - } - - @patch - static String _pathSeparator() { - throw UnsupportedError("Platform._pathSeparator"); - } - - @patch - static String _operatingSystem() { - throw UnsupportedError("Platform._operatingSystem"); - } - - @patch - static _operatingSystemVersion() { - throw UnsupportedError("Platform._operatingSystemVersion"); - } - - @patch - static _localHostname() { - throw UnsupportedError("Platform._localHostname"); - } - - @patch - static _executable() { - throw UnsupportedError("Platform._executable"); - } - - @patch - static _resolvedExecutable() { - throw UnsupportedError("Platform._resolvedExecutable"); - } - - @patch - static List _executableArguments() { - throw UnsupportedError("Platform._executableArguments"); - } - - @patch - static String _packageRoot() { - throw UnsupportedError("Platform._packageRoot"); - } - - @patch - static String _packageConfig() { - throw UnsupportedError("Platform._packageConfig"); - } - - @patch - static _environment() { - throw UnsupportedError("Platform._environment"); - } - - @patch - static String _version() { - throw UnsupportedError("Platform._version"); - } - - @patch - static String _localeName() { - throw UnsupportedError("Platform._localeName"); - } - - @patch - static Uri _script() { - throw UnsupportedError("Platform._script"); - } -} - -@patch -class _ProcessUtils { - @patch - static Never _exit(int status) { - throw UnsupportedError("ProcessUtils._exit"); - } - - @patch - static void _setExitCode(int status) { - throw UnsupportedError("ProcessUtils._setExitCode"); - } - - @patch - static int _getExitCode() { - throw UnsupportedError("ProcessUtils._getExitCode"); - } - - @patch - static void _sleep(int millis) { - throw UnsupportedError("ProcessUtils._sleep"); - } - - @patch - static int _pid(Process? process) { - throw UnsupportedError("ProcessUtils._pid"); - } - - @patch - static Stream _watchSignal(ProcessSignal signal) { - throw UnsupportedError("ProcessUtils._watchSignal"); - } -} - -@patch -class ProcessInfo { - @patch - static int get currentRss { - throw UnsupportedError("ProcessInfo.currentRss"); - } - - @patch - static int get maxRss { - throw UnsupportedError("ProcessInfo.maxRss"); - } -} - -@patch -class Process { - @patch - static Future start(String executable, List arguments, - {String? workingDirectory, - Map? environment, - bool includeParentEnvironment = true, - bool runInShell = false, - ProcessStartMode mode = ProcessStartMode.normal}) { - throw UnsupportedError("Process.start"); - } - - @patch - static Future run(String executable, List arguments, - {String? workingDirectory, - Map? environment, - bool includeParentEnvironment = true, - bool runInShell = false, - Encoding stdoutEncoding = systemEncoding, - Encoding stderrEncoding = systemEncoding}) { - throw UnsupportedError("Process.run"); - } - - @patch - static ProcessResult runSync(String executable, List arguments, - {String? workingDirectory, - Map? environment, - bool includeParentEnvironment = true, - bool runInShell = false, - Encoding stdoutEncoding = systemEncoding, - Encoding stderrEncoding = systemEncoding}) { - throw UnsupportedError("Process.runSync"); - } - - @patch - static bool killPid(int pid, [ProcessSignal signal = ProcessSignal.sigterm]) { - throw UnsupportedError("Process.killPid"); - } -} - -@patch -class InternetAddress { - @patch - static InternetAddress get LOOPBACK_IP_V4 { - throw UnsupportedError("InternetAddress.LOOPBACK_IP_V4"); - } - - @patch - static InternetAddress get LOOPBACK_IP_V6 { - throw UnsupportedError("InternetAddress.LOOPBACK_IP_V6"); - } - - @patch - static InternetAddress get ANY_IP_V4 { - throw UnsupportedError("InternetAddress.ANY_IP_V4"); - } - - @patch - static InternetAddress get ANY_IP_V6 { - throw UnsupportedError("InternetAddress.ANY_IP_V6"); - } - - @patch - factory InternetAddress(String address, {InternetAddressType? type}) { - throw UnsupportedError("InternetAddress"); - } - - @patch - factory InternetAddress.fromRawAddress(Uint8List rawAddress, - {InternetAddressType? type}) { - throw new UnsupportedError("InternetAddress.fromRawAddress"); - } - - @patch - static Future> lookup(String host, - {InternetAddressType type = InternetAddressType.any}) { - throw UnsupportedError("InternetAddress.lookup"); - } - - @patch - static InternetAddress _cloneWithNewHost( - InternetAddress address, String host) { - throw UnsupportedError("InternetAddress._cloneWithNewHost"); - } - - @patch - static InternetAddress? tryParse(String address) { - throw UnsupportedError("InternetAddress.tryParse"); - } -} - -@patch -class NetworkInterface { - @patch - static bool get listSupported { - throw UnsupportedError("NetworkInterface.listSupported"); - } - - @patch - static Future> list( - {bool includeLoopback = false, - bool includeLinkLocal = false, - InternetAddressType type = InternetAddressType.any}) { - throw UnsupportedError("NetworkInterface.list"); - } -} - -@patch -class RawServerSocket { - @patch - static Future bind(address, int port, - {int backlog = 0, bool v6Only = false, bool shared = false}) { - throw UnsupportedError("RawServerSocket.bind"); - } -} - -@patch -class ServerSocket { - @patch - static Future _bind(address, int port, - {int backlog = 0, bool v6Only = false, bool shared = false}) { - throw UnsupportedError("ServerSocket.bind"); - } -} - -@patch -class RawSocket { - @patch - static Future connect(dynamic host, int port, - {dynamic sourceAddress, Duration? timeout}) { - throw UnsupportedError("RawSocket constructor"); - } - - @patch - static Future> startConnect(dynamic host, int port, - {dynamic sourceAddress}) { - throw UnsupportedError("RawSocket constructor"); - } -} - -@patch -class Socket { - @patch - static Future _connect(dynamic host, int port, - {dynamic sourceAddress, Duration? timeout}) { - throw UnsupportedError("Socket constructor"); - } - - @patch - static Future> _startConnect(dynamic host, int port, - {dynamic sourceAddress}) { - throw UnsupportedError("Socket constructor"); - } -} - -@patch -class SecureSocket { - @patch - factory SecureSocket._(RawSecureSocket rawSocket) { - throw UnsupportedError("SecureSocket constructor"); - } -} - -@patch -class RawSynchronousSocket { - @patch - static RawSynchronousSocket connectSync(dynamic host, int port) { - throw UnsupportedError("RawSynchronousSocket.connectSync"); - } -} - -@patch -class RawSocketOption { - @patch - static int _getOptionValue(int key) { - throw UnsupportedError("RawSocketOption._getOptionValue"); - } -} - -@patch -class SecurityContext { - @patch - factory SecurityContext({bool withTrustedRoots = false}) { - throw UnsupportedError("SecurityContext constructor"); - } - - @patch - static SecurityContext get defaultContext { - throw UnsupportedError("default SecurityContext getter"); - } - - @patch - static bool get alpnSupported { - throw UnsupportedError("SecurityContext alpnSupported getter"); - } -} - -@patch -class X509Certificate { - @patch - factory X509Certificate._() { - throw UnsupportedError("X509Certificate constructor"); - } -} - -@patch -class RawDatagramSocket { - @patch - static Future bind(dynamic host, int port, - {bool reuseAddress = true, bool reusePort = false, int ttl = 1}) { - throw UnsupportedError("RawDatagramSocket.bind"); - } -} - -@patch -class _SecureFilter { - @patch - factory _SecureFilter._() { - throw UnsupportedError("_SecureFilter._SecureFilter"); - } -} - -@patch -class _StdIOUtils { - @patch - static Stdin _getStdioInputStream(int fd) { - throw UnsupportedError("StdIOUtils._getStdioInputStream"); - } - - @patch - static _getStdioOutputStream(int fd) { - throw UnsupportedError("StdIOUtils._getStdioOutputStream"); - } - - @patch - static int _socketType(Socket socket) { - throw UnsupportedError("StdIOUtils._socketType"); - } - - @patch - static _getStdioHandleType(int fd) { - throw UnsupportedError("StdIOUtils._getStdioHandleType"); - } -} - -@patch -class _WindowsCodePageDecoder { - @patch - static String _decodeBytes(List bytes) { - throw UnsupportedError("_WindowsCodePageDecoder._decodeBytes"); - } -} - -@patch -class _WindowsCodePageEncoder { - @patch - static List _encodeString(String string) { - throw UnsupportedError("_WindowsCodePageEncoder._encodeString"); - } -} - -@patch -class RawZLibFilter { - @patch - static RawZLibFilter _makeZLibDeflateFilter( - bool gzip, - int level, - int windowBits, - int memLevel, - int strategy, - List? dictionary, - bool raw) { - throw UnsupportedError("_newZLibDeflateFilter"); - } - - @patch - static RawZLibFilter _makeZLibInflateFilter( - int windowBits, List? dictionary, bool raw) { - throw UnsupportedError("_newZLibInflateFilter"); - } -} - -@patch -class Stdin { - @patch - int readByteSync() { - throw UnsupportedError("Stdin.readByteSync"); - } - - @patch - bool get echoMode { - throw UnsupportedError("Stdin.echoMode"); - } - - @patch - void set echoMode(bool enabled) { - throw UnsupportedError("Stdin.echoMode"); - } - - @patch - bool get lineMode { - throw UnsupportedError("Stdin.lineMode"); - } - - @patch - void set lineMode(bool enabled) { - throw UnsupportedError("Stdin.lineMode"); - } - - @patch - bool get supportsAnsiEscapes { - throw UnsupportedError("Stdin.supportsAnsiEscapes"); - } -} - -@patch -class Stdout { - @patch - bool _hasTerminal(int fd) { - throw UnsupportedError("Stdout.hasTerminal"); - } - - @patch - int _terminalColumns(int fd) { - throw UnsupportedError("Stdout.terminalColumns"); - } - - @patch - int _terminalLines(int fd) { - throw UnsupportedError("Stdout.terminalLines"); - } - - @patch - static bool _supportsAnsiEscapes(int fd) { - throw UnsupportedError("Stdout.supportsAnsiEscapes"); - } -} - -@patch -class _FileSystemWatcher { - @patch - static Stream _watch( - String path, int events, bool recursive) { - throw UnsupportedError("_FileSystemWatcher.watch"); - } - - @patch - static bool get isSupported { - throw UnsupportedError("_FileSystemWatcher.isSupported"); - } -} - -@patch -class _IOService { - @patch - static Future _dispatch(int request, List data) { - throw UnsupportedError("_IOService._dispatch"); - } -} diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/isolate_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/isolate_patch.dart deleted file mode 100644 index 9b45b66e681..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/isolate_patch.dart +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright (c) 2012, 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. - -// Patch file for the dart:isolate library. - -import 'dart:_js_helper' show patch, NoReifyGeneric; -import 'dart:async'; -import "dart:typed_data" show TypedData; - -@patch -class Isolate { - // `current` must be a getter, not just a final field, - // to match the external declaration. - @patch - static Isolate get current => _unsupported(); - - @patch - String? get debugName => _unsupported(); - - @patch - static Future get packageRoot => _unsupported(); - - @patch - static Future get packageConfig => _unsupported(); - - @patch - static Future resolvePackageUri(Uri packageUri) => _unsupported(); - - @patch - static Future spawn(void entryPoint(T message), T message, - {bool paused = false, - bool errorsAreFatal = true, - SendPort? onExit, - SendPort? onError}) => - _unsupported(); - - @patch - static Future spawnUri(Uri uri, List args, var message, - {bool paused = false, - SendPort? onExit, - SendPort? onError, - bool errorsAreFatal = true, - bool? checked, - Map? environment, - Uri? packageRoot, - Uri? packageConfig, - bool automaticPackageResolution = false, - String? debugName}) => - _unsupported(); - - @patch - void _pause(Capability resumeCapability) => _unsupported(); - - @patch - void resume(Capability resumeCapability) => _unsupported(); - - @patch - void addOnExitListener(SendPort responsePort, {Object? response}) => - _unsupported(); - - @patch - void removeOnExitListener(SendPort responsePort) => _unsupported(); - - @patch - void setErrorsFatal(bool errorsAreFatal) => _unsupported(); - - @patch - void kill({int priority = beforeNextEvent}) => _unsupported(); - @patch - void ping(SendPort responsePort, - {Object? response, int priority = immediate}) => - _unsupported(); - - @patch - void addErrorListener(SendPort port) => _unsupported(); - - @patch - void removeErrorListener(SendPort port) => _unsupported(); -} - -/** Default factory for receive ports. */ -@patch -class ReceivePort { - @patch - factory ReceivePort() = _ReceivePort; - - @patch - factory ReceivePort.fromRawReceivePort(RawReceivePort rawPort) => - _unsupported(); -} - -/// ReceivePort is supported by dev_compiler because async test packages -/// (async_helper, unittest) create a dummy receive port to keep the Dart VM -/// alive. -class _ReceivePort extends Stream implements ReceivePort { - close() {} - - get sendPort => _unsupported(); - - StreamSubscription listen(void Function(dynamic)? onData, - {Function? onError, - void Function()? onDone, - bool? cancelOnError = true}) => - _unsupported(); -} - -@patch -class RawReceivePort { - @patch - factory RawReceivePort([Function? handler]) => _unsupported(); -} - -@patch -class Capability { - @patch - factory Capability() => _unsupported(); -} - -@patch -abstract class TransferableTypedData { - @patch - factory TransferableTypedData.fromList(List list) => - _unsupported(); -} - -@NoReifyGeneric() -T _unsupported() { - throw UnsupportedError('dart:isolate is not supported on dart4web'); -} diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/js_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/js_patch.dart deleted file mode 100644 index feb5ef1b186..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/js_patch.dart +++ /dev/null @@ -1,442 +0,0 @@ -// 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. - -// Patch file for dart:js library. -library dart.js; - -import 'dart:collection' show HashMap, ListMixin; - -import 'dart:_js_helper' show patch, NoReifyGeneric, Primitives; -import 'dart:_foreign_helper' show JS; -import 'dart:_runtime' as dart; - -@patch -JsObject get context => _context; - -final JsObject _context = _wrapToDart(dart.global_); - -@patch -class JsObject { - // The wrapped JS object. - final Object _jsObject; - - // This should only be called from _wrapToDart - JsObject._fromJs(this._jsObject) { - assert(_jsObject != null); - } - - @patch - factory JsObject(JsFunction constructor, [List? arguments]) { - var ctor = constructor._jsObject; - if (arguments == null) { - return _wrapToDart(JS('', 'new #()', ctor)); - } - var unwrapped = List.from(arguments.map(_convertToJS)); - return _wrapToDart(JS('', 'new #(...#)', ctor, unwrapped)); - } - - @patch - factory JsObject.fromBrowserObject(Object object) { - if (object is num || object is String || object is bool || object == null) { - throw ArgumentError("object cannot be a num, string, bool, or null"); - } - return _wrapToDart(_convertToJS(object)!); - } - - @patch - factory JsObject.jsify(Object object) { - if ((object is! Map) && (object is! Iterable)) { - throw ArgumentError("object must be a Map or Iterable"); - } - return _wrapToDart(_convertDataTree(object)); - } - - static _convertDataTree(Object data) { - var _convertedObjects = HashMap.identity(); - - _convert(Object? o) { - if (_convertedObjects.containsKey(o)) { - return _convertedObjects[o]; - } - if (o is Map) { - final convertedMap = JS('', '{}'); - _convertedObjects[o] = convertedMap; - for (var key in o.keys) { - JS('', '#[#] = #', convertedMap, key, _convert(o[key])); - } - return convertedMap; - } else if (o is Iterable) { - var convertedList = []; - _convertedObjects[o] = convertedList; - convertedList.addAll(o.map(_convert)); - return convertedList; - } else { - return _convertToJS(o); - } - } - - return _convert(data); - } - - @patch - dynamic operator [](Object property) { - if (property is! String && property is! num) { - throw ArgumentError("property is not a String or num"); - } - return _convertToDart(JS('', '#[#]', _jsObject, property)); - } - - @patch - void operator []=(Object property, Object? value) { - if (property is! String && property is! num) { - throw ArgumentError("property is not a String or num"); - } - JS('', '#[#] = #', _jsObject, property, _convertToJS(value)); - } - - @patch - bool operator ==(Object other) => - other is JsObject && JS('!', '# === #', _jsObject, other._jsObject); - - @patch - bool hasProperty(Object property) { - if (property is! String && property is! num) { - throw ArgumentError("property is not a String or num"); - } - return JS('!', '# in #', property, _jsObject); - } - - @patch - void deleteProperty(Object property) { - if (property is! String && property is! num) { - throw ArgumentError("property is not a String or num"); - } - JS('!', 'delete #[#]', _jsObject, property); - } - - @patch - bool instanceof(JsFunction type) { - return JS('!', '# instanceof #', _jsObject, _convertToJS(type)); - } - - @patch - String toString() { - try { - return JS('!', 'String(#)', _jsObject); - } catch (e) { - return super.toString(); - } - } - - @patch - dynamic callMethod(Object method, [List? args]) { - if (method is! String && method is! num) { - throw ArgumentError("method is not a String or num"); - } - if (args != null) args = List.from(args.map(_convertToJS)); - var fn = JS('', '#[#]', _jsObject, method); - if (JS('!', 'typeof(#) !== "function"', fn)) { - throw NoSuchMethodError(_jsObject, Symbol('$method'), args, {}); - } - return _convertToDart(JS('', '#.apply(#, #)', fn, _jsObject, args)); - } -} - -@patch -class JsFunction extends JsObject { - @patch - factory JsFunction.withThis(Function f) { - return JsFunction._fromJs(JS( - '', - 'function(/*...arguments*/) {' - ' let args = [#(this)];' - ' for (let arg of arguments) {' - ' args.push(#(arg));' - ' }' - ' return #(#(...args));' - '}', - _convertToDart, - _convertToDart, - _convertToJS, - f)); - } - - JsFunction._fromJs(Object jsObject) : super._fromJs(jsObject); - - @patch - dynamic apply(List args, {thisArg}) => _convertToDart(JS( - '', - '#.apply(#, #)', - _jsObject, - _convertToJS(thisArg), - args == null ? null : List.from(args.map(_convertToJS)))); -} - -// TODO(jmesserly): this is totally unnecessary in dev_compiler. -@patch -class JsArray extends JsObject with ListMixin { - @patch - factory JsArray() => JsArray._fromJs([]); - - @patch - factory JsArray.from(Iterable other) => - JsArray._fromJs([]..addAll(other.map(_convertToJS))); - - JsArray._fromJs(Object jsObject) : super._fromJs(jsObject); - - _checkIndex(int index) { - if (index < 0 || index >= length) { - throw RangeError.range(index, 0, length); - } - } - - _checkInsertIndex(int index) { - if (index < 0 || index >= length + 1) { - throw RangeError.range(index, 0, length); - } - } - - static _checkRange(int start, int end, int length) { - if (start < 0 || start > length) { - throw RangeError.range(start, 0, length); - } - if (end < start || end > length) { - throw RangeError.range(end, start, length); - } - } - - @patch - E operator [](Object index) { - if (index is int) { - _checkIndex(index); - } - return super[index] as E; - } - - @patch - void operator []=(Object index, value) { - if (index is int) { - _checkIndex(index); - } - super[index] = value; - } - - @patch - int get length { - // Check the length honours the List contract. - var len = JS('', '#.length', _jsObject); - // JavaScript arrays have lengths which are unsigned 32-bit integers. - if (JS( - '!', 'typeof # === "number" && (# >>> 0) === #', len, len, len)) { - return JS('!', '#', len); - } - throw StateError('Bad JsArray length'); - } - - @patch - void set length(int length) { - super['length'] = length; - } - - @patch - void add(E value) { - callMethod('push', [value]); - } - - @patch - void addAll(Iterable iterable) { - var list = (JS('!', '# instanceof Array', iterable)) - ? JS('', '#', iterable) - : List.from(iterable); - callMethod('push', list); - } - - @patch - void insert(int index, E element) { - _checkInsertIndex(index); - callMethod('splice', [index, 0, element]); - } - - @patch - E removeAt(int index) { - _checkIndex(index); - return callMethod('splice', [index, 1])[0] as E; - } - - @patch - E removeLast() { - if (length == 0) throw RangeError(-1); - return callMethod('pop') as E; - } - - @patch - void removeRange(int start, int end) { - _checkRange(start, end, length); - callMethod('splice', [start, end - start]); - } - - @patch - void setRange(int start, int end, Iterable iterable, [int skipCount = 0]) { - _checkRange(start, end, this.length); - int length = end - start; - if (length == 0) return; - if (skipCount < 0) throw ArgumentError(skipCount); - var args = [start, length] - ..addAll(iterable.skip(skipCount).take(length)); - callMethod('splice', args); - } - - @patch - void sort([int compare(E a, E b)?]) { - // Note: arr.sort(null) is a type error in FF - callMethod('sort', compare == null ? [] : [compare]); - } -} - -// Cross frame objects should not be considered browser types. -// We include the instanceof Object test to filter out cross frame objects -// on FireFox. Surprisingly on FireFox the instanceof Window test succeeds for -// cross frame windows while the instanceof Object test fails. -bool _isBrowserType(Object o) => JS( - 'bool', - '# instanceof Object && (' - '# instanceof Blob || ' - '# instanceof Event || ' - '(window.KeyRange && # instanceof KeyRange) || ' - '(window.IDBKeyRange && # instanceof IDBKeyRange) || ' - '# instanceof ImageData || ' - '# instanceof Node || ' - '(window.DataView && # instanceof DataView) || ' - // Int8Array.__proto__ is TypedArray. - '(window.Int8Array && # instanceof Int8Array.__proto__) || ' - '# instanceof Window)', - o, - o, - o, - o, - o, - o, - o, - o, - o, - o); - -class _DartObject { - final Object _dartObj; - _DartObject(this._dartObj); -} - -Object? _convertToJS(Object? o) { - if (o == null || o is String || o is num || o is bool || _isBrowserType(o)) { - return o; - } else if (o is DateTime) { - return Primitives.lazyAsJsDate(o); - } else if (o is JsObject) { - return o._jsObject; - } else if (o is Function) { - return _putIfAbsent(_jsProxies, o, _wrapDartFunction); - } else { - // TODO(jmesserly): for now, we wrap other objects, to keep compatibility - // with the original dart:js behavior. - return _putIfAbsent(_jsProxies, o, (o) => _DartObject(o)); - } -} - -Object _wrapDartFunction(Object f) { - var wrapper = JS( - '', - 'function(/*...arguments*/) {' - ' let args = Array.prototype.map.call(arguments, #);' - ' return #(#(...args));' - '}', - _convertToDart, - _convertToJS, - f); - JS('', '#.set(#, #)', _dartProxies, wrapper, f); - - return wrapper; -} - -// converts a Dart object to a reference to a native JS object -// which might be a DartObject JS->Dart proxy -Object? _convertToDart(Object? o) { - if (o == null || o is String || o is num || o is bool || _isBrowserType(o)) { - return o; - } else if (JS('!', '# instanceof Date', o)) { - int ms = JS('!', '#.getTime()', o); - return DateTime.fromMillisecondsSinceEpoch(ms); - } else if (o is _DartObject && - !identical(dart.getReifiedType(o), dart.jsobject)) { - return o._dartObj; - } else { - return _wrapToDart(o); - } -} - -JsObject _wrapToDart(Object o) => - _putIfAbsent(_dartProxies, o, _wrapToDartHelper); - -JsObject _wrapToDartHelper(Object o) { - if (JS('!', 'typeof # == "function"', o)) { - return JsFunction._fromJs(o); - } - if (JS('!', '# instanceof Array', o)) { - return JsArray._fromJs(o); - } - return JsObject._fromJs(o); -} - -final Object _dartProxies = JS('', 'new WeakMap()'); -final Object _jsProxies = JS('', 'new WeakMap()'); - -@NoReifyGeneric() -T _putIfAbsent(Object weakMap, Object o, T getValue(Object o)) { - T? value = JS('', '#.get(#)', weakMap, o); - if (value == null) { - value = getValue(o); - JS('', '#.set(#, #)', weakMap, o, value); - } - // TODO(vsm): Static cast. Unnecessary? - return JS('', '#', value); -} - -Expando _interopExpando = Expando(); - -@patch -F allowInterop(F f) { - if (!dart.isDartFunction(f)) return f; - var ret = _interopExpando[f] as F?; - if (ret == null) { - ret = JS( - '', - 'function (...args) {' - ' return #(#, args);' - '}', - dart.dcall, - f); - _interopExpando[f] = ret; - } - return ret; -} - -Expando _interopCaptureThisExpando = Expando(); - -@patch -Function allowInteropCaptureThis(Function f) { - if (!dart.isDartFunction(f)) return f; - var ret = _interopCaptureThisExpando[f]; - if (ret == null) { - ret = JS( - '', - 'function(...arguments) {' - ' let args = [this];' - ' args.push.apply(args, arguments);' - ' return #(#, args);' - '}', - dart.dcall, - f); - _interopCaptureThisExpando[f] = ret; - } - return ret; -} diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/math_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/math_patch.dart deleted file mode 100644 index 288f66e838d..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/math_patch.dart +++ /dev/null @@ -1,348 +0,0 @@ -// Copyright (c) 2012, 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. - -// Patch file for dart:math library. -import 'dart:_foreign_helper' show JS; -import 'dart:_js_helper' show patch, nullCheck, notNull; -import 'dart:typed_data' show ByteData; - -@patch -@notNull -T min(@nullCheck T a, @nullCheck T b) => - JS('-dynamic', r'Math.min(#, #)', a, b); - -@patch -@notNull -T max(@nullCheck T a, @nullCheck T b) => - JS('-dynamic', r'Math.max(#, #)', a, b); - -@patch -@notNull -double sqrt(@nullCheck num x) => JS('!', r'Math.sqrt(#)', x); - -@patch -@notNull -double sin(@nullCheck num radians) => JS('!', r'Math.sin(#)', radians); - -@patch -@notNull -double cos(@nullCheck num radians) => JS('!', r'Math.cos(#)', radians); - -@patch -@notNull -double tan(@nullCheck num radians) => JS('!', r'Math.tan(#)', radians); - -@patch -@notNull -double acos(@nullCheck num x) => JS('!', r'Math.acos(#)', x); - -@patch -@notNull -double asin(@nullCheck num x) => JS('!', r'Math.asin(#)', x); - -@patch -@notNull -double atan(@nullCheck num x) => JS('!', r'Math.atan(#)', x); - -@patch -@notNull -double atan2(@nullCheck num a, @nullCheck num b) => - JS('!', r'Math.atan2(#, #)', a, b); - -@patch -@notNull -double exp(@nullCheck num x) => JS('!', r'Math.exp(#)', x); - -@patch -@notNull -double log(@nullCheck num x) => JS('!', r'Math.log(#)', x); - -@patch -@notNull -num pow(@nullCheck num x, @nullCheck num exponent) => - JS('!', r'Math.pow(#, #)', x, exponent); - -const int _POW2_32 = 0x100000000; - -@patch -class Random { - static Random? _secureRandom; - - @patch - factory Random([int? seed]) => - (seed == null) ? const _JSRandom() : _Random(seed); - - @patch - factory Random.secure() => _secureRandom ??= _JSSecureRandom(); -} - -class _JSRandom implements Random { - // The Dart2JS implementation of Random doesn't use a seed. - const _JSRandom(); - - @notNull - int nextInt(int max) { - if (max <= 0 || max > _POW2_32) { - throw RangeError("max must be in range 0 < max ≤ 2^32, was $max"); - } - return JS("int", "(Math.random() * #) >>> 0", max); - } - - /** - * Generates a positive random floating point value uniformly distributed on - * the range from 0.0, inclusive, to 1.0, exclusive. - */ - @notNull - double nextDouble() => JS("double", "Math.random()"); - - /** - * Generates a random boolean value. - */ - @notNull - bool nextBool() => JS("bool", "Math.random() < 0.5"); -} - -class _Random implements Random { - // Constants used by the algorithm or masking. - static const double _POW2_53_D = 1.0 * (0x20000000000000); - static const double _POW2_27_D = 1.0 * (1 << 27); - static const int _MASK32 = 0xFFFFFFFF; - - // State comprised of two unsigned 32 bit integers. - @notNull - int _lo = 0; - @notNull - int _hi = 0; - - // Implements: - // uint64_t hash = 0; - // do { - // hash = hash * 1037 ^ mix64((uint64_t)seed); - // seed >>= 64; - // } while (seed != 0 && seed != -1); // Limits for pos/neg seed. - // if (hash == 0) { - // hash = 0x5A17; - // } - // _lo = hash & _MASK_32; - // _hi = hash >> 32; - // and then does four _nextState calls to shuffle bits around. - _Random(int seed) { - int empty_seed = 0; - if (seed < 0) { - empty_seed = -1; - } - do { - int low = seed & _MASK32; - seed = (seed - low) ~/ _POW2_32; - int high = seed & _MASK32; - seed = (seed - high) ~/ _POW2_32; - - // Thomas Wang's 64-bit mix function. - // http://www.concentric.net/~Ttwang/tech/inthash.htm - // via. http://web.archive.org/web/20071223173210/http://www.concentric.net/~Ttwang/tech/inthash.htm - - // key = ~key + (key << 21); - int tmplow = low << 21; - int tmphigh = (high << 21) | (low >> 11); - tmplow = (~low & _MASK32) + tmplow; - low = tmplow & _MASK32; - high = (~high + tmphigh + ((tmplow - low) ~/ 0x100000000)) & _MASK32; - // key = key ^ (key >> 24). - tmphigh = high >> 24; - tmplow = (low >> 24) | (high << 8); - low ^= tmplow; - high ^= tmphigh; - // key = key * 265 - tmplow = low * 265; - low = tmplow & _MASK32; - high = (high * 265 + (tmplow - low) ~/ 0x100000000) & _MASK32; - // key = key ^ (key >> 14); - tmphigh = high >> 14; - tmplow = (low >> 14) | (high << 18); - low ^= tmplow; - high ^= tmphigh; - // key = key * 21 - tmplow = low * 21; - low = tmplow & _MASK32; - high = (high * 21 + (tmplow - low) ~/ 0x100000000) & _MASK32; - // key = key ^ (key >> 28). - tmphigh = high >> 28; - tmplow = (low >> 28) | (high << 4); - low ^= tmplow; - high ^= tmphigh; - // key = key + (key << 31); - tmplow = low << 31; - tmphigh = (high << 31) | (low >> 1); - tmplow += low; - low = tmplow & _MASK32; - high = (high + tmphigh + (tmplow - low) ~/ 0x100000000) & _MASK32; - // Mix end. - - // seed = seed * 1037 ^ key; - tmplow = _lo * 1037; - _lo = tmplow & _MASK32; - _hi = (_hi * 1037 + (tmplow - _lo) ~/ 0x100000000) & _MASK32; - _lo ^= low; - _hi ^= high; - } while (seed != empty_seed); - - if (_hi == 0 && _lo == 0) { - _lo = 0x5A17; - } - _nextState(); - _nextState(); - _nextState(); - _nextState(); - } - - // The algorithm used here is Multiply with Carry (MWC) with a Base b = 2^32. - // http://en.wikipedia.org/wiki/Multiply-with-carry - // The constant A (0xFFFFDA61) is selected from "Numerical Recipes 3rd - // Edition" p.348 B1. - - // Implements: - // var state = (A * _lo + _hi) & _MASK_64; - // _lo = state & _MASK_32; - // _hi = state >> 32; - void _nextState() { - // Simulate (0xFFFFDA61 * lo + hi) without overflowing 53 bits. - int tmpHi = 0xFFFF0000 * _lo; // At most 48 bits of significant result. - int tmpHiLo = tmpHi & _MASK32; // Get the lower 32 bits. - int tmpHiHi = tmpHi - tmpHiLo; // And just the upper 32 bits. - int tmpLo = 0xDA61 * _lo; - int tmpLoLo = tmpLo & _MASK32; - int tmpLoHi = tmpLo - tmpLoLo; - - int newLo = tmpLoLo + tmpHiLo + _hi; - _lo = newLo & _MASK32; - int newLoHi = newLo - _lo; - _hi = ((tmpLoHi + tmpHiHi + newLoHi) ~/ _POW2_32) & _MASK32; - assert(_lo < _POW2_32); - assert(_hi < _POW2_32); - } - - @notNull - int nextInt(@nullCheck int max) { - if (max <= 0 || max > _POW2_32) { - throw RangeError("max must be in range 0 < max ≤ 2^32, was $max"); - } - if ((max & (max - 1)) == 0) { - // Fast case for powers of two. - _nextState(); - return _lo & (max - 1); - } - - int rnd32; - int result; - do { - _nextState(); - rnd32 = _lo; - result = rnd32.remainder(max).toInt(); // % max; - } while ((rnd32 - result + max) >= _POW2_32); - return result; - } - - @notNull - double nextDouble() { - _nextState(); - int bits26 = _lo & ((1 << 26) - 1); - _nextState(); - int bits27 = _lo & ((1 << 27) - 1); - return (bits26 * _POW2_27_D + bits27) / _POW2_53_D; - } - - @notNull - bool nextBool() { - _nextState(); - return (_lo & 1) == 0; - } -} - -class _JSSecureRandom implements Random { - // Reused buffer with room enough for a double. - final _buffer = ByteData(8); - - _JSSecureRandom() { - var crypto = JS("", "self.crypto"); - if (crypto != null) { - var getRandomValues = JS("", "#.getRandomValues", crypto); - if (getRandomValues != null) { - return; - } - } - throw UnsupportedError( - "No source of cryptographically secure random numbers available."); - } - - /// Fill _buffer from [start] to `start + length` with random bytes. - void _getRandomBytes(int start, int length) { - JS("void", "crypto.getRandomValues(#)", - _buffer.buffer.asUint8List(start, length)); - } - - @notNull - bool nextBool() { - _getRandomBytes(0, 1); - return _buffer.getUint8(0).isOdd; - } - - @notNull - double nextDouble() { - _getRandomBytes(1, 7); - // Set top bits 12 of double to 0x3FF which is the exponent for numbers - // between 1.0 and 2.0. - _buffer.setUint8(0, 0x3F); - int highByte = _buffer.getUint8(1); - _buffer.setUint8(1, highByte | 0xF0); - - // Buffer now contains double in the range [1.0-2.0) - // with 52 bits of entropy (not 53). - // To get 53 bits, we extract the 53rd bit from higthByte before - // overwriting it, and add that as a least significant bit. - // The getFloat64 method is big-endian as default. - double result = _buffer.getFloat64(0) - 1.0; - if (highByte & 0x10 != 0) { - result += 1.1102230246251565e-16; // pow(2,-53). - } - return result; - } - - @notNull - int nextInt(@nullCheck int max) { - if (max <= 0 || max > _POW2_32) { - throw RangeError("max must be in range 0 < max ≤ 2^32, was $max"); - } - int byteCount = 1; - if (max > 0xFF) { - byteCount++; - if (max > 0xFFFF) { - byteCount++; - if (max > 0xFFFFFF) { - byteCount++; - } - } - } - _buffer.setUint32(0, 0); - int start = 4 - byteCount; - int randomLimit = pow(256, byteCount).toInt(); - while (true) { - _getRandomBytes(start, byteCount); - // The getUint32 method is big-endian as default. - int random = _buffer.getUint32(0); - if (max & (max - 1) == 0) { - // Max is power of 2. - return random & (max - 1); - } - int result = random.remainder(max).toInt(); - // Ensure results have equal probability by rejecting values in the - // last range of k*max .. 256**byteCount. - // TODO: Consider picking a higher byte count if the last range is a - // significant portion of the entire range - a 50% chance of having - // to use two more bytes is no worse than always using one more. - if (random - result + max < randomLimit) { - return result; - } - } - } -} diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/typed_data_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/typed_data_patch.dart deleted file mode 100644 index d1c6a1a19f3..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/typed_data_patch.dart +++ /dev/null @@ -1,190 +0,0 @@ -// Copyright (c) 2013, 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 'dart:_js_helper' show patch; -import 'dart:_native_typed_data'; - -@patch -class ByteData { - @patch - factory ByteData(int length) = NativeByteData; -} - -@patch -class Float32List { - @patch - factory Float32List(int length) = NativeFloat32List; - - @patch - factory Float32List.fromList(List elements) = - NativeFloat32List.fromList; -} - -@patch -class Float64List { - @patch - factory Float64List(int length) = NativeFloat64List; - - @patch - factory Float64List.fromList(List elements) = - NativeFloat64List.fromList; -} - -@patch -class Int16List { - @patch - factory Int16List(int length) = NativeInt16List; - - @patch - factory Int16List.fromList(List elements) = NativeInt16List.fromList; -} - -@patch -class Int32List { - @patch - factory Int32List(int length) = NativeInt32List; - - @patch - factory Int32List.fromList(List elements) = NativeInt32List.fromList; -} - -@patch -class Int8List { - @patch - factory Int8List(int length) = NativeInt8List; - - @patch - factory Int8List.fromList(List elements) = NativeInt8List.fromList; -} - -@patch -class Uint32List { - @patch - factory Uint32List(int length) = NativeUint32List; - - @patch - factory Uint32List.fromList(List elements) = NativeUint32List.fromList; -} - -@patch -class Uint16List { - @patch - factory Uint16List(int length) = NativeUint16List; - - @patch - factory Uint16List.fromList(List elements) = NativeUint16List.fromList; -} - -@patch -class Uint8ClampedList { - @patch - factory Uint8ClampedList(int length) = NativeUint8ClampedList; - - @patch - factory Uint8ClampedList.fromList(List elements) = - NativeUint8ClampedList.fromList; -} - -@patch -class Uint8List { - @patch - factory Uint8List(int length) = NativeUint8List; - - @patch - factory Uint8List.fromList(List elements) = NativeUint8List.fromList; -} - -@patch -class Int64List { - @patch - factory Int64List(int length) { - throw UnsupportedError("Int64List not supported on the web."); - } - - @patch - factory Int64List.fromList(List elements) { - throw UnsupportedError("Int64List not supported on the web."); - } -} - -@patch -class Uint64List { - @patch - factory Uint64List(int length) { - throw UnsupportedError("Uint64List not supported on the web."); - } - - @patch - factory Uint64List.fromList(List elements) { - throw UnsupportedError("Uint64List not supported on the web."); - } -} - -@patch -class Int32x4List { - @patch - factory Int32x4List(int length) = NativeInt32x4List; - - @patch - factory Int32x4List.fromList(List elements) = - NativeInt32x4List.fromList; -} - -@patch -class Float32x4List { - @patch - factory Float32x4List(int length) = NativeFloat32x4List; - - @patch - factory Float32x4List.fromList(List elements) = - NativeFloat32x4List.fromList; -} - -@patch -class Float64x2List { - @patch - factory Float64x2List(int length) = NativeFloat64x2List; - - @patch - factory Float64x2List.fromList(List elements) = - NativeFloat64x2List.fromList; -} - -@patch -class Float32x4 { - @patch - factory Float32x4(double x, double y, double z, double w) = NativeFloat32x4; - @patch - factory Float32x4.splat(double v) = NativeFloat32x4.splat; - @patch - factory Float32x4.zero() = NativeFloat32x4.zero; - @patch - factory Float32x4.fromInt32x4Bits(Int32x4 x) = - NativeFloat32x4.fromInt32x4Bits; - @patch - factory Float32x4.fromFloat64x2(Float64x2 v) = NativeFloat32x4.fromFloat64x2; -} - -@patch -class Int32x4 { - @patch - factory Int32x4(int x, int y, int z, int w) = NativeInt32x4; - @patch - factory Int32x4.bool(bool x, bool y, bool z, bool w) = NativeInt32x4.bool; - @patch - factory Int32x4.fromFloat32x4Bits(Float32x4 x) = - NativeInt32x4.fromFloat32x4Bits; -} - -@patch -class Float64x2 { - @patch - factory Float64x2(double x, double y) = NativeFloat64x2; - @patch - factory Float64x2.splat(double v) = NativeFloat64x2.splat; - @patch - factory Float64x2.zero() = NativeFloat64x2.zero; - @patch - factory Float64x2.fromFloat32x4(Float32x4 v) = NativeFloat64x2.fromFloat32x4; -} diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/annotations.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/annotations.dart deleted file mode 100644 index 9062f3170e6..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/annotations.dart +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright (c) 2013, 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. - -part of dart._js_helper; - -/// Tells the optimizing compiler to always inline the annotated method. -class ForceInline { - const ForceInline(); -} - -class _NotNull { - const _NotNull(); -} - -/// Marks a variable or API to be non-nullable. -/// ****CAUTION****** -/// This is currently unchecked, and hence should never be used -/// on any public interface where user code could subclass, implement, -/// or otherwise cause the contract to be violated. -/// TODO(leafp): Consider adding static checking and exposing -/// this to user code. -const notNull = _NotNull(); - -/// Marks a generic function or static method API to be not reified. -/// ****CAUTION****** -/// This is currently unchecked, and hence should be used very carefully for -/// internal SDK APIs only. -class NoReifyGeneric { - const NoReifyGeneric(); -} - -/// Enables/disables reification of functions within the body of this function. -/// ****CAUTION****** -/// This is currently unchecked, and hence should be used very carefully for -/// internal SDK APIs only. -class ReifyFunctionTypes { - final bool value; - const ReifyFunctionTypes(this.value); -} - -class _NullCheck { - const _NullCheck(); -} - -/// Annotation indicating the parameter should default to the JavaScript -/// undefined constant. -const undefined = _Undefined(); - -class _Undefined { - const _Undefined(); -} - -/// Tells the development compiler to check a variable for null at its -/// declaration point, and then to assume that the variable is non-null -/// from that point forward. -/// ****CAUTION****** -/// This is currently unchecked, and hence will not catch re-assignments -/// of a variable with null -const nullCheck = _NullCheck(); - -/// Tells the optimizing compiler that the annotated method cannot throw. -/// Requires @NoInline() to function correctly. -class NoThrows { - const NoThrows(); -} - -/// Tells the optimizing compiler to not inline the annotated method. -class NoInline { - const NoInline(); -} - -/// Marks a class as native and defines its JavaScript name(s). -class Native { - final String name; - const Native(this.name); -} - -class JsPeerInterface { - /// The JavaScript type that we should match the API of. - /// Used for classes where Dart subclasses should be callable from JavaScript - /// matching the JavaScript calling conventions. - final String name; - const JsPeerInterface({required this.name}); -} - -/// A Dart interface may only be implemented by a native JavaScript object -/// if it is marked with this annotation. -class SupportJsExtensionMethods { - const SupportJsExtensionMethods(); -} diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/custom_hash_map.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/custom_hash_map.dart deleted file mode 100644 index 14444e32ff6..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/custom_hash_map.dart +++ /dev/null @@ -1,197 +0,0 @@ -// Copyright (c) 2017, 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. - -part of dart._js_helper; - -class CustomKeyHashMap extends CustomHashMap { - final _Predicate _validKey; - CustomKeyHashMap(_Equality equals, _Hasher hashCode, this._validKey) - : super(equals, hashCode); - - @override - @notNull - bool containsKey(Object? key) { - if (!_validKey(key)) return false; - return super.containsKey(key); - } - - @override - V? operator [](Object? key) { - if (!_validKey(key)) return null; - return super[key]; - } - - @override - V? remove(Object? key) { - if (!_validKey(key)) return null; - return super.remove(key); - } -} - -class CustomHashMap extends InternalMap { - /// The backing store for this map. - @notNull - final _map = JS('', 'new Map()'); - - /// Our map used to map keys onto the canonical key that is stored in [_map]. - @notNull - final _keyMap = JS('', 'new Map()'); - - // We track the number of modifications done to the key set of the - // hash map to be able to throw when the map is modified while being - // iterated over. - // - // Value cycles after 2^30 modifications so that modification counts are - // always unboxed (Smi) values. Modification detection will be missed if you - // make exactly some multiple of 2^30 modifications between advances of an - // iterator. - @notNull - int _modifications = 0; - - final _Equality _equals; - final _Hasher _hashCode; - - CustomHashMap(this._equals, this._hashCode); - - @notNull - int get length => JS('!', '#.size', _map); - - @notNull - bool get isEmpty => JS('!', '#.size == 0', _map); - - @notNull - bool get isNotEmpty => JS('!', '#.size != 0', _map); - - Iterable get keys => _JSMapIterable(this, true); - Iterable get values => _JSMapIterable(this, false); - - @notNull - bool containsKey(Object? key) { - if (key is K) { - var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, _hashCode(key)); - if (buckets != null) { - var equals = _equals; - for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) { - K k = JS('', '#[#]', buckets, i); - if (equals(k, key)) return true; - } - } - } - return false; - } - - bool containsValue(Object? value) { - for (var v in JS('', '#.values()', _map)) { - if (value == v) return true; - } - return false; - } - - void addAll(Map other) { - other.forEach((K key, V value) { - this[key] = value; - }); - } - - V? operator [](Object? key) { - if (key is K) { - var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, _hashCode(key)); - if (buckets != null) { - var equals = _equals; - for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) { - K k = JS('', '#[#]', buckets, i); - if (equals(k, key)) { - V value = JS('', '#.get(#)', _map, k); - return value == null ? null : value; // coerce undefined to null. - } - } - } - } - return null; - } - - void operator []=(K key, V value) { - var keyMap = _keyMap; - int hash = JS('!', '# & 0x3ffffff', _hashCode(key)); - var buckets = JS('', '#.get(#)', keyMap, hash); - if (buckets == null) { - JS('', '#.set(#, [#])', keyMap, hash, key); - } else { - var equals = _equals; - for (int i = 0, n = JS('!', '#.length', buckets);;) { - K k = JS('', '#[#]', buckets, i); - if (equals(k, key)) { - key = k; - break; - } - if (++i >= n) { - JS('', '#.push(#)', buckets, key); - break; - } - } - } - JS('', '#.set(#, #)', _map, key, value); - _modifications = (_modifications + 1) & 0x3ffffff; - } - - V putIfAbsent(K key, V ifAbsent()) { - var keyMap = _keyMap; - int hash = JS('!', '# & 0x3ffffff', _hashCode(key)); - var buckets = JS('', '#.get(#)', keyMap, hash); - if (buckets == null) { - JS('', '#.set(#, [#])', keyMap, hash, key); - } else { - var equals = _equals; - for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) { - K k = JS('', '#[#]', buckets, i); - if (equals(k, key)) return JS('', '#.get(#)', _map, k); - } - JS('', '#.push(#)', buckets, key); - } - V value = ifAbsent(); - if (value == null) JS('', '# = null', value); // coerce undefined to null. - JS('', '#.set(#, #)', _map, key, value); - _modifications = (_modifications + 1) & 0x3ffffff; - return value; - } - - V? remove(Object? key) { - if (key is K) { - int hash = JS('!', '# & 0x3ffffff', _hashCode(key)); - var keyMap = _keyMap; - var buckets = JS('', '#.get(#)', keyMap, hash); - if (buckets == null) return null; // not found - var equals = _equals; - for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) { - K k = JS('', '#[#]', buckets, i); - if (equals(k, key)) { - if (n == 1) { - JS('', '#.delete(#)', keyMap, hash); - } else { - JS('', '#.splice(#, 1)', buckets, i); - } - var map = _map; - V value = JS('', '#.get(#)', map, k); - JS('', '#.delete(#)', map, k); - _modifications = (_modifications + 1) & 0x3ffffff; - return value == null ? null : value; // coerce undefined to null. - } - } - } - return null; - } - - void clear() { - var map = _map; - if (JS('!', '#.size', map) > 0) { - JS('', '#.clear()', map); - JS('', '#.clear()', _keyMap); - _modifications = (_modifications + 1) & 0x3ffffff; - } - } -} - -typedef bool _Equality(K a, K b); -typedef int _Hasher(K object); -typedef bool _Predicate(T value); diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/classes.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/classes.dart deleted file mode 100644 index bb580634fd9..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/classes.dart +++ /dev/null @@ -1,595 +0,0 @@ -// 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. - -/// This library defines the operations that define and manipulate Dart -/// classes. Included in this are: -/// - Generics -/// - Class metadata -/// - Extension methods -/// - -// TODO(leafp): Consider splitting some of this out. -part of dart._runtime; - -/// Returns a new type that mixes members from base and the mixin. -void applyMixin(to, from) { - JS('', '#[#] = #', to, _mixin, from); - var toProto = JS('', '#.prototype', to); - var fromProto = JS('', '#.prototype', from); - _copyMembers(toProto, fromProto); - _mixinSignature(to, from, _methodSig); - _mixinSignature(to, from, _fieldSig); - _mixinSignature(to, from, _getterSig); - _mixinSignature(to, from, _setterSig); - var mixinOnFn = JS('', '#[#]', from, mixinOn); - if (mixinOnFn != null) { - var proto = JS('', '#(#.__proto__).prototype', mixinOnFn, to); - _copyMembers(toProto, proto); - } -} - -void _copyMembers(to, from) { - var names = getOwnNamesAndSymbols(from); - for (int i = 0, n = JS('!', '#.length', names); i < n; ++i) { - String name = JS('', '#[#]', names, i); - if (name == 'constructor') continue; - _copyMember(to, from, name); - } - return to; -} - -void _copyMember(to, from, name) { - var desc = getOwnPropertyDescriptor(from, name); - if (JS('!', '# == Symbol.iterator', name)) { - // On native types, Symbol.iterator may already be present. - // TODO(jmesserly): investigate if we still need this. - // If so, we need to find a better solution. - // See https://github.com/dart-lang/sdk/issues/28324 - var existing = getOwnPropertyDescriptor(to, name); - if (existing != null) { - if (JS('!', '#.writable', existing)) { - JS('', '#[#] = #.value', to, name, desc); - } - return; - } - } - var getter = JS('', '#.get', desc); - var setter = JS('', '#.set', desc); - if (getter != null) { - if (setter == null) { - var obj = JS( - '!', - '#.set = { __proto__: #.__proto__, ' - 'set [#](x) { return super[#] = x; } }', - desc, - to, - name, - name); - JS( - '!', '#.set = #.set', desc, getOwnPropertyDescriptor(obj, name)); - } - } else if (setter != null) { - if (getter == null) { - var obj = JS( - '!', - '#.get = { __proto__: #.__proto__, ' - 'get [#]() { return super[#]; } }', - desc, - to, - name, - name); - JS( - '!', '#.get = #.get', desc, getOwnPropertyDescriptor(obj, name)); - } - } - defineProperty(to, name, desc); -} - -void _mixinSignature(to, from, kind) { - JS('', '#[#] = #', to, kind, () { - var baseMembers = _getMembers(JS('', '#.__proto__', to), kind); - var fromMembers = _getMembers(from, kind); - if (fromMembers == null) return baseMembers; - var toSignature = JS('', '{ __proto__: # }', baseMembers); - copyProperties(toSignature, fromMembers); - return toSignature; - }); -} - -final _mixin = JS('', 'Symbol("mixin")'); - -getMixin(clazz) => JS('', 'Object.hasOwnProperty.call(#, #) ? #[#] : null', - clazz, _mixin, clazz, _mixin); - -final mixinOn = JS('', 'Symbol("mixinOn")'); - -@JSExportName('implements') -final implements_ = JS('', 'Symbol("implements")'); - -List? Function() getImplements(clazz) => JS( - '', - 'Object.hasOwnProperty.call(#, #) ? #[#] : null', - clazz, - implements_, - clazz, - implements_); - -/// The Symbol for storing type arguments on a specialized generic type. -final _typeArguments = JS('', 'Symbol("typeArguments")'); - -final _variances = JS('', 'Symbol("variances")'); - -final _originalDeclaration = JS('', 'Symbol("originalDeclaration")'); - -final mixinNew = JS('', 'Symbol("dart.mixinNew")'); - -/// Normalizes `FutureOr` types when they are constructed at runtime. -/// -/// This normalization should mirror the normalization performed at compile time -/// in the method named `_normalizeFutureOr()`. -/// -/// **NOTE** Normalization of FutureOr? --> FutureOr is handled in -/// [nullable]. -normalizeFutureOr(typeConstructor, setBaseClass) { - // The canonical version of the generic FutureOr type constructor. - var genericFutureOrType = - JS('!', '#', generic(typeConstructor, setBaseClass)); - - normalize(typeArg) { - // Normalize raw FutureOr --> dynamic - if (JS('!', '# == void 0', typeArg)) return _dynamic; - - // FutureOr --> - // dynamic|void|Object?|Object*|Object - if (_isTop(typeArg) || - _equalType(typeArg, Object) || - (_jsInstanceOf(typeArg, LegacyType) && - JS('!', '#.type === #', typeArg, Object))) { - return typeArg; - } - - // FutureOr --> Future - if (_equalType(typeArg, Never)) { - return JS('!', '#(#)', getGenericClass(Future), typeArg); - } - // FutureOr --> Future? - if (_equalType(typeArg, Null)) { - return nullable(JS('!', '#(#)', getGenericClass(Future), typeArg)); - } - // Otherwise, create the FutureOr type as a normal generic type. - var genericType = JS('!', '#(#)', genericFutureOrType, typeArg); - // Overwrite the original declaration so that it correctly points back to - // this method. This ensures that the we can test a type value returned here - // as a FutureOr because it is equal to 'async.FutureOr` (in the JS). - JS('!', '#[#] = #', genericType, _originalDeclaration, normalize); - JS('!', '#(#)', addTypeCaches, genericType); - return genericType; - } - - return normalize; -} - -/// Memoize a generic type constructor function. -generic(typeConstructor, setBaseClass) => JS('', '''(() => { - let length = $typeConstructor.length; - if (length < 1) { - $throwInternalError('must have at least one generic type argument'); - } - let resultMap = new Map(); - // TODO(vsm): Rethink how to clear the resultMap on hot restart. - // A simple clear via: - // _cacheMaps.push(resultMap); - // will break (a) we hoist type expressions in generated code and - // (b) we don't clear those type expressions in the presence of a - // hot restart. Not clearing this map (as we're doing now) should - // not affect correctness, but can result in a memory leak across - // multiple restarts. - function makeGenericType(...args) { - if (args.length != length && args.length != 0) { - $throwInternalError('requires ' + length + ' or 0 type arguments'); - } - while (args.length < length) args.push($dynamic); - - let value = resultMap; - for (let i = 0; i < length; i++) { - let arg = args[i]; - if (arg == null) { - $throwInternalError('type arguments should not be null: ' - + $typeConstructor); - } - let map = value; - value = map.get(arg); - if (value === void 0) { - if (i + 1 == length) { - value = $typeConstructor.apply(null, args); - // Save the type constructor and arguments for reflection. - if (value) { - value[$_typeArguments] = args; - value[$_originalDeclaration] = makeGenericType; - } - map.set(arg, value); - if ($setBaseClass != null) $setBaseClass.apply(null, args); - } else { - value = new Map(); - map.set(arg, value); - } - } - } - return value; - } - makeGenericType[$_genericTypeCtor] = $typeConstructor; - $addTypeCaches(makeGenericType); - return makeGenericType; -})()'''); - -getGenericClass(type) => safeGetOwnProperty(type, _originalDeclaration); - -// TODO(markzipan): Make this non-nullable if we can ensure this returns -// an empty list or if null and the empty list are semantically the same. -List? getGenericArgs(type) => - JS('', '#', safeGetOwnProperty(type, _typeArguments)); - -List? getGenericArgVariances(type) => - JS('', '#', safeGetOwnProperty(type, _variances)); - -void setGenericArgVariances(f, variances) => - JS('', '#[#] = #', f, _variances, variances); - -List getGenericTypeFormals(genericClass) { - return _typeFormalsFromFunction(getGenericTypeCtor(genericClass)); -} - -Object instantiateClass(Object genericClass, List typeArgs) { - return JS('', '#.apply(null, #)', genericClass, typeArgs); -} - -final _constructorSig = JS('', 'Symbol("sigCtor")'); -final _methodSig = JS('', 'Symbol("sigMethod")'); -final _fieldSig = JS('', 'Symbol("sigField")'); -final _getterSig = JS('', 'Symbol("sigGetter")'); -final _setterSig = JS('', 'Symbol("sigSetter")'); -final _staticMethodSig = JS('', 'Symbol("sigStaticMethod")'); -final _staticFieldSig = JS('', 'Symbol("sigStaticField")'); -final _staticGetterSig = JS('', 'Symbol("sigStaticGetter")'); -final _staticSetterSig = JS('', 'Symbol("sigStaticSetter")'); -final _genericTypeCtor = JS('', 'Symbol("genericType")'); -final _libraryUri = JS('', 'Symbol("libraryUri")'); - -getConstructors(value) => _getMembers(value, _constructorSig); -getMethods(value) => _getMembers(value, _methodSig); -getFields(value) => _getMembers(value, _fieldSig); -getGetters(value) => _getMembers(value, _getterSig); -getSetters(value) => _getMembers(value, _setterSig); -getStaticMethods(value) => _getMembers(value, _staticMethodSig); -getStaticFields(value) => _getMembers(value, _staticFieldSig); -getStaticGetters(value) => _getMembers(value, _staticGetterSig); -getStaticSetters(value) => _getMembers(value, _staticSetterSig); - -getGenericTypeCtor(value) => JS('', '#[#]', value, _genericTypeCtor); - -/// Get the type of a method from an object using the stored signature -getType(obj) => - JS('', '# == null ? # : #.__proto__.constructor', obj, Object, obj); - -getLibraryUri(value) => JS('', '#[#]', value, _libraryUri); -setLibraryUri(f, uri) => JS('', '#[#] = #', f, _libraryUri, uri); - -bool isJsInterop(obj) { - if (obj == null) return false; - if (JS('!', 'typeof # === "function"', obj)) { - // A function is a Dart function if it has runtime type information. - return JS('!', '#[#] == null', obj, _runtimeType); - } - // Primitive types are not JS interop types. - if (JS('!', 'typeof # !== "object"', obj)) return false; - - // Extension types are not considered JS interop types. - // Note that it is still possible to call typed JS interop methods on - // extension types but the calls must be statically typed. - if (JS('!', '#[#] != null', obj, _extensionType)) return false; - return !_jsInstanceOf(obj, Object); -} - -/// Get the type of a method from a type using the stored signature -getMethodType(type, name) { - var m = getMethods(type); - return m != null ? JS('', '#[#]', m, name) : null; -} - -/// Gets the type of the corresponding setter (this includes writable fields). -getSetterType(type, name) { - var setters = getSetters(type); - if (setters != null) { - var type = JS('', '#[#]', setters, name); - if (type != null) { - return type; - } - } - var fields = getFields(type); - if (fields != null) { - var fieldInfo = JS('', '#[#]', fields, name); - if (fieldInfo != null && JS('!', '!#.isFinal', fieldInfo)) { - return JS('', '#.type', fieldInfo); - } - } - return null; -} - -finalFieldType(type, metadata) => - JS('', '{ type: #, isFinal: true, metadata: # }', type, metadata); - -fieldType(type, metadata) => - JS('', '{ type: #, isFinal: false, metadata: # }', type, metadata); - -/// Get the type of a constructor from a class using the stored signature -/// If name is undefined, returns the type of the default constructor -/// Returns undefined if the constructor is not found. -classGetConstructorType(cls, name) { - if (cls == null) return null; - if (name == null) name = 'new'; - var ctors = getConstructors(cls); - return ctors != null ? JS('', '#[#]', ctors, name) : null; -} - -void setMethodSignature(f, sigF) => JS('', '#[#] = #', f, _methodSig, sigF); -void setFieldSignature(f, sigF) => JS('', '#[#] = #', f, _fieldSig, sigF); -void setGetterSignature(f, sigF) => JS('', '#[#] = #', f, _getterSig, sigF); -void setSetterSignature(f, sigF) => JS('', '#[#] = #', f, _setterSig, sigF); - -// Set up the constructor signature field on the constructor -void setConstructorSignature(f, sigF) => - JS('', '#[#] = #', f, _constructorSig, sigF); - -// Set up the static signature field on the constructor -void setStaticMethodSignature(f, sigF) => - JS('', '#[#] = #', f, _staticMethodSig, sigF); - -void setStaticFieldSignature(f, sigF) => - JS('', '#[#] = #', f, _staticFieldSig, sigF); - -void setStaticGetterSignature(f, sigF) => - JS('', '#[#] = #', f, _staticGetterSig, sigF); - -void setStaticSetterSignature(f, sigF) => - JS('', '#[#] = #', f, _staticSetterSig, sigF); - -_getMembers(type, kind) { - var sig = JS('', '#[#]', type, kind); - return JS('!', 'typeof # == "function"', sig) - ? JS('', '#[#] = #()', type, kind, sig) - : sig; -} - -bool _hasMember(type, kind, name) { - var sig = _getMembers(type, kind); - return sig != null && JS('!', '# in #', name, sig); -} - -bool hasMethod(type, name) => _hasMember(type, _methodSig, name); -bool hasGetter(type, name) => _hasMember(type, _getterSig, name); -bool hasSetter(type, name) => _hasMember(type, _setterSig, name); -bool hasField(type, name) => _hasMember(type, _fieldSig, name); - -final _extensionType = JS('', 'Symbol("extensionType")'); - -final dartx = JS('', 'dartx'); - -/// Install properties in prototype-first order. Properties / descriptors from -/// more specific types should overwrite ones from less specific types. -void _installProperties(jsProto, dartType, installedParent) { - if (JS('!', '# === #', dartType, Object)) { - _installPropertiesForObject(jsProto); - return; - } - // If the extension methods of the parent have been installed on the parent - // of [jsProto], the methods will be available via prototype inheritance. - var dartSupertype = JS('!', '#.__proto__', dartType); - if (JS('!', '# !== #', dartSupertype, installedParent)) { - _installProperties(jsProto, dartSupertype, installedParent); - } - - var dartProto = JS('!', '#.prototype', dartType); - copyTheseProperties(jsProto, dartProto, getOwnPropertySymbols(dartProto)); -} - -void _installPropertiesForObject(jsProto) { - // core.Object members need to be copied from the non-symbol name to the - // symbol name. - var coreObjProto = JS('!', '#.prototype', Object); - var names = getOwnPropertyNames(coreObjProto); - for (int i = 0, n = JS('!', '#.length', names); i < n; ++i) { - var name = JS('!', '#[#]', names, i); - if (name == 'constructor') continue; - var desc = getOwnPropertyDescriptor(coreObjProto, name); - defineProperty(jsProto, JS('', '#.#', dartx, name), desc); - } -} - -void _installPropertiesForGlobalObject(jsProto) { - _installPropertiesForObject(jsProto); - // Use JS toString for JS objects, rather than the Dart one. - JS('', '#[dartx.toString] = function() { return this.toString(); }', jsProto); - identityEquals ??= JS('', '#[dartx._equals]', jsProto); -} - -final _extensionMap = JS('', 'new Map()'); - -void _applyExtension(jsType, dartExtType) { - // TODO(vsm): Not all registered js types are real. - if (jsType == null) return; - var jsProto = JS('', '#.prototype', jsType); - if (jsProto == null) return; - - if (JS('!', '# === #', dartExtType, Object)) { - _installPropertiesForGlobalObject(jsProto); - return; - } - - _installProperties( - jsProto, dartExtType, JS('', '#[#]', jsProto, _extensionType)); - - // Mark the JS type's instances so we can easily check for extensions. - if (JS('!', '# !== #', dartExtType, JSFunction)) { - JS('', '#[#] = #', jsProto, _extensionType, dartExtType); - } - JS('', '#[#] = #[#]', jsType, _methodSig, dartExtType, _methodSig); - JS('', '#[#] = #[#]', jsType, _fieldSig, dartExtType, _fieldSig); - JS('', '#[#] = #[#]', jsType, _getterSig, dartExtType, _getterSig); - JS('', '#[#] = #[#]', jsType, _setterSig, dartExtType, _setterSig); -} - -/// Apply the previously registered extension to the type of [nativeObject]. -/// This is intended for types that are not available to polyfill at startup. -applyExtension(name, nativeObject) { - var dartExtType = JS('', '#.get(#)', _extensionMap, name); - var jsType = JS('', '#.constructor', nativeObject); - _applyExtension(jsType, dartExtType); -} - -/// Apply all registered extensions to a window. This is intended for -/// different frames, where registrations need to be reapplied. -applyAllExtensions(global) { - JS('', '#.forEach((dartExtType, name) => #(#[name], dartExtType))', - _extensionMap, _applyExtension, global); -} - -/// Copy symbols from the prototype of the source to destination. -/// These are the only properties safe to copy onto an existing public -/// JavaScript class. -registerExtension(name, dartExtType) { - JS('', '#.set(#, #)', _extensionMap, name, dartExtType); - var jsType = JS('', '#[#]', global_, name); - _applyExtension(jsType, dartExtType); -} - -/// -/// Mark a concrete type as implementing extension methods. -/// For example: `class MyIter implements Iterable`. -/// -/// This takes a list of names, which are the extension methods implemented. -/// It will add a forwarder, so the extension method name redirects to the -/// normal Dart method name. For example: -/// -/// defineExtensionMembers(MyType, ['add', 'remove']); -/// -/// Results in: -/// -/// MyType.prototype[dartx.add] = MyType.prototype.add; -/// MyType.prototype[dartx.remove] = MyType.prototype.remove; -/// -// TODO(jmesserly): essentially this gives two names to the same method. -// This benefit is roughly equivalent call performance either way, but the -// cost is we need to call defineExtensionMembers any time a subclass -// overrides one of these methods. -defineExtensionMethods(type, Iterable memberNames) { - var proto = JS('', '#.prototype', type); - for (var name in memberNames) { - JS('', '#[dartx.#] = #[#]', proto, name, proto, name); - } -} - -/// Like [defineExtensionMethods], but for getter/setter pairs. -void defineExtensionAccessors(type, Iterable memberNames) { - var proto = JS('!', '#.prototype', type); - for (var name in memberNames) { - // Find the member. It should always exist (or we have a compiler bug). - var member; - var p = proto; - for (;; p = JS('!', '#.__proto__', p)) { - member = getOwnPropertyDescriptor(p, name); - if (member != null) break; - } - defineProperty(proto, JS('', 'dartx[#]', name), member); - } -} - -definePrimitiveHashCode(proto) { - defineProperty(proto, identityHashCode_, - getOwnPropertyDescriptor(proto, extensionSymbol('hashCode'))); -} - -/// Link the extension to the type it's extending as a base class. -setBaseClass(derived, base) { - JS('', '#.prototype.__proto__ = #.prototype', derived, base); - // We use __proto__ to track the superclass hierarchy (see isSubtypeOf). - JS('', '#.__proto__ = #', derived, base); -} - -/// Like [setBaseClass], but for generic extension types such as `JSArray`. -setExtensionBaseClass(dartType, jsType) { - // Mark the generic type as an extension type and link the prototype objects. - var dartProto = JS('', '#.prototype', dartType); - JS('', '#[#] = #', dartProto, _extensionType, dartType); - JS('', '#.__proto__ = #.prototype', dartProto, jsType); -} - -/// Adds type test predicates to a class/interface type [ctor], using the -/// provided [isClass] JS Symbol. -/// -/// This will operate quickly for non-generic types, native extension types, -/// as well as matching exact generic type arguments: -/// -/// class C {} -/// class D extends C {} -/// main() { dynamic d = new D(); d as C; } -/// -addTypeTests(ctor, isClass) { - if (isClass == null) isClass = JS('', 'Symbol("_is_" + ctor.name)'); - // TODO(jmesserly): since we know we're dealing with class/interface types, - // we can optimize this rather than go through the generic `dart.is` helpers. - JS('', '#.prototype[#] = true', ctor, isClass); - JS( - '', - '''#.is = function is_C(obj) { - return obj != null && (obj[#] || #(obj, this)); - }''', - ctor, - isClass, - instanceOf); - JS( - '', - '''#.as = function as_C(obj) { - if (obj != null && obj[#]) return obj; - return #(obj, this); - }''', - ctor, - isClass, - cast); -} - -/// Pre-initializes types with empty type caches. -/// -/// Allows us to perform faster lookups on local caches without having to -/// filter out the prototype chain. Also allows types to remain relatively -/// monomorphic, which results in faster execution in V8. -addTypeCaches(type) { - JS('', '#[#] = void 0', type, _cachedLegacy); - JS('', '#[#] = void 0', type, _cachedNullable); - var subtypeCacheMap = JS('!', 'new Map()'); - JS('', '#[#] = #', type, _subtypeCache, subtypeCacheMap); - JS('', '#.push(#)', _cacheMaps, subtypeCacheMap); -} - -// TODO(jmesserly): should we do this for all interfaces? - -/// The well known symbol for testing `is Future` -final isFuture = JS('', 'Symbol("_is_Future")'); - -/// The well known symbol for testing `is Iterable` -final isIterable = JS('', 'Symbol("_is_Iterable")'); - -/// The well known symbol for testing `is List` -final isList = JS('', 'Symbol("_is_List")'); - -/// The well known symbol for testing `is Map` -final isMap = JS('', 'Symbol("_is_Map")'); - -/// The well known symbol for testing `is Stream` -final isStream = JS('', 'Symbol("_is_Stream")'); - -/// The well known symbol for testing `is StreamSubscription` -final isStreamSubscription = JS('', 'Symbol("_is_StreamSubscription")'); - -/// The default `operator ==` that calls [identical]. -var identityEquals; diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart deleted file mode 100644 index ba418a46805..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart +++ /dev/null @@ -1,292 +0,0 @@ -// 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. - -part of dart._runtime; - -// We need to set these properties while the sdk is only partially initialized -// so we cannot use regular Dart fields. -// The default values for these properties are set when the global_ final field -// in runtime.dart is initialized. - -argumentError(value) { - throw ArgumentError.value(value); -} - -throwUnimplementedError(String message) { - throw UnimplementedError(message); -} - -// TODO(nshahan) Cleanup embeded strings and extract file location at runtime -// from the stacktrace. -assertFailed(String? message, - [String? fileUri, int? line, int? column, String? conditionSource]) { - throw AssertionErrorImpl(message, fileUri, line, column, conditionSource); -} - -final _nullFailedSet = JS('!', 'new Set()'); -// Run-time null safety assertion per: -// https://github.com/dart-lang/language/blob/master/accepted/future-releases/nnbd/feature-specification.md#automatic-debug-assertion-insertion -nullFailed(String? fileUri, int? line, int? column, String? variable) { - if (strictNullSafety) { - throw AssertionErrorImpl( - 'A null value was passed into a non-nullable parameter $variable', - fileUri, - line, - column, - '$variable != null'); - } else { - var key = '$fileUri:$line:$column'; - if (!JS('!', '#.has(#)', _nullFailedSet, key)) { - JS('', '#.add(#)', _nullFailedSet, key); - _nullWarn( - 'A null value was passed into a non-nullable parameter $variable'); - } - } -} - -throwCyclicInitializationError([String? field]) { - throw CyclicInitializationError(field); -} - -throwNullValueError() { - // TODO(vsm): Per spec, we should throw an NSM here. Technically, we ought - // to thread through method info, but that uglifies the code and can't - // actually be queried ... it only affects how the error is printed. - throw NoSuchMethodError(null, Symbol(''), null, null); -} - -castError(obj, expectedType) { - var actualType = getReifiedType(obj); - var message = _castErrorMessage(actualType, expectedType); - throw TypeErrorImpl(message); -} - -String _castErrorMessage(from, to) { - // If both types are generic classes, see if we can infer generic type - // arguments for `from` that would allow the subtype relation to work. - // TODO(#40326) Fix suggested type or remove this code if no longer needed. - // var fromClass = getGenericClass(from); - // if (fromClass != null) { - // var fromTypeFormals = getGenericTypeFormals(fromClass); - // var fromType = instantiateClass(fromClass, fromTypeFormals); - // var inferrer = _TypeInferrer(fromTypeFormals); - // if (inferrer.trySubtypeMatch(fromType, to)) { - // var inferredTypes = inferrer.getInferredTypes(); - // if (inferredTypes != null) { - // var inferred = instantiateClass(fromClass, inferredTypes); - // return "Type '${typeName(from)}' should be '${typeName(inferred)}' " - // "to implement expected type '${typeName(to)}'."; - // } - // } - // } - return "Expected a value of type '${typeName(to)}', " - "but got one of type '${typeName(from)}'"; -} - -/// The symbol that references the thrown Dart Object (typically but not -/// necessarily an [Error] or [Exception]), used by the [exception] function. -final Object _thrownValue = JS('', 'Symbol("_thrownValue")'); - -/// For a Dart [Error], this provides access to the JS Error object that -/// contains the stack trace if the error was thrown. -final Object _jsError = JS('', 'Symbol("_jsError")'); - -/// Gets the thrown Dart Object from an [error] caught by a JS catch. -/// -/// If the throw originated in Dart, the result will typically be an [Error] -/// or [Exception], but it could be any Dart object. -/// -/// If the throw originated in JavaScript, then there is not a corresponding -/// Dart value, so we just return the error object. -Object? getThrown(Object? error) { - if (error != null) { - // Get the Dart thrown value, if any. - var value = JS('', '#[#]', error, _thrownValue); - if (value != null) return value; - } - // Otherwise return the original object. - return error; -} - -final _stackTrace = JS('', 'Symbol("_stackTrace")'); - -/// Returns the stack trace from an [error] caught by a JS catch. -/// -/// If the throw originated in Dart, we should always have JS Error -/// (see [throw_]) so we can create a Dart [StackTrace] from that (or return a -/// previously created instance). -/// -/// If the throw originated in JavaScript and was an `Error`, then we can get -/// the corresponding stack trace the same way we do for Dart throws. If the -/// throw object was not an Error, then we don't have a JS trace, so we create -/// one here. -StackTrace stackTrace(Object? error) { - if (JS('!', '!(# instanceof Error)', error)) { - // We caught something that isn't a JS Error. - // - // We should only hit this path when a non-Error was thrown from JS. In - // case, there is no stack trace available, so create one here. - return _StackTrace.missing(error); - } - - // If we've already created the Dart stack trace object, return it. - StackTrace? trace = JS('', '#[#]', error, _stackTrace); - if (trace != null) return trace; - - // Otherwise create the Dart stack trace (by parsing the JS stack), and - // cache it so we don't repeat the parsing/allocation. - return JS('', '#[#] = #', error, _stackTrace, _StackTrace(error)); -} - -StackTrace stackTraceForError(Error error) { - return stackTrace(JS('', '#[#]', error, _jsError)); -} - -/// Implements `rethrow` of [error], allowing rethrow in an expression context. -/// -/// Note: [error] must be the raw JS error caught in the JS catch, not the -/// unwrapped value returned by [getThrown]. -@JSExportName('rethrow') -void rethrow_(Object error) { - JS('', 'throw #', error); -} - -/// Subclass of JS `Error` that wraps a thrown Dart object, and evaluates the -/// message lazily by calling `toString()` on the wrapped Dart object. -/// -/// Also creates a pointer from the thrown Dart object to the JS Error -/// (via [_jsError]). This is used to implement [Error.stackTrace], but also -/// provides a way to recover the stack trace if we lose track of it. -/// [Error] requires preserving the original stack trace if an error is -/// rethrown, so we only update the pointer if it wasn't already set. -/// -/// TODO(jmesserly): Dart Errors should simply be JS Errors. -final Object DartError = JS( - '!', - '''class DartError extends Error { - constructor(error) { - super(); - if (error == null) error = #; - this[#] = error; - if (error != null && typeof error == "object" && error[#] == null) { - error[#] = this; - } - } - get message() { - return #(this[#]); - } - }''', - NullThrownError(), - _thrownValue, - _jsError, - _jsError, - _toString, - _thrownValue); - -/// Subclass of [DartError] for cases where we're rethrowing with a different, -/// original Dart StackTrace object. -/// -/// This includes the original stack trace in the JS Error message so it doesn't -/// get lost if the exception reaches JS. -final Object RethrownDartError = JS( - '!', - '''class RethrownDartError extends # { - constructor(error, stackTrace) { - super(error); - this[#] = stackTrace; - } - get message() { - return super.message + "\\n " + #(this[#]) + "\\n"; - } - }''', - DartError, - _stackTrace, - _toString, - _stackTrace); - -/// Implements `throw` of [exception], allowing for throw in an expression -/// context, and capturing the current stack trace. -@JSExportName('throw') -void throw_(Object? exception) { - /// Wrap the object so we capture a new stack trace, and so it will print - /// nicely from JS, as if it were a normal JS error. - JS('', 'throw new #(#)', DartError, exception); -} - -/// Returns a JS error for throwing the Dart [exception] Object and using the -/// provided stack [trace]. -/// -/// This is used by dart:async to rethrow unhandled errors in [Zone]s, and by -/// `async`/`async*` to rethrow errors from Futures/Streams into the generator -/// (so a try/catch in there can catch it). -/// -/// If the exception and trace originated from the same Dart throw, then we can -/// simply return the original JS Error. Otherwise, we have to create a new JS -/// Error. The new error will have the correct Dart trace, but it will not have -/// the correct JS stack trace (visible if JavaScript ends up handling it). To -/// fix that, we use [RethrownDartError] to preserve the Dart trace and make -/// sure it gets displayed in the JS error message. -/// -/// If the stack trace is null, this will preserve the original stack trace -/// on the exception, if available, otherwise it will capture the current stack -/// trace. -Object? createErrorWithStack(Object exception, StackTrace? trace) { - if (trace == null) { - var error = JS('', '#[#]', exception, _jsError); - return error != null ? error : JS('', 'new #(#)', DartError, exception); - } - if (trace is _StackTrace) { - /// Optimization: if this stack trace and exception already have a matching - /// Error, we can just rethrow it. - var originalError = trace._jsError; - if (identical(exception, getThrown(originalError))) { - return originalError; - } - } - return JS('', 'new #(#, #)', RethrownDartError, exception, trace); -} - -// This is a utility function: it is only intended to be called from dev -// tools. -void stackPrint(Object error) { - JS('', 'console.log(#.stack ? #.stack : "No stack trace for: " + #)', error, - error, error); -} - -class _StackTrace implements StackTrace { - final Object? _jsError; - final Object? _jsObjectMissingTrace; - String? _trace; - - _StackTrace(this._jsError) : _jsObjectMissingTrace = null; - - _StackTrace.missing(Object? caughtObj) - : _jsObjectMissingTrace = caughtObj != null ? caughtObj : 'null', - _jsError = JS('', 'Error()'); - - String toString() { - if (_trace != null) return _trace!; - - var e = _jsError; - String trace = ''; - if (e != null && JS('!', 'typeof # === "object"', e)) { - trace = e is NativeError ? e.dartStack() : JS('', '#.stack', e); - var mapper = stackTraceMapper; - if (trace != null && mapper != null) { - trace = mapper(trace); - } - } - if (trace.isEmpty || _jsObjectMissingTrace != null) { - String jsToString; - try { - jsToString = JS('', '"" + #', _jsObjectMissingTrace); - } catch (_) { - jsToString = ''; - } - trace = 'Non-error `$jsToString` thrown by JS does not have stack trace.' - '\nCaught in Dart at:\n\n$trace'; - } - return _trace = trace; - } -} diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart deleted file mode 100644 index fd9a7d40ecf..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart +++ /dev/null @@ -1,841 +0,0 @@ -// 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. - -/// This library defines runtime operations on objects used by the code -/// generator. -part of dart._runtime; - -// TODO(jmesserly): remove this in favor of _Invocation. -class InvocationImpl extends Invocation { - final Symbol memberName; - final List positionalArguments; - final Map namedArguments; - final List typeArguments; - final bool isMethod; - final bool isGetter; - final bool isSetter; - final String failureMessage; - - InvocationImpl(memberName, List positionalArguments, - {namedArguments, - List typeArguments = const [], - this.isMethod = false, - this.isGetter = false, - this.isSetter = false, - this.failureMessage = 'method not found'}) - : memberName = - isSetter ? _setterSymbol(memberName) : _dartSymbol(memberName), - positionalArguments = List.unmodifiable(positionalArguments), - namedArguments = _namedArgsToSymbols(namedArguments), - typeArguments = List.unmodifiable(typeArguments.map(wrapType)); - - static Map _namedArgsToSymbols(namedArgs) { - if (namedArgs == null) return const {}; - return Map.unmodifiable(Map.fromIterable(getOwnPropertyNames(namedArgs), - key: _dartSymbol, value: (k) => JS('', '#[#]', namedArgs, k))); - } -} - -/// Given an object and a method name, tear off the method. -/// Sets the runtime type of the torn off method appropriately, -/// and also binds the object. -/// -/// If the optional `f` argument is passed in, it will be used as the method. -/// This supports cases like `super.foo` where we need to tear off the method -/// from the superclass, not from the `obj` directly. -// TODO(leafp): Consider caching the tearoff on the object? -bind(obj, name, method) { - if (obj == null) obj = jsNull; - if (method == null) method = JS('', '#[#]', obj, name); - var f = JS('', '#.bind(#)', method, obj); - // TODO(jmesserly): canonicalize tearoffs. - JS('', '#._boundObject = #', f, obj); - JS('', '#._boundMethod = #', f, method); - JS('', '#[#] = #', f, _runtimeType, getMethodType(getType(obj), name)); - return f; -} - -/// Binds the `call` method of an interface type, handling null. -/// -/// Essentially this works like `obj?.call`. It also handles the needs of -/// [dsend]/[dcall], returning `null` if no method was found with the given -/// canonical member [name]. -/// -/// [name] is typically `"call"` but it could be the [extensionSymbol] for -/// `call`, if we define it on a native type, and [obj] is known statially to be -/// a native type/interface with `call`. -bindCall(obj, name) { - if (obj == null) return null; - var ftype = getMethodType(getType(obj), name); - if (ftype == null) return null; - var method = JS('', '#[#]', obj, name); - var f = JS('', '#.bind(#)', method, obj); - // TODO(jmesserly): canonicalize tearoffs. - JS('', '#._boundObject = #', f, obj); - JS('', '#._boundMethod = #', f, method); - JS('', '#[#] = #', f, _runtimeType, ftype); - return f; -} - -/// Instantiate a generic method. -/// -/// We need to apply the type arguments both to the function, as well as its -/// associated function type. -gbind(f, @rest List typeArgs) { - GenericFunctionType type = JS('!', '#[#]', f, _runtimeType); - type.checkBounds(typeArgs); - // Create a JS wrapper function that will also pass the type arguments, and - // tag it with the instantiated function type. - var result = - JS('', '(...args) => #.apply(null, #.concat(args))', f, typeArgs); - return fn(result, type.instantiate(typeArgs)); -} - -dloadRepl(obj, field) => dload(obj, replNameLookup(obj, field)); - -// Warning: dload, dput, and dsend assume they are never called on methods -// implemented by the Object base class as those methods can always be -// statically resolved. -dload(obj, field) { - if (JS('!', 'typeof # == "function" && # == "call"', obj, field)) { - return obj; - } - var f = _canonicalMember(obj, field); - - trackCall(obj); - if (f != null) { - var type = getType(obj); - - if (hasField(type, f) || hasGetter(type, f)) return JS('', '#[#]', obj, f); - if (hasMethod(type, f)) return bind(obj, f, null); - - // Always allow for JS interop objects. - if (isJsInterop(obj)) return JS('', '#[#]', obj, f); - } - return noSuchMethod(obj, InvocationImpl(field, JS('', '[]'), isGetter: true)); -} - -_stripGenericArguments(type) { - var genericClass = getGenericClass(type); - if (genericClass != null) return JS('', '#()', genericClass); - return type; -} - -dputRepl(obj, field, value) => dput(obj, replNameLookup(obj, field), value); - -dput(obj, field, value) { - var f = _canonicalMember(obj, field); - trackCall(obj); - if (f != null) { - var setterType = getSetterType(getType(obj), f); - if (setterType != null) { - return JS('', '#[#] = #.as(#)', obj, f, setterType, value); - } - // Always allow for JS interop objects. - if (isJsInterop(obj)) return JS('', '#[#] = #', obj, f, value); - } - noSuchMethod( - obj, InvocationImpl(field, JS('', '[#]', value), isSetter: true)); - return value; -} - -/// Returns an error message if function of a given [type] can't be applied to -/// [actuals] and [namedActuals]. -/// -/// Returns `null` if all checks pass. -String? _argumentErrors(FunctionType type, List actuals, namedActuals) { - // Check for too few required arguments. - int actualsCount = JS('!', '#.length', actuals); - var required = type.args; - int requiredCount = JS('!', '#.length', required); - if (actualsCount < requiredCount) { - return 'Dynamic call with too few arguments. ' - 'Expected: $requiredCount Actual: $actualsCount'; - } - - // Check for too many postional arguments. - var extras = actualsCount - requiredCount; - var optionals = type.optionals; - if (extras > JS('!', '#.length', optionals)) { - return 'Dynamic call with too many arguments. ' - 'Expected: $requiredCount Actual: $actualsCount'; - } - - // Check if we have invalid named arguments. - Iterable? names; - var named = type.named; - var requiredNamed = type.requiredNamed; - if (namedActuals != null) { - names = getOwnPropertyNames(namedActuals); - for (var name in names) { - if (!JS('!', '(#.hasOwnProperty(#) || #.hasOwnProperty(#))', named, - name, requiredNamed, name)) { - return "Dynamic call with unexpected named argument '$name'."; - } - } - } - // Verify that all required named parameters are provided an argument. - Iterable requiredNames = getOwnPropertyNames(requiredNamed); - if (requiredNames.isNotEmpty) { - var missingRequired = namedActuals == null - ? requiredNames - : requiredNames.where((name) => - !JS('!', '#.hasOwnProperty(#)', namedActuals, name)); - if (missingRequired.isNotEmpty) { - var error = "Dynamic call with missing required named arguments: " - "${missingRequired.join(', ')}."; - if (!strictNullSafety) { - _nullWarn(error); - } else { - return error; - } - } - } - // Now that we know the signature matches, we can perform type checks. - for (var i = 0; i < requiredCount; ++i) { - JS('', '#[#].as(#[#])', required, i, actuals, i); - } - for (var i = 0; i < extras; ++i) { - JS('', '#[#].as(#[#])', optionals, i, actuals, i + requiredCount); - } - if (names != null) { - for (var name in names) { - JS('', '(#[#] || #[#]).as(#[#])', named, name, requiredNamed, name, - namedActuals, name); - } - } - return null; -} - -_toSymbolName(symbol) => JS('', '''(() => { - let str = $symbol.toString(); - // Strip leading 'Symbol(' and trailing ')' - return str.substring(7, str.length-1); - })()'''); - -_toDisplayName(name) => JS('', '''(() => { - // Names starting with _ are escaped names used to disambiguate Dart and - // JS names. - if ($name[0] === '_') { - // Inverse of - switch($name) { - case '_get': - return '[]'; - case '_set': - return '[]='; - case '_negate': - return 'unary-'; - case '_constructor': - case '_prototype': - return $name.substring(1); - } - } - return $name; - })()'''); - -Symbol _dartSymbol(name) { - return (JS('!', 'typeof # === "symbol"', name)) - ? JS('Symbol', '#(new #.new(#, #))', const_, PrivateSymbol, - _toSymbolName(name), name) - : JS('Symbol', '#(new #.new(#))', const_, internal.Symbol, - _toDisplayName(name)); -} - -Symbol _setterSymbol(name) { - return (JS('!', 'typeof # === "symbol"', name)) - ? JS('Symbol', '#(new #.new(# + "=", #))', const_, PrivateSymbol, - _toSymbolName(name), name) - : JS('Symbol', '#(new #.new(# + "="))', const_, internal.Symbol, - _toDisplayName(name)); -} - -_checkAndCall(f, ftype, obj, typeArgs, args, named, displayName) => - JS('', '''(() => { - $trackCall($obj); - - let originalTarget = obj === void 0 ? f : obj; - - function callNSM(errorMessage) { - return $noSuchMethod(originalTarget, new $InvocationImpl.new( - $displayName, $args, { - namedArguments: $named, - // Repeated the default value here to avoid passing null from JS to a - // non-nullable argument. - typeArguments: $typeArgs || [], - isMethod: true, - failureMessage: errorMessage - })); - } - if ($f == null) return callNSM('Dynamic call of null.'); - if (!($f instanceof Function)) { - // We're not a function (and hence not a method either) - // Grab the `call` method if it's not a function. - if ($f != null) { - // Getting the member succeeded, so update the originalTarget. - // (we're now trying `call()` on `f`, so we want to call its nSM rather - // than the original target's nSM). - originalTarget = f; - $f = ${bindCall(f, _canonicalMember(f, 'call'))}; - $ftype = null; - $displayName = "call"; - } - if ($f == null) return callNSM( - "Dynamic call of object has no instance method 'call'."); - } - // If f is a function, but not a method (no method type) - // then it should have been a function valued field, so - // get the type from the function. - if ($ftype == null) $ftype = $f[$_runtimeType]; - - if ($ftype == null) { - // TODO(leafp): Allow JS objects to go through? - if ($typeArgs != null) { - // TODO(jmesserly): is there a sensible way to handle these? - $throwTypeError('call to JS object `' + $obj + - '` with type arguments <' + $typeArgs + '> is not supported.'); - } - - if ($named != null) $args.push($named); - return $f.apply($obj, $args); - } - - // Apply type arguments - if (${_jsInstanceOf(ftype, GenericFunctionType)}) { - let formalCount = $ftype.formalCount; - - if ($typeArgs == null) { - $typeArgs = $ftype.instantiateDefaultBounds(); - } else if ($typeArgs.length != formalCount) { - return callNSM('Dynamic call with incorrect number of type arguments. ' + - 'Expected: ' + formalCount + ' Actual: ' + $typeArgs.length); - } else { - $ftype.checkBounds($typeArgs); - } - $ftype = $ftype.instantiate($typeArgs); - } else if ($typeArgs != null) { - return callNSM('Dynamic call with unexpected type arguments. ' + - 'Expected: 0 Actual: ' + $typeArgs.length); - } - let errorMessage = $_argumentErrors($ftype, $args, $named); - if (errorMessage == null) { - if ($typeArgs != null) $args = $typeArgs.concat($args); - if ($named != null) $args.push($named); - return $f.apply($obj, $args); - } - return callNSM(errorMessage); -})()'''); - -dcall(f, args, [@undefined named]) => _checkAndCall( - f, null, JS('', 'void 0'), null, args, named, JS('', 'f.name')); - -dgcall(f, typeArgs, args, [@undefined named]) => _checkAndCall(f, null, - JS('', 'void 0'), typeArgs, args, named, JS('', "f.name || 'call'")); - -/// Helper for REPL dynamic invocation variants that make a best effort to -/// enable accessing private members across library boundaries. -replNameLookup(object, field) => JS('', '''(() => { - let rawField = $field; - if (typeof(field) == 'symbol') { - // test if the specified field exists in which case it is safe to use it. - if ($field in $object) return $field; - - // Symbol is from a different library. Make a best effort to - $field = $field.toString(); - $field = $field.substring('Symbol('.length, field.length - 1); - - } else if ($field.charAt(0) != '_') { - // Not a private member so default call path is safe. - return $field; - } - - // If the exact field name is present, invoke callback with it. - if ($field in $object) return $field; - - // TODO(jacobr): warn if there are multiple private members with the same - // name which could happen if super classes in different libraries have - // the same private member name. - let proto = $object; - while (proto !== null) { - // Private field (indicated with "_"). - let symbols = Object.getOwnPropertySymbols(proto); - let target = 'Symbol(' + $field + ')'; - - for (let s = 0; s < symbols.length; s++) { - let sym = symbols[s]; - if (target == sym.toString()) return sym; - } - proto = proto.__proto__; - } - // We didn't find a plausible alternate private symbol so just fall back - // to the regular field. - return rawField; -})()'''); - -/// Shared code for dsend, dindex, and dsetindex. -callMethod(obj, name, typeArgs, args, named, displayName) { - if (JS('!', 'typeof # == "function" && # == "call"', obj, name)) { - return dgcall(obj, typeArgs, args, named); - } - var symbol = _canonicalMember(obj, name); - if (symbol == null) { - return noSuchMethod(obj, InvocationImpl(displayName, args, isMethod: true)); - } - var f = obj != null ? JS('', '#[#]', obj, symbol) : null; - var type = getType(obj); - var ftype = getMethodType(type, symbol); - // No such method if dart object and ftype is missing. - return _checkAndCall(f, ftype, obj, typeArgs, args, named, displayName); -} - -dsend(obj, method, args, [@undefined named]) => - callMethod(obj, method, null, args, named, method); - -dgsend(obj, typeArgs, method, args, [@undefined named]) => - callMethod(obj, method, typeArgs, args, named, method); - -dsendRepl(obj, method, args, [@undefined named]) => - callMethod(obj, replNameLookup(obj, method), null, args, named, method); - -dgsendRepl(obj, typeArgs, method, args, [@undefined named]) => - callMethod(obj, replNameLookup(obj, method), typeArgs, args, named, method); - -dindex(obj, index) => callMethod(obj, '_get', null, [index], null, '[]'); - -dsetindex(obj, index, value) => - callMethod(obj, '_set', null, [index, value], null, '[]='); - -/// General implementation of the Dart `is` operator. -/// -/// Some basic cases are handled directly by the `.is` methods that are attached -/// directly on types, but any query that requires checking subtyping relations -/// is handled here. -@notNull -@JSExportName('is') -bool instanceOf(obj, type) { - if (obj == null) { - return _equalType(type, Null) || - _isTop(type) || - _jsInstanceOf(type, NullableType); - } - return isSubtypeOf(getReifiedType(obj), type); -} - -/// General implementation of the Dart `as` operator. -/// -/// Some basic cases are handled directly by the `.as` methods that are attached -/// directly on types, but any query that requires checking subtyping relations -/// is handled here. -@JSExportName('as') -cast(obj, type) { - // We hoist the common case where null is checked against another type here - // for better performance. - if (obj == null && !strictNullSafety) { - // Check the null comparison cache to avoid emitting repeated warnings. - _nullWarnOnType(type); - return obj; - } else { - var actual = getReifiedType(obj); - if (isSubtypeOf(actual, type)) return obj; - } - - return castError(obj, type); -} - -bool test(bool? obj) { - if (obj == null) throw BooleanConversionAssertionError(); - return obj; -} - -bool dtest(obj) { - // Only throw an AssertionError in weak mode for compatibility. Strong mode - // should throw a TypeError. - if (obj is! bool) booleanConversionFailed(strictNullSafety ? obj : test(obj)); - return obj; -} - -void booleanConversionFailed(obj) { - var actual = typeName(getReifiedType(obj)); - throw TypeErrorImpl("type '$actual' is not a 'bool' in boolean expression"); -} - -asInt(obj) { - // Note: null (and undefined) will fail this test. - if (JS('!', 'Math.floor(#) != #', obj, obj)) { - if (obj == null && !strictNullSafety) { - _nullWarnOnType(JS('', '#', int)); - return null; - } else { - castError(obj, JS('', '#', int)); - } - } - return obj; -} - -asNullableInt(obj) => obj == null ? null : asInt(obj); - -/// Checks that `x` is not null or undefined. -// -// TODO(jmesserly): inline this, either by generating it as a function into -// the module, or via some other pattern such as: -// -// || nullErr() -// (t0 = ) != null ? t0 : nullErr() -@JSExportName('notNull') -_notNull(x) { - if (x == null) throwNullValueError(); - return x; -} - -/// Checks that `x` is not null or undefined. -/// -/// Unlike `_notNull`, this throws a `CastError` (under strict checking) -/// or emits a runtime warning (otherwise). This is only used by the -/// compiler when casting from nullable to non-nullable variants of the -/// same type. -nullCast(x, type) { - if (x == null) { - if (!strictNullSafety) { - _nullWarnOnType(type); - } else { - castError(x, type); - } - } - return x; -} - -/// The global constant map table. -final constantMaps = JS('!', 'new Map()'); - -// TODO(leafp): This table gets quite large in apps. -// Keeping the paths is probably expensive. It would probably -// be more space efficient to just use a direct hash table with -// an appropriately defined structural equality function. -Object _lookupNonTerminal(Object map, Object? key) { - var result = JS('', '#.get(#)', map, key); - if (result != null) return result; - JS('', '#.set(#, # = new Map())', map, key, result); - return result!; -} - -Map constMap(JSArray elements) { - var count = elements.length; - var map = _lookupNonTerminal(constantMaps, count); - for (var i = 0; i < count; i++) { - map = _lookupNonTerminal(map, JS('', '#[#]', elements, i)); - } - map = _lookupNonTerminal(map, K); - Map? result = JS('', '#.get(#)', map, V); - if (result != null) return result; - result = ImmutableMap.from(elements); - JS('', '#.set(#, #)', map, V, result); - return result; -} - -final constantSets = JS('!', 'new Map()'); -var _immutableSetConstructor; - -// We cannot invoke private class constructors directly in Dart. -Set _createImmutableSet(JSArray elements) { - _immutableSetConstructor ??= - JS('', '#.#', getLibrary('dart:collection'), '_ImmutableSet\$'); - return JS('', 'new (#(#)).from(#)', _immutableSetConstructor, E, elements); -} - -Set constSet(JSArray elements) { - var count = elements.length; - var map = _lookupNonTerminal(constantSets, count); - for (var i = 0; i < count; i++) { - map = _lookupNonTerminal(map, JS('', '#[#]', elements, i)); - } - Set? result = JS('', '#.get(#)', map, E); - if (result != null) return result; - result = _createImmutableSet(elements); - JS('', '#.set(#, #)', map, E, result); - return result; -} - -final _value = JS('', 'Symbol("_value")'); - -/// -/// Looks up a sequence of [keys] in [map], recursively, and -/// returns the result. If the value is not found, [valueFn] will be called to -/// add it. For example: -/// -/// let map = new Map(); -/// putIfAbsent(map, [1, 2, 'hi ', 'there '], () => 'world'); -/// -/// ... will create a Map with a structure like: -/// -/// { 1: { 2: { 'hi ': { 'there ': 'world' } } } } -/// -multiKeyPutIfAbsent(map, keys, valueFn) => JS('', '''(() => { - for (let k of $keys) { - let value = $map.get(k); - if (!value) { - // TODO(jmesserly): most of these maps are very small (e.g. 1 item), - // so it may be worth optimizing for that. - $map.set(k, value = new Map()); - } - $map = value; - } - if ($map.has($_value)) return $map.get($_value); - let value = $valueFn(); - $map.set($_value, value); - return value; -})()'''); - -/// The global constant table. -/// This maps the number of names in the object (n) -/// to a path of length 2*n of maps indexed by the name and -/// and value of the field. The final map is -/// indexed by runtime type, and contains the canonical -/// version of the object. -final constants = JS('!', 'new Map()'); - -/// -/// Canonicalize a constant object. -/// -/// Preconditions: -/// - `obj` is an objects or array, not a primitive. -/// - nested values of the object are themselves already canonicalized. -/// -@JSExportName('const') -const_(obj) => JS('', '''(() => { - let names = $getOwnNamesAndSymbols($obj); - let count = names.length; - // Index by count. All of the paths through this map - // will have 2*count length. - let map = $_lookupNonTerminal($constants, count); - // TODO(jmesserly): there's no guarantee in JS that names/symbols are - // returned in the same order. - // - // We could probably get the same order if we're judicious about - // initializing fields in a consistent order across all const constructors. - // Alternatively we need a way to sort them to make consistent. - // - // Right now we use the (name,value) pairs in sequence, which prevents - // an object with incorrect field values being returned, but won't - // canonicalize correctly if key order is different. - // - // See issue https://github.com/dart-lang/sdk/issues/30876 - for (let i = 0; i < count; i++) { - let name = names[i]; - map = $_lookupNonTerminal(map, name); - map = $_lookupNonTerminal(map, $obj[name]); - } - // TODO(leafp): It may be the case that the reified type - // is always one of the keys already used above? - let type = $getReifiedType($obj); - let value = map.get(type); - if (value) return value; - map.set(type, $obj); - return $obj; -})()'''); - -/// The global constant list table. -/// This maps the number of elements in the list (n) -/// to a path of length n of maps indexed by the value -/// of the field. The final map is indexed by the element -/// type and contains the canonical version of the list. -final constantLists = JS('', 'new Map()'); - -/// Canonicalize a constant list -constList(elements, elementType) => JS('', '''(() => { - let count = $elements.length; - let map = $_lookupNonTerminal($constantLists, count); - for (let i = 0; i < count; i++) { - map = $_lookupNonTerminal(map, elements[i]); - } - let value = map.get($elementType); - if (value) return value; - - ${getGenericClass(JSArray)}($elementType).unmodifiable($elements); - map.set($elementType, elements); - return elements; -})()'''); - -constFn(x) => JS('', '() => x'); - -/// Gets the extension symbol given a member [name]. -/// -/// This is inlined by the compiler when used with a literal string. -extensionSymbol(String name) => JS('', 'dartx[#]', name); - -// The following are helpers for Object methods when the receiver -// may be null. These should only be generated by the compiler. -bool equals(x, y) { - // We handle `y == null` inside our generated operator methods, to keep this - // function minimal. - // This pattern resulted from performance testing; it found that dispatching - // was the fastest solution, even for primitive types. - return JS('!', '# == null ? # == null : #[#](#)', x, y, x, - extensionSymbol('_equals'), y); -} - -int hashCode(obj) { - return obj == null ? 0 : JS('!', '#[#]', obj, extensionSymbol('hashCode')); -} - -@JSExportName('toString') -String _toString(obj) { - if (obj == null) return "null"; - if (obj is String) return obj; - return JS('!', '#[#]()', obj, extensionSymbol('toString')); -} - -/// Converts to a non-null [String], equivalent to -/// `dart.notNull(dart.toString(obj))`. -/// -/// This is commonly used in string interpolation. -@notNull -String str(obj) { - if (obj == null) return "null"; - if (obj is String) return obj; - return _notNull(JS('!', '#[#]()', obj, extensionSymbol('toString'))); -} - -// TODO(jmesserly): is the argument type verified statically? -noSuchMethod(obj, Invocation invocation) { - if (obj == null) defaultNoSuchMethod(obj, invocation); - return JS('', '#[#](#)', obj, extensionSymbol('noSuchMethod'), invocation); -} - -/// The default implementation of `noSuchMethod` to match `Object.noSuchMethod`. -defaultNoSuchMethod(obj, Invocation i) { - throw NoSuchMethodError.withInvocation(obj, i); -} - -runtimeType(obj) { - return obj == null ? Null : JS('', '#[dartx.runtimeType]', obj); -} - -final identityHashCode_ = JS('!', 'Symbol("_identityHashCode")'); - -/// Adapts a Dart `get iterator` into a JS `[Symbol.iterator]`. -// TODO(jmesserly): instead of an adaptor, we could compile Dart iterators -// natively implementing the JS iterator protocol. This would allow us to -// optimize them a bit. -final JsIterator = JS('', ''' - class JsIterator { - constructor(dartIterator) { - this.dartIterator = dartIterator; - } - next() { - let i = this.dartIterator; - let done = !i.moveNext(); - return { done: done, value: done ? void 0 : i.current }; - } - } -'''); - -_canonicalMember(obj, name) { - // Private names are symbols and are already canonical. - if (JS('!', 'typeof # === "symbol"', name)) return name; - - if (obj != null && JS('!', '#[#] != null', obj, _extensionType)) { - return JS('', 'dartx.#', name); - } - - // Check for certain names that we can't use in JS - if (JS('!', '# == "constructor" || # == "prototype"', name, name)) { - JS('', '# = "+" + #', name, name); - } - return name; -} - -/// Emulates the implicit "loadLibrary" function provided by a deferred library. -/// -/// Libraries are not actually deferred in DDC, so this just returns a future -/// that completes immediately. -Future loadLibrary() => Future.value(); - -/// Defines lazy statics. -/// -/// TODO: Remove useOldSemantics when non-null-safe late static field behavior is -/// deprecated. -void defineLazy(to, from, bool useOldSemantics) { - for (var name in getOwnNamesAndSymbols(from)) { - if (useOldSemantics) { - defineLazyFieldOld(to, name, getOwnPropertyDescriptor(from, name)); - } else { - defineLazyField(to, name, getOwnPropertyDescriptor(from, name)); - } - } -} - -/// Defines a lazy static field. -/// After initial get or set, it will replace itself with a value property. -// TODO(jmesserly): reusing descriptor objects has been shown to improve -// performance in other projects (e.g. webcomponents.js ShadowDOM polyfill). -defineLazyField(to, name, desc) => JS('', '''(() => { - const initializer = $desc.get; - let init = initializer; - let value = null; - let executed = false; - $desc.get = function() { - if (init == null) return value; - if (!executed) { - // Record the field on first execution so we can reset it later if - // needed (hot restart). - $_resetFields.push(() => { - init = initializer; - value = null; - executed = false; - }); - executed = true; - } - value = init(); - init = null; - return value; - }; - $desc.configurable = true; - if ($desc.set != null) { - $desc.set = function(x) { - init = null; - value = x; - // executed is dead since init is set to null - }; - } - return ${defineProperty(to, name, desc)}; -})()'''); - -/// Defines a lazy static field with pre-null-safety semantics. -defineLazyFieldOld(to, name, desc) => JS('', '''(() => { - const initializer = $desc.get; - let init = initializer; - let value = null; - $desc.get = function() { - if (init == null) return value; - let f = init; - init = $throwCyclicInitializationError; - if (f === init) f($name); // throw cycle error - - // On the first (non-cyclic) execution, record the field so we can reset it - // later if needed (hot restart). - $_resetFields.push(() => { - init = initializer; - value = null; - }); - - // Try to evaluate the field, using try+catch to ensure we implement the - // correct Dart error semantics. - try { - value = f(); - init = null; - return value; - } catch (e) { - init = null; - value = null; - throw e; - } - }; - $desc.configurable = true; - if ($desc.set != null) { - $desc.set = function(x) { - init = null; - value = x; - }; - } - return ${defineProperty(to, name, desc)}; -})()'''); diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/rtti.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/rtti.dart deleted file mode 100644 index 1f362a8cab1..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/rtti.dart +++ /dev/null @@ -1,227 +0,0 @@ -// 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. - -/// This library defines the association between runtime objects and -/// runtime types. -part of dart._runtime; - -/// Runtime type information. This module defines the mapping from -/// runtime objects to their runtime type information. See the types -/// module for the definition of how type information is represented. -/// -/// There are two kinds of objects that represent "types" at runtime. A -/// "runtime type" contains all of the data needed to implement the runtime -/// type checking inserted by the compiler. These objects fall into four -/// categories: -/// -/// - Things represented by javascript primitives, such as -/// null, numbers, booleans, strings, and symbols. For these -/// we map directly from the javascript type (given by typeof) -/// to the appropriate class type from core, which serves as their -/// rtti. -/// -/// - Functions, which are represented by javascript functions. -/// Representations of Dart functions always have a -/// _runtimeType property attached to them with the appropriate -/// rtti. -/// -/// - Objects (instances) which are represented by instances of -/// javascript (ES6) classes. Their types are given by their -/// classes, and the rtti is accessed by projecting out their -/// constructor field. -/// -/// - Types objects, which are represented as described in the types -/// module. Types always have a _runtimeType property attached to -/// them with the appropriate rtti. The rtti for these is always -/// core.Type. TODO(leafp): consider the possibility that we can -/// reliably recognize type objects and map directly to core.Type -/// rather than attaching this property everywhere. -/// -/// The other kind of object representing a "type" is the instances of the -/// dart:core Type class. These are the user visible objects you get by calling -/// "runtimeType" on an object or using a class literal expression. These are -/// different from the above objects, and are created by calling `wrapType()` -/// on a runtime type. - -/// Tag a closure with a type. -/// -/// `dart.fn(closure, type)` marks [closure] with the provided runtime [type]. -fn(closure, type) { - JS('', '#[#] = #', closure, _runtimeType, type); - return closure; -} - -/// Tag a closure with a type that's computed lazily. -/// -/// `dart.fn(closure, type)` marks [closure] with a getter that uses -/// [computeType] to return the runtime type. -/// -/// The getter/setter replaces the property with a value property, so the -/// resulting function is compatible with [fn] and the type can be set again -/// safely. -lazyFn(closure, Object Function() computeType) { - defineAccessor(closure, _runtimeType, - get: () => defineValue(closure, _runtimeType, computeType()), - set: (value) => defineValue(closure, _runtimeType, value), - configurable: true); - return closure; -} - -// TODO(vsm): How should we encode the runtime type? -final Object _runtimeType = JS('!', 'Symbol("_runtimeType")'); - -final Object _moduleName = JS('!', 'Symbol("_moduleName")'); - -getFunctionType(obj) { - // TODO(vsm): Encode this properly on the function for Dart-generated code. - var args = JS('!', 'Array(#.length).fill(#)', obj, dynamic); - return fnType(bottom, args, JS('', 'void 0')); -} - -/// Returns the runtime representation of the type of obj. -/// -/// The resulting object is used internally for runtime type checking. This is -/// different from the user-visible Type object returned by calling -/// `runtimeType` on some Dart object. -getReifiedType(obj) { - switch (JS('!', 'typeof #', obj)) { - case "object": - if (obj == null) return JS('', '#', Null); - if (_jsInstanceOf(obj, Object)) { - return JS('', '#.constructor', obj); - } - var result = JS('', '#[#]', obj, _extensionType); - if (result == null) return JS('', '#', jsobject); - return result; - case "function": - // All Dart functions and callable classes must set _runtimeType - var result = JS('', '#[#]', obj, _runtimeType); - if (result != null) return result; - return JS('', '#', jsobject); - case "undefined": - return JS('', '#', Null); - case "number": - return JS('', 'Math.floor(#) == # ? # : #', obj, obj, int, double); - case "boolean": - return JS('', '#', bool); - case "string": - return JS('', '#', String); - case "symbol": - default: - return JS('', '#', jsobject); - } -} - -/// Return the module name for a raw library object. -String? getModuleName(Object module) => JS('', '#[#]', module, _moduleName); - -final _loadedModules = JS('', 'new Map()'); -final _loadedPartMaps = JS('', 'new Map()'); -final _loadedSourceMaps = JS('', 'new Map()'); - -List getModuleNames() { - return JS>('', 'Array.from(#.keys())', _loadedModules); -} - -String? getSourceMap(String moduleName) { - return JS('!', '#.get(#)', _loadedSourceMaps, moduleName); -} - -/// Return all library objects in the specified module. -getModuleLibraries(String name) { - var module = JS('', '#.get(#)', _loadedModules, name); - if (module == null) return null; - JS('', '#[#] = #', module, _moduleName, name); - return module; -} - -/// Return the part map for a specific module. -getModulePartMap(String name) => JS('', '#.get(#)', _loadedPartMaps, name); - -/// Track all libraries -void trackLibraries( - String moduleName, Object libraries, Object parts, String? sourceMap) { - if (parts is String) { - // Added for backwards compatibility. - // package:build_web_compilers currently invokes this without [parts] - // in its bootstrap code. - sourceMap = parts; - parts = JS('', '{}'); - } - JS('', '#.set(#, #)', _loadedSourceMaps, moduleName, sourceMap); - JS('', '#.set(#, #)', _loadedModules, moduleName, libraries); - JS('', '#.set(#, #)', _loadedPartMaps, moduleName, parts); - _libraries = null; - _libraryObjects = null; - _parts = null; -} - -List? _libraries; -Map? _libraryObjects; -Map?>? _parts; - -_computeLibraryMetadata() { - _libraries = []; - _libraryObjects = {}; - _parts = {}; - var modules = getModuleNames(); - for (var name in modules) { - // Add libraries from each module. - var module = getModuleLibraries(name); - // TODO(nshahan) Can we optimize this cast and the one below to use - // JsArray.of() to be more efficient? - var libraries = getOwnPropertyNames(module).cast(); - _libraries!.addAll(libraries); - for (var library in libraries) { - _libraryObjects![library] = JS('', '#.#', module, library); - } - - // Add parts from each module. - var partMap = getModulePartMap(name); - libraries = getOwnPropertyNames(partMap).cast(); - for (var library in libraries) { - _parts![library] = List.from(JS('List', '#.#', partMap, library)); - } - } -} - -/// Returns the JS library object for a given library [uri] or -/// undefined / null if it isn't loaded. Top-level types and -/// methods are available on this object. -Object? getLibrary(String uri) { - if (_libraryObjects == null) { - _computeLibraryMetadata(); - } - return _libraryObjects![uri]; -} - -/// Returns a JSArray of library uris (e.g, -/// ['dart:core', 'dart:_internal', ..., 'package:foo/bar.dart', ... 'main.dart']) -/// loaded in this application. -List getLibraries() { - if (_libraries == null) { - _computeLibraryMetadata(); - } - return _libraries!; -} - -/// Returns a JSArray of part uris for a given [libraryUri]. -/// The part uris will be relative to the [libraryUri]. -/// -/// E.g., invoking `getParts('package:intl/intl.dart')` returns (as of this -/// writing): ``` -/// ["src/intl/bidi_formatter.dart", "src/intl/bidi_utils.dart", -/// "src/intl/compact_number_format.dart", "src/intl/date_format.dart", -/// "src/intl/date_format_field.dart", "src/intl/date_format_helpers.dart", -/// "src/intl/number_format.dart"] -/// ``` -/// -/// If [libraryUri] doesn't map to a library or maps to a library with no -/// parts, an empty list is returned. -List getParts(String libraryUri) { - if (_parts == null) { - _computeLibraryMetadata(); - } - return _parts![libraryUri] ?? []; -} diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart deleted file mode 100644 index 4867462ec9e..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart +++ /dev/null @@ -1,221 +0,0 @@ -// 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. - -@ReifyFunctionTypes(false) -library dart._runtime; - -import 'dart:async'; -import 'dart:collection'; - -import 'dart:_debugger' show stackTraceMapper, trackCall; -import 'dart:_foreign_helper' show JS, JSExportName, rest, spread; -import 'dart:_interceptors' show JSArray, jsNull, JSFunction, NativeError; -import 'dart:_internal' as internal show Symbol; -import 'dart:_js_helper' - show - AssertionErrorImpl, - BooleanConversionAssertionError, - CastErrorImpl, - DartIterator, - TypeErrorImpl, - JsLinkedHashMap, - ImmutableMap, - PrivateSymbol, - ReifyFunctionTypes, - NoReifyGeneric, - notNull, - undefined; - -export 'dart:_debugger' show getDynamicStats, clearDynamicStats, trackCall; - -part 'utils.dart'; -part 'classes.dart'; -part 'rtti.dart'; -part 'types.dart'; -part 'errors.dart'; -part 'operations.dart'; - -// TODO(vsm): Move polyfill code to dart:html. -// Note, native extensions are registered onto types in dart.global. -// This polyfill needs to run before the corresponding dart:html code is run. -final _polyfilled = JS('', 'Symbol("_polyfilled")'); - -bool polyfill(window) => JS('', '''(() => { - if ($window[$_polyfilled]) return false; - $window[$_polyfilled] = true; - - if (typeof $window.NodeList !== "undefined") { - // TODO(vsm): Do we still need these? - $window.NodeList.prototype.get = function(i) { return this[i]; }; - $window.NamedNodeMap.prototype.get = function(i) { return this[i]; }; - $window.DOMTokenList.prototype.get = function(i) { return this[i]; }; - $window.HTMLCollection.prototype.get = function(i) { return this[i]; }; - - // Expose constructors for DOM types dart:html needs to assume are - // available on window. - if (typeof $window.PannerNode == "undefined") { - let audioContext; - if (typeof $window.AudioContext == "undefined" && - (typeof $window.webkitAudioContext != "undefined")) { - audioContext = new $window.webkitAudioContext(); - } else { - audioContext = new $window.AudioContext(); - $window.StereoPannerNode = - audioContext.createStereoPanner().constructor; - } - $window.PannerNode = audioContext.createPanner().constructor; - } - if (typeof $window.AudioSourceNode == "undefined") { - $window.AudioSourceNode = MediaElementAudioSourceNode.__proto__; - } - if (typeof $window.FontFaceSet == "undefined") { - // CSS Font Loading is not supported on Edge. - if (typeof $window.document.fonts != "undefined") { - $window.FontFaceSet = $window.document.fonts.__proto__.constructor; - } - } - if (typeof $window.MemoryInfo == "undefined") { - if (typeof $window.performance.memory != "undefined") { - $window.MemoryInfo = $window.performance.memory.constructor; - } - } - if (typeof $window.Geolocation == "undefined") { - $window.Geolocation == $window.navigator.geolocation.constructor; - } - if (typeof $window.Animation == "undefined") { - let d = $window.document.createElement('div'); - if (typeof d.animate != "undefined") { - $window.Animation = d.animate(d).constructor; - } - } - if (typeof $window.SourceBufferList == "undefined") { - if ('MediaSource' in $window) { - $window.SourceBufferList = - new $window.MediaSource().sourceBuffers.constructor; - } - } - if (typeof $window.SpeechRecognition == "undefined") { - $window.SpeechRecognition = $window.webkitSpeechRecognition; - $window.SpeechRecognitionError = $window.webkitSpeechRecognitionError; - $window.SpeechRecognitionEvent = $window.webkitSpeechRecognitionEvent; - } - } - return true; -})()'''); - -@JSExportName('global') -final Object global_ = JS('', ''' - function () { - // Find global object. - var globalState = (typeof window != "undefined") ? window - : (typeof global != "undefined") ? global - : (typeof self != "undefined") ? self : null; - if (!globalState) { - // Some platforms (e.g., d8) do not define any of the above. The - // following is a non-CSP safe way to access the global object: - globalState = new Function('return this;')(); - } - - $polyfill(globalState); - - // By default, stack traces cutoff at 10. Set the limit to Infinity for - // better debugging. - if (globalState.Error) { - globalState.Error.stackTraceLimit = Infinity; - } - - // These settings must be configured before the application starts so that - // user code runs with the correct configuration. - let settings = 'ddcSettings' in globalState ? globalState.ddcSettings : {}; - - $trackProfile( - 'trackProfile' in settings ? settings.trackProfile : false); - - return globalState; - }() -'''); - -void trackProfile(bool flag) { - JS('', 'dart.__trackProfile = #', flag); -} - -final JsSymbol = JS('', 'Symbol'); - -/// The prototype used for all Dart libraries. -/// -/// This makes it easy to identify Dart library objects, and also improves -/// performance (JS engines such as V8 tend to assume `Object.create(null)` is -/// used for a Map, so they don't optimize it as they normally would for -/// class-like objects). -/// -/// The `dart.library` field is set by the compiler during SDK bootstrapping -/// (because it is needed for dart:_runtime itself), so we don't need to -/// initialize it here. The name `dart.library` is used because it reads nicely, -/// for example: -/// -/// const my_library = Object.create(dart.library); -/// -Object libraryPrototype = JS('', 'dart.library'); - -// TODO(vsm): Remove once this flag we've removed the ability to -// whitelist / fallback on the old behavior. -bool startAsyncSynchronously = true; -void setStartAsyncSynchronously([bool value = true]) { - startAsyncSynchronously = value; -} - -/// A list of all JS Maps used for caching results, such as by [isSubtypeOf] and -/// [generic]. -/// -/// This is used by [hotRestart] to ensure we don't leak types from previous -/// libraries. -/// Results made against Null are cached in _nullComparisonSet and must be -/// cleared separately. -@notNull -final List _cacheMaps = JS('!', '[]'); - -/// A list of functions to reset static fields back to their uninitialized -/// state. -/// -/// This is populated by [defineLazyField], and only contains the list of fields -/// that have actually been initialized. -@notNull -final List _resetFields = JS('', '[]'); - -/// A counter to track each time [hotRestart] is invoked. This is used to ensure -/// that pending callbacks that were created on a previous iteration (e.g. a -/// timer callback or a DOM callback) will not execute when they get invoked. -// TODO(sigmund): consider whether we should track and cancel callbacks to -// reduce memory leaks. -int hotRestartIteration = 0; - -/// Clears out runtime state in `dartdevc` so we can hot-restart. -/// -/// This should be called when the user requests a hot-restart, when the UI is -/// handling that user action. -void hotRestart() { - // TODO(sigmund): prevent DOM callbacks from firing. - hotRestartIteration++; - for (var f in _resetFields) f(); - _resetFields.clear(); - for (var m in _cacheMaps) JS('', '#.clear()', m); - _cacheMaps.clear(); - JS('', '#.clear()', _nullComparisonSet); - JS('', '#.clear()', constantMaps); -} - -/// Marks enqueuing an async operation. -/// -/// This will be called by library code when enqueuing an async operation -/// controlled by the JavaScript event handler. -/// -/// It will also call [removeAsyncCallback] when Dart callback is about to be -/// executed (note this is called *before* the callback executes, so more -/// async operations could be added from that). -void Function() addAsyncCallback = JS('', 'function() {}'); - -/// Marks leaving a javascript async operation. -/// -/// See [addAsyncCallback]. -void Function() removeAsyncCallback = JS('', 'function() {}'); diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart deleted file mode 100644 index f5f25a0cc46..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart +++ /dev/null @@ -1,2022 +0,0 @@ -// 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. - -/// This library defines the representation of runtime types. -part of dart._runtime; - -_throwNullSafetyWarningError() => throw UnsupportedError( - 'Null safety errors cannot be shown as warnings when running with sound ' - 'null safety.'); - -@notNull -bool _setNullSafety = false; - -@notNull -bool strictNullSafety = false; - -/// Sets the mode of the runtime subtype checks. -/// -/// Changing the mode after the application has started running is not -/// supported. -void nullSafety(bool soundNullSafety) { - if (_setNullSafety) { - throw UnsupportedError('The Null Safety mode can only be set once.'); - } - - if (soundNullSafety && _weakNullSafetyWarnings) - _throwNullSafetyWarningError(); - - strictNullSafety = soundNullSafety; - _setNullSafety = true; -} - -@notNull -bool _weakNullSafetyWarnings = false; - -/// Sets the runtime mode to show warnings when running with weak null safety. -/// -/// These are warnings for issues that will become errors when sound null safety -/// is enabled. Showing warnings while running with sound null safety is not -/// supported (they will be errors). -void weakNullSafetyWarnings(bool showWarnings) { - if (showWarnings && strictNullSafety) _throwNullSafetyWarningError(); - - _weakNullSafetyWarnings = showWarnings; -} - -final metadata = JS('', 'Symbol("metadata")'); - -/// Types in dart are represented internally at runtime as follows. -/// -/// - Normal nominal types, produced from classes, are represented -/// at runtime by the JS class of which they are an instance. -/// If the type is the result of instantiating a generic class, -/// then the "classes" module manages the association between the -/// instantiated class and the original class declaration -/// and the type arguments with which it was instantiated. This -/// association can be queried via the "classes" module". -/// -/// - All other types are represented as instances of class [DartType], -/// defined in this module. -/// - Dynamic, Void, and Bottom are singleton instances of sentinel -/// classes. -/// - Function types are instances of subclasses of AbstractFunctionType. -/// -/// Function types are represented in one of two ways: -/// - As an instance of FunctionType. These are eagerly computed. -/// - As an instance of TypeDef. The TypeDef representation lazily -/// computes an instance of FunctionType, and delegates to that instance. -/// -/// These above "runtime types" are what is used for implementing DDC's -/// internal type checks. These objects are distinct from the objects exposed -/// to user code by class literals and calling `Object.runtimeType`. In DDC, -/// the latter are represented by instances of WrappedType which contain a -/// real runtime type internally. This ensures that the returned object only -/// exposes the API that Type defines: -/// -/// get String name; -/// String toString(); -/// -/// These "runtime types" have methods for performing type checks. The methods -/// have the following JavaScript names which are designed to not collide with -/// static methods, which are also placed 'on' the class constructor function. -/// -/// T.is(o): Implements 'o is T'. -/// T.as(o): Implements 'o as T'. -/// -/// By convention, we used named JavaScript functions for these methods with the -/// name 'is_X' and 'as_X' for various X to indicate the type or the -/// implementation strategy for the test (e.g 'is_String', 'is_G' for generic -/// types, etc.) -// TODO(jmesserly): we shouldn't implement Type here. It should be moved down -// to AbstractFunctionType. -class DartType implements Type { - String get name => this.toString(); - - // TODO(jmesserly): these should never be reached, can be make them abstract? - @notNull - @JSExportName('is') - bool is_T(object) => instanceOf(object, this); - - @JSExportName('as') - as_T(object) => cast(object, this); - - DartType() { - // Every instance of a DartType requires a set of type caches. - JS('', '#(this)', addTypeCaches); - } -} - -class DynamicType extends DartType { - toString() => 'dynamic'; - - @notNull - @JSExportName('is') - bool is_T(object) => true; - - @JSExportName('as') - Object? as_T(Object? object) => object; -} - -@notNull -bool _isJsObject(obj) => JS('!', '# === #', getReifiedType(obj), jsobject); - -/// Asserts that [f] is a native JS functions and returns it if so. -/// -/// This function should be used to ensure that a function is a native JS -/// function before it is passed to native JS code. -@NoReifyGeneric() -F assertInterop(F f) { - assert( - _isJsObject(f) || - !JS('bool', '# instanceof #.Function', f, global_), - 'Dart function requires `allowInterop` to be passed to JavaScript.'); - return f; -} - -bool isDartFunction(obj) => - JS('!', '# instanceof Function', obj) && - JS('!', '#[#] != null', obj, _runtimeType); - -Expando _assertInteropExpando = Expando(); - -@NoReifyGeneric() -F tearoffInterop(F f) { - // Wrap a JS function with a closure that ensures all function arguments are - // native JS functions. - if (!_isJsObject(f) || f == null) return f; - var ret = _assertInteropExpando[f]; - if (ret == null) { - ret = JS( - '', - 'function (...arguments) {' - ' var args = arguments.map(#);' - ' return #.apply(this, args);' - '}', - assertInterop, - f); - _assertInteropExpando[f] = ret; - } - // Suppress a cast back to F. - return JS('', '#', ret); -} - -/// The Dart type that represents a JavaScript class(/constructor) type. -/// -/// The JavaScript type may not exist, either because it's not loaded yet, or -/// because it's not available (such as with mocks). To handle this gracefully, -/// we disable type checks for in these cases, and allow any JS object to work -/// as if it were an instance of this JS type. -class LazyJSType extends DartType { - Function()? _getRawJSTypeFn; - @notNull - final String _dartName; - Object? _rawJSType; - - LazyJSType(this._getRawJSTypeFn, this._dartName); - - toString() { - var raw = _getRawJSType(); - return raw != null ? typeName(raw) : "JSObject<$_dartName>"; - } - - Object? _getRawJSType() { - var raw = _rawJSType; - if (raw != null) return raw; - - // Try to evaluate the JS type. If this fails for any reason, we'll try - // again next time. - // TODO(jmesserly): is it worth trying again? It may create unnecessary - // overhead, especially if exceptions are being thrown. Also it means the - // behavior of a given type check can change later on. - try { - raw = _getRawJSTypeFn!(); - } catch (e) {} - - if (raw == null) { - _warn('Cannot find native JavaScript type ($_dartName) for type check'); - } else { - _rawJSType = raw; - _getRawJSTypeFn = null; // Free the function that computes the JS type. - } - return raw; - } - - Object rawJSTypeForCheck() => _getRawJSType() ?? jsobject; - - @notNull - bool isRawJSType(obj) { - var raw = _getRawJSType(); - if (raw != null) return JS('!', '# instanceof #', obj, raw); - return _isJsObject(obj); - } - - @notNull - @JSExportName('is') - bool is_T(obj) => isRawJSType(obj) || instanceOf(obj, this); - - @JSExportName('as') - as_T(obj) => obj == null || is_T(obj) ? obj : castError(obj, this); -} - -/// An anonymous JS type -/// -/// For the purposes of subtype checks, these match any JS type. -class AnonymousJSType extends DartType { - final String _dartName; - AnonymousJSType(this._dartName); - toString() => _dartName; - - @JSExportName('is') - bool is_T(obj) => _isJsObject(obj) || instanceOf(obj, this); - - @JSExportName('as') - as_T(obj) => obj == null || _isJsObject(obj) ? obj : cast(obj, this); -} - -void _warn(arg) { - JS('void', 'console.warn(#)', arg); -} - -void _nullWarn(arg) { - if (_weakNullSafetyWarnings) { - _warn('$arg\n' - 'This will become a failure when runtime null safety is enabled.'); - } -} - -/// Tracks objects that have been compared against null (i.e., null is Type). -/// Separating this null set out from _cacheMaps lets us fast-track common -/// legacy type checks. -/// TODO: Delete this set when legacy nullability is phased out. -var _nullComparisonSet = JS('', 'new Set()'); - -/// Warn on null cast failures when casting to a particular non-nullable -/// `type`. Note, we cache by type to avoid excessive warning messages at -/// runtime. -/// TODO(vsm): Consider changing all invocations to pass / cache on location -/// instead. That gives more useful feedback to the user. -void _nullWarnOnType(type) { - bool result = JS('', '#.has(#)', _nullComparisonSet, type); - if (!result) { - JS('', '#.add(#)', _nullComparisonSet, type); - _nullWarn("Null is not a subtype of $type."); - } -} - -var _lazyJSTypes = JS('', 'new Map()'); -var _anonymousJSTypes = JS('', 'new Map()'); - -lazyJSType(Function() getJSTypeCallback, String name) { - var ret = JS('', '#.get(#)', _lazyJSTypes, name); - if (ret == null) { - ret = LazyJSType(getJSTypeCallback, name); - JS('', '#.set(#, #)', _lazyJSTypes, name, ret); - } - return ret; -} - -anonymousJSType(String name) { - var ret = JS('', '#.get(#)', _anonymousJSTypes, name); - if (ret == null) { - ret = AnonymousJSType(name); - JS('', '#.set(#, #)', _anonymousJSTypes, name, ret); - } - return ret; -} - -/// A javascript Symbol used to store a canonical version of T? on T. -final _cachedNullable = JS('', 'Symbol("cachedNullable")'); - -/// A javascript Symbol used to store a canonical version of T* on T. -final _cachedLegacy = JS('', 'Symbol("cachedLegacy")'); - -/// A javascript Symbol used to store prior subtype checks and their results. -final _subtypeCache = JS('', 'Symbol("_subtypeCache")'); - -/// Returns a nullable (question, ?) version of [type]. -/// -/// The resulting type returned in a normalized form based on the rules from the -/// normalization doc: -/// https://github.com/dart-lang/language/blob/master/resources/type-system/normalization.md -@notNull -Object nullable(@notNull Object type) { - // Check if a nullable version of this type has already been created. - var cached = JS('', '#[#]', type, _cachedNullable); - if (JS('!', '# !== void 0', cached)) { - return cached; - } - - // Cache a canonical nullable version of this type on this type. - Object cachedType = _computeNullable(type); - JS('', '#[#] = #', type, _cachedNullable, cachedType); - return cachedType; -} - -Object _computeNullable(@notNull Object type) { - // *? normalizes to ?. - if (_jsInstanceOf(type, LegacyType)) { - return nullable(JS('!', '#.type', type)); - } - if (_jsInstanceOf(type, NullableType) || - _isTop(type) || - _equalType(type, Null) || - // Normalize FutureOr? --> FutureOr - // All other runtime FutureOr normalization is in `normalizeFutureOr()`. - ((_isFutureOr(type)) && - _jsInstanceOf( - JS('!', '#[0]', getGenericArgs(type)), NullableType))) { - return type; - } - if (_equalType(type, Never)) return unwrapType(Null); - return NullableType(JS('!', '#', type)); -} - -/// Returns a legacy (star, *) version of [type]. -/// -/// The resulting type returned in a normalized form based on the rules from the -/// normalization doc: -/// https://github.com/dart-lang/language/blob/master/resources/type-system/normalization.md -@notNull -Object legacy(@notNull Object type) { - // Check if a legacy version of this type has already been created. - var cached = JS('', '#[#]', type, _cachedLegacy); - if (JS('!', '# !== void 0', cached)) { - return cached; - } - - // Cache a canonical legacy version of this type on this type. - Object cachedType = _computeLegacy(type); - JS('', '#[#] = #', type, _cachedLegacy, cachedType); - return cachedType; -} - -Object _computeLegacy(@notNull Object type) { - // Note: ?* normalizes to ?, so we cache type? at type?[_cachedLegacy]. - if (_jsInstanceOf(type, LegacyType) || - _jsInstanceOf(type, NullableType) || - _isTop(type) || - _equalType(type, Null)) { - return type; - } - return LegacyType(JS('!', '#', type)); -} - -/// A wrapper to identify a nullable (question, ?) type of the form [type]?. -class NullableType extends DartType { - final Type type; - - NullableType(@notNull this.type); - - @override - String get name => '$type?'; - - @override - String toString() => name; - - @JSExportName('is') - bool is_T(obj) => obj == null || JS('!', '#.is(#)', type, obj); - - @JSExportName('as') - as_T(obj) => obj == null || JS('!', '#.is(#)', type, obj) - ? obj - : cast(obj, this); -} - -/// A wrapper to identify a legacy (star, *) type of the form [type]*. -class LegacyType extends DartType { - final Type type; - - LegacyType(@notNull this.type); - - @override - String get name => '$type'; - - @override - String toString() => name; - - @JSExportName('is') - bool is_T(obj) { - if (obj == null) { - // Object and Never are the only legacy types that should return true if - // obj is `null`. - return _equalType(type, Object) || _equalType(type, Never); - } - return JS('!', '#.is(#)', type, obj); - } - - @JSExportName('as') - as_T(obj) => obj == null || JS('!', '#.is(#)', type, obj) - ? obj - : cast(obj, this); -} - -// TODO(nshahan) Add override optimizations for is and as? -class NeverType extends DartType { - @override - toString() => 'Never'; -} - -@JSExportName('Never') -final _never = NeverType(); - -@JSExportName('dynamic') -final _dynamic = DynamicType(); - -class VoidType extends DartType { - toString() => 'void'; - - @notNull - @JSExportName('is') - bool is_T(object) => true; - - @JSExportName('as') - Object? as_T(Object? object) => object; -} - -@JSExportName('void') -final void_ = VoidType(); - -// TODO(nshahan): Cleanup and consolidate NeverType, BottomType, bottom, _never. -class BottomType extends DartType { - toString() => 'bottom'; -} - -final bottom = unwrapType(Null); - -class JSObjectType extends DartType { - toString() => 'NativeJavaScriptObject'; -} - -final jsobject = JSObjectType(); - -/// Dev Compiler's implementation of Type, wrapping its internal [_type]. -class _Type extends Type { - /// The internal type representation, either a [DartType] or class constructor - /// function. - // TODO(jmesserly): introduce InterfaceType so we don't have to special case - // classes - @notNull - final Object _type; - - _Type(this._type); - - toString() => typeName(_type); - - Type get runtimeType => Type; -} - -/// Given an internal runtime type object [type], wraps it in a `_Type` object -/// that implements the dart:core Type interface. -/// -/// [isNormalized] is true when [type] is known to be in a canonicalized -/// normal form, so the algorithm can directly wrap and return the value. -Type wrapType(type, [@notNull bool isNormalized = false]) { - // If we've already wrapped this type once, use the previous wrapper. This - // way, multiple references to the same type return an identical Type. - if (JS('!', '#.hasOwnProperty(#)', type, _typeObject)) { - return JS('', '#[#]', type, _typeObject); - } - var result = isNormalized - ? _Type(type) - : (_jsInstanceOf(type, LegacyType) - ? wrapType(JS('!', '#.type', type)) - : _canonicalizeNormalizedTypeObject(type)); - JS('', '#[#] = #', type, _typeObject, result); - return result; -} - -/// Constructs a normalized version of a type. -/// -/// Used for type object identity. Normalization requires us to return a -/// canonicalized version of the input with all legacy wrappers removed. -Type _canonicalizeNormalizedTypeObject(type) { - assert(!_jsInstanceOf(type, LegacyType)); - // We don't call _canonicalizeNormalizedTypeObject recursively but call wrap - // + unwrap to handle legacy types automatically and force caching the - // canonicalized type under the _typeObject cache property directly. This - // way we ensure we always use the canonical normalized instance for each - // type term. - Object normalizeHelper(a) => unwrapType(wrapType(a)); - - // GenericFunctionTypeIdentifiers are implicitly normalized. - if (_jsInstanceOf(type, GenericFunctionTypeIdentifier)) { - return wrapType(type, true); - } - if (_jsInstanceOf(type, FunctionType)) { - var normReturnType = normalizeHelper(type.returnType); - var normArgs = type.args.map(normalizeHelper).toList(); - if (JS('!', '#.Object.keys(#).length === 0', global_, type.named) && - JS('!', '#.Object.keys(#).length === 0', global_, - type.requiredNamed)) { - if (type.optionals.isEmpty) { - var normType = fnType(normReturnType, normArgs); - return wrapType(normType, true); - } - var normOptionals = type.optionals.map(normalizeHelper).toList(); - var normType = fnType(normReturnType, normArgs, normOptionals); - return wrapType(normType, true); - } - var normNamed = JS('', '{}'); - _transformJSObject(type.named, normNamed, normalizeHelper); - var normRequiredNamed = JS('', '{}'); - _transformJSObject(type.requiredNamed, normRequiredNamed, normalizeHelper); - var normType = - fnType(normReturnType, normArgs, normNamed, normRequiredNamed); - return wrapType(normType, true); - } - if (_jsInstanceOf(type, GenericFunctionType)) { - var formals = _getCanonicalTypeFormals(type.typeFormals.length); - var normBounds = - type.instantiateTypeBounds(formals).map(normalizeHelper).toList(); - var normFunc = normalizeHelper(type.instantiate(formals)) as FunctionType; - // Create a comparison key for structural identity. - var typeObjectIdKey = JS('', '[]'); - JS('', '#.push(...#)', typeObjectIdKey, normBounds); - JS('', '#.push(#)', typeObjectIdKey, normFunc); - var memoizedId = _memoizeArray(_gFnTypeTypeMap, typeObjectIdKey, - () => GenericFunctionTypeIdentifier(formals, normBounds, normFunc)); - return wrapType(memoizedId, true); - } - var args = getGenericArgs(type); - var normType; - if (args == null || args.isEmpty) { - normType = type; - } else { - var genericClass = getGenericClass(type); - var normArgs = args.map(normalizeHelper).toList(); - normType = JS('!', '#(...#)', genericClass, normArgs); - } - return wrapType(normType, true); -} - -/// Generates new values by applying [transform] to the values of [srcObject], -/// storing them in [dstObject] with the same key. -void _transformJSObject(srcObject, dstObject, Function transform) { - for (Object key in JS('!', '#.Object.keys(#)', global_, srcObject)) { - JS('', '#[#] = #', dstObject, key, - transform(JS('', '#[#]', srcObject, key))); - } -} - -/// The symbol used to store the cached `Type` object associated with a class. -final _typeObject = JS('', 'Symbol("typeObject")'); - -/// Given a WrappedType, return the internal runtime type object. -Object unwrapType(Type obj) => JS<_Type>('', '#', obj)._type; - -// Marker class for generic functions, typedefs, and non-generic functions. -abstract class AbstractFunctionType extends DartType {} - -/// Memo table for named argument groups. A named argument packet -/// {name1 : type1, ..., namen : typen} corresponds to the path -/// n, name1, type1, ...., namen, typen. The element of the map -/// reached via this path (if any) is the canonical representative -/// for this packet. -final _fnTypeNamedArgMap = JS('', 'new Map()'); - -/// Memo table for positional argument groups. A positional argument -/// packet [type1, ..., typen] (required or optional) corresponds to -/// the path n, type1, ...., typen. The element reached via -/// this path (if any) is the canonical representative for this -/// packet. Note that required and optional parameters packages -/// may have the same canonical representation. -final _fnTypeArrayArgMap = JS('', 'new Map()'); - -/// Memo table for function types. The index path consists of the -/// path length - 1, the returnType, the canonical positional argument -/// packet, and if present, the canonical optional or named argument -/// packet. A level of indirection could be avoided here if desired. -final _fnTypeTypeMap = JS('', 'new Map()'); - -/// Memo table for small function types with no optional or named -/// arguments and less than a fixed n (currently 3) number of -/// required arguments. Indexing into this table by the number -/// of required arguments yields a map which is indexed by the -/// argument types themselves. The element reached via this -/// index path (if present) is the canonical function type. -final List _fnTypeSmallMap = JS('', '[new Map(), new Map(), new Map()]'); - -/// Memo table for generic function types. The index path consists of the -/// type parameters' bounds and the underlying function instantiated to its -/// bounds, subject to the same restrictions mentioned in _fnTypeTypeMap. -final _gFnTypeTypeMap = JS('', 'new Map()'); - -/// Pre-initialized type variables used to ensure that generic functions with -/// the same generic relationship structure but different names canonicalize -/// correctly. -final _typeVariablePool = []; - -/// Returns a canonicalized sequence of type variables of size [count]. -List _getCanonicalTypeFormals(int count) { - while (count > _typeVariablePool.length) { - _fillTypeVariable(); - } - return _typeVariablePool.sublist(0, count); -} - -/// Inserts a new type variable into _typeVariablePool according to a -/// pre-determined pattern. -/// -/// The first 26 generics are alphanumerics; the remainder are represented as -/// T$N, where N increments from 0. -void _fillTypeVariable() { - if (_typeVariablePool.length < 26) { - _typeVariablePool - .add(TypeVariable(String.fromCharCode(65 + _typeVariablePool.length))); - } else { - _typeVariablePool.add(TypeVariable('T${_typeVariablePool.length - 26}')); - } -} - -@NoReifyGeneric() -T _memoizeArray(map, arr, T create()) => JS('', '''(() => { - let len = $arr.length; - $map = $_lookupNonTerminal($map, len); - for (var i = 0; i < len-1; ++i) { - $map = $_lookupNonTerminal($map, $arr[i]); - } - let result = $map.get($arr[len-1]); - if (result !== void 0) return result; - $map.set($arr[len-1], result = $create()); - return result; -})()'''); - -List _canonicalizeArray(List array, map) => - _memoizeArray(map, array, () => array); - -// TODO(leafp): This only canonicalizes if the names are emitted -// in a consistent order. -_canonicalizeNamed(named, map) => JS('', '''(() => { - let key = []; - let names = $getOwnPropertyNames($named); - for (var i = 0; i < names.length; ++i) { - let name = names[i]; - let type = $named[name]; - key.push(name); - key.push(type); - } - return $_memoizeArray($map, key, () => $named); -})()'''); - -// TODO(leafp): This handles some low hanging fruit, but -// really we should make all of this faster, and also -// handle more cases here. -FunctionType _createSmall(returnType, List required) => JS('', '''(() => { - let count = $required.length; - let map = $_fnTypeSmallMap[count]; - for (var i = 0; i < count; ++i) { - map = $_lookupNonTerminal(map, $required[i]); - } - let result = map.get($returnType); - if (result !== void 0) return result; - result = ${new FunctionType(returnType, required, [], JS('', '{}'), JS('', '{}'))}; - map.set($returnType, result); - return result; -})()'''); - -class FunctionType extends AbstractFunctionType { - final Type returnType; - final List args; - final List optionals; - // Named arguments native JS Object of the form { namedArgName: namedArgType } - final named; - final requiredNamed; - String? _stringValue; - - /// Construct a function type. - /// - /// We eagerly normalize the argument types to avoid having to deal with this - /// logic in multiple places. - /// - /// This code does best effort canonicalization. It does not guarantee that - /// all instances will share. - /// - /// Note: Generic function subtype checks assume types have been canonicalized - /// when testing if type bounds are equal. - static FunctionType create( - returnType, List args, optionalArgs, requiredNamedArgs) { - // Note that if optionalArgs is ever passed as an empty array or an empty - // map, we can end up with semantically identical function types that don't - // canonicalize to the same object since we won't fall into this fast path. - var noOptionalArgs = optionalArgs == null && requiredNamedArgs == null; - if (noOptionalArgs && JS('!', '#.length < 3', args)) { - return _createSmall(returnType, args); - } - args = _canonicalizeArray(args, _fnTypeArrayArgMap); - var keys = []; - FunctionType Function() create; - if (noOptionalArgs) { - keys = [returnType, args]; - create = - () => FunctionType(returnType, args, [], JS('', '{}'), JS('', '{}')); - } else if (JS('!', '# instanceof Array', optionalArgs)) { - var optionals = - _canonicalizeArray(JS('', '#', optionalArgs), _fnTypeArrayArgMap); - keys = [returnType, args, optionals]; - create = () => - FunctionType(returnType, args, optionals, JS('', '{}'), JS('', '{}')); - } else { - var named = _canonicalizeNamed(optionalArgs, _fnTypeNamedArgMap); - var requiredNamed = - _canonicalizeNamed(requiredNamedArgs, _fnTypeNamedArgMap); - keys = [returnType, args, named, requiredNamed]; - create = () => FunctionType(returnType, args, [], named, requiredNamed); - } - return _memoizeArray(_fnTypeTypeMap, keys, create); - } - - FunctionType(this.returnType, this.args, this.optionals, this.named, - this.requiredNamed); - - toString() => name; - - int get requiredParameterCount => args.length; - int get positionalParameterCount => args.length + optionals.length; - - getPositionalParameter(int i) { - int n = args.length; - return i < n ? args[i] : optionals[i + n]; - } - - /// Maps argument names to their canonicalized type. - Map _createNameMap(List names) { - var result = {}; - // TODO: Remove this sort if ordering can be conserved. - JS('', '#.sort()', names); - for (var i = 0; JS('!', '# < #.length', i, names); ++i) { - String name = JS('!', '#[#]', names, i); - result[name] = JS('', '#[#]', named, name); - } - return result; - } - - /// Maps optional named parameter names to their canonicalized type. - Map getNamedParameters() => - _createNameMap(getOwnPropertyNames(named).toList()); - - /// Maps required named parameter names to their canonicalized type. - Map getRequiredNamedParameters() => - _createNameMap(getOwnPropertyNames(requiredNamed).toList()); - - get name { - if (_stringValue != null) return _stringValue!; - var buffer = '('; - for (var i = 0; JS('!', '# < #.length', i, args); ++i) { - if (i > 0) { - buffer += ', '; - } - buffer += typeName(JS('', '#[#]', args, i)); - } - if (JS('!', '#.length > 0', optionals)) { - if (JS('!', '#.length > 0', args)) buffer += ', '; - buffer += '['; - for (var i = 0; JS('!', '# < #.length', i, optionals); ++i) { - if (i > 0) { - buffer += ', '; - } - buffer += typeName(JS('', '#[#]', optionals, i)); - } - buffer += ']'; - } else if (JS('!', 'Object.keys(#).length > 0 || Object.keys(#).length > 0', - named, requiredNamed)) { - if (JS('!', '#.length > 0', args)) buffer += ', '; - buffer += '{'; - var names = getOwnPropertyNames(named); - JS('', '#.sort()', names); - for (var i = 0; JS('!', '# < #.length', i, names); i++) { - if (i > 0) { - buffer += ', '; - } - var typeNameString = typeName(JS('', '#[#[#]]', named, names, i)); - buffer += '$typeNameString ${JS('', '#[#]', names, i)}'; - } - if (JS('!', 'Object.keys(#).length > 0 && #.length > 0', requiredNamed, - names)) buffer += ', '; - names = getOwnPropertyNames(requiredNamed); - JS('', '#.sort()', names); - for (var i = 0; JS('!', '# < #.length', i, names); i++) { - if (i > 0) { - buffer += ', '; - } - var typeNameString = - typeName(JS('', '#[#[#]]', requiredNamed, names, i)); - buffer += 'required $typeNameString ${JS('', '#[#]', names, i)}'; - } - buffer += '}'; - } - var returnTypeName = typeName(returnType); - buffer += ') => $returnTypeName'; - _stringValue = buffer; - return buffer; - } - - @JSExportName('is') - bool is_T(obj) { - if (JS('!', 'typeof # == "function"', obj)) { - var actual = JS('', '#[#]', obj, _runtimeType); - // If there's no actual type, it's a JS function. - // Allow them to subtype all Dart function types. - return actual == null || isSubtypeOf(actual, this); - } - return false; - } - - @JSExportName('as') - as_T(obj) { - if (is_T(obj)) return obj; - // TODO(nshahan) This could directly call castError after we no longer allow - // a cast of null to succeed in weak mode. - return cast(obj, this); - } -} - -/// A type variable, used by [GenericFunctionType] to represent a type formal. -class TypeVariable extends DartType { - final String name; - - TypeVariable(this.name); - - toString() => name; -} - -class Variance { - static const int unrelated = 0; - static const int covariant = 1; - static const int contravariant = 2; - static const int invariant = 3; -} - -/// Uniquely identifies the runtime type object of a generic function. -/// -/// We require that all objects stored in this object not have legacy -/// nullability wrappers. -class GenericFunctionTypeIdentifier extends AbstractFunctionType { - final typeFormals; - final typeBounds; - final FunctionType function; - String? _stringValue; - - GenericFunctionTypeIdentifier( - this.typeFormals, this.typeBounds, this.function); - - /// Returns the string-representation of the first generic function - /// with this runtime type object canonicalization. - /// - /// Type formal names may not correspond to those of the originating type. - /// We should consider auto-generating these to avoid confusion. - toString() { - if (_stringValue != null) return _stringValue!; - String s = "<"; - var typeFormals = this.typeFormals; - var typeBounds = this.typeBounds; - for (int i = 0, n = typeFormals.length; i < n; i++) { - if (i != 0) s += ", "; - s += JS('!', '#[#].name', typeFormals, i); - var bound = typeBounds[i]; - if (_equalType(bound, dynamic) || - JS('!', '# === #', bound, nullable(unwrapType(Object))) || - (!strictNullSafety && _equalType(bound, Object))) { - // Do not print the bound when it is a top type. In weak mode the bounds - // of Object and Object* will also be elided. - continue; - } - s += " extends $bound"; - } - s += ">" + this.function.toString(); - return this._stringValue = s; - } -} - -class GenericFunctionType extends AbstractFunctionType { - final _instantiateTypeParts; - final int formalCount; - final _instantiateTypeBounds; - final List _typeFormals; - - GenericFunctionType(instantiateTypeParts, this._instantiateTypeBounds) - : _instantiateTypeParts = instantiateTypeParts, - formalCount = JS('!', '#.length', instantiateTypeParts), - _typeFormals = _typeFormalsFromFunction(instantiateTypeParts); - - List get typeFormals => _typeFormals; - - /// `true` if there are bounds on any of the generic type parameters. - get hasTypeBounds => _instantiateTypeBounds != null; - - /// Checks that [typeArgs] satisfies the upper bounds of the [typeFormals], - /// and throws a [TypeError] if they do not. - void checkBounds(List typeArgs) { - // If we don't have explicit type parameter bounds, the bounds default to - // a top type, so there's nothing to check here. - if (!hasTypeBounds) return; - - var bounds = instantiateTypeBounds(typeArgs); - var typeFormals = this.typeFormals; - for (var i = 0; i < typeArgs.length; i++) { - checkTypeBound(typeArgs[i], bounds[i], typeFormals[i].name); - } - } - - FunctionType instantiate(typeArgs) { - var parts = JS('', '#.apply(null, #)', _instantiateTypeParts, typeArgs); - return FunctionType.create(JS('', '#[0]', parts), JS('', '#[1]', parts), - JS('', '#[2]', parts), JS('', '#[3]', parts)); - } - - List instantiateTypeBounds(List typeArgs) { - if (!hasTypeBounds) { - // We omit the a bound to represent Object*. Other bounds are explicitly - // represented, including Object, Object? and dynamic. - // TODO(nshahan) Revisit this representation when more libraries have - // migrated to null safety. - return List.filled(formalCount, legacy(unwrapType(Object))); - } - // Bounds can be recursive or depend on other type parameters, so we need to - // apply type arguments and return the resulting bounds. - return JS>( - '!', '#.apply(null, #)', _instantiateTypeBounds, typeArgs); - } - - toString() { - String s = "<"; - var typeFormals = this.typeFormals; - var typeBounds = instantiateTypeBounds(typeFormals); - for (int i = 0, n = typeFormals.length; i < n; i++) { - if (i != 0) s += ", "; - s += JS('!', '#[#].name', typeFormals, i); - var bound = typeBounds[i]; - if (JS('!', '# !== # && # !== #', bound, dynamic, bound, Object)) { - s += " extends $bound"; - } - } - s += ">" + instantiate(typeFormals).toString(); - return s; - } - - /// Given a [DartType] [type], if [type] is an uninstantiated - /// parameterized type then instantiate the parameters to their - /// bounds and return those type arguments. - /// - /// See the issue for the algorithm description: - /// - List instantiateDefaultBounds() { - /// Returns `true` if the default value for the type bound should be - /// `dynamic`. - /// - /// Dart 2 with null safety uses dynamic as the default value for types - /// without explicit bounds. - /// - /// This is similar to [_isTop] but removes the check for `void` (it can't - /// be written as a bound) and adds a check of `Object*` in weak mode. - bool defaultsToDynamic(type) { - // Technically this is wrong, only implicit bounds of `Object?` and - // `Object*` should default to dynamic but code that observes the - // difference is rare. - if (_equalType(type, dynamic)) return true; - if (_jsInstanceOf(type, NullableType) || - (!strictNullSafety && _jsInstanceOf(type, LegacyType))) { - return _equalType(JS('!', '#.type', type), Object); - } - return false; - } - - var typeFormals = this.typeFormals; - - // All type formals - var all = HashMap.identity(); - // ground types, by index. - // - // For each index, this will be a ground type for the corresponding type - // formal if known, or it will be the original TypeVariable if we are still - // solving for it. This array is passed to `instantiateToBounds` as we are - // progressively solving for type variables. - var defaults = List.filled(typeFormals.length, null); - // not ground - var partials = Map.identity(); - - var typeBounds = this.instantiateTypeBounds(typeFormals); - for (var i = 0; i < typeFormals.length; i++) { - var typeFormal = typeFormals[i]; - var bound = typeBounds[i]; - all[typeFormal] = i; - if (defaultsToDynamic(bound)) { - // TODO(nshahan) Persist the actual default values into the runtime so - // they can be used here instead of using dynamic for all top types - // implicit or explicit. - defaults[i] = _dynamic; - } else { - defaults[i] = typeFormal; - partials[typeFormal] = bound; - } - } - - bool hasFreeFormal(t) { - if (partials.containsKey(t)) return true; - - // Ignore nullability wrappers. - if (_jsInstanceOf(t, LegacyType) || _jsInstanceOf(t, NullableType)) { - return hasFreeFormal(JS('!', '#.type', t)); - } - // Generic classes and typedefs. - var typeArgs = getGenericArgs(t); - if (typeArgs != null) return typeArgs.any(hasFreeFormal); - if (t is GenericFunctionType) { - return hasFreeFormal(t.instantiate(t.typeFormals)); - } - if (t is FunctionType) { - return hasFreeFormal(t.returnType) || t.args.any(hasFreeFormal); - } - return false; - } - - var hasProgress = true; - while (hasProgress) { - hasProgress = false; - for (var typeFormal in partials.keys) { - var partialBound = partials[typeFormal]!; - if (!hasFreeFormal(partialBound)) { - int index = all[typeFormal]!; - defaults[index] = instantiateTypeBounds(defaults)[index]; - partials.remove(typeFormal); - hasProgress = true; - break; - } - } - } - - // If we stopped making progress, and not all types are ground, - // then the whole type is malbounded and an error should be reported - // if errors are requested, and a partially completed type should - // be returned. - if (partials.isNotEmpty) { - throwTypeError('Instantiate to bounds failed for type with ' - 'recursive generic bounds: ${typeName(this)}. ' - 'Try passing explicit type arguments.'); - } - return defaults; - } - - @notNull - @JSExportName('is') - bool is_T(obj) { - if (JS('!', 'typeof # == "function"', obj)) { - var actual = JS('', '#[#]', obj, _runtimeType); - return actual != null && isSubtypeOf(actual, this); - } - return false; - } - - @JSExportName('as') - as_T(obj) { - if (is_T(obj)) return obj; - // TODO(nshahan) This could directly call castError after we no longer allow - // a cast of null to succeed in weak mode. - return cast(obj, this); - } -} - -List _typeFormalsFromFunction(Object? typeConstructor) { - // Extract parameter names from the function parameters. - // - // This is not robust in general for user-defined JS functions, but it - // should handle the functions generated by our compiler. - // - // TODO(jmesserly): names of TypeVariables are only used for display - // purposes, such as when an error happens or if someone calls - // `Type.toString()`. So we could recover them lazily rather than eagerly. - // Alternatively we could synthesize new names. - String str = JS('!', '#.toString()', typeConstructor); - var hasParens = str[0] == '('; - var end = str.indexOf(hasParens ? ')' : '=>'); - if (hasParens) { - return str - .substring(1, end) - .split(',') - .map((n) => TypeVariable(n.trim())) - .toList(); - } else { - return [TypeVariable(str.substring(0, end).trim())]; - } -} - -/// Create a function type. -FunctionType fnType(returnType, List args, - [@undefined optional, @undefined requiredNamed]) => - FunctionType.create(returnType, args, optional, requiredNamed); - -/// Creates a generic function type from [instantiateFn] and [typeBounds]. -/// -/// A function type consists of two things: -/// * An instantiate function that takes type arguments and returns the -/// function signature in the form of a two element list. The first element -/// is the return type. The second element is a list of the argument types. -/// * A function that returns a list of upper bound constraints for each of -/// the type formals. -/// -/// Both functions accept the type parameters, allowing us to substitute values. -/// The upper bound constraints can be omitted if all of the type parameters use -/// the default upper bound. -/// -/// For example given the type >(T) -> T, we can declare -/// this type with `gFnType(T => [T, [T]], T => [Iterable$(T)])`. -gFnType(instantiateFn, typeBounds) => - GenericFunctionType(instantiateFn, typeBounds); - -/// Whether the given JS constructor [obj] is a Dart class type. -@notNull -bool isType(obj) => JS('', '#[#] === #', obj, _runtimeType, Type); - -void checkTypeBound( - @notNull Object type, @notNull Object bound, @notNull String name) { - if (!isSubtypeOf(type, bound)) { - throwTypeError('type `$type` does not extend `$bound` of `$name`.'); - } -} - -@notNull -String typeName(type) => JS('', '''(() => { - if ($type === void 0) return "undefined type"; - if ($type === null) return "null type"; - // Non-instance types - if (${_jsInstanceOf(type, DartType)}) { - return $type.toString(); - } - - // Instance types - let tag = $type[$_runtimeType]; - if (tag === $Type) { - let name = $type.name; - let args = ${getGenericArgs(type)}; - if (args == null) return name; - - if (${getGenericClass(type)} == ${getGenericClass(JSArray)}) name = 'List'; - - let result = name; - result += '<'; - for (let i = 0; i < args.length; ++i) { - if (i > 0) result += ', '; - result += $typeName(args[i]); - } - result += '>'; - return result; - } - if (tag) return "Not a type: " + tag.name; - return "JSObject<" + $type.name + ">"; -})()'''); - -/// Returns true if [ft1] <: [ft2]. -_isFunctionSubtype(ft1, ft2, @notNull bool strictMode) => JS('', '''(() => { - let ret1 = $ft1.returnType; - let ret2 = $ft2.returnType; - - let args1 = $ft1.args; - let args2 = $ft2.args; - - if (args1.length > args2.length) { - return false; - } - - for (let i = 0; i < args1.length; ++i) { - if (!$_isSubtype(args2[i], args1[i], strictMode)) { - return false; - } - } - - let optionals1 = $ft1.optionals; - let optionals2 = $ft2.optionals; - - if (args1.length + optionals1.length < args2.length + optionals2.length) { - return false; - } - - let j = 0; - for (let i = args1.length; i < args2.length; ++i, ++j) { - if (!$_isSubtype(args2[i], optionals1[j], strictMode)) { - return false; - } - } - - for (let i = 0; i < optionals2.length; ++i, ++j) { - if (!$_isSubtype(optionals2[i], optionals1[j], strictMode)) { - return false; - } - } - - // Named parameter invariants: - // 1) All named params in the superclass are named params in the subclass. - // 2) All required named params in the subclass are required named params - // in the superclass. - // 3) With strict null checking disabled, we treat required named params as - // optional named params. - let named1 = $ft1.named; - let requiredNamed1 = $ft1.requiredNamed; - let named2 = $ft2.named; - let requiredNamed2 = $ft2.requiredNamed; - if (!strictMode) { - // In weak mode, treat required named params as optional named params. - named1 = Object.assign({}, named1, requiredNamed1); - named2 = Object.assign({}, named2, requiredNamed2); - requiredNamed1 = {}; - requiredNamed2 = {}; - } - - let names = $getOwnPropertyNames(requiredNamed1); - for (let i = 0; i < names.length; ++i) { - let name = names[i]; - let n2 = requiredNamed2[name]; - if (n2 === void 0) { - return false; - } - } - names = $getOwnPropertyNames(named2); - for (let i = 0; i < names.length; ++i) { - let name = names[i]; - let n1 = named1[name]; - let n2 = named2[name]; - if (n1 === void 0) { - return false; - } - if (!$_isSubtype(n2, n1, strictMode)) { - return false; - } - } - names = $getOwnPropertyNames(requiredNamed2); - for (let i = 0; i < names.length; ++i) { - let name = names[i]; - let n1 = named1[name] || requiredNamed1[name]; - let n2 = requiredNamed2[name]; - if (n1 === void 0) { - return false; - } - if (!$_isSubtype(n2, n1, strictMode)) { - return false; - } - } - - return $_isSubtype(ret1, ret2, strictMode); -})()'''); - -/// Returns true if [t1] <: [t2]. -@notNull -bool isSubtypeOf(@notNull Object t1, @notNull Object t2) { - // TODO(jmesserly): we've optimized `is`/`as`/implicit type checks, so they're - // dispatched on the type. Can we optimize the subtype relation too? - var map = JS('!', '#[#]', t1, _subtypeCache); - bool result = JS('', '#.get(#)', map, t2); - if (JS('!', '# !== void 0', result)) return result; - - var validSubtype = _isSubtype(t1, t2, true); - if (!validSubtype && !strictNullSafety) { - validSubtype = _isSubtype(t1, t2, false); - if (validSubtype) { - // TODO(nshahan) Need more information to be helpful here. - // File and line number that caused the subtype check? - // Possibly break into debugger? - _nullWarn("$t1 is not a subtype of $t2."); - } - } - JS('', '#.set(#, #)', map, t2, validSubtype); - return validSubtype; -} - -@notNull -bool _isBottom(type, @notNull bool strictMode) => - _equalType(type, Never) || (!strictMode && _equalType(type, Null)); - -@notNull -bool _isTop(type) { - if (_jsInstanceOf(type, NullableType)) - return JS('!', '#.type === #', type, Object); - - return _equalType(type, dynamic) || JS('!', '# === #', type, void_); -} - -/// Wraps the JavaScript `instanceof` operator returning `true` if [type] is an -/// instance of [cls]. -/// -/// This method is equivalent to: -/// -/// JS('!', '# instanceof #', type, cls); -/// -/// but the code is generated by the compiler directly (a low-tech way of -/// inlining). -@notNull -external bool _jsInstanceOf(type, cls); - -/// Returns `true` if [type] is [cls]. -/// -/// This method is equivalent to: -/// -/// JS('!', '# === #', type, unwrapType(cls)); -/// -/// but the code is generated by the compiler directly (a low-tech way of -/// inlining). -@notNull -external bool _equalType(type, cls); - -/// Extracts the type argument as an unwrapped type preserving all forms of -/// nullability. -/// -/// Acts as a way to bypass extra calls of [wrapType] and [unwrapType]. For -/// example `typeRep()` emits `dart.nullable(core.Object)` directly. -@notNull -external Type typeRep(); - -/// Extracts the type argument as an unwrapped type and performs a shallow -/// replacement of the nullability to a legacy type. -/// -/// Acts as a way to bypass extra calls of [wrapType] and [unwrapType]. For -/// example `legacyTypeRep()` emits `dart.legacy(core.Object)` directly. -@notNull -external Type legacyTypeRep(); - -@notNull -bool _isFutureOr(type) { - var genericClass = getGenericClass(type); - return JS('!', '# && # === #', genericClass, genericClass, - getGenericClass(FutureOr)); -} - -@notNull -bool _isSubtype(t1, t2, @notNull bool strictMode) => JS('!', '''(() => { - if (!$strictMode) { - // Strip nullable types when performing check in weak mode. - // TODO(nshahan) Investigate stripping off legacy types as well. - if (${_jsInstanceOf(t1, NullableType)}) { - t1 = t1.type; - } - if (${_jsInstanceOf(t2, NullableType)}) { - t2 = t2.type; - } - } - if ($t1 === $t2) { - return true; - } - - // Trivially true, "Right Top" or "Left Bottom". - if (${_isTop(t2)} || ${_isBottom(t1, strictMode)}) { - return true; - } - - // "Left Top". - if (${_equalType(t1, dynamic)} || $t1 === $void_) { - return $_isSubtype($nullable($Object), $t2, $strictMode); - } - - // "Right Object". - if (${_equalType(t2, Object)}) { - // TODO(nshahan) Need to handle type variables. - // https://github.com/dart-lang/sdk/issues/38816 - if (${_isFutureOr(t1)}) { - let t1TypeArg = ${getGenericArgs(t1)}[0]; - return $_isSubtype(t1TypeArg, $Object, $strictMode); - } - - if (${_jsInstanceOf(t1, LegacyType)}) { - return $_isSubtype(t1.type, t2, $strictMode); - } - - if (${_equalType(t1, Null)} || ${_jsInstanceOf(t1, NullableType)}) { - // Checks for t1 is dynamic or void already performed in "Left Top" test. - return false; - } - return true; - } - - // "Left Null". - if (${_equalType(t1, Null)}) { - // TODO(nshahan) Need to handle type variables. - // https://github.com/dart-lang/sdk/issues/38816 - if (${_isFutureOr(t2)}) { - let t2TypeArg = ${getGenericArgs(t2)}[0]; - return $_isSubtype($Null, t2TypeArg, $strictMode); - } - - return ${_equalType(t2, Null)} || ${_jsInstanceOf(t2, LegacyType)} || - ${_jsInstanceOf(t2, NullableType)}; - } - - // "Left Legacy". - if (${_jsInstanceOf(t1, LegacyType)}) { - return $_isSubtype(t1.type, t2, $strictMode); - } - - // "Right Legacy". - if (${_jsInstanceOf(t2, LegacyType)}) { - return $_isSubtype(t1, $nullable(t2.type), $strictMode); - } - - // Handle FutureOr union type. - if (${_isFutureOr(t1)}) { - let t1TypeArg = ${getGenericArgs(t1)}[0]; - if (${_isFutureOr(t2)}) { - let t2TypeArg = ${getGenericArgs(t2)}[0]; - // FutureOr <: FutureOr if A <: B - if ($_isSubtype(t1TypeArg, t2TypeArg, $strictMode)) { - return true; - } - } - - // given t1 is Future | A, then: - // (Future | A) <: t2 iff Future <: t2 and A <: t2. - let t1Future = ${getGenericClass(Future)}(t1TypeArg); - // Known to handle the case FutureOr <: Future. - return $_isSubtype(t1Future, $t2, $strictMode) && - $_isSubtype(t1TypeArg, $t2, $strictMode); - } - - // "Left Nullable". - if (${_jsInstanceOf(t1, NullableType)}) { - // TODO(nshahan) Need to handle type variables. - // https://github.com/dart-lang/sdk/issues/38816 - return $_isSubtype(t1.type, t2, $strictMode) && $_isSubtype($Null, t2, $strictMode); - } - - if ($_isFutureOr($t2)) { - // given t2 is Future | A, then: - // t1 <: (Future | A) iff t1 <: Future or t1 <: A - let t2TypeArg = ${getGenericArgs(t2)}[0]; - let t2Future = ${getGenericClass(Future)}(t2TypeArg); - // TODO(nshahan) Need to handle type variables on the left. - // https://github.com/dart-lang/sdk/issues/38816 - return $_isSubtype($t1, t2Future, $strictMode) || $_isSubtype($t1, t2TypeArg, $strictMode); - } - - // "Right Nullable". - if (${_jsInstanceOf(t2, NullableType)}) { - // TODO(nshahan) Need to handle type variables. - // https://github.com/dart-lang/sdk/issues/38816 - return $_isSubtype(t1, t2.type, $strictMode) || $_isSubtype(t1, $Null, $strictMode); - } - - // "Traditional" name-based subtype check. Avoid passing - // function types to the class subtype checks, since we don't - // currently distinguish between generic typedefs and classes. - if (!${_jsInstanceOf(t2, AbstractFunctionType)}) { - // t2 is an interface type. - - if (${_jsInstanceOf(t1, AbstractFunctionType)}) { - // Function types are only subtypes of interface types `Function` (and top - // types, handled already above). - return ${_equalType(t2, Function)}; - } - - // All JS types are subtypes of anonymous JS types. - if ($t1 === $jsobject && ${_jsInstanceOf(t2, AnonymousJSType)}) { - return true; - } - - // Compare two interface types. - return ${_isInterfaceSubtype(t1, t2, strictMode)}; - } - - // Function subtyping. - if (!${_jsInstanceOf(t1, AbstractFunctionType)}) { - return false; - } - - // Handle generic functions. - if (${_jsInstanceOf(t1, GenericFunctionType)}) { - if (!${_jsInstanceOf(t2, GenericFunctionType)}) { - return false; - } - - // Given generic functions g1 and g2, g1 <: g2 iff: - // - // g1 <: g2 - // - // where TFresh is a list of fresh type variables that both g1 and g2 will - // be instantiated with. - let formalCount = $t1.formalCount; - if (formalCount !== $t2.formalCount) { - return false; - } - - // Using either function's type formals will work as long as they're both - // instantiated with the same ones. The instantiate operation is guaranteed - // to avoid capture because it does not depend on its TypeVariable objects, - // rather it uses JS function parameters to ensure correct binding. - let fresh = $t2.typeFormals; - - // Without type bounds all will instantiate to dynamic. Only need to check - // further if at least one of the functions has type bounds. - if ($t1.hasTypeBounds || $t2.hasTypeBounds) { - // Check the bounds of the type parameters of g1 and g2. Given a type - // parameter `T1 extends U1` from g1, and a type parameter `T2 extends U2` - // from g2, we must ensure that U1 and U2 are mutual subtypes. - // - // (Note there is no variance in the type bounds of type parameters of - // generic functions). - let t1Bounds = $t1.instantiateTypeBounds(fresh); - let t2Bounds = $t2.instantiateTypeBounds(fresh); - for (let i = 0; i < formalCount; i++) { - if (t1Bounds[i] != t2Bounds[i]) { - if (!($_isSubtype(t1Bounds[i], t2Bounds[i], $strictMode) - && $_isSubtype(t2Bounds[i], t1Bounds[i], $strictMode))) { - return false; - } - } - } - } - - $t1 = $t1.instantiate(fresh); - $t2 = $t2.instantiate(fresh); - } else if (${_jsInstanceOf(t2, GenericFunctionType)}) { - return false; - } - - // Handle non-generic functions. - return ${_isFunctionSubtype(t1, t2, strictMode)}; -})()'''); - -bool _isInterfaceSubtype(t1, t2, @notNull bool strictMode) => JS('', '''(() => { - // If we have lazy JS types, unwrap them. This will effectively - // reduce to a prototype check below. - if (${_jsInstanceOf(t1, LazyJSType)}) $t1 = $t1.rawJSTypeForCheck(); - if (${_jsInstanceOf(t2, LazyJSType)}) $t2 = $t2.rawJSTypeForCheck(); - - if ($t1 === $t2) { - return true; - } - if (${_equalType(t1, Object)}) { - return false; - } - - // Classes cannot subtype `Function` or vice versa. - if (${_equalType(t1, Function)} || ${_equalType(t2, Function)}) { - return false; - } - - // If t1 is a JS Object, we may not hit core.Object. - if ($t1 == null) { - return ${_equalType(t2, Object)} || ${_equalType(t2, dynamic)}; - } - - // Check if t1 and t2 have the same raw type. If so, check covariance on - // type parameters. - let raw1 = $getGenericClass($t1); - let raw2 = $getGenericClass($t2); - if (raw1 != null && raw1 == raw2) { - let typeArguments1 = $getGenericArgs($t1); - let typeArguments2 = $getGenericArgs($t2); - if (typeArguments1.length != typeArguments2.length) { - $assertFailed(); - } - let variances = $getGenericArgVariances($t1); - for (let i = 0; i < typeArguments1.length; ++i) { - // When using implicit variance, variances will be undefined and - // considered covariant. - if (variances === void 0 || variances[i] == ${Variance.covariant}) { - if (!$_isSubtype(typeArguments1[i], typeArguments2[i], $strictMode)) { - return false; - } - } else if (variances[i] == ${Variance.contravariant}) { - if (!$_isSubtype(typeArguments2[i], typeArguments1[i], $strictMode)) { - return false; - } - } else if (variances[i] == ${Variance.invariant}) { - if (!$_isSubtype(typeArguments1[i], typeArguments2[i], $strictMode) || - !$_isSubtype(typeArguments2[i], typeArguments1[i], $strictMode)) { - return false; - } - } - } - return true; - } - - if ($_isInterfaceSubtype(t1.__proto__, $t2, $strictMode)) { - return true; - } - - // Check mixin. - let m1 = $getMixin($t1); - if (m1 != null && $_isInterfaceSubtype(m1, $t2, $strictMode)) { - return true; - } - - // Check interfaces. - let getInterfaces = $getImplements($t1); - if (getInterfaces) { - for (let i1 of getInterfaces()) { - if ($_isInterfaceSubtype(i1, $t2, $strictMode)) { - return true; - } - } - } - return false; -})()'''); - -Object? extractTypeArguments(T instance, Function f) { - if (instance == null) { - throw ArgumentError('Cannot extract type of null instance.'); - } - var type = unwrapType(T); - // Get underlying type from nullability wrappers if needed. - type = JS('!', '#.type || #', type, type); - - if (type is AbstractFunctionType || _isFutureOr(type)) { - throw ArgumentError('Cannot extract from non-class type ($type).'); - } - var typeArguments = getGenericArgs(type); - if (typeArguments!.isEmpty) { - throw ArgumentError('Cannot extract from non-generic type ($type).'); - } - var supertype = _getMatchingSupertype(getReifiedType(instance), type); - // The signature of this method guarantees that instance is a T, so we - // should have a valid non-empty list at this point. - assert(supertype != null); - var typeArgs = getGenericArgs(supertype); - assert(typeArgs != null && typeArgs.isNotEmpty); - return dgcall(f, typeArgs, []); -} - -/// Infers type variables based on a series of [trySubtypeMatch] calls, followed -/// by [getInferredTypes] to return the type. -class _TypeInferrer { - final Map _typeVariables; - - /// Creates a [TypeConstraintGatherer] which is prepared to gather type - /// constraints for the given type parameters. - _TypeInferrer(Iterable typeVariables) - : _typeVariables = Map.fromIterables( - typeVariables, typeVariables.map((_) => TypeConstraint())); - - /// Returns the inferred types based on the current constraints. - List? getInferredTypes() { - var result = []; - for (var constraint in _typeVariables.values) { - // Prefer the known bound, if any. - if (constraint.lower != null) { - result.add(constraint.lower!); - } else if (constraint.upper != null) { - result.add(constraint.upper!); - } else { - return null; - } - } - return result; - } - - /// Tries to match [subtype] against [supertype]. - /// - /// If the match succeeds, the resulting type constraints are recorded for - /// later use by [computeConstraints]. If the match fails, the set of type - /// constraints is unchanged. - bool trySubtypeMatch(Object subtype, Object supertype) => - _isSubtypeMatch(subtype, supertype); - - void _constrainLower(TypeVariable parameter, Object lower) { - _typeVariables[parameter]!._constrainLower(lower); - } - - void _constrainUpper(TypeVariable parameter, Object upper) { - _typeVariables[parameter]!._constrainUpper(upper); - } - - bool _isFunctionSubtypeMatch(FunctionType subtype, FunctionType supertype) { - // A function type `(M0,..., Mn, [M{n+1}, ..., Mm]) -> R0` is a subtype - // match for a function type `(N0,..., Nk, [N{k+1}, ..., Nr]) -> R1` with - // respect to `L` under constraints `C0 + ... + Cr + C` - // - If `R0` is a subtype match for a type `R1` with respect to `L` under - // constraints `C`: - // - If `n <= k` and `r <= m`. - // - And for `i` in `0...r`, `Ni` is a subtype match for `Mi` with respect - // to `L` under constraints `Ci`. - // Function types with named parameters are treated analogously to the - // positional parameter case above. - // A generic function type `F0` is a - // subtype match for a generic function type `F1` with respect to `L` under constraints `Cl`: - // - If `F0[Z0/T0, ..., Zn/Tn]` is a subtype match for `F0[Z0/S0, ..., - // Zn/Sn]` with respect to `L` under constraints `C`, where each `Zi` is a - // fresh type variable with bound `Bi`. - // - And `Cl` is `C` with each constraint replaced with its closure with - // respect to `[Z0, ..., Zn]`. - if (subtype.requiredParameterCount > supertype.requiredParameterCount) { - return false; - } - if (subtype.positionalParameterCount < supertype.positionalParameterCount) { - return false; - } - // Test the return types. - if (supertype.returnType is! VoidType && - !_isSubtypeMatch(subtype.returnType, supertype.returnType)) { - return false; - } - - // Test the parameter types. - for (int i = 0, n = supertype.positionalParameterCount; i < n; ++i) { - if (!_isSubtypeMatch(supertype.getPositionalParameter(i), - subtype.getPositionalParameter(i))) { - return false; - } - } - - // Named parameter invariants: - // 1) All named params in the superclass are named params in the subclass. - // 2) All required named params in the subclass are required named params - // in the superclass. - // 3) With strict null checking disabled, we treat required named params as - // optional named params. - var supertypeNamed = supertype.getNamedParameters(); - var supertypeRequiredNamed = supertype.getRequiredNamedParameters(); - var subtypeNamed = supertype.getNamedParameters(); - var subtypeRequiredNamed = supertype.getRequiredNamedParameters(); - if (!strictNullSafety) { - // In weak mode, treat required named params as optional named params. - supertypeNamed = {...supertypeNamed, ...supertypeRequiredNamed}; - subtypeNamed = {...subtypeNamed, ...subtypeRequiredNamed}; - supertypeRequiredNamed = {}; - subtypeRequiredNamed = {}; - } - for (var name in subtypeRequiredNamed.keys) { - var supertypeParamType = supertypeRequiredNamed[name]; - if (supertypeParamType == null) return false; - } - for (var name in supertypeNamed.keys) { - var subtypeParamType = subtypeNamed[name]; - if (subtypeParamType == null) return false; - if (!_isSubtypeMatch(supertypeNamed[name]!, subtypeParamType)) { - return false; - } - } - for (var name in supertypeRequiredNamed.keys) { - var subtypeParamType = subtypeRequiredNamed[name] ?? subtypeNamed[name]!; - if (!_isSubtypeMatch(supertypeRequiredNamed[name]!, subtypeParamType)) { - return false; - } - } - return true; - } - - bool _isInterfaceSubtypeMatch(Object subtype, Object supertype) { - // A type `P` is a subtype match for `P` with - // respect to `L` under constraints `C0 + ... + Ck`: - // - If `Mi` is a subtype match for `Ni` with respect to `L` under - // constraints `Ci`. - // A type `P` is a subtype match for `Q` with - // respect to `L` under constraints `C`: - // - If `R` is the superclass of `P` and `R` is a subtype match for `Q` with respect to `L` - // under constraints `C`. - // - Or `R` is one of the interfaces implemented by `P` (considered in lexical order) and `R` is a subtype - // match for `Q` with respect to `L` under constraints `C`. - // - Or `R` is a mixin into `P` (considered in - // lexical order) and `R` is a subtype match for `Q` with respect to `L` under constraints `C`. - - // Note that since kernel requires that no class may only appear in the set - // of supertypes of a given type more than once, the order of the checks - // above is irrelevant; we just need to find the matched superclass, - // substitute, and then iterate through type variables. - var matchingSupertype = _getMatchingSupertype(subtype, supertype); - if (matchingSupertype == null) return false; - - var matchingTypeArgs = getGenericArgs(matchingSupertype)!; - var supertypeTypeArgs = getGenericArgs(supertype)!; - for (int i = 0; i < supertypeTypeArgs.length; i++) { - if (!_isSubtypeMatch(matchingTypeArgs[i], supertypeTypeArgs[i])) { - return false; - } - } - return true; - } - - /// Attempts to match [subtype] as a subtype of [supertype], gathering any - /// constraints discovered in the process. - /// - /// If a set of constraints was found, `true` is returned and the caller - /// may proceed to call [computeConstraints]. Otherwise, `false` is returned. - /// - /// In the case where `false` is returned, some bogus constraints may have - /// been added to [_protoConstraints]. It is the caller's responsibility to - /// discard them if necessary. - // TODO(#40326) Update to support null safety subtyping algorithm. - bool _isSubtypeMatch(Object subtype, Object supertype) { - // A type variable `T` in `L` is a subtype match for any type schema `Q`: - // - Under constraint `T <: Q`. - if (subtype is TypeVariable && _typeVariables.containsKey(subtype)) { - _constrainUpper(subtype, supertype); - return true; - } - // A type schema `Q` is a subtype match for a type variable `T` in `L`: - // - Under constraint `Q <: T`. - if (supertype is TypeVariable && _typeVariables.containsKey(supertype)) { - _constrainLower(supertype, subtype); - return true; - } - // Any two equal types `P` and `Q` are subtype matches under no constraints. - // Note: to avoid making the algorithm quadratic, we just check for - // identical(). If P and Q are equal but not identical, recursing through - // the types will give the proper result. - if (identical(subtype, supertype)) return true; - // Any type `P` is a subtype match for `dynamic`, `Object`, or `void` under - // no constraints. - if (_isTop(supertype)) return true; - // `Null` is a subtype match for any type `Q` under no constraints. - // Note that nullable types will change this. - if (_equalType(subtype, Null)) return true; - - // Handle FutureOr union type. - if (_isFutureOr(subtype)) { - var subtypeArg = getGenericArgs(subtype)![0]; - if (_isFutureOr(supertype)) { - // `FutureOr

` is a subtype match for `FutureOr` with respect to `L` - // under constraints `C`: - // - If `P` is a subtype match for `Q` with respect to `L` under constraints - // `C`. - var supertypeArg = getGenericArgs(supertype)![0]; - return _isSubtypeMatch(subtypeArg, supertypeArg); - } - - // `FutureOr

` is a subtype match for `Q` with respect to `L` under - // constraints `C0 + C1`: - // - If `Future

` is a subtype match for `Q` with respect to `L` under - // constraints `C0`. - // - And `P` is a subtype match for `Q` with respect to `L` under - // constraints `C1`. - var subtypeFuture = - JS('!', '#(#)', getGenericClass(Future), subtypeArg); - return _isSubtypeMatch(subtypeFuture, supertype) && - _isSubtypeMatch(subtypeArg!, supertype); - } - - if (_isFutureOr(supertype)) { - // `P` is a subtype match for `FutureOr` with respect to `L` under - // constraints `C`: - // - If `P` is a subtype match for `Future` with respect to `L` under - // constraints `C`. - // - Or `P` is not a subtype match for `Future` with respect to `L` under - // constraints `C` - // - And `P` is a subtype match for `Q` with respect to `L` under - // constraints `C` - var supertypeArg = getGenericArgs(supertype)![0]; - var supertypeFuture = - JS('!', '#(#)', getGenericClass(Future), supertypeArg); - return _isSubtypeMatch(subtype, supertypeFuture) || - _isSubtypeMatch(subtype, supertypeArg); - } - - // A type variable `T` not in `L` with bound `P` is a subtype match for the - // same type variable `T` with bound `Q` with respect to `L` under - // constraints `C`: - // - If `P` is a subtype match for `Q` with respect to `L` under constraints - // `C`. - if (subtype is TypeVariable) { - return supertype is TypeVariable && identical(subtype, supertype); - } - if (subtype is GenericFunctionType) { - if (supertype is GenericFunctionType) { - // Given generic functions g1 and g2, g1 <: g2 iff: - // - // g1 <: g2 - // - // where TFresh is a list of fresh type variables that both g1 and g2 will - // be instantiated with. - var formalCount = subtype.formalCount; - if (formalCount != supertype.formalCount) return false; - - // Using either function's type formals will work as long as they're - // both instantiated with the same ones. The instantiate operation is - // guaranteed to avoid capture because it does not depend on its - // TypeVariable objects, rather it uses JS function parameters to ensure - // correct binding. - var fresh = supertype.typeFormals; - - // Check the bounds of the type parameters of g1 and g2. - // given a type parameter `T1 extends U1` from g1, and a type parameter - // `T2 extends U2` from g2, we must ensure that: - // - // U2 <: U1 - // - // (Note the reversal of direction -- type formal bounds are - // contravariant, similar to the function's formal parameter types). - // - var t1Bounds = subtype.instantiateTypeBounds(fresh); - var t2Bounds = supertype.instantiateTypeBounds(fresh); - // TODO(jmesserly): we could optimize for the common case of no bounds. - for (var i = 0; i < formalCount; i++) { - if (!_isSubtypeMatch(t2Bounds[i], t1Bounds[i])) { - return false; - } - } - return _isFunctionSubtypeMatch( - subtype.instantiate(fresh), supertype.instantiate(fresh)); - } else { - return false; - } - } else if (supertype is GenericFunctionType) { - return false; - } - - // A type `P` is a subtype match for `Function` with respect to `L` under no - // constraints: - // - If `P` implements a call method. - // - Or if `P` is a function type. - // TODO(paulberry): implement this case. - // A type `P` is a subtype match for a type `Q` with respect to `L` under - // constraints `C`: - // - If `P` is an interface type which implements a call method of type `F`, - // and `F` is a subtype match for a type `Q` with respect to `L` under - // constraints `C`. - // TODO(paulberry): implement this case. - if (subtype is FunctionType) { - if (supertype is! FunctionType) { - if (_equalType(supertype, Function) || _equalType(supertype, Object)) { - return true; - } else { - return false; - } - } - if (supertype is FunctionType) { - return _isFunctionSubtypeMatch(subtype, supertype); - } - } - return _isInterfaceSubtypeMatch(subtype, supertype); - } - - bool _isTop(Object type) => - identical(type, _dynamic) || - identical(type, void_) || - _equalType(type, Object); -} - -/// A constraint on a type parameter that we're inferring. -class TypeConstraint { - /// The lower bound of the type being constrained. This bound must be a - /// subtype of the type being constrained. - Object? lower; - - /// The upper bound of the type being constrained. The type being constrained - /// must be a subtype of this bound. - Object? upper; - - void _constrainLower(Object type) { - var _lower = lower; - if (_lower != null) { - if (isSubtypeOf(_lower, type)) { - // nothing to do, existing lower bound is lower than the new one. - return; - } - if (!isSubtypeOf(type, _lower)) { - // Neither bound is lower and we don't have GLB, so use bottom type. - type = unwrapType(Null); - } - } - lower = type; - } - - void _constrainUpper(Object type) { - var _upper = upper; - if (_upper != null) { - if (isSubtypeOf(type, _upper)) { - // nothing to do, existing upper bound is higher than the new one. - return; - } - if (!isSubtypeOf(_upper, type)) { - // Neither bound is higher and we don't have LUB, so use top type. - type = unwrapType(Object); - } - } - upper = type; - } - - String toString() => '${typeName(lower)} <: <: ${typeName(upper)}'; -} - -/// Finds a supertype of [subtype] that matches the class [supertype], but may -/// contain different generic type arguments. -Object? _getMatchingSupertype(Object? subtype, Object supertype) { - if (identical(subtype, supertype)) return supertype; - if (subtype == null || _equalType(subtype, Object)) return null; - - var subclass = getGenericClass(subtype); - var superclass = getGenericClass(supertype); - if (subclass != null && identical(subclass, superclass)) { - return subtype; // matching supertype found! - } - - var result = _getMatchingSupertype(JS('', '#.__proto__', subtype), supertype); - if (result != null) return result; - - // Check mixin. - var mixin = getMixin(subtype); - if (mixin != null) { - result = _getMatchingSupertype(mixin, supertype); - if (result != null) return result; - } - - // Check interfaces. - var getInterfaces = getImplements(subtype); - if (getInterfaces != null) { - for (var iface in getInterfaces()!) { - result = _getMatchingSupertype(iface, supertype); - if (result != null) return result; - } - } - - return null; -} diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/utils.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/utils.dart deleted file mode 100644 index 07a2faa1c22..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/utils.dart +++ /dev/null @@ -1,97 +0,0 @@ -// 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. - -part of dart._runtime; - -/// This library defines a set of general javascript utilities for us -/// by the Dart runtime. -// TODO(ochafik): Rewrite some of these in Dart when possible. - -final Function(Object, Object, Object) defineProperty = - JS('', 'Object.defineProperty'); - -defineValue(obj, name, value) { - defineAccessor(obj, name, value: value, configurable: true, writable: true); - return value; -} - -final Function(Object, Object, - {Object? get, - Object? set, - Object? value, - bool? configurable, - bool? writable}) defineAccessor = JS('', 'Object.defineProperty'); - -final dynamic Function(Object, Object) getOwnPropertyDescriptor = - JS('', 'Object.getOwnPropertyDescriptor'); - -final List Function(Object) getOwnPropertyNames = - JS('', 'Object.getOwnPropertyNames'); - -final List Function(Object) getOwnPropertySymbols = - JS('', 'Object.getOwnPropertySymbols'); - -final Function(Object) getPrototypeOf = JS('', 'Object.getPrototypeOf'); - -/// This error indicates a strong mode specific failure, other than a type -/// assertion failure (TypeError) or CastError. -void throwTypeError(String message) { - throw TypeErrorImpl(message); -} - -/// This error indicates a bug in the runtime or the compiler. -void throwInternalError(String message) { - JS('', 'throw Error(#)', message); -} - -Iterable getOwnNamesAndSymbols(obj) { - var names = getOwnPropertyNames(obj); - var symbols = getOwnPropertySymbols(obj); - return JS('', '#.concat(#)', names, symbols); -} - -/// Returns the value of field `name` on `obj`. -/// -/// We use this instead of obj[name] since obj[name] checks the entire -/// prototype chain instead of just `obj`. -safeGetOwnProperty(obj, name) { - if (JS('!', '#.hasOwnProperty(#)', obj, name)) - return JS('', '#[#]', obj, name); -} - -copyTheseProperties(to, from, names) { - for (int i = 0, n = JS('!', '#.length', names); i < n; ++i) { - var name = JS('', '#[#]', names, i); - if (name == 'constructor') continue; - copyProperty(to, from, name); - } - return to; -} - -copyProperty(to, from, name) { - var desc = getOwnPropertyDescriptor(from, name); - if (JS('!', '# == Symbol.iterator', name)) { - // On native types, Symbol.iterator may already be present. - // TODO(jmesserly): investigate if we still need this. - // If so, we need to find a better solution. - // See https://github.com/dart-lang/sdk/issues/28324 - var existing = getOwnPropertyDescriptor(to, name); - if (existing != null) { - if (JS('!', '#.writable', existing)) { - JS('', '#[#] = #.value', to, name, desc); - } - return; - } - } - defineProperty(to, name, desc); -} - -@JSExportName('export') -exportProperty(to, from, name) => copyProperty(to, from, name); - -/// Copy properties from source to destination object. -/// This operation is commonly called `mixin` in JS. -copyProperties(to, from) { - return copyTheseProperties(to, from, getOwnNamesAndSymbols(from)); -} diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/debugger.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/debugger.dart deleted file mode 100644 index f77d5c329d9..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/debugger.dart +++ /dev/null @@ -1,1015 +0,0 @@ -// 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 dart._debugger; - -import 'dart:_foreign_helper' show JS; -import 'dart:_interceptors' show JSArray; -import 'dart:_js_helper' show InternalMap; -import 'dart:_runtime' as dart; -import 'dart:core'; -import 'dart:collection'; -import 'dart:math'; - -part 'profile.dart'; - -/// JsonMLConfig object to pass to devtools to specify how an Object should -/// be displayed. skipDart signals that an object should not be formatted -/// by the Dart formatter. This is used to specify that an Object -/// should just be displayed using the regular JavaScript view instead of a -/// custom Dart view. For example, this is used to display the JavaScript view -/// of a Dart Function as a child of the regular Function object. keyToString -/// signals that a map key object should have its toString() displayed by -/// the Dart formatter. -/// -/// We'd like this to be an enum, but we can't because it's a dev_compiler bug. -class JsonMLConfig { - const JsonMLConfig(this.name); - - final String name; - static const none = JsonMLConfig("none"); - static const skipDart = JsonMLConfig("skipDart"); - static const keyToString = JsonMLConfig("keyToString"); - static const asClass = JsonMLConfig("asClass"); - static const asObject = JsonMLConfig("asObject"); - static const asMap = JsonMLConfig("asMap"); - toString() => "JsonMLConfig($name)"; -} - -int _maxSpanLength = 100; -var _devtoolsFormatter = JsonMLFormatter(DartFormatter()); - -/// We truncate a toString() longer than [maxStringLength]. -int maxFormatterStringLength = 100; - -String _typeof(object) => JS('!', 'typeof #', object); - -List getOwnPropertyNames(object) => - JSArray.of(dart.getOwnPropertyNames(object)); - -List getOwnPropertySymbols(object) => - JS('List', 'Object.getOwnPropertySymbols(#)', object); - -// TODO(jacobr): move this to dart:js and fully implement. -class JSNative { - // Name may be a String or a Symbol. - static getProperty(object, name) => JS('', '#[#]', object, name); - // Name may be a String or a Symbol. - static setProperty(object, name, value) => - JS('', '#[#]=#', object, name, value); -} - -void addMetadataChildren(object, Set ret) { - ret.add(NameValuePair( - name: "[[class]]", - value: dart.getReifiedType(object), - config: JsonMLConfig.asClass)); -} - -/// Add properties from a signature definition [sig] for [object]. -/// Walk the prototype chain if [walkProtypeChain] is set. -/// Tag types on function typed properties of [object] if [tagTypes] is set. -/// -void addPropertiesFromSignature( - sig, Set properties, object, bool walkPrototypeChain, - {tagTypes = false}) { - // Including these property names doesn't add any value and just clutters - // the debugger output. - // TODO(jacobr): consider adding runtimeType to this list. - var skippedNames = Set()..add('hashCode'); - var objectPrototype = JS('', 'Object.prototype'); - while (sig != null && !identical(sig, objectPrototype)) { - for (var symbol in getOwnPropertySymbols(sig)) { - var dartName = symbolName(symbol); - String dartXPrefix = 'dartx.'; - if (dartName.startsWith(dartXPrefix)) { - dartName = dartName.substring(dartXPrefix.length); - } - if (skippedNames.contains(dartName)) continue; - var value = safeGetProperty(object, symbol); - // Tag the function with its runtime type. - if (tagTypes && _typeof(value) == 'function') { - dart.fn(value, JS('', '#[#]', sig, symbol)); - } - properties.add(NameValuePair(name: dartName, value: value)); - } - - for (var name in getOwnPropertyNames(sig)) { - var value = safeGetProperty(object, name); - if (skippedNames.contains(name)) continue; - // Tag the function with its runtime type. - if (tagTypes && _typeof(value) == 'function') { - dart.fn(value, JS('', '#[#]', sig, name)); - } - properties.add(NameValuePair(name: name, value: value)); - } - - if (!walkPrototypeChain) break; - - sig = dart.getPrototypeOf(sig); - } -} - -/// Sort properties sorting public names before private names. -List sortProperties(Iterable properties) { - var sortedProperties = properties.toList(); - - sortedProperties.sort((a, b) { - var aPrivate = a.name.startsWith('_'); - var bPrivate = b.name.startsWith('_'); - if (aPrivate != bPrivate) return aPrivate ? 1 : -1; - return a.name.compareTo(b.name); - }); - return sortedProperties; -} - -String getObjectTypeName(object) { - var reifiedType = dart.getReifiedType(object); - if (reifiedType == null) { - if (_typeof(object) == 'function') { - return '[[Raw JavaScript Function]]'; - } - return ''; - } - return getTypeName(reifiedType); -} - -String getTypeName(type) { - // TODO(jacobr): it would be nice if there was a way we could distinguish - // between a List created from Dart and an Array passed in from - // JavaScript. - return dart.typeName(type); -} - -String safePreview(object, config) { - try { - var preview = _devtoolsFormatter._simpleFormatter.preview(object, config); - if (preview != null) return preview; - return object.toString(); - } catch (e) { - return ' $e'; - } -} - -String symbolName(symbol) { - var name = symbol.toString(); - assert(name.startsWith('Symbol(')); - return name.substring('Symbol('.length, name.length - 1); -} - -bool hasMethod(object, String name) { - try { - return dart.hasMethod(object, name); - } catch (e) { - return false; - } -} - -/// [JsonMLFormatter] consumes [NameValuePair] objects and -class NameValuePair { - NameValuePair( - {this.name = '', - this.value, - this.config = JsonMLConfig.none, - this.hideName = false}); - - // Define equality and hashCode so that NameValuePair can be used - // in a Set to dedupe entries with duplicate names. - bool operator ==(other) { - if (other is! NameValuePair) return false; - if (this.hideName || other.hideName) return identical(this, other); - return other.name == name; - } - - int get hashCode => name.hashCode; - - final String name; - final Object? value; - final JsonMLConfig config; - final bool hideName; - - String get displayName => hideName ? '' : name; -} - -class MapEntry { - MapEntry({this.key, this.value}); - - final Object? key; - final Object? value; -} - -class IterableSpan { - IterableSpan(this.start, this.end, this.iterable); - - final int start; - final int end; - final Iterable iterable; - int get length => end - start; - - /// Using length - .5, a list of length 10000 results in a - /// maxPowerOfSubsetSize of 1, so the list will be broken up into 100, - /// 100-length subsets. A list of length 10001 results in a - /// maxPowerOfSubsetSize of 2, so the list will be broken up into 1 - /// 10000-length subset and 1 1-length subset. - int get maxPowerOfSubsetSize => - (log(length - .5) / log(_maxSpanLength)).truncate(); - int get subsetSize => pow(_maxSpanLength, maxPowerOfSubsetSize).toInt(); - - Map asMap() => - iterable.skip(start).take(length).toList().asMap(); - - List children() { - var children = []; - if (length <= _maxSpanLength) { - asMap().forEach((i, element) { - children - .add(NameValuePair(name: (i + start).toString(), value: element)); - }); - } else { - for (var i = start; i < end; i += subsetSize) { - var subSpan = IterableSpan(i, min(end, subsetSize + i), iterable); - if (subSpan.length == 1) { - children.add( - NameValuePair(name: i.toString(), value: iterable.elementAt(i))); - } else { - children.add(NameValuePair( - name: '[${i}...${subSpan.end - 1}]', - value: subSpan, - hideName: true)); - } - } - } - return children; - } -} - -class Library { - Library(this.name, this.object); - - final String name; - final Object object; -} - -class NamedConstructor { - NamedConstructor(this.object); - - final Object object; -} - -class HeritageClause { - HeritageClause(this.name, this.types); - - final String name; - final List types; -} - -Object safeGetProperty(Object protoChain, Object name) { - try { - return JSNative.getProperty(protoChain, name); - } catch (e) { - return ' $e'; - } -} - -safeProperties(object) => Map.fromIterable( - getOwnPropertyNames(object) - .where((each) => safeGetProperty(object, each) != null), - key: (name) => name, - value: (name) => safeGetProperty(object, name)); - -/// Class to simplify building the JsonML objects expected by the -/// Devtools Formatter API. -class JsonMLElement { - dynamic _attributes; - late List _jsonML; - - JsonMLElement(tagName) { - _attributes = JS('', '{}'); - _jsonML = [tagName, _attributes]; - } - - appendChild(element) { - _jsonML.add(element.toJsonML()); - } - - JsonMLElement createChild(String tagName) { - var c = JsonMLElement(tagName); - _jsonML.add(c.toJsonML()); - return c; - } - - JsonMLElement createObjectTag(object) => - createChild('object')..addAttribute('object', object); - - void setStyle(String style) { - _attributes.style = style; - } - - addStyle(String style) { - if (_attributes.style == null) { - _attributes.style = style; - } else { - _attributes.style += style; - } - } - - addAttribute(key, value) { - JSNative.setProperty(_attributes, key, value); - } - - createTextChild(String text) { - _jsonML.add(text); - } - - toJsonML() => _jsonML; -} - -/// Whether an object is a native JavaScript type where we should display the -/// JavaScript view of the object instead of the custom Dart specific render -/// of properties. -bool isNativeJavaScriptObject(object) { - var type = _typeof(object); - if (type != 'object' && type != 'function') return true; - - // Consider all regular JS objects that do not represent Dart modules native - // JavaScript objects. - if (dart.isJsInterop(object) && dart.getModuleName(object) == null) { - return true; - } - - // Treat Node objects as a native JavaScript type as the regular DOM render - // in devtools is superior to the dart specific view. - return JS('!', '# instanceof Node', object); -} - -/// Class implementing the Devtools Formatter API described by: -/// https://docs.google.com/document/d/1FTascZXT9cxfetuPRT2eXPQKXui4nWFivUnS_335T3U -/// Specifically, a formatter implements a header, hasBody, and body method. -/// This class renders the simple structured format objects [_simpleFormatter] -/// provides as JsonML. -class JsonMLFormatter { - // TODO(jacobr): define a SimpleFormatter base class that DartFormatter - // implements if we decide to use this class elsewhere. We specify that the - // type is DartFormatter here purely to get type checking benefits not because - // this class is really intended to only support instances of type - // DartFormatter. - DartFormatter _simpleFormatter; - - bool customFormattersOn = false; - - JsonMLFormatter(this._simpleFormatter); - - void setMaxSpanLengthForTestingOnly(int spanLength) { - _maxSpanLength = spanLength; - } - - header(object, config) { - customFormattersOn = true; - if (config == JsonMLConfig.skipDart || isNativeJavaScriptObject(object)) { - return null; - } - var c = _simpleFormatter.preview(object, config); - if (c == null) return null; - - if (config == JsonMLConfig.keyToString) { - c = object.toString(); - } - - // Indicate this is a Dart Object by using a Dart background color. - // This is stylistically a bit ugly but it eases distinguishing Dart and - // JS objects. - var element = JsonMLElement('span') - ..setStyle('background-color: #d9edf7;color: black') - ..createTextChild(c); - return element.toJsonML(); - } - - bool hasBody(object, config) => _simpleFormatter.hasChildren(object, config); - - body(object, config) { - var body = JsonMLElement('ol') - ..setStyle('list-style-type: none;' - 'padding-left: 0px;' - 'margin-top: 0px;' - 'margin-bottom: 0px;' - 'margin-left: 12px;'); - if (object is StackTrace) { - body.addStyle('background-color: thistle;color: rgb(196, 26, 22);'); - } - var children = _simpleFormatter.children(object, config); - if (children == null) return body.toJsonML(); - for (NameValuePair child in children) { - var li = body.createChild('li'); - li.setStyle("padding-left: 13px;"); - - // The value is indented when it is on a different line from the name - // by setting right padding of the name to -13px and the padding of the - // value to 13px. - JsonMLElement? nameSpan; - var valueStyle = ''; - if (!child.hideName) { - nameSpan = JsonMLElement('span') - ..createTextChild( - child.displayName.isNotEmpty ? '${child.displayName}: ' : '') - ..setStyle( - 'background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px'); - valueStyle = 'margin-left: 13px'; - } - - if (_typeof(child.value) == 'object' || - _typeof(child.value) == 'function') { - var valueSpan = JsonMLElement('span')..setStyle(valueStyle); - valueSpan.createObjectTag(child.value) - ..addAttribute('config', child.config); - if (nameSpan != null) { - li.appendChild(nameSpan); - } - li.appendChild(valueSpan); - } else { - var line = li.createChild('span'); - if (nameSpan != null) { - line.appendChild(nameSpan); - } - line.appendChild(JsonMLElement('span') - ..createTextChild(safePreview(child.value, child.config)) - ..setStyle(valueStyle)); - } - } - return body.toJsonML(); - } -} - -abstract class Formatter { - bool accept(object, config); - String? preview(object); - bool hasChildren(object); - List? children(object); -} - -class DartFormatter { - final List _formatters; - - DartFormatter() - : _formatters = [ - // Formatters earlier in the list take precedence. - ObjectInternalsFormatter(), - ClassFormatter(), - TypeFormatter(), - NamedConstructorFormatter(), - MapFormatter(), - MapOverviewFormatter(), - IterableFormatter(), - IterableSpanFormatter(), - MapEntryFormatter(), - StackTraceFormatter(), - ErrorAndExceptionFormatter(), - FunctionFormatter(), - HeritageClauseFormatter(), - LibraryModuleFormatter(), - LibraryFormatter(), - ObjectFormatter(), - ]; - - String? preview(object, config) { - try { - if (object == null || - object is num || - object is String || - isNativeJavaScriptObject(object)) { - return object.toString(); - } - for (var formatter in _formatters) { - if (formatter.accept(object, config)) return formatter.preview(object); - } - } catch (e, trace) { - // Log formatter internal errors as unfortunately the devtools cannot - // be used to debug formatter errors. - _printConsoleError("Caught exception $e\n trace:\n$trace"); - } - - return null; - } - - bool hasChildren(object, config) { - if (object == null) return false; - try { - for (var formatter in _formatters) { - if (formatter.accept(object, config)) - return formatter.hasChildren(object); - } - } catch (e, trace) { - // See comment for preview. - _printConsoleError("[hasChildren] Caught exception $e\n trace:\n$trace"); - } - return false; - } - - List? children(object, config) { - try { - if (object != null) { - for (var formatter in _formatters) { - if (formatter.accept(object, config)) - return formatter.children(object); - } - } - } catch (e, trace) { - // See comment for preview. - _printConsoleError("Caught exception $e\n trace:\n$trace"); - } - return []; - } - - void _printConsoleError(String message) => - JS('', 'window.console.error(#)', message); -} - -/// Default formatter for Dart Objects. -class ObjectFormatter extends Formatter { - bool accept(object, config) => !isNativeJavaScriptObject(object); - - String preview(object) { - var typeName = getObjectTypeName(object); - try { - // An explicit toString() call might not actually be a string. This way - // we're sure. - var toString = "$object"; - if (toString.length > maxFormatterStringLength) { - toString = toString.substring(0, maxFormatterStringLength - 3) + "..."; - } - // The default toString() will be "Instance of 'Foo'", in which case we - // don't need any further indication of the class. - if (toString.contains(typeName)) { - return toString; - } else { - // If there's no class indication, e.g. an Int64 that just prints as a - // number, then add the class name. - return "$toString ($typeName)"; - } - } catch (e) {} - // We will only get here if there was an error getting the toString, in - // which case we just use the type name. - return typeName; - } - - bool hasChildren(object) => true; - - children(object) { - var type = dart.getType(object); - var ret = LinkedHashSet(); - // We use a Set rather than a List to avoid duplicates. - var fields = Set(); - addPropertiesFromSignature(dart.getFields(type), fields, object, true); - var getters = Set(); - addPropertiesFromSignature(dart.getGetters(type), getters, object, true); - ret.addAll(sortProperties(fields)); - ret.addAll(sortProperties(getters)); - addMetadataChildren(object, ret); - return ret.toList(); - } -} - -/// Show the object instance members and a reduced preview. -/// -/// Used as a sub-entry to show the internals of objects that have a different -/// primary format. For example, a Map shows the key-value pairs, but this makes -/// the internals of the map visible for debugging. -class ObjectInternalsFormatter extends ObjectFormatter { - bool accept(object, config) => - super.accept(object, config) && config == JsonMLConfig.asObject; - - // A minimal preview because we expect a full preview is already shown in a - // parent formatter. - String preview(object) { - return getObjectTypeName(object); - } -} - -/// Formatter for module Dart Library objects. -class LibraryModuleFormatter implements Formatter { - bool accept(object, config) => dart.getModuleName(object) != null; - - bool hasChildren(object) => true; - - String preview(object) { - var libraryNames = dart.getModuleName(object)!.split('/'); - // Library names are received with a repeat directory name, so strip the - // last directory entry here to make the path cleaner. For example, the - // library "third_party/dart/utf/utf" shoud display as - // "third_party/dart/utf/". - if (libraryNames.length > 1 && - libraryNames.last == libraryNames[libraryNames.length - 2]) { - libraryNames[libraryNames.length - 1] = ''; - } - return 'Library Module: ${libraryNames.join('/')}'; - } - - List children(object) { - var children = LinkedHashSet(); - for (var name in getOwnPropertyNames(object)) { - var value = safeGetProperty(object, name); - children.add(NameValuePair( - name: name, value: Library(name, value), hideName: true)); - } - return children.toList(); - } -} - -class LibraryFormatter implements Formatter { - var genericParameters = HashMap(); - - bool accept(object, config) => object is Library; - - bool hasChildren(object) => true; - - String preview(object) => object.name; - - List children(object) { - // Maintain library member order rather than sorting members as is the - // case for class members. - var children = LinkedHashSet(); - var objectProperties = safeProperties(object.object); - objectProperties.forEach((name, value) { - // Skip the generic constructors for each class as users are only - // interested in seeing the actual classes. - if (dart.getGenericTypeCtor(value) != null) return; - - children.add(dart.isType(value) - ? classChild(name, value) - : NameValuePair(name: name, value: value)); - }); - return children.toList(); - } - - classChild(String name, Object child) { - var typeName = getTypeName(child); - return NameValuePair( - name: typeName, value: child, config: JsonMLConfig.asClass); - } -} - -/// Formatter for Dart Function objects. -/// Dart functions happen to be regular JavaScript Function objects but -/// we can distinguish them based on whether they have been tagged with -/// runtime type information. -class FunctionFormatter implements Formatter { - bool accept(object, config) { - if (_typeof(object) != 'function') return false; - return dart.getReifiedType(object) != null; - } - - bool hasChildren(object) => true; - - String preview(object) { - // The debugger can createa a preview of a FunctionType while it's being - // constructed (before argument types exist), so we need to catch errors. - try { - return dart.typeName(dart.getReifiedType(object)); - } catch (e) { - return safePreview(object, JsonMLConfig.none); - } - } - - List children(object) => [ - NameValuePair(name: 'signature', value: preview(object)), - NameValuePair( - name: 'JavaScript Function', - value: object, - config: JsonMLConfig.skipDart) - ]; -} - -/// Formatter for Objects that implement Map but are not system Maps. -/// -/// This shows two sub-views, one for instance fields and one for -/// Map key/value pairs. -class MapOverviewFormatter implements Formatter { - // Because this comes after MapFormatter in the list, internal - // maps will be picked up by that formatter. - bool accept(object, config) => object is Map; - - bool hasChildren(object) => true; - - String preview(object) { - Map map = object; - try { - return '${getObjectTypeName(map)}'; - } catch (e) { - return safePreview(object, JsonMLConfig.none); - } - } - - List children(object) => [ - NameValuePair( - name: "[[instance view]]", - value: object, - config: JsonMLConfig.asObject), - NameValuePair( - name: "[[entries]]", value: object, config: JsonMLConfig.asMap) - ]; -} - -/// Formatter for Dart Map objects. -/// -/// This is only used for internal maps, or when shown as [[entries]] -/// from MapOverViewFormatter. -class MapFormatter implements Formatter { - bool accept(object, config) => - object is InternalMap || config == JsonMLConfig.asMap; - - bool hasChildren(object) => true; - - String preview(object) { - Map map = object; - try { - return '${getObjectTypeName(map)} length ${map.length}'; - } catch (e) { - return safePreview(object, JsonMLConfig.none); - } - } - - List children(object) { - // TODO(jacobr): be lazier about enumerating contents of Maps that are not - // the build in LinkedHashMap class. - // TODO(jacobr): handle large Maps better. - Map map = object; - var entries = LinkedHashSet(); - map.forEach((key, value) { - var entryWrapper = MapEntry(key: key, value: value); - entries.add( - NameValuePair(name: entries.length.toString(), value: entryWrapper)); - }); - addMetadataChildren(object, entries); - return entries.toList(); - } -} - -/// Formatter for Dart Iterable objects including List and Set. -class IterableFormatter implements Formatter { - bool accept(object, config) => object is Iterable; - - String preview(object) { - Iterable iterable = object; - try { - var length = iterable.length; - return '${getObjectTypeName(iterable)} length $length'; - } catch (_) { - return '${getObjectTypeName(iterable)}'; - } - } - - bool hasChildren(object) => true; - - List children(object) { - // TODO(jacobr): be lazier about enumerating contents of Iterables that - // are not the built in Set or List types. - // TODO(jacobr): handle large Iterables better. - // TODO(jacobr): consider only using numeric indices - var children = LinkedHashSet(); - children.addAll(IterableSpan(0, object.length, object).children()); - // TODO(jacobr): provide a link to show regular class properties here. - // required for subclasses of iterable, etc. - addMetadataChildren(object, children); - return children.toList(); - } -} - -class NamedConstructorFormatter implements Formatter { - bool accept(object, config) => object is NamedConstructor; - - // TODO(bmilligan): Display the signature of the named constructor as the - // preview. - String preview(object) => 'Named Constructor'; - - bool hasChildren(object) => true; - - List children(object) => [ - NameValuePair( - name: 'JavaScript Function', - value: object, - config: JsonMLConfig.skipDart) - ]; -} - -/// Formatter for synthetic MapEntry objects used to display contents of a Map -/// cleanly. -class MapEntryFormatter implements Formatter { - bool accept(object, config) => object is MapEntry; - - String preview(object) { - MapEntry entry = object; - return '${safePreview(entry.key, JsonMLConfig.none)} => ${safePreview(entry.value, JsonMLConfig.none)}'; - } - - bool hasChildren(object) => true; - - List children(object) => [ - NameValuePair( - name: 'key', value: object.key, config: JsonMLConfig.keyToString), - NameValuePair(name: 'value', value: object.value) - ]; -} - -/// Formatter for Dart Iterable objects including List and Set. -class HeritageClauseFormatter implements Formatter { - bool accept(object, config) => object is HeritageClause; - - String preview(object) { - HeritageClause clause = object; - var typeNames = clause.types.map(getTypeName); - return '${clause.name} ${typeNames.join(", ")}'; - } - - bool hasChildren(object) => true; - - List children(object) { - HeritageClause clause = object; - var children = []; - for (var type in clause.types) { - children.add(NameValuePair(value: type, config: JsonMLConfig.asClass)); - } - return children; - } -} - -/// Formatter for synthetic IterableSpan objects used to display contents of -/// an Iterable cleanly. -class IterableSpanFormatter implements Formatter { - bool accept(object, config) => object is IterableSpan; - - String preview(object) { - return '[${object.start}...${object.end - 1}]'; - } - - bool hasChildren(object) => true; - - List children(object) => object.children(); -} - -/// Formatter for Dart Errors and Exceptions. -class ErrorAndExceptionFormatter extends ObjectFormatter { - static final RegExp _pattern = RegExp(r'\d+\:\d+'); - - bool accept(object, config) => object is Error || object is Exception; - - bool hasChildren(object) => true; - - String preview(object) { - var trace = dart.stackTrace(object); - // TODO(vsm): Pull our stack mapping logic here. We should aim to - // provide the first meaningful stack frame. - var line = '$trace'.split('\n').firstWhere( - (l) => - l.contains(_pattern) && - !l.contains('dart:sdk') && - !l.contains('dart_sdk'), - orElse: () => ''); - return line != '' ? '${object} at ${line}' : '${object}'; - } - - List children(object) { - var trace = dart.stackTrace(object); - var entries = LinkedHashSet(); - entries.add(NameValuePair(name: 'stackTrace', value: trace)); - addInstanceMembers(object, entries); - addMetadataChildren(object, entries); - return entries.toList(); - } - - // Add an ObjectFormatter view underneath. - void addInstanceMembers(object, Set ret) { - ret.add(NameValuePair( - name: "[[instance members]]", - value: object, - config: JsonMLConfig.asObject)); - } -} - -class StackTraceFormatter implements Formatter { - bool accept(object, config) => object is StackTrace; - - String preview(object) => 'StackTrace'; - - bool hasChildren(object) => true; - - // Using the stack_trace formatting would be ideal, but adding the - // dependency or re-writing the code is too messy, so each line of the - // StackTrace will be added as its own child. - List children(object) => object - .toString() - .split('\n') - .map((line) => NameValuePair( - value: line.replaceFirst(RegExp(r'^\s+at\s'), ''), hideName: true)) - .toList(); -} - -class ClassFormatter implements Formatter { - bool accept(object, config) => config == JsonMLConfig.asClass; - - String preview(type) { - var implements = dart.getImplements(type)(); - var typeName = getTypeName(type); - if (implements != null) { - var typeNames = implements.map(getTypeName); - return '${typeName} implements ${typeNames.join(", ")}'; - } else { - return typeName; - } - } - - bool hasChildren(object) => true; - - List children(type) { - // TODO(jacobr): add other entries describing the class such as - // implemented interfaces, and methods. - var ret = LinkedHashSet(); - - var staticProperties = Set(); - var staticMethods = Set(); - // Static fields and properties. - addPropertiesFromSignature( - dart.getStaticFields(type), staticProperties, type, false); - addPropertiesFromSignature( - dart.getStaticGetters(type), staticProperties, type, false); - // static methods. - addPropertiesFromSignature( - dart.getStaticMethods(type), staticMethods, type, false); - - if (staticProperties.isNotEmpty || staticMethods.isNotEmpty) { - ret - ..add(NameValuePair(value: '[[Static members]]', hideName: true)) - ..addAll(sortProperties(staticProperties)) - ..addAll(sortProperties(staticMethods)); - } - - // instance methods. - var instanceMethods = Set(); - // Instance methods are defined on the prototype not the constructor object. - addPropertiesFromSignature(dart.getMethods(type), instanceMethods, - JS('', '#.prototype', type), false, - tagTypes: true); - if (instanceMethods.isNotEmpty) { - ret - ..add(NameValuePair(value: '[[Instance Methods]]', hideName: true)) - ..addAll(sortProperties(instanceMethods)); - } - - var mixin = dart.getMixin(type); - if (mixin != null) { - // TODO(jmesserly): this can only be one value. - ret.add(NameValuePair( - name: '[[Mixins]]', value: HeritageClause('mixins', [mixin]))); - } - - var baseProto = JS('', '#.__proto__', type); - if (baseProto != null && !dart.isJsInterop(baseProto)) { - ret.add(NameValuePair( - name: "[[base class]]", - value: baseProto, - config: JsonMLConfig.asClass)); - } - - // TODO(jacobr): add back fields for named constructors. - return ret.toList(); - } -} - -class TypeFormatter implements Formatter { - bool accept(object, config) => object is Type; - - String preview(object) => object.toString(); - - bool hasChildren(object) => false; - - List children(object) => []; -} - -typedef String StackTraceMapper(String stackTrace); - -/// Hook for other parts of the SDK To use to map JS stack traces to Dart -/// stack traces. -/// -/// Raw JS stack traces are used if $dartStackTraceUtility has not been -/// specified. -StackTraceMapper? get stackTraceMapper { - var _util = JS('', r'#.$dartStackTraceUtility', dart.global_); - return _util != null ? JS('!', '#.mapper', _util) : null; -} - -/// This entry point is automatically invoked by the code generated by -/// Dart Dev Compiler -registerDevtoolsFormatter() { - JS('', '#.devtoolsFormatters = [#]', dart.global_, _devtoolsFormatter); -} - -// These methods are exposed here for debugger tests. -// -// TODO(jmesserly): these are not exports because there is existing code that -// calls into them from JS. Currently `dartdevc` always resolves exports at -// compile time, so there is no need to make exports available at runtime by -// copying properties. For that reason we cannot use re-export. -// -// If these methods are only for tests, we should move them here, or change the -// tests to call the methods directly on dart:_runtime. -List getModuleNames() => dart.getModuleNames(); -getModuleLibraries(String name) => dart.getModuleLibraries(name); diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/foreign_helper.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/foreign_helper.dart deleted file mode 100644 index 7f115054065..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/foreign_helper.dart +++ /dev/null @@ -1,285 +0,0 @@ -// Copyright (c) 2012, 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 dart._foreign_helper; - -/** - * Emits a JavaScript code fragment parameterized by arguments. - * - * Hash characters `#` in the [codeTemplate] are replaced in left-to-right order - * with expressions that contain the values of, or evaluate to, the arguments. - * The number of hash marks must match the number or arguments. Although - * declared with arguments [arg0] through [arg2], the form actually has no limit - * on the number of arguments. - * - * The [typeDescription] argument is interpreted as a description of the - * behavior of the JavaScript code. Currently it describes the types that may - * be returned by the expression, with the additional behavior that the returned - * values may be fresh instances of the types. The type information must be - * correct as it is trusted by the compiler in optimizations, and it must be - * precise as possible since it is used for native live type analysis to - * tree-shake large parts of the DOM libraries. If poorly written, the - * [typeDescription] will cause unnecessarily bloated programs. (You can check - * for this by compiling with `--verbose`; there is an info message describing - * the number of native (DOM) types that can be removed, which usually should be - * greater than zero.) - * - * The [typeDescription] is a [String] which contains a union of types separated - * by vertical bar `|` symbols, e.g. `"num|String"` describes the union of - * numbers and Strings. There is no type in Dart that is this precise. The - * Dart alternative would be `Object` or `dynamic`, but these types imply that - * the JS-code might also be creating instances of all the DOM types. If `null` - * is possible, it must be specified explicitly, e.g. `"String|Null"`. - * [typeDescription] has several extensions to help describe the behavior more - * accurately. In addition to the union type already described: - * - * + `=Object` is a plain JavaScript object. Some DOM methods return instances - * that have no corresponding Dart type (e.g. cross-frame documents), - * `=Object` can be used to describe these untyped' values. - * - * + `var` (or empty string). If the entire [typeDescription] is `var` (or - * empty string) then the type is `dynamic` but the code is known to not - * create any instances. - * - * Examples: - * - * // Parent window might be an opaque cross-frame window. - * var thing = JS('=Object|Window', '#.parent', myWindow); - * - * Guidelines: - * - * + Do not use any parameter, local, method or field names in the - * [codeTemplate]. These names are all subject to arbitrary renaming by the - * compiler. Pass the values in via `#` substition, and test with the - * `--minify` dart2js command-line option. - * - * + The substituted expressions are values, not locations. - * - * JS('void', '# += "x"', this.field); - * - * `this.field` might not be a substituted as a reference to the field. The - * generated code might accidentally work as intended, but it also might be - * - * var t1 = this.field; - * t1 += "x"; - * - * or - * - * this.get$field() += "x"; - * - * The remedy in this case is to expand the `+=` operator, leaving all - * references to the Dart field as Dart code: - * - * this.field = JS('!', '# + "x"', this.field); - * - * + Never use `#` in function bodies. - * - * This is a variation on the previous guideline. Since `#` is replaced with - * an *expression* and the expression is only valid in the immediate context, - * `#` should never appear in a function body. Doing so might defer the - * evaluation of the expression, and its side effects, until the function is - * called. - * - * For example, - * - * var value = foo(); - * var f = JS('', 'function(){return #}', value) - * - * might result in no immediate call to `foo` and a call to `foo` on every - * call to the JavaScript function bound to `f`. This is better: - * - * var f = JS('', - * '(function(val) { return function(){return val}; })(#)', value); - * - * Since `#` occurs in the immediately evaluated expression, the expression - * is immediately evaluated and bound to `val` in the immediate call. - * - * - * Additional notes. - * - * In the future we may extend [typeDescription] to include other aspects of the - * behavior, for example, separating the returned types from the instantiated - * types, or including effects to allow the compiler to perform more - * optimizations around the code. This might be an extension of [JS] or a new - * function similar to [JS] with additional arguments for the new information. - */ -// Add additional optional arguments if needed. The method is treated internally -// as a variable argument method. -external T JS(String typeDescription, String codeTemplate, - [arg0, - arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7, - arg8, - arg9, - arg10, - arg11, - arg12, - arg13, - arg14, - arg15, - arg16, - arg17, - arg18, - arg19]); - -/// Annotates the compiled Js name for fields and methods. -/// Similar behaviour to `JS` from `package:js/js.dart` (but usable from runtime -/// files), and not to be confused with `JSName` from `js_helper` (which deals -/// with names of externs). -// TODO(jmesserly): remove this in favor of js_helper's `@JSName` -// (Currently they have slightly different semantics, but they can be unified.) -class JSExportName { - final String name; - const JSExportName(this.name); -} - -/** - * Returns the JavaScript constructor function for Dart's Object class. - * This can be used for type tests, as in - * - * if (JS('!', '# instanceof #', obj, JS_DART_OBJECT_CONSTRUCTOR())) - * ... - */ -JS_DART_OBJECT_CONSTRUCTOR() {} - -/** - * Returns the interceptor for class [type]. The interceptor is the type's - * constructor's `prototype` property. [type] will typically be the class, not - * an interface, e.g. `JS_INTERCEPTOR_CONSTANT(JSInt)`, not - * `JS_INTERCEPTOR_CONSTANT(int)`. - */ -JS_INTERCEPTOR_CONSTANT(Type type) {} - -/** - * Returns the prefix used for generated is checks on classes. - */ -external String JS_OPERATOR_IS_PREFIX(); - -/** - * Returns the prefix used for generated type argument substitutions on classes. - */ -external String JS_OPERATOR_AS_PREFIX(); - -/// Returns the name of the class `Object` in the generated code. -external String JS_OBJECT_CLASS_NAME(); - -/// Returns the name of the class `Null` in the generated code. -external String JS_NULL_CLASS_NAME(); - -/// Returns the name of the class `Function` in the generated code. -external String JS_FUNCTION_CLASS_NAME(); - -/** - * Returns the field name used for determining if an object or its - * interceptor has JavaScript indexing behavior. - */ -external String JS_IS_INDEXABLE_FIELD_NAME(); - -/// Returns the name used for generated function types on classes and methods. -external String JS_SIGNATURE_NAME(); - -/// Returns the name used to tag typedefs. -external String JS_TYPEDEF_TAG(); - -/// Returns the name used to tag function type representations in JavaScript. -external String JS_FUNCTION_TYPE_TAG(); - -/** - * Returns the name used to tag void return in function type representations - * in JavaScript. - */ -external String JS_FUNCTION_TYPE_VOID_RETURN_TAG(); - -/** - * Returns the name used to tag return types in function type representations - * in JavaScript. - */ -external String JS_FUNCTION_TYPE_RETURN_TYPE_TAG(); - -/** - * Returns the name used to tag required parameters in function type - * representations in JavaScript. - */ -external String JS_FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG(); - -/** - * Returns the name used to tag optional parameters in function type - * representations in JavaScript. - */ -external String JS_FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG(); - -/** - * Returns the name used to tag named parameters in function type - * representations in JavaScript. - */ -external String JS_FUNCTION_TYPE_NAMED_PARAMETERS_TAG(); - -/// Returns the JS name for [name] from the Namer. -external String JS_GET_NAME(String name); - -/// Returns the state of a flag that is determined by the state of the compiler -/// when the program has been analyzed. -external bool JS_GET_FLAG(String name); - -/** - * Pretend [code] is executed. Generates no executable code. This is used to - * model effects at some other point in external code. For example, the - * following models an assignment to foo with an unknown value. - * - * var foo; - * - * main() { - * JS_EFFECT((_){ foo = _; }) - * } - * - * TODO(sra): Replace this hack with something to mark the volatile or - * externally initialized elements. - */ -void JS_EFFECT(Function code) { - code(null); -} - -/** - * Use this class for creating constants that hold JavaScript code. - * For example: - * - * const constant = JS_CONST('typeof window != "undefined"); - * - * This code will generate: - * $.JS_CONST_1 = typeof window != "undefined"; - */ -class JS_CONST { - final String code; - const JS_CONST(this.code); -} - -/** - * JavaScript string concatenation. Inputs must be Strings. Corresponds to the - * HStringConcat SSA instruction and may be constant-folded. - */ -String JS_STRING_CONCAT(String a, String b) { - // This body is unused, only here for type analysis. - return JS('!', '# + #', a, b); -} - -/// Same `@rest` annotation and `spread` function as in -/// `package:js/src/varargs.dart`. -/// -/// Runtime files cannot import packages, which is why we have an ad-hoc copy. - -class _Rest { - const _Rest(); -} - -const _Rest rest = _Rest(); - -dynamic spread(args) { - throw StateError('The spread function cannot be called, ' - 'it should be compiled away.'); -} diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/identity_hash_map.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/identity_hash_map.dart deleted file mode 100644 index eda6c44b4eb..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/identity_hash_map.dart +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright (c) 2017, 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. - -part of dart._js_helper; - -class IdentityMap extends InternalMap { - final _map = JS('', 'new Map()'); - - // We track the number of modifications done to the key set of the - // hash map to be able to throw when the map is modified while being - // iterated over. - // - // Value cycles after 2^30 modifications so that modification counts are - // always unboxed (Smi) values. Modification detection will be missed if you - // make exactly some multiple of 2^30 modifications between advances of an - // iterator. - @notNull - int _modifications = 0; - - IdentityMap(); - IdentityMap.from(JSArray entries) { - var map = _map; - for (int i = 0, n = JS('!', '#.length', entries); i < n; i += 2) { - JS('', '#.set(#[#], #[#])', map, entries, i, entries, i + 1); - } - } - - int get length => JS('!', '#.size', _map); - bool get isEmpty => JS('!', '#.size == 0', _map); - bool get isNotEmpty => JS('!', '#.size != 0', _map); - - Iterable get keys => _JSMapIterable(this, true); - Iterable get values => _JSMapIterable(this, false); - - bool containsKey(Object? key) { - return JS('!', '#.has(#)', _map, key); - } - - bool containsValue(Object? value) { - for (var v in JS('', '#.values()', _map)) { - if (v == value) return true; - } - return false; - } - - void addAll(Map other) { - if (other.isNotEmpty) { - var map = _map; - other.forEach((key, value) { - JS('', '#.set(#, #)', map, key, value); - }); - _modifications = (_modifications + 1) & 0x3ffffff; - } - } - - V? operator [](Object? key) { - V value = JS('', '#.get(#)', _map, key); - return value == null ? null : value; // coerce undefined to null. - } - - void operator []=(K key, V value) { - var map = _map; - int length = JS('!', '#.size', map); - JS('', '#.set(#, #)', map, key, value); - if (length != JS('!', '#.size', map)) { - _modifications = (_modifications + 1) & 0x3ffffff; - } - } - - V putIfAbsent(K key, V ifAbsent()) { - if (JS('!', '#.has(#)', _map, key)) { - return JS('', '#.get(#)', _map, key); - } - V value = ifAbsent(); - if (value == null) JS('', '# = null', value); - JS('', '#.set(#, #)', _map, key, value); - _modifications = (_modifications + 1) & 0x3ffffff; - return value; - } - - V? remove(Object? key) { - V value = JS('', '#.get(#)', _map, key); - if (JS('!', '#.delete(#)', _map, key)) { - _modifications = (_modifications + 1) & 0x3ffffff; - } - return value == null ? null : value; // coerce undefined to null. - } - - void clear() { - if (JS('!', '#.size', _map) > 0) { - JS('', '#.clear()', _map); - _modifications = (_modifications + 1) & 0x3ffffff; - } - } -} - -class _JSMapIterable extends EfficientLengthIterable { - final InternalMap _map; - @notNull - final bool _isKeys; - _JSMapIterable(this._map, this._isKeys); - - int get length => _map.length; - bool get isEmpty => _map.isEmpty; - - @JSExportName('Symbol.iterator') - _jsIterator() { - var map = _map; - var iterator = - JS('', '# ? #.keys() : #.values()', _isKeys, map._map, map._map); - int modifications = map._modifications; - return JS( - '', - '''{ - next() { - if (# != #) { - throw #; - } - return #.next(); - } - }''', - modifications, - map._modifications, - ConcurrentModificationError(map), - iterator); - } - - Iterator get iterator => DartIterator(_jsIterator()); - - bool contains(Object? element) => - _isKeys ? _map.containsKey(element) : _map.containsValue(element); - - void forEach(void Function(E) f) { - for (var entry in this) f(entry); - } -} diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/interceptors.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/interceptors.dart deleted file mode 100644 index 04d492fd7fd..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/interceptors.dart +++ /dev/null @@ -1,233 +0,0 @@ -// Copyright (c) 2012, 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 dart._interceptors; - -import 'dart:collection'; -import 'dart:_internal' hide Symbol; -import 'dart:_js_helper'; -import 'dart:_foreign_helper' show JS, JSExportName; -import 'dart:math' show Random, ln2; -import 'dart:_runtime' as dart; - -part 'js_array.dart'; -part 'js_number.dart'; -part 'js_string.dart'; - -// TODO(jmesserly): remove, this doesn't do anything for us. -abstract class Interceptor { - const Interceptor(); - - // Use native JS toString method instead of standard Dart Object.toString. - String toString() => JS('!', '#.toString()', this); -} - -// TODO(jmesserly): remove -getInterceptor(obj) => obj; - -/** - * The interceptor class for [bool]. - */ -@JsPeerInterface(name: 'Boolean') -class JSBool extends Interceptor implements bool { - const JSBool(); - - // Note: if you change this, also change the function [S]. - @notNull - String toString() => JS('!', r'String(#)', this); - - // The values here are SMIs, co-prime and differ about half of the bit - // positions, including the low bit, so they are different mod 2^k. - @notNull - int get hashCode => this ? (2 * 3 * 23 * 3761) : (269 * 811); - - @notNull - bool operator &(@nullCheck bool other) => - JS('!', "# && #", other, this); - - @notNull - bool operator |(@nullCheck bool other) => - JS('!', "# || #", other, this); - - @notNull - bool operator ^(@nullCheck bool other) => !identical(this, other); - - Type get runtimeType => bool; -} - -/** - * The supertype for JSString and JSArray. Used by the backend as to - * have a type mask that contains the objects that we can use the - * native JS [] operator and length on. - */ -abstract class JSIndexable { - int get length; - E operator [](int index); -} - -/** - * The interface implemented by JavaScript objects. These are methods in - * addition to the regular Dart Object methods like [Object.hashCode]. - * - * This is the type that should be exported by a JavaScript interop library. - */ -abstract class JSObject {} - -/** - * Interceptor base class for JavaScript objects not recognized as some more - * specific native type. - */ -abstract class JavaScriptObject extends Interceptor implements JSObject { - const JavaScriptObject(); - - // It would be impolite to stash a property on the object. - int get hashCode => 0; - - Type get runtimeType => JSObject; -} - -/** - * Interceptor for plain JavaScript objects created as JavaScript object - * literals or `new Object()`. - */ -class PlainJavaScriptObject extends JavaScriptObject { - const PlainJavaScriptObject(); -} - -/** - * Interceptor for unclassified JavaScript objects, typically objects with a - * non-trivial prototype chain. - * - * This class also serves as a fallback for unknown JavaScript exceptions. - */ -class UnknownJavaScriptObject extends JavaScriptObject { - const UnknownJavaScriptObject(); - - String toString() => JS('!', 'String(#)', this); -} - -class NativeError extends Interceptor { - String dartStack() => JS('!', '#.stack', this); -} - -// Note that this needs to be in interceptors.dart in order for -// it to be picked up as an extension type. -@JsPeerInterface(name: 'TypeError') -class JSNoSuchMethodError extends NativeError implements NoSuchMethodError { - static final _nullError = RegExp(r"^Cannot read property '(.+)' of null$"); - static final _notAFunction = RegExp(r"^(.+) is not a function$"); - static final _extensionName = RegExp(r"^Symbol\(dartx\.(.+)\)$"); - static final _privateName = RegExp(r"^Symbol\((_.+)\)$"); - - String? _fieldName(String message) { - RegExpMatch? match = _nullError.firstMatch(message); - if (match == null) return null; - String name = match[1]!; - match = _extensionName.firstMatch(name) ?? _privateName.firstMatch(name); - return match != null ? match[1] : name; - } - - String? _functionCallTarget(String message) { - var match = _notAFunction.firstMatch(message); - return match != null ? match[1] : null; - } - - String dartStack() { - var stack = super.dartStack(); - // Strip TypeError from first line. - stack = toString() + '\n' + stack.split('\n').sublist(1).join('\n'); - return stack; - } - - StackTrace get stackTrace => dart.stackTrace(this); - - String toString() { - String message = JS('!', '#.message', this); - var callTarget = _functionCallTarget(message); - if (callTarget != null) { - return "NoSuchMethodError: tried to call a non-function, such as null: " - "'$callTarget'"; - } - // TODO(vsm): Distinguish between null reference errors and other - // TypeErrors. We should not get non-null TypeErrors from DDC code, - // but we may from native JavaScript. - var name = _fieldName(message); - if (name == null) { - // Not a Null NSM error: fallback to JS. - return JS('!', '#.toString()', this); - } - return "NoSuchMethodError: invalid member on null: '$name'"; - } -} - -@JsPeerInterface(name: 'Function') -class JSFunction extends Interceptor { - toString() { - // If the function is a Type object, we should just display the type name. - // - // Regular Dart code should typically get wrapped type objects instead of - // raw type (aka JS constructor) objects, however raw type objects can be - // exposed to Dart code via JS interop or debugging tools. - if (dart.isType(this)) return dart.typeName(this); - - return JS('!', r'"Closure: " + # + " from: " + #', - dart.typeName(dart.getReifiedType(this)), this); - } - - // TODO(jmesserly): remove these once we canonicalize tearoffs. - operator ==(other) { - if (other == null) return false; - var boundObj = JS('', '#._boundObject', this); - if (boundObj == null) return JS('!', '# === #', this, other); - return JS( - 'bool', - '# === #._boundObject && #._boundMethod === #._boundMethod', - boundObj, - other, - this, - other); - } - - get hashCode { - var boundObj = JS('', '#._boundObject', this); - if (boundObj == null) return identityHashCode(this); - - var boundMethod = JS('!', '#._boundMethod', this); - int hash = (17 * 31 + boundObj.hashCode) & 0x1fffffff; - return (hash * 31 + identityHashCode(boundMethod)) & 0x1fffffff; - } - - get runtimeType => dart.wrapType(dart.getReifiedType(this)); -} - -/// A class used for implementing `null` tear-offs. -class JSNull { - toString() => 'null'; - noSuchMethod(Invocation i) => dart.defaultNoSuchMethod(null, i); -} - -final Object jsNull = JSNull(); - -// Note that this needs to be in interceptors.dart in order for -// it to be picked up as an extension type. -@JsPeerInterface(name: 'RangeError') -class JSRangeError extends Interceptor implements ArgumentError { - StackTrace get stackTrace => dart.stackTrace(this); - - get invalidValue => null; - get name => null; - get message => JS('!', '#.message', this); - - String toString() => "Invalid argument: $message"; -} - -// Obsolete in dart dev compiler. Added only so that the same version of -// dart:html can be used in dart2js an dev compiler. -// Warning: calls to these methods need to be removed before custom elements -// and cross-frame dom objects behave correctly in ddc. -// See https://github.com/dart-lang/sdk/issues/28326 -findInterceptorConstructorForType(Type? type) {} -findConstructorForNativeSubclassType(Type? type, String name) {} -getNativeInterceptor(object) {} -setDispatchProperty(object, value) {} diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/isolate_helper.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/isolate_helper.dart deleted file mode 100644 index 65766534c7b..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/isolate_helper.dart +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright (c) 2012, 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 dart._isolate_helper; - -import 'dart:_runtime' as dart; -import 'dart:async'; -import 'dart:_foreign_helper' show JS; - -/// Deprecated way of initializing `main()` in DDC, typically called from JS. -@deprecated -void startRootIsolate(main, args) { - if (args == null) args = []; - if (args is List) { - if (args is! List) args = List.from(args); - // DDC attaches signatures only when torn off, and the typical way of - // getting `main` via the JS ABI won't do this. So use JS to invoke main. - if (JS('!', 'typeof # == "function"', main)) { - // JS will ignore extra arguments. - JS('', '#(#, #)', main, args, null); - } else { - // Not a function. Use a dynamic call to throw an error. - (main as dynamic)(args); - } - } else { - throw ArgumentError("Arguments to main must be a List: $args"); - } -} - -// TODO(vsm): Other libraries import global from here. Consider replacing -// those uses to just refer to the one in dart:runtime. -final global = dart.global_; - -class TimerImpl implements Timer { - final bool _once; - int? _handle; - int _tick = 0; - - TimerImpl(int milliseconds, void callback()) : _once = true { - if (hasTimer()) { - int currentHotRestartIteration = dart.hotRestartIteration; - void internalCallback() { - _handle = null; - dart.removeAsyncCallback(); - _tick = 1; - if (currentHotRestartIteration == dart.hotRestartIteration) { - callback(); - } - } - - dart.addAsyncCallback(); - - _handle = JS( - 'int', '#.setTimeout(#, #)', global, internalCallback, milliseconds); - } else { - throw UnsupportedError("`setTimeout()` not found."); - } - } - - TimerImpl.periodic(int milliseconds, void callback(Timer timer)) - : _once = false { - if (hasTimer()) { - dart.addAsyncCallback(); - int start = JS('!', 'Date.now()'); - int currentHotRestartIteration = dart.hotRestartIteration; - _handle = JS('!', '#.setInterval(#, #)', global, () { - if (currentHotRestartIteration != dart.hotRestartIteration) { - cancel(); - return; - } - int tick = this._tick + 1; - if (milliseconds > 0) { - int duration = JS('!', 'Date.now()') - start; - if (duration > (tick + 1) * milliseconds) { - tick = duration ~/ milliseconds; - } - } - this._tick = tick; - callback(this); - }, milliseconds); - } else { - throw UnsupportedError("Periodic timer."); - } - } - - int get tick => _tick; - - void cancel() { - if (hasTimer()) { - if (_handle == null) return; - dart.removeAsyncCallback(); - if (_once) { - JS('void', '#.clearTimeout(#)', global, _handle); - } else { - JS('void', '#.clearInterval(#)', global, _handle); - } - _handle = null; - } else { - throw UnsupportedError("Canceling a timer."); - } - } - - bool get isActive => _handle != null; -} - -bool hasTimer() { - return JS('', '#.setTimeout', global) != null; -} diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_array.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_array.dart deleted file mode 100644 index 4538120ee4e..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_array.dart +++ /dev/null @@ -1,671 +0,0 @@ -// Copyright (c) 2012, 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. - -part of dart._interceptors; - -/** - * The interceptor class for [List]. The compiler recognizes this - * class as an interceptor, and changes references to [:this:] to - * actually use the receiver of the method, which is generated as an extra - * argument added to each member. - */ -@JsPeerInterface(name: 'Array') -class JSArray implements List, JSIndexable { - const JSArray(); - - /** - * Constructor for adding type parameters to an existing JavaScript - * Array. Used for creating literal lists. - */ - factory JSArray.of(list) { - // TODO(sra): Move this to core.List for better readability. - // - // TODO(jmesserly): this uses special compiler magic to close over the - // parameterized ES6 'JSArray' class. - JS('', '#.__proto__ = JSArray.prototype', list); - return JS('-dynamic', '#', list); - } - - // TODO(jmesserly): consider a fixed array subclass instead. - factory JSArray.fixed(list) { - JS('', '#.__proto__ = JSArray.prototype', list); - JS('', r'#.fixed$length = Array', list); - return JS('-dynamic', '#', list); - } - - factory JSArray.unmodifiable(list) { - JS('', '#.__proto__ = JSArray.prototype', list); - JS('', r'#.fixed$length = Array', list); - JS('', r'#.immutable$list = Array', list); - return JS('-dynamic', '#', list); - } - - static void markFixedList(list) { - // Functions are stored in the hidden class and not as properties in - // the object. We never actually look at the value, but only want - // to know if the property exists. - JS('', r'#.fixed$length = Array', list); - } - - static void markUnmodifiableList(list) { - // Functions are stored in the hidden class and not as properties in - // the object. We never actually look at the value, but only want - // to know if the property exists. - JS('', r'#.fixed$length = Array', list); - JS('', r'#.immutable$list = Array', list); - } - - checkMutable(reason) { - if (JS('!', r'#.immutable$list', this)) { - throw UnsupportedError(reason); - } - } - - checkGrowable(reason) { - if (JS('!', r'#.fixed$length', this)) { - throw UnsupportedError(reason); - } - } - - List cast() => List.castFrom(this); - void add(E value) { - checkGrowable('add'); - JS('void', r'#.push(#)', this, value); - } - - E removeAt(@nullCheck int index) { - checkGrowable('removeAt'); - if (index < 0 || index >= length) { - throw RangeError.value(index); - } - return JS('-dynamic', r'#.splice(#, 1)[0]', this, index); - } - - void insert(@nullCheck int index, E value) { - checkGrowable('insert'); - if (index < 0 || index > length) { - throw RangeError.value(index); - } - JS('void', r'#.splice(#, 0, #)', this, index, value); - } - - void insertAll(@nullCheck int index, Iterable iterable) { - checkGrowable('insertAll'); - RangeError.checkValueInInterval(index, 0, this.length, "index"); - if (iterable is! EfficientLengthIterable) { - iterable = iterable.toList(); - } - @nullCheck - int insertionLength = iterable.length; - this.length += insertionLength; - int end = index + insertionLength; - this.setRange(end, this.length, this, index); - this.setRange(index, end, iterable); - } - - void setAll(@nullCheck int index, Iterable iterable) { - checkMutable('setAll'); - RangeError.checkValueInInterval(index, 0, this.length, "index"); - for (var element in iterable) { - this[index++] = element; - } - } - - E removeLast() { - checkGrowable('removeLast'); - if (length == 0) throw diagnoseIndexError(this, -1); - return JS('var', r'#.pop()', this); - } - - bool remove(Object? element) { - checkGrowable('remove'); - var length = this.length; - for (int i = 0; i < length; i++) { - if (this[i] == element) { - JS('var', r'#.splice(#, 1)', this, i); - return true; - } - } - return false; - } - - /** - * Removes elements matching [test] from [this] List. - */ - void removeWhere(bool Function(E) test) { - checkGrowable('removeWhere'); - _removeWhere(test, true); - } - - void retainWhere(bool Function(E) test) { - checkGrowable('retainWhere'); - _removeWhere(test, false); - } - - void _removeWhere(bool Function(E) test, bool removeMatching) { - // Performed in two steps, to avoid exposing an inconsistent state - // to the [test] function. First the elements to retain are found, and then - // the original list is updated to contain those elements. - - // TODO(sra): Replace this algorithm with one that retains a list of ranges - // to be removed. Most real uses remove 0, 1 or a few clustered elements. - - List retained = []; - int end = this.length; - for (int i = 0; i < end; i++) { - var element = JS('', '#[#]', this, i); - // !test() ensures bool conversion in checked mode. - if (!test(element) == removeMatching) { - retained.add(element); - } - if (this.length != end) throw ConcurrentModificationError(this); - } - if (retained.length == end) return; - this.length = retained.length; - @nullCheck - var length = retained.length; - for (int i = 0; i < length; i++) { - JS('', '#[#] = #[#]', this, i, retained, i); - } - } - - Iterable where(bool Function(E) f) { - return WhereIterable(this, f); - } - - Iterable expand(Iterable Function(E) f) { - return ExpandIterable(this, f); - } - - void addAll(Iterable collection) { - int i = this.length; - checkGrowable('addAll'); - for (E e in collection) { - assert(i == this.length || (throw ConcurrentModificationError(this))); - i++; - JS('void', r'#.push(#)', this, e); - } - } - - void clear() { - length = 0; - } - - void forEach(void Function(E) f) { - int end = this.length; - for (int i = 0; i < end; i++) { - var element = JS('', '#[#]', this, i); - f(element); - if (this.length != end) throw ConcurrentModificationError(this); - } - } - - Iterable map(T Function(E) f) { - return MappedListIterable(this, f); - } - - String join([String separator = ""]) { - var length = this.length; - var list = List.filled(length, ""); - for (int i = 0; i < length; i++) { - list[i] = "${this[i]}"; - } - return JS('!', "#.join(#)", list, separator); - } - - Iterable take(int n) { - return SubListIterable(this, 0, n); - } - - Iterable takeWhile(bool test(E value)) { - return TakeWhileIterable(this, test); - } - - Iterable skip(int n) { - return SubListIterable(this, n, null); - } - - Iterable skipWhile(bool Function(E) test) { - return SkipWhileIterable(this, test); - } - - E reduce(E combine(E previousValue, E element)) { - int length = this.length; - if (length == 0) throw IterableElementError.noElement(); - E value = this[0]; - for (int i = 1; i < length; i++) { - var element = JS('', '#[#]', this, i); - value = combine(value, element); - if (length != this.length) throw ConcurrentModificationError(this); - } - return value; - } - - T fold(T initialValue, T Function(T previousValue, E element) combine) { - var value = initialValue; - int length = this.length; - for (int i = 0; i < length; i++) { - var element = JS('', '#[#]', this, i); - value = combine(value, element); - if (this.length != length) throw ConcurrentModificationError(this); - } - return value; - } - - E firstWhere(bool Function(E) test, {E Function()? orElse}) { - int end = this.length; - for (int i = 0; i < end; ++i) { - var element = JS('', '#[#]', this, i); - if (test(element)) return element; - if (this.length != end) throw ConcurrentModificationError(this); - } - if (orElse != null) return orElse(); - throw IterableElementError.noElement(); - } - - E lastWhere(bool Function(E) test, {E Function()? orElse}) { - int length = this.length; - for (int i = length - 1; i >= 0; i--) { - var element = JS('', '#[#]', this, i); - if (test(element)) return element; - if (length != this.length) { - throw ConcurrentModificationError(this); - } - } - if (orElse != null) return orElse(); - throw IterableElementError.noElement(); - } - - E singleWhere(bool Function(E) test, {E Function()? orElse}) { - int length = this.length; - E? match = null; - bool matchFound = false; - for (int i = 0; i < length; i++) { - var element = JS('', '#[#]', this, i); - if (test(element)) { - if (matchFound) { - throw IterableElementError.tooMany(); - } - matchFound = true; - match = element; - } - if (length != this.length) { - throw ConcurrentModificationError(this); - } - } - if (matchFound) return match as E; - if (orElse != null) return orElse(); - throw IterableElementError.noElement(); - } - - E elementAt(int index) { - return this[index]; - } - - List sublist(@nullCheck int start, [int? end]) { - if (start < 0 || start > length) { - throw RangeError.range(start, 0, length, "start"); - } - if (end == null) { - end = length; - } else { - @notNull - var _end = end; - if (_end < start || _end > length) { - throw RangeError.range(end, start, length, "end"); - } - } - if (start == end) return []; - return JSArray.of(JS('', r'#.slice(#, #)', this, start, end)); - } - - Iterable getRange(int start, int end) { - RangeError.checkValidRange(start, end, this.length); - return SubListIterable(this, start, end); - } - - E get first { - if (length > 0) return this[0]; - throw IterableElementError.noElement(); - } - - E get last { - if (length > 0) return this[length - 1]; - throw IterableElementError.noElement(); - } - - E get single { - if (length == 1) return this[0]; - if (length == 0) throw IterableElementError.noElement(); - throw IterableElementError.tooMany(); - } - - void removeRange(@nullCheck int start, @nullCheck int end) { - checkGrowable('removeRange'); - RangeError.checkValidRange(start, end, this.length); - int deleteCount = end - start; - JS('', '#.splice(#, #)', this, start, deleteCount); - } - - void setRange(@nullCheck int start, @nullCheck int end, Iterable iterable, - [@nullCheck int skipCount = 0]) { - checkMutable('set range'); - - RangeError.checkValidRange(start, end, this.length); - int length = end - start; - if (length == 0) return; - RangeError.checkNotNegative(skipCount, "skipCount"); - - var otherList = []; - int otherStart = 0; - // TODO(floitsch): Make this accept more. - if (iterable is List) { - otherList = iterable; - otherStart = skipCount; - } else { - otherList = iterable.skip(skipCount).toList(growable: false); - otherStart = 0; - } - if (otherStart + length > otherList.length) { - throw IterableElementError.tooFew(); - } - if (otherStart < start) { - // Copy backwards to ensure correct copy if [from] is this. - // TODO(sra): If [from] is the same Array as [this], we can copy without - // type annotation checks on the stores. - for (int i = length - 1; i >= 0; i--) { - // Use JS to avoid bounds check (the bounds check elimination - // optimzation is too weak). The 'E' type annotation is a store type - // check - we can't rely on iterable, it could be List. - var element = otherList[otherStart + i]; - JS('', '#[#] = #', this, start + i, element); - } - } else { - for (int i = 0; i < length; i++) { - var element = otherList[otherStart + i]; - JS('', '#[#] = #', this, start + i, element); - } - } - } - - void fillRange(@nullCheck int start, @nullCheck int end, [E? fillValue]) { - checkMutable('fill range'); - RangeError.checkValidRange(start, end, this.length); - E checkedFillValue = fillValue as E; - for (int i = start; i < end; i++) { - JS('', '#[#] = #', this, i, checkedFillValue); - } - } - - void replaceRange( - @nullCheck int start, @nullCheck int end, Iterable replacement) { - checkGrowable('replace range'); - RangeError.checkValidRange(start, end, this.length); - if (replacement is! EfficientLengthIterable) { - replacement = replacement.toList(); - } - int removeLength = end - start; - @nullCheck - int insertLength = replacement.length; - if (removeLength >= insertLength) { - int delta = removeLength - insertLength; - int insertEnd = start + insertLength; - int newLength = this.length - delta; - this.setRange(start, insertEnd, replacement); - if (delta != 0) { - this.setRange(insertEnd, newLength, this, end); - this.length = newLength; - } - } else { - int delta = insertLength - removeLength; - int newLength = this.length + delta; - int insertEnd = start + insertLength; // aka. end + delta. - this.length = newLength; - this.setRange(insertEnd, newLength, this, end); - this.setRange(start, insertEnd, replacement); - } - } - - bool any(bool Function(E) test) { - int end = this.length; - for (int i = 0; i < end; i++) { - var element = JS('', '#[#]', this, i); - if (test(element)) return true; - if (this.length != end) throw ConcurrentModificationError(this); - } - return false; - } - - bool every(bool Function(E) test) { - int end = this.length; - for (int i = 0; i < end; i++) { - var element = JS('', '#[#]', this, i); - if (!test(element)) return false; - if (this.length != end) throw ConcurrentModificationError(this); - } - return true; - } - - Iterable get reversed => ReversedListIterable(this); - - void sort([int Function(E, E)? compare]) { - checkMutable('sort'); - if (compare == null) { - Sort.sort( - this, (a, b) => Comparable.compare(a as Comparable, b as Comparable)); - } else { - Sort.sort(this, compare); - } - } - - void shuffle([Random? random]) { - checkMutable('shuffle'); - if (random == null) random = Random(); - int length = this.length; - while (length > 1) { - int pos = random.nextInt(length); - length -= 1; - var tmp = this[length]; - this[length] = this[pos]; - this[pos] = tmp; - } - } - - int indexOf(Object? element, [@nullCheck int start = 0]) { - int length = this.length; - if (start >= length) { - return -1; - } - if (start < 0) { - start = 0; - } - for (int i = start; i < length; i++) { - if (this[i] == element) { - return i; - } - } - return -1; - } - - int lastIndexOf(Object? element, [int? startIndex]) { - @notNull - int start = startIndex ?? this.length - 1; - if (start >= this.length) { - start = this.length - 1; - } else if (start < 0) { - return -1; - } - for (int i = start; i >= 0; i--) { - if (this[i] == element) { - return i; - } - } - return -1; - } - - bool contains(Object? other) { - var length = this.length; - for (int i = 0; i < length; i++) { - var element = JS('', '#[#]', this, i); - if (element == other) return true; - } - return false; - } - - @notNull - bool get isEmpty => length == 0; - - @notNull - bool get isNotEmpty => !isEmpty; - - String toString() => ListBase.listToString(this); - - List toList({@nullCheck bool growable = true}) { - var list = JS('', '#.slice()', this); - if (!growable) markFixedList(list); - return JSArray.of(list); - } - - Set toSet() => Set.from(this); - - Iterator get iterator => ArrayIterator(this); - - int get hashCode => identityHashCode(this); - - @notNull - bool operator ==(other) => identical(this, other); - - @notNull - int get length => JS('!', r'#.length', this); - - void set length(@nullCheck int newLength) { - checkGrowable('set length'); - // TODO(sra): Remove this test and let JavaScript throw an error. - if (newLength < 0) { - throw RangeError.range(newLength, 0, null, 'newLength'); - } - // JavaScript with throw a RangeError for numbers that are too big. The - // message does not contain the value. - JS('void', r'#.length = #', this, newLength); - } - - E operator [](int index) { - // Suppress redundant null checks via JS. - if (index == null || - JS('!', '#', index) >= JS('!', '#.length', this) || - JS('!', '#', index) < 0) { - throw diagnoseIndexError(this, index); - } - return JS('', '#[#]', this, index); - } - - void operator []=(int index, E value) { - checkMutable('indexed set'); - if (index == null || - JS('!', '#', index) >= JS('!', '#.length', this) || - JS('!', '#', index) < 0) { - throw diagnoseIndexError(this, index); - } - JS('void', r'#[#] = #', this, index, value); - } - - Map asMap() { - return ListMapView(this); - } - - Type get runtimeType => - dart.wrapType(JS('', '#(#)', dart.getGenericClass(List), E)); - - Iterable followedBy(Iterable other) => - FollowedByIterable.firstEfficient(this, other); - - Iterable whereType() => new WhereTypeIterable(this); - - List operator +(List other) => [...this, ...other]; - - int indexWhere(bool Function(E) test, [int start = 0]) { - if (start >= this.length) return -1; - if (start < 0) start = 0; - for (int i = start; i < this.length; i++) { - if (test(this[i])) return i; - } - return -1; - } - - int lastIndexWhere(bool Function(E) test, [int? start]) { - if (start == null) start = this.length - 1; - if (start < 0) return -1; - for (int i = start; i >= 0; i--) { - if (test(this[i])) return i; - } - return -1; - } - - void set first(E element) { - if (this.isEmpty) throw RangeError.index(0, this); - this[0] = element; - } - - void set last(E element) { - if (this.isEmpty) throw RangeError.index(0, this); - this[this.length - 1] = element; - } -} - -/** - * Dummy subclasses that allow the backend to track more precise - * information about arrays through their type. The CPA type inference - * relies on the fact that these classes do not override [] nor []=. - * - * These classes are really a fiction, and can have no methods, since - * getInterceptor always returns JSArray. We should consider pushing the - * 'isGrowable' and 'isMutable' checks into the getInterceptor implementation so - * these classes can have specialized implementations. Doing so will challenge - * many assumptions in the JS backend. - */ -class JSMutableArray extends JSArray {} - -class JSFixedArray extends JSMutableArray {} - -class JSExtendableArray extends JSMutableArray {} - -class JSUnmodifiableArray extends JSArray {} // Already is JSIndexable. - -/// An [Iterator] that iterates a JSArray. -/// -class ArrayIterator implements Iterator { - final JSArray _iterable; - @notNull - final int _length; - @notNull - int _index; - E? _current; - - ArrayIterator(JSArray iterable) - : _iterable = iterable, - _length = iterable.length, - _index = 0; - - E get current => _current as E; - - bool moveNext() { - @notNull - int length = _iterable.length; - - // We have to do the length check even on fixed length Arrays. If we can - // inline moveNext() we might be able to GVN the length and eliminate this - // check on known fixed length JSArray. - if (_length != length) { - throw throwConcurrentModificationError(_iterable); - } - - if (_index >= length) { - _current = null; - return false; - } - _current = _iterable[_index]; - _index++; - return true; - } -} diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_helper.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_helper.dart deleted file mode 100644 index 11a3a8eee71..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_helper.dart +++ /dev/null @@ -1,806 +0,0 @@ -// Copyright (c) 2013, 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 dart._js_helper; - -import 'dart:collection'; - -import 'dart:_foreign_helper' show JS, JS_STRING_CONCAT, JSExportName; - -import 'dart:_interceptors'; -import 'dart:_internal' - show - EfficientLengthIterable, - MappedIterable, - IterableElementError, - SubListIterable; - -import 'dart:_native_typed_data'; -import 'dart:_runtime' as dart; - -part 'annotations.dart'; -part 'linked_hash_map.dart'; -part 'identity_hash_map.dart'; -part 'custom_hash_map.dart'; -part 'native_helper.dart'; -part 'regexp_helper.dart'; -part 'string_helper.dart'; -part 'js_rti.dart'; - -class _Patch { - const _Patch(); -} - -const _Patch patch = _Patch(); - -/// Adapts a JS `[Symbol.iterator]` to a Dart `get iterator`. -/// -/// This is the inverse of `JsIterator`, for classes where we can more -/// efficiently obtain a JS iterator instead of a Dart one. -/// -// TODO(jmesserly): this adapter is to work around -// https://github.com/dart-lang/sdk/issues/28320 -class DartIterator implements Iterator { - final _jsIterator; - E? _current; - - DartIterator(this._jsIterator); - - E get current => _current as E; - - bool moveNext() { - final ret = JS('', '#.next()', _jsIterator); - _current = JS('', '#.value', ret); - return JS('!', '!#.done', ret); - } -} - -/// Used to compile `sync*`. -class SyncIterable extends IterableBase { - final Function() _initGenerator; - SyncIterable(this._initGenerator); - - @JSExportName('Symbol.iterator') - _jsIterator() => _initGenerator(); - - get iterator => DartIterator(_initGenerator()); -} - -class Primitives { - static int? parseInt(@nullCheck String source, int? _radix) { - var re = JS('', r'/^\s*[+-]?((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$/i'); - // TODO(jmesserly): this isn't reified List, but it's safe to use as - // long as we use it locally and don't expose it to user code. - List? match = JS('', '#.exec(#)', re, source); - int digitsIndex = 1; - int hexIndex = 2; - int decimalIndex = 3; - if (match == null) { - // TODO(sra): It might be that the match failed due to unrecognized U+0085 - // spaces. We could replace them with U+0020 spaces and try matching - // again. - return null; - } - String? decimalMatch = match[decimalIndex]; - if (_radix == null) { - if (decimalMatch != null) { - // Cannot fail because we know that the digits are all decimal. - return JS('!', r'parseInt(#, 10)', source); - } - if (match[hexIndex] != null) { - // Cannot fail because we know that the digits are all hex. - return JS('!', r'parseInt(#, 16)', source); - } - return null; - } - @notNull - var radix = _radix; - if (radix < 2 || radix > 36) { - throw RangeError.range(radix, 2, 36, 'radix'); - } - if (radix == 10 && decimalMatch != null) { - // Cannot fail because we know that the digits are all decimal. - return JS('!', r'parseInt(#, 10)', source); - } - // If radix >= 10 and we have only decimal digits the string is safe. - // Otherwise we need to check the digits. - if (radix < 10 || decimalMatch == null) { - // We know that the characters must be ASCII as otherwise the - // regexp wouldn't have matched. Lowercasing by doing `| 0x20` is thus - // guaranteed to be a safe operation, since it preserves digits - // and lower-cases ASCII letters. - int maxCharCode; - if (radix <= 10) { - // Allow all digits less than the radix. For example 0, 1, 2 for - // radix 3. - // "0".codeUnitAt(0) + radix - 1; - maxCharCode = (0x30 - 1) + radix; - } else { - // Letters are located after the digits in ASCII. Therefore we - // only check for the character code. The regexp above made already - // sure that the string does not contain anything but digits or - // letters. - // "a".codeUnitAt(0) + (radix - 10) - 1; - maxCharCode = (0x61 - 10 - 1) + radix; - } - assert(match[digitsIndex] is String); - String digitsPart = JS('!', '#[#]', match, digitsIndex); - for (int i = 0; i < digitsPart.length; i++) { - int characterCode = digitsPart.codeUnitAt(i) | 0x20; - if (characterCode > maxCharCode) { - return null; - } - } - } - // The above matching and checks ensures the source has at least one digits - // and all digits are suitable for the radix, so parseInt cannot return NaN. - return JS('!', r'parseInt(#, #)', source, radix); - } - - static double? parseDouble(@nullCheck String source) { - // Notice that JS parseFloat accepts garbage at the end of the string. - // Accept only: - // - [+/-]NaN - // - [+/-]Infinity - // - a Dart double literal - // We do allow leading or trailing whitespace. - if (!JS( - 'bool', - r'/^\s*[+-]?(?:Infinity|NaN|' - r'(?:\.\d+|\d+(?:\.\d*)?)(?:[eE][+-]?\d+)?)\s*$/.test(#)', - source)) { - return null; - } - var result = JS('!', r'parseFloat(#)', source); - if (result.isNaN) { - var trimmed = source.trim(); - if (trimmed == 'NaN' || trimmed == '+NaN' || trimmed == '-NaN') { - return result; - } - return null; - } - return result; - } - - /** `r"$".codeUnitAt(0)` */ - static const int DOLLAR_CHAR_VALUE = 36; - - static int dateNow() => JS('!', r'Date.now()'); - - static void initTicker() { - if (timerFrequency != 0) return; - // Start with low-resolution. We overwrite the fields if we find better. - timerFrequency = 1000; - if (JS('!', 'typeof window == "undefined"')) return; - var jsWindow = JS('var', 'window'); - if (jsWindow == null) return; - var performance = JS('var', '#.performance', jsWindow); - if (performance == null) return; - if (JS('!', 'typeof #.now != "function"', performance)) return; - timerFrequency = 1000000; - timerTicks = () => (1000 * JS('!', '#.now()', performance)).floor(); - } - - /// 0 frequency indicates the default uninitialized state. - static int timerFrequency = 0; - static int Function() timerTicks = dateNow; // Low-resolution version. - - static bool get isD8 { - return JS( - 'bool', - 'typeof version == "function"' - ' && typeof os == "object" && "system" in os'); - } - - static bool get isJsshell { - return JS( - 'bool', 'typeof version == "function" && typeof system == "function"'); - } - - static String currentUri() { - // In a browser return self.location.href. - if (JS('!', '!!#.location', dart.global_)) { - return JS('!', '#.location.href', dart.global_); - } - - // TODO(vsm): Consider supporting properly in non-browser settings. - return ''; - } - - // This is to avoid stack overflows due to very large argument arrays in - // apply(). It fixes http://dartbug.com/6919 - @notNull - static String _fromCharCodeApply(List array) { - const kMaxApply = 500; - @nullCheck - int end = array.length; - if (end <= kMaxApply) { - return JS('!', r'String.fromCharCode.apply(null, #)', array); - } - String result = ''; - for (int i = 0; i < end; i += kMaxApply) { - int chunkEnd = (i + kMaxApply < end) ? i + kMaxApply : end; - result = JS( - 'String', - r'# + String.fromCharCode.apply(null, #.slice(#, #))', - result, - array, - i, - chunkEnd); - } - return result; - } - - @notNull - static String stringFromCodePoints(JSArray codePoints) { - List a = []; - for (@nullCheck var i in codePoints) { - if (i <= 0xffff) { - a.add(i); - } else if (i <= 0x10ffff) { - a.add(0xd800 + ((((i - 0x10000) >> 10) & 0x3ff))); - a.add(0xdc00 + (i & 0x3ff)); - } else { - throw argumentErrorValue(i); - } - } - return _fromCharCodeApply(a); - } - - @notNull - static String stringFromCharCodes(JSArray charCodes) { - for (@nullCheck var i in charCodes) { - if (i < 0) throw argumentErrorValue(i); - if (i > 0xffff) return stringFromCodePoints(charCodes); - } - return _fromCharCodeApply(charCodes); - } - - // [start] and [end] are validated. - @notNull - static String stringFromNativeUint8List( - NativeUint8List charCodes, @nullCheck int start, @nullCheck int end) { - const kMaxApply = 500; - if (end <= kMaxApply && start == 0 && end == charCodes.length) { - return JS('!', r'String.fromCharCode.apply(null, #)', charCodes); - } - String result = ''; - for (int i = start; i < end; i += kMaxApply) { - int chunkEnd = (i + kMaxApply < end) ? i + kMaxApply : end; - result = JS( - 'String', - r'# + String.fromCharCode.apply(null, #.subarray(#, #))', - result, - charCodes, - i, - chunkEnd); - } - return result; - } - - @notNull - static String stringFromCharCode(@nullCheck int charCode) { - if (0 <= charCode) { - if (charCode <= 0xffff) { - return JS('!', 'String.fromCharCode(#)', charCode); - } - if (charCode <= 0x10ffff) { - var bits = charCode - 0x10000; - var low = 0xDC00 | (bits & 0x3ff); - var high = 0xD800 | (bits >> 10); - return JS('!', 'String.fromCharCode(#, #)', high, low); - } - } - throw RangeError.range(charCode, 0, 0x10ffff); - } - - static String stringConcatUnchecked(String string1, String string2) { - return JS_STRING_CONCAT(string1, string2); - } - - static String flattenString(String str) { - return JS('!', "#.charCodeAt(0) == 0 ? # : #", str, str, str); - } - - static String getTimeZoneName(DateTime receiver) { - // Firefox and Chrome emit the timezone in parenthesis. - // Example: "Wed May 16 2012 21:13:00 GMT+0200 (CEST)". - // We extract this name using a regexp. - var d = lazyAsJsDate(receiver); - List? match = JS('JSArray|Null', r'/\((.*)\)/.exec(#.toString())', d); - if (match != null) return match[1]; - - // Internet Explorer 10+ emits the zone name without parenthesis: - // Example: Thu Oct 31 14:07:44 PDT 2013 - match = JS( - 'JSArray|Null', - // Thu followed by a space. - r'/^[A-Z,a-z]{3}\s' - // Oct 31 followed by space. - r'[A-Z,a-z]{3}\s\d+\s' - // Time followed by a space. - r'\d{2}:\d{2}:\d{2}\s' - // The time zone name followed by a space. - r'([A-Z]{3,5})\s' - // The year. - r'\d{4}$/' - '.exec(#.toString())', - d); - if (match != null) return match[1]; - - // IE 9 and Opera don't provide the zone name. We fall back to emitting the - // UTC/GMT offset. - // Example (IE9): Wed Nov 20 09:51:00 UTC+0100 2013 - // (Opera): Wed Nov 20 2013 11:03:38 GMT+0100 - match = JS('JSArray|Null', r'/(?:GMT|UTC)[+-]\d{4}/.exec(#.toString())', d); - if (match != null) return match[0]; - return ""; - } - - static int getTimeZoneOffsetInMinutes(DateTime receiver) { - // Note that JS and Dart disagree on the sign of the offset. - return -JS('!', r'#.getTimezoneOffset()', lazyAsJsDate(receiver)); - } - - static int? valueFromDecomposedDate( - @nullCheck int years, - @nullCheck int month, - @nullCheck int day, - @nullCheck int hours, - @nullCheck int minutes, - @nullCheck int seconds, - @nullCheck int milliseconds, - @nullCheck bool isUtc) { - final int MAX_MILLISECONDS_SINCE_EPOCH = 8640000000000000; - var jsMonth = month - 1; - int value; - if (isUtc) { - value = JS('!', r'Date.UTC(#, #, #, #, #, #, #)', years, jsMonth, - day, hours, minutes, seconds, milliseconds); - } else { - value = JS('!', r'new Date(#, #, #, #, #, #, #).valueOf()', years, - jsMonth, day, hours, minutes, seconds, milliseconds); - } - if (value.isNaN || - value < -MAX_MILLISECONDS_SINCE_EPOCH || - value > MAX_MILLISECONDS_SINCE_EPOCH) { - return null; - } - if (years <= 0 || years < 100) return patchUpY2K(value, years, isUtc); - return value; - } - - static int patchUpY2K(value, years, isUtc) { - var date = JS('!', r'new Date(#)', value); - if (isUtc) { - JS('!', r'#.setUTCFullYear(#)', date, years); - } else { - JS('!', r'#.setFullYear(#)', date, years); - } - return JS('!', r'#.valueOf()', date); - } - - // Lazily keep a JS Date stored in the JS object. - static lazyAsJsDate(DateTime receiver) { - if (JS('!', r'#.date === (void 0)', receiver)) { - JS('void', r'#.date = new Date(#)', receiver, - receiver.millisecondsSinceEpoch); - } - return JS('var', r'#.date', receiver); - } - - // The getters for date and time parts below add a positive integer to ensure - // that the result is really an integer, because the JavaScript implementation - // may return -0.0 instead of 0. - - static int getYear(DateTime receiver) { - return (receiver.isUtc) - ? JS('!', r'(#.getUTCFullYear() + 0)', lazyAsJsDate(receiver)) - : JS('!', r'(#.getFullYear() + 0)', lazyAsJsDate(receiver)); - } - - static int getMonth(DateTime receiver) { - return (receiver.isUtc) - ? JS('!', r'#.getUTCMonth() + 1', lazyAsJsDate(receiver)) - : JS('!', r'#.getMonth() + 1', lazyAsJsDate(receiver)); - } - - static int getDay(DateTime receiver) { - return (receiver.isUtc) - ? JS('!', r'(#.getUTCDate() + 0)', lazyAsJsDate(receiver)) - : JS('!', r'(#.getDate() + 0)', lazyAsJsDate(receiver)); - } - - static int getHours(DateTime receiver) { - return (receiver.isUtc) - ? JS('!', r'(#.getUTCHours() + 0)', lazyAsJsDate(receiver)) - : JS('!', r'(#.getHours() + 0)', lazyAsJsDate(receiver)); - } - - static int getMinutes(DateTime receiver) { - return (receiver.isUtc) - ? JS('!', r'(#.getUTCMinutes() + 0)', lazyAsJsDate(receiver)) - : JS('!', r'(#.getMinutes() + 0)', lazyAsJsDate(receiver)); - } - - static int getSeconds(DateTime receiver) { - return (receiver.isUtc) - ? JS('!', r'(#.getUTCSeconds() + 0)', lazyAsJsDate(receiver)) - : JS('!', r'(#.getSeconds() + 0)', lazyAsJsDate(receiver)); - } - - static int getMilliseconds(DateTime receiver) { - return (receiver.isUtc) - ? JS('!', r'(#.getUTCMilliseconds() + 0)', lazyAsJsDate(receiver)) - : JS('!', r'(#.getMilliseconds() + 0)', lazyAsJsDate(receiver)); - } - - static int getWeekday(DateTime receiver) { - int weekday = (receiver.isUtc) - ? JS('!', r'#.getUTCDay() + 0', lazyAsJsDate(receiver)) - : JS('!', r'#.getDay() + 0', lazyAsJsDate(receiver)); - // Adjust by one because JS weeks start on Sunday. - return (weekday + 6) % 7 + 1; - } - - static num valueFromDateString(str) { - if (str is! String) throw argumentErrorValue(str); - num value = JS('!', r'Date.parse(#)', str); - if (value.isNaN) throw argumentErrorValue(str); - return value; - } - - static Object? getProperty(Object? object, Object key) { - if (object == null || object is bool || object is num || object is String) { - throw argumentErrorValue(object); - } - return JS('var', '#[#]', object, key); - } - - static void setProperty(object, key, value) { - if (object == null || object is bool || object is num || object is String) { - throw argumentErrorValue(object); - } - JS('void', '#[#] = #', object, key, value); - } -} - -/** - * Diagnoses an indexing error. Returns the ArgumentError or RangeError that - * describes the problem. - */ -@NoInline() -Error diagnoseIndexError(indexable, int index) { - int length = indexable.length; - // The following returns the same error that would be thrown by calling - // [RangeError.checkValidIndex] with no optional parameters provided. - if (index < 0 || index >= length) { - return RangeError.index(index, indexable, 'index', null, length); - } - // The above should always match, but if it does not, use the following. - return RangeError.value(index, 'index'); -} - -/** - * Diagnoses a range error. Returns the ArgumentError or RangeError that - * describes the problem. - */ -@NoInline() -Error diagnoseRangeError(int? start, int? end, int length) { - if (start == null) { - return ArgumentError.value(start, 'start'); - } - if (start < 0 || start > length) { - return RangeError.range(start, 0, length, 'start'); - } - if (end != null) { - if (end < start || end > length) { - return RangeError.range(end, start, length, 'end'); - } - } - // The above should always match, but if it does not, use the following. - return ArgumentError.value(end, "end"); -} - -@notNull -int stringLastIndexOfUnchecked(receiver, element, start) => - JS('!', r'#.lastIndexOf(#, #)', receiver, element, start); - -/// 'factory' for constructing ArgumentError.value to keep the call sites small. -@NoInline() -ArgumentError argumentErrorValue(object) { - return ArgumentError.value(object); -} - -void throwArgumentErrorValue(value) { - throw argumentErrorValue(value); -} - -checkInt(value) { - if (value is! int) throw argumentErrorValue(value); - return value; -} - -throwRuntimeError(message) { - throw RuntimeError(message); -} - -throwAbstractClassInstantiationError(className) { - throw AbstractClassInstantiationError(className); -} - -@NoInline() -throwConcurrentModificationError(collection) { - throw ConcurrentModificationError(collection); -} - -class JsNoSuchMethodError extends Error implements NoSuchMethodError { - final String? _message; - final String? _method; - final String? _receiver; - - JsNoSuchMethodError(this._message, match) - : _method = match == null ? null : JS('String|Null', '#.method', match), - _receiver = - match == null ? null : JS('String|Null', '#.receiver', match); - - String toString() { - if (_method == null) return 'NoSuchMethodError: $_message'; - if (_receiver == null) { - return "NoSuchMethodError: method not found: '$_method' ($_message)"; - } - return "NoSuchMethodError: " - "method not found: '$_method' on '$_receiver' ($_message)"; - } -} - -class UnknownJsTypeError extends Error { - final String _message; - - UnknownJsTypeError(this._message); - - String toString() => _message.isEmpty ? 'Error' : 'Error: $_message'; -} - -/** - * Called by generated code to build a map literal. [keyValuePairs] is - * a list of key, value, key, value, ..., etc. - */ -fillLiteralMap(keyValuePairs, Map result) { - // TODO(johnniwinther): Use JSArray to optimize this code instead of calling - // [getLength] and [getIndex]. - int index = 0; - int length = getLength(keyValuePairs); - while (index < length) { - var key = getIndex(keyValuePairs, index++); - var value = getIndex(keyValuePairs, index++); - result[key] = value; - } - return result; -} - -bool jsHasOwnProperty(jsObject, String property) { - return JS('!', r'#.hasOwnProperty(#)', jsObject, property); -} - -jsPropertyAccess(jsObject, String property) { - return JS('var', r'#[#]', jsObject, property); -} - -/** - * Called at the end of unaborted switch cases to get the singleton - * FallThroughError exception that will be thrown. - */ -getFallThroughError() => FallThroughErrorImplementation(); - -/** - * A metadata annotation describing the types instantiated by a native element. - * - * The annotation is valid on a native method and a field of a native class. - * - * By default, a field of a native class is seen as an instantiation point for - * all native classes that are a subtype of the field's type, and a native - * method is seen as an instantiation point fo all native classes that are a - * subtype of the method's return type, or the argument types of the declared - * type of the method's callback parameter. - * - * An @[Creates] annotation overrides the default set of instantiated types. If - * one or more @[Creates] annotations are present, the type of the native - * element is ignored, and the union of @[Creates] annotations is used instead. - * The names in the strings are resolved and the program will fail to compile - * with dart2js if they do not name types. - * - * The argument to [Creates] is a string. The string is parsed as the names of - * one or more types, separated by vertical bars `|`. There are some special - * names: - * - * * `=Object`. This means 'exactly Object', which is a plain JavaScript object - * with properties and none of the subtypes of Object. - * - * Example: we may know that a method always returns a specific implementation: - * - * @Creates('_NodeList') - * List getElementsByTagName(String tag) native; - * - * Useful trick: A method can be marked as not instantiating any native classes - * with the annotation `@Creates('Null')`. This is useful for fields on native - * classes that are used only in Dart code. - * - * @Creates('Null') - * var _cachedFoo; - */ -class Creates { - final String types; - const Creates(this.types); -} - -/** - * A metadata annotation describing the types returned or yielded by a native - * element. - * - * The annotation is valid on a native method and a field of a native class. - * - * By default, a native method or field is seen as returning or yielding all - * subtypes if the method return type or field type. This annotation allows a - * more precise set of types to be specified. - * - * See [Creates] for the syntax of the argument. - * - * Example: IndexedDB keys are numbers, strings and JavaScript Arrays of keys. - * - * @Returns('String|num|JSExtendableArray') - * dynamic key; - * - * // Equivalent: - * @Returns('String') @Returns('num') @Returns('JSExtendableArray') - * dynamic key; - */ -class Returns { - final String types; - const Returns(this.types); -} - -/** - * A metadata annotation placed on native methods and fields of native classes - * to specify the JavaScript name. - * - * This example declares a Dart field + getter + setter called `$dom_title` that - * corresponds to the JavaScript property `title`. - * - * class Document native "*Foo" { - * @JSName('title') - * String $dom_title; - * } - */ -class JSName { - final String name; - const JSName(this.name); -} - -/** - * Special interface recognized by the compiler and implemented by DOM - * objects that support integer indexing. This interface is not - * visible to anyone, and is only injected into special libraries. - */ -abstract class JavaScriptIndexingBehavior {} - -/// Thrown by type assertions that fail. -class TypeErrorImpl extends Error implements TypeError, CastError { - final String _message; - - TypeErrorImpl(this._message); - - String toString() => _message; -} - -/// Thrown by the 'as' operator if the cast isn't valid. -class CastErrorImpl extends Error implements CastError, TypeError { - final String _message; - - CastErrorImpl(this._message); - - String toString() => _message; -} - -class FallThroughErrorImplementation extends FallThroughError { - String toString() => "Switch case fall-through."; -} - -/** - * Error thrown when a runtime error occurs. - */ -class RuntimeError extends Error { - final message; - RuntimeError(this.message); - String toString() => "RuntimeError: $message"; -} - -/// Error thrown by DDC when an `assert()` fails (with or without a message). -class AssertionErrorImpl extends AssertionError { - final String? _fileUri; - final int? _line; - final int? _column; - final String? _conditionSource; - - AssertionErrorImpl(Object? message, - [this._fileUri, this._line, this._column, this._conditionSource]) - : super(message); - - String toString() { - var failureMessage = ""; - if (_fileUri != null && - _line != null && - _column != null && - _conditionSource != null) { - failureMessage += "$_fileUri:${_line}:${_column}\n$_conditionSource\n"; - } - failureMessage += - message != null ? Error.safeToString(message) : "is not true"; - - return "Assertion failed: $failureMessage"; - } -} - -/** - * Creates a random number with 64 bits of randomness. - * - * This will be truncated to the 53 bits available in a double. - */ -int random64() { - // TODO(lrn): Use a secure random source. - int int32a = JS("int", "(Math.random() * 0x100000000) >>> 0"); - int int32b = JS("int", "(Math.random() * 0x100000000) >>> 0"); - return int32a + int32b * 0x100000000; -} - -class BooleanConversionAssertionError extends AssertionError { - toString() => 'Failed assertion: boolean expression must not be null'; -} - -// Hook to register new global object. This is invoked from dart:html -// whenever a new window is accessed for the first time. -void registerGlobalObject(object) { - try { - if (dart.polyfill(object)) { - dart.applyAllExtensions(object); - } - } catch (e) { - // This may fail due to cross-origin errors. In that case, we shouldn't - // need to polyfill as we can't get objects from that frame. - - // TODO(vsm): Detect this more robustly - ideally before we try to polyfill. - } -} - -/// Expose browser JS classes. -void applyExtension(name, nativeObject) { - dart.applyExtension(name, nativeObject); -} - -/// Used internally by DDC to map ES6 symbols to Dart. -class PrivateSymbol implements Symbol { - // TODO(jmesserly): could also get this off the native symbol instead of - // storing it. Mirrors already does this conversion. - final String _name; - final Object _nativeSymbol; - - const PrivateSymbol(this._name, this._nativeSymbol); - - static String getName(Symbol symbol) => (symbol as PrivateSymbol)._name; - - static Object? getNativeSymbol(Symbol symbol) { - if (symbol is PrivateSymbol) return symbol._nativeSymbol; - return null; - } - - bool operator ==(other) => - other is PrivateSymbol && - _name == other._name && - identical(_nativeSymbol, other._nativeSymbol); - - get hashCode => _name.hashCode; - - // TODO(jmesserly): is this equivalent to _nativeSymbol toString? - toString() => 'Symbol("$_name")'; -} diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_number.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_number.dart deleted file mode 100644 index d2b9661247a..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_number.dart +++ /dev/null @@ -1,627 +0,0 @@ -// Copyright (c) 2012, 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. - -part of dart._interceptors; - -/** - * The implementation of Dart's int & double methods. - * These are made available as extension methods on `Number` in JS. - */ -@JsPeerInterface(name: 'Number') -class JSNumber extends Interceptor implements int, double { - const JSNumber(); - - @notNull - int compareTo(@nullCheck num b) { - if (this < b) { - return -1; - } else if (this > b) { - return 1; - } else if (this == b) { - if (this == 0) { - bool bIsNegative = b.isNegative; - if (isNegative == bIsNegative) return 0; - if (isNegative) return -1; - return 1; - } - return 0; - } else if (isNaN) { - if (b.isNaN) { - return 0; - } - return 1; - } else { - return -1; - } - } - - @notNull - bool get isNegative => (this == 0) ? (1 / this) < 0 : this < 0; - - @notNull - bool get isNaN => JS('!', r'isNaN(#)', this); - - @notNull - bool get isInfinite { - return JS('!', r'# == (1/0)', this) || - JS('!', r'# == (-1/0)', this); - } - - @notNull - bool get isFinite => JS('!', r'isFinite(#)', this); - - @notNull - JSNumber remainder(@nullCheck num b) { - return JS('!', r'# % #', this, b); - } - - @notNull - JSNumber abs() => JS('!', r'Math.abs(#)', this); - - @notNull - JSNumber get sign => (this > 0 ? 1 : this < 0 ? -1 : this) as JSNumber; - - @notNull - static const int _MIN_INT32 = -0x80000000; - @notNull - static const int _MAX_INT32 = 0x7FFFFFFF; - - @notNull - int toInt() { - if (this >= _MIN_INT32 && this <= _MAX_INT32) { - return JS('!', '# | 0', this); - } - if (JS('!', r'isFinite(#)', this)) { - return JS( - '!', r'# + 0', truncateToDouble()); // Converts -0.0 to +0.0. - } - // This is either NaN, Infinity or -Infinity. - throw UnsupportedError(JS("String", '"" + #', this)); - } - - @notNull - int truncate() => toInt(); - - @notNull - int ceil() => ceilToDouble().toInt(); - - @notNull - int floor() => floorToDouble().toInt(); - - @notNull - int round() { - if (this > 0) { - // This path excludes the special cases -0.0, NaN and -Infinity, leaving - // only +Infinity, for which a direct test is faster than [isFinite]. - if (JS('!', r'# !== (1/0)', this)) { - return JS('!', r'Math.round(#)', this); - } - } else if (JS('!', '# > (-1/0)', this)) { - // This test excludes NaN and -Infinity, leaving only -0.0. - // - // Subtraction from zero rather than negation forces -0.0 to 0.0 so code - // inside Math.round and code to handle result never sees -0.0, which on - // some JavaScript VMs can be a slow path. - return JS('!', r'0 - Math.round(0 - #)', this); - } - // This is either NaN, Infinity or -Infinity. - throw UnsupportedError(JS("String", '"" + #', this)); - } - - @notNull - double ceilToDouble() => JS('!', r'Math.ceil(#)', this); - - @notNull - double floorToDouble() => JS('!', r'Math.floor(#)', this); - - @notNull - double roundToDouble() { - if (this < 0) { - return JS('!', r'-Math.round(-#)', this); - } else { - return JS('!', r'Math.round(#)', this); - } - } - - @notNull - double truncateToDouble() => this < 0 ? ceilToDouble() : floorToDouble(); - - @notNull - num clamp(@nullCheck num lowerLimit, @nullCheck num upperLimit) { - if (lowerLimit.compareTo(upperLimit) > 0) { - throw argumentErrorValue(lowerLimit); - } - if (this.compareTo(lowerLimit) < 0) return lowerLimit; - if (this.compareTo(upperLimit) > 0) return upperLimit; - return this; - } - - @notNull - double toDouble() => this; - - @notNull - String toStringAsFixed(@notNull int fractionDigits) { - if (fractionDigits < 0 || fractionDigits > 20) { - throw RangeError.range(fractionDigits, 0, 20, "fractionDigits"); - } - String result = JS('!', r'#.toFixed(#)', this, fractionDigits); - if (this == 0 && isNegative) return "-$result"; - return result; - } - - @notNull - String toStringAsExponential([int? fractionDigits]) { - String result; - if (fractionDigits != null) { - @notNull - var _fractionDigits = fractionDigits; - if (_fractionDigits < 0 || _fractionDigits > 20) { - throw RangeError.range(_fractionDigits, 0, 20, "fractionDigits"); - } - result = JS('!', r'#.toExponential(#)', this, _fractionDigits); - } else { - result = JS('!', r'#.toExponential()', this); - } - if (this == 0 && isNegative) return "-$result"; - return result; - } - - @notNull - String toStringAsPrecision(@nullCheck int precision) { - if (precision < 1 || precision > 21) { - throw RangeError.range(precision, 1, 21, "precision"); - } - String result = JS('!', r'#.toPrecision(#)', this, precision); - if (this == 0 && isNegative) return "-$result"; - return result; - } - - @notNull - String toRadixString(@nullCheck int radix) { - if (radix < 2 || radix > 36) { - throw RangeError.range(radix, 2, 36, "radix"); - } - String result = JS('!', r'#.toString(#)', this, radix); - const int rightParenCode = 0x29; - if (result.codeUnitAt(result.length - 1) != rightParenCode) { - return result; - } - return _handleIEtoString(result); - } - - @notNull - static String _handleIEtoString(String result) { - // Result is probably IE's untraditional format for large numbers, - // e.g., "8.0000000000008(e+15)" for 0x8000000000000800.toString(16). - var match = JS( - '', r'/^([\da-z]+)(?:\.([\da-z]+))?\(e\+(\d+)\)$/.exec(#)', result); - if (match == null) { - // Then we don't know how to handle it at all. - throw UnsupportedError("Unexpected toString result: $result"); - } - result = JS('!', '#', match[1]); - int exponent = JS("!", "+#", match[3]); - if (match[2] != null) { - result = JS('!', '# + #', result, match[2]); - exponent -= JS('!', '#.length', match[2]); - } - return result + "0" * exponent; - } - - // Note: if you change this, also change the function [S]. - @notNull - String toString() { - if (this == 0 && JS('!', '(1 / #) < 0', this)) { - return '-0.0'; - } else { - return JS('!', r'"" + (#)', this); - } - } - - @notNull - int get hashCode { - int intValue = JS('!', '# | 0', this); - // Fast exit for integers in signed 32-bit range. Masking converts -0.0 to 0 - // and ensures that result fits in JavaScript engine's Smi range. - if (this == intValue) return 0x1FFFFFFF & intValue; - - // We would like to access the exponent and mantissa as integers but there - // are no JavaScript operations that do this, so use log2-floor-pow-divide - // to extract the values. - num absolute = JS('!', 'Math.abs(#)', this); - num lnAbsolute = JS('!', 'Math.log(#)', absolute); - num log2 = lnAbsolute / ln2; - // Floor via '# | 0' converts NaN to zero so the final result is not NaN. - int floorLog2 = JS('!', '# | 0', log2); - num factor = JS('!', 'Math.pow(2, #)', floorLog2); - num scaled = absolute < 1 ? absolute / factor : factor / absolute; - // [scaled] is in the range [0.5, 1]. - - // Multiply and truncate to pick up all the mantissa bits. Multiplying by - // 0x20000000000000 (which has 53 zero bits) converts the mantissa into an - // integer. There are interesting subsets where all the bit variance is in - // the most significant bits of the mantissa (e.g. 0.5, 0.625, 0.75), so we - // need to mix in the most significant bits. We do this by scaling with a - // constant that has many bits set to use the multiplier to mix in bits from - // all over the mantissa into low positions. - num rescaled1 = scaled * 0x20000000000000; - num rescaled2 = scaled * 0x0C95A6C285A6C9; - int d1 = JS('!', '# | 0', rescaled1); - int d2 = JS('!', '# | 0', rescaled2); - // Mix in exponent to distinguish e.g. 1.25 from 2.5. - int d3 = floorLog2; - int h = 0x1FFFFFFF & ((d1 + d2) * (601 * 997) + d3 * (1259)); - return h; - } - - @notNull - JSNumber operator -() => JS('!', r'-#', this); - - @notNull - JSNumber operator +(@nullCheck num other) { - return JS('!', '# + #', this, other); - } - - @notNull - JSNumber operator -(@nullCheck num other) { - return JS('!', '# - #', this, other); - } - - @notNull - double operator /(@nullCheck num other) { - return JS('!', '# / #', this, other); - } - - @notNull - JSNumber operator *(@nullCheck num other) { - return JS('!', '# * #', this, other); - } - - @notNull - JSNumber operator %(@nullCheck num other) { - // Euclidean Modulo. - JSNumber result = JS('!', r'# % #', this, other); - if (result == 0) return (0 as JSNumber); // Make sure we don't return -0.0. - if (result > 0) return result; - if (JS('!', '#', other) < 0) { - return result - JS('!', '#', other); - } else { - return result + JS('!', '#', other); - } - } - - @notNull - bool _isInt32(@notNull num value) => - JS('!', '(# | 0) === #', value, value); - - @notNull - int operator ~/(@nullCheck num other) { - if (_isInt32(this) && _isInt32(other) && 0 != other && -1 != other) { - return JS('!', r'(# / #) | 0', this, other); - } else { - return _tdivSlow(other); - } - } - - @notNull - int _tdivSlow(num other) { - return JS('!', r'# / #', this, other).toInt(); - } - - // TODO(ngeoffray): Move the bit operations below to [JSInt] and - // make them take an int. Because this will make operations slower, - // we define these methods on number for now but we need to decide - // the grain at which we do the type checks. - - @notNull - int operator <<(@nullCheck num other) { - if (other < 0) throwArgumentErrorValue(other); - return _shlPositive(other); - } - - @notNull - int _shlPositive(@notNull num other) { - // JavaScript only looks at the last 5 bits of the shift-amount. Shifting - // by 33 is hence equivalent to a shift by 1. - return JS('!', r'# > 31', other) - ? 0 - : JS('!', r'(# << #) >>> 0', this, other); - } - - @notNull - int operator >>(@nullCheck num other) { - if (JS('!', '#', other) < 0) throwArgumentErrorValue(other); - return _shrOtherPositive(other); - } - - @notNull - int _shrOtherPositive(@notNull num other) { - return JS('!', '#', this) > 0 - ? _shrBothPositive(other) - // For negative numbers we just clamp the shift-by amount. - // `this` could be negative but not have its 31st bit set. - // The ">>" would then shift in 0s instead of 1s. Therefore - // we cannot simply return 0xFFFFFFFF. - : JS('!', r'(# >> #) >>> 0', this, other > 31 ? 31 : other); - } - - @notNull - int _shrBothPositive(@notNull num other) { - return JS('!', r'# > 31', other) - // JavaScript only looks at the last 5 bits of the shift-amount. In JS - // shifting by 33 is hence equivalent to a shift by 1. Shortcut the - // computation when that happens. - ? 0 - // Given that `this` is positive we must not use '>>'. Otherwise a - // number that has the 31st bit set would be treated as negative and - // shift in ones. - : JS('!', r'# >>> #', this, other); - } - - @notNull - int operator &(@nullCheck num other) { - return JS('!', r'(# & #) >>> 0', this, other); - } - - @notNull - int operator |(@nullCheck num other) { - return JS('!', r'(# | #) >>> 0', this, other); - } - - @notNull - int operator ^(@nullCheck num other) { - return JS('!', r'(# ^ #) >>> 0', this, other); - } - - @notNull - bool operator <(@nullCheck num other) { - return JS('!', '# < #', this, other); - } - - @notNull - bool operator >(@nullCheck num other) { - return JS('!', '# > #', this, other); - } - - @notNull - bool operator <=(@nullCheck num other) { - return JS('!', '# <= #', this, other); - } - - @notNull - bool operator >=(@nullCheck num other) { - return JS('!', '# >= #', this, other); - } - - // int members. - // TODO(jmesserly): all numbers will have these in dynamic dispatch. - // We can fix by checking it at dispatch time but we'd need to structure them - // differently. - - @notNull - bool get isEven => (this & 1) == 0; - - @notNull - bool get isOdd => (this & 1) == 1; - - @notNull - int toUnsigned(@nullCheck int width) { - return this & ((1 << width) - 1); - } - - @notNull - int toSigned(@nullCheck int width) { - int signMask = 1 << (width - 1); - return (this & (signMask - 1)) - (this & signMask); - } - - @notNull - int get bitLength { - int nonneg = this < 0 ? -this - 1 : this; - int wordBits = 32; - while (nonneg >= 0x100000000) { - nonneg = nonneg ~/ 0x100000000; - wordBits += 32; - } - return wordBits - _clz32(nonneg); - } - - @notNull - static int _clz32(@notNull int uint32) { - // TODO(sra): Use `Math.clz32(uint32)` (not available on IE11). - return 32 - _bitCount(_spread(uint32)); - } - - // Returns pow(this, e) % m. - @notNull - int modPow(@nullCheck int e, @nullCheck int m) { - if (e < 0) throw RangeError.range(e, 0, null, "exponent"); - if (m <= 0) throw RangeError.range(m, 1, null, "modulus"); - if (e == 0) return 1; - - const int maxPreciseInteger = 9007199254740991; - - // Reject inputs that are outside the range of integer values that can be - // represented precisely as a Number (double). - if (this < -maxPreciseInteger || this > maxPreciseInteger) { - throw RangeError.range( - this, -maxPreciseInteger, maxPreciseInteger, 'receiver'); - } - if (e > maxPreciseInteger) { - throw RangeError.range(e, 0, maxPreciseInteger, 'exponent'); - } - if (m > maxPreciseInteger) { - throw RangeError.range(e, 1, maxPreciseInteger, 'modulus'); - } - - // This is floor(sqrt(maxPreciseInteger)). - const int maxValueThatCanBeSquaredWithoutTruncation = 94906265; - if (m > maxValueThatCanBeSquaredWithoutTruncation) { - // Use BigInt version to avoid truncation in multiplications below. The - // 'maxPreciseInteger' check on [m] ensures that toInt() does not round. - return BigInt.from(this).modPow(BigInt.from(e), BigInt.from(m)).toInt(); - } - - int b = this; - if (b < 0 || b > m) { - b %= m; - } - int r = 1; - while (e > 0) { - if (e.isOdd) { - r = (r * b) % m; - } - e ~/= 2; - b = (b * b) % m; - } - return r; - } - - // If inv is false, returns gcd(x, y). - // If inv is true and gcd(x, y) = 1, returns d, so that c*x + d*y = 1. - // If inv is true and gcd(x, y) != 1, throws Exception("Not coprime"). - @notNull - static int _binaryGcd(@notNull int x, @notNull int y, @notNull bool inv) { - int s = 1; - if (!inv) { - while (x.isEven && y.isEven) { - x ~/= 2; - y ~/= 2; - s *= 2; - } - if (y.isOdd) { - var t = x; - x = y; - y = t; - } - } - final bool ac = x.isEven; - int u = x; - int v = y; - int a = 1, b = 0, c = 0, d = 1; - do { - while (u.isEven) { - u ~/= 2; - if (ac) { - if (!a.isEven || !b.isEven) { - a += y; - b -= x; - } - a ~/= 2; - } else if (!b.isEven) { - b -= x; - } - b ~/= 2; - } - while (v.isEven) { - v ~/= 2; - if (ac) { - if (!c.isEven || !d.isEven) { - c += y; - d -= x; - } - c ~/= 2; - } else if (!d.isEven) { - d -= x; - } - d ~/= 2; - } - if (u >= v) { - u -= v; - if (ac) a -= c; - b -= d; - } else { - v -= u; - if (ac) c -= a; - d -= b; - } - } while (u != 0); - if (!inv) return s * v; - if (v != 1) throw Exception("Not coprime"); - if (d < 0) { - d += x; - if (d < 0) d += x; - } else if (d > x) { - d -= x; - if (d > x) d -= x; - } - return d; - } - - // Returns 1/this % m, with m > 0. - @notNull - int modInverse(@nullCheck int m) { - if (m <= 0) throw RangeError.range(m, 1, null, "modulus"); - if (m == 1) return 0; - int t = this; - if ((t < 0) || (t >= m)) t %= m; - if (t == 1) return 1; - if ((t == 0) || (t.isEven && m.isEven)) { - throw Exception("Not coprime"); - } - return _binaryGcd(m, t, true); - } - - // Returns gcd of abs(this) and abs(other). - @notNull - int gcd(@nullCheck int other) { - int x = this.abs(); - int y = other.abs(); - if (x == 0) return y; - if (y == 0) return x; - if ((x == 1) || (y == 1)) return 1; - return _binaryGcd(x, y, false); - } - - // Assumes i is <= 32-bit and unsigned. - @notNull - static int _bitCount(@notNull int i) { - // See "Hacker's Delight", section 5-1, "Counting 1-Bits". - - // The basic strategy is to use "divide and conquer" to - // add pairs (then quads, etc.) of bits together to obtain - // sub-counts. - // - // A straightforward approach would look like: - // - // i = (i & 0x55555555) + ((i >> 1) & 0x55555555); - // i = (i & 0x33333333) + ((i >> 2) & 0x33333333); - // i = (i & 0x0F0F0F0F) + ((i >> 4) & 0x0F0F0F0F); - // i = (i & 0x00FF00FF) + ((i >> 8) & 0x00FF00FF); - // i = (i & 0x0000FFFF) + ((i >> 16) & 0x0000FFFF); - // - // The code below removes unnecessary &'s and uses a - // trick to remove one instruction in the first line. - - i = _shru(i, 0) - (_shru(i, 1) & 0x55555555); - i = (i & 0x33333333) + (_shru(i, 2) & 0x33333333); - i = 0x0F0F0F0F & (i + _shru(i, 4)); - i += _shru(i, 8); - i += _shru(i, 16); - return (i & 0x0000003F); - } - - @notNull - static int _shru(int value, int shift) => - JS('!', '# >>> #', value, shift); - @notNull - static int _shrs(int value, int shift) => - JS('!', '# >> #', value, shift); - @notNull - static int _ors(int a, int b) => JS('!', '# | #', a, b); - - // Assumes i is <= 32-bit - @notNull - static int _spread(@notNull int i) { - i = _ors(i, _shrs(i, 1)); - i = _ors(i, _shrs(i, 2)); - i = _ors(i, _shrs(i, 4)); - i = _ors(i, _shrs(i, 8)); - i = _shru(_ors(i, _shrs(i, 16)), 0); - return i; - } - - @notNull - int operator ~() => JS('!', r'(~#) >>> 0', this); -} diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_primitives.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_primitives.dart deleted file mode 100644 index 1347b621ffe..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_primitives.dart +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) 2013, 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. - -/// dart2js "primitives", that is, features that cannot be implemented without -/// access to JavaScript features. -library dart2js._js_primitives; - -import 'dart:_foreign_helper' show JS; - -/** - * This is the low-level method that is used to implement [print]. It is - * possible to override this function from JavaScript by defining a function in - * JavaScript called "dartPrint". - * - * Notice that it is also possible to intercept calls to [print] from within a - * Dart program using zones. This means that there is no guarantee that a call - * to print ends in this method. - */ -void printString(String string) { - if (JS('!', r'typeof dartPrint == "function"')) { - // Support overriding print from JavaScript. - JS('void', r'dartPrint(#)', string); - return; - } - - // Inside browser or nodejs. - if (JS('!', r'typeof console == "object"') && - JS('!', r'typeof console.log != "undefined"')) { - JS('void', r'console.log(#)', string); - return; - } - - // Don't throw inside IE, the console is only defined if dev tools is open. - if (JS('!', r'typeof window == "object"')) { - return; - } - - // Running in d8, the V8 developer shell, or in Firefox' js-shell. - if (JS('!', r'typeof print == "function"')) { - JS('void', r'print(#)', string); - return; - } - - // This is somewhat nasty, but we don't want to drag in a bunch of - // dependencies to handle a situation that cannot happen. So we - // avoid using Dart [:throw:] and Dart [toString]. - JS('void', 'throw "Unable to print message: " + String(#)', string); -} diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_rti.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_rti.dart deleted file mode 100644 index 483e721d286..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_rti.dart +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2013, 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. - -part of dart._js_helper; - -// TODO(leafp): Maybe get rid of this? Currently used by the interceptors -// library, but that should probably be culled as well. -Type? getRuntimeType(object) => - JS('Type|null', 'dart.getReifiedType(#)', object); - -/// Returns the property [index] of the JavaScript array [array]. -getIndex(array, int index) { - assert(isJsArray(array)); - return JS('var', r'#[#]', array, index); -} - -/// Returns the length of the JavaScript array [array]. -int getLength(array) { - assert(isJsArray(array)); - return JS('!', r'#.length', array); -} - -/// Returns whether [value] is a JavaScript array. -bool isJsArray(value) { - return value is JSArray; -} diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_string.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_string.dart deleted file mode 100644 index 2987812ee4e..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_string.dart +++ /dev/null @@ -1,507 +0,0 @@ -// Copyright (c) 2012, 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. - -part of dart._interceptors; - -/** - * The interceptor class for [String]. The compiler recognizes this - * class as an interceptor, and changes references to [:this:] to - * actually use the receiver of the method, which is generated as an extra - * argument added to each member. - */ -@JsPeerInterface(name: 'String') -class JSString extends Interceptor implements String, JSIndexable { - const JSString(); - - @notNull - int codeUnitAt(@nullCheck int index) { - // Suppress 2nd null check on index and null check on length - // (JS String.length cannot be null). - final len = this.length; - if (index < 0 || index >= len) { - throw RangeError.index(index, this, 'index', null, len); - } - return JS('!', r'#.charCodeAt(#)', this, index); - } - - @notNull - Iterable allMatches(@nullCheck String string, - [@nullCheck int start = 0]) { - final len = string.length; - if (0 > start || start > len) { - throw RangeError.range(start, 0, len); - } - return allMatchesInStringUnchecked(this, string, start); - } - - Match? matchAsPrefix(@nullCheck String string, [@nullCheck int start = 0]) { - int stringLength = JS('!', '#.length', string); - if (start < 0 || start > stringLength) { - throw RangeError.range(start, 0, stringLength); - } - int thisLength = JS('!', '#.length', this); - if (start + thisLength > stringLength) return null; - for (int i = 0; i < thisLength; i++) { - if (string.codeUnitAt(start + i) != this.codeUnitAt(i)) { - return null; - } - } - return StringMatch(start, string, this); - } - - @notNull - String operator +(@nullCheck String other) { - return JS('!', r'# + #', this, other); - } - - @notNull - bool endsWith(@nullCheck String other) { - var otherLength = other.length; - var thisLength = this.length; - if (otherLength > thisLength) return false; - return other == substring(thisLength - otherLength); - } - - @notNull - String replaceAll(Pattern from, @nullCheck String to) { - return stringReplaceAllUnchecked(this, from, to); - } - - @notNull - String replaceAllMapped(Pattern from, String Function(Match) convert) { - return this.splitMapJoin(from, onMatch: convert); - } - - @notNull - String splitMapJoin(Pattern from, - {String Function(Match)? onMatch, String Function(String)? onNonMatch}) { - return stringReplaceAllFuncUnchecked(this, from, onMatch, onNonMatch); - } - - @notNull - String replaceFirst(Pattern from, @nullCheck String to, - [@nullCheck int startIndex = 0]) { - RangeError.checkValueInInterval(startIndex, 0, this.length, "startIndex"); - return stringReplaceFirstUnchecked(this, from, to, startIndex); - } - - @notNull - String replaceFirstMapped( - Pattern from, @nullCheck String replace(Match match), - [@nullCheck int startIndex = 0]) { - RangeError.checkValueInInterval(startIndex, 0, this.length, "startIndex"); - return stringReplaceFirstMappedUnchecked(this, from, replace, startIndex); - } - - @notNull - List split(@nullCheck Pattern pattern) { - if (pattern is String) { - return JSArray.of(JS('', r'#.split(#)', this, pattern)); - } else if (pattern is JSSyntaxRegExp && regExpCaptureCount(pattern) == 0) { - var re = regExpGetNative(pattern); - return JSArray.of(JS('', r'#.split(#)', this, re)); - } else { - return _defaultSplit(pattern); - } - } - - @notNull - String replaceRange( - @nullCheck int start, int? end, @nullCheck String replacement) { - var e = RangeError.checkValidRange(start, end, this.length); - return stringReplaceRangeUnchecked(this, start, e, replacement); - } - - @notNull - List _defaultSplit(Pattern pattern) { - List result = []; - // End of most recent match. That is, start of next part to add to result. - int start = 0; - // Length of most recent match. - // Set >0, so no match on the empty string causes the result to be [""]. - int length = 1; - for (var match in pattern.allMatches(this)) { - @notNull - int matchStart = match.start; - @notNull - int matchEnd = match.end; - length = matchEnd - matchStart; - if (length == 0 && start == matchStart) { - // An empty match right after another match is ignored. - // This includes an empty match at the start of the string. - continue; - } - int end = matchStart; - result.add(this.substring(start, end)); - start = matchEnd; - } - if (start < this.length || length > 0) { - // An empty match at the end of the string does not cause a "" at the end. - // A non-empty match ending at the end of the string does add a "". - result.add(this.substring(start)); - } - return result; - } - - @notNull - bool startsWith(Pattern pattern, [@nullCheck int index = 0]) { - // Suppress null check on length and all but the first - // reference to index. - int length = JS('!', '#.length', this); - if (index < 0 || JS('!', '#', index) > length) { - throw RangeError.range(index, 0, this.length); - } - if (pattern is String) { - String other = pattern; - int otherLength = JS('!', '#.length', other); - int endIndex = index + otherLength; - if (endIndex > length) return false; - return other == - JS('!', r'#.substring(#, #)', this, index, endIndex); - } - return pattern.matchAsPrefix(this, index) != null; - } - - @notNull - String substring(@nullCheck int startIndex, [int? _endIndex]) { - var length = this.length; - final endIndex = _endIndex ?? length; - if (startIndex < 0) throw RangeError.value(startIndex); - if (startIndex > endIndex) throw RangeError.value(startIndex); - if (endIndex > length) throw RangeError.value(endIndex); - return JS('!', r'#.substring(#, #)', this, startIndex, endIndex); - } - - @notNull - String toLowerCase() { - return JS('!', r'#.toLowerCase()', this); - } - - @notNull - String toUpperCase() { - return JS('!', r'#.toUpperCase()', this); - } - - // Characters with Whitespace property (Unicode 6.3). - // 0009..000D ; White_Space # Cc .. - // 0020 ; White_Space # Zs SPACE - // 0085 ; White_Space # Cc - // 00A0 ; White_Space # Zs NO-BREAK SPACE - // 1680 ; White_Space # Zs OGHAM SPACE MARK - // 2000..200A ; White_Space # Zs EN QUAD..HAIR SPACE - // 2028 ; White_Space # Zl LINE SEPARATOR - // 2029 ; White_Space # Zp PARAGRAPH SEPARATOR - // 202F ; White_Space # Zs NARROW NO-BREAK SPACE - // 205F ; White_Space # Zs MEDIUM MATHEMATICAL SPACE - // 3000 ; White_Space # Zs IDEOGRAPHIC SPACE - // - // BOM: 0xFEFF - @notNull - static bool _isWhitespace(@notNull int codeUnit) { - // Most codeUnits should be less than 256. Special case with a smaller - // switch. - if (codeUnit < 256) { - switch (codeUnit) { - case 0x09: - case 0x0A: - case 0x0B: - case 0x0C: - case 0x0D: - case 0x20: - case 0x85: - case 0xA0: - return true; - default: - return false; - } - } - switch (codeUnit) { - case 0x1680: - case 0x2000: - case 0x2001: - case 0x2002: - case 0x2003: - case 0x2004: - case 0x2005: - case 0x2006: - case 0x2007: - case 0x2008: - case 0x2009: - case 0x200A: - case 0x2028: - case 0x2029: - case 0x202F: - case 0x205F: - case 0x3000: - case 0xFEFF: - return true; - default: - return false; - } - } - - /// Finds the index of the first non-whitespace character, or the - /// end of the string. Start looking at position [index]. - @notNull - static int _skipLeadingWhitespace(String string, @nullCheck int index) { - const int SPACE = 0x20; - const int CARRIAGE_RETURN = 0x0D; - var stringLength = string.length; - while (index < stringLength) { - int codeUnit = string.codeUnitAt(index); - if (codeUnit != SPACE && - codeUnit != CARRIAGE_RETURN && - !_isWhitespace(codeUnit)) { - break; - } - index++; - } - return index; - } - - /// Finds the index after the last non-whitespace character, or 0. - /// Start looking at position [index - 1]. - @notNull - static int _skipTrailingWhitespace(String string, @nullCheck int index) { - const int SPACE = 0x20; - const int CARRIAGE_RETURN = 0x0D; - while (index > 0) { - int codeUnit = string.codeUnitAt(index - 1); - if (codeUnit != SPACE && - codeUnit != CARRIAGE_RETURN && - !_isWhitespace(codeUnit)) { - break; - } - index--; - } - return index; - } - - // Dart2js can't use JavaScript trim directly, - // because JavaScript does not trim - // the NEXT LINE (NEL) character (0x85). - @notNull - String trim() { - const int NEL = 0x85; - - // Start by doing JS trim. Then check if it leaves a NEL at - // either end of the string. - String result = JS('!', '#.trim()', this); - final length = result.length; - if (length == 0) return result; - int firstCode = result.codeUnitAt(0); - int startIndex = 0; - if (firstCode == NEL) { - startIndex = _skipLeadingWhitespace(result, 1); - if (startIndex == length) return ""; - } - - int endIndex = length; - // We know that there is at least one character that is non-whitespace. - // Therefore we don't need to verify that endIndex > startIndex. - int lastCode = result.codeUnitAt(endIndex - 1); - if (lastCode == NEL) { - endIndex = _skipTrailingWhitespace(result, endIndex - 1); - } - if (startIndex == 0 && endIndex == length) return result; - return JS('!', r'#.substring(#, #)', result, startIndex, endIndex); - } - - // Dart2js can't use JavaScript trimLeft directly, - // because it is not in ES5, so not every browser implements it, - // and because those that do will not trim the NEXT LINE character (0x85). - @notNull - String trimLeft() { - const int NEL = 0x85; - - // Start by doing JS trim. Then check if it leaves a NEL at - // the beginning of the string. - String result; - int startIndex = 0; - if (JS('!', 'typeof #.trimLeft != "undefined"', this)) { - result = JS('!', '#.trimLeft()', this); - if (result.length == 0) return result; - int firstCode = result.codeUnitAt(0); - if (firstCode == NEL) { - startIndex = _skipLeadingWhitespace(result, 1); - } - } else { - result = this; - startIndex = _skipLeadingWhitespace(this, 0); - } - if (startIndex == 0) return result; - if (startIndex == result.length) return ""; - return JS('!', r'#.substring(#)', result, startIndex); - } - - // Dart2js can't use JavaScript trimRight directly, - // because it is not in ES5 and because JavaScript does not trim - // the NEXT LINE character (0x85). - @notNull - String trimRight() { - const int NEL = 0x85; - - // Start by doing JS trim. Then check if it leaves a NEL or BOM at - // the end of the string. - String result; - @notNull - int endIndex = 0; - // trimRight is implemented by Firefox and Chrome/Blink, - // so use it if it is there. - if (JS('!', 'typeof #.trimRight != "undefined"', this)) { - result = JS('!', '#.trimRight()', this); - endIndex = result.length; - if (endIndex == 0) return result; - int lastCode = result.codeUnitAt(endIndex - 1); - if (lastCode == NEL) { - endIndex = _skipTrailingWhitespace(result, endIndex - 1); - } - } else { - result = this; - endIndex = _skipTrailingWhitespace(this, this.length); - } - - if (endIndex == result.length) return result; - if (endIndex == 0) return ""; - return JS('!', r'#.substring(#, #)', result, 0, endIndex); - } - - @notNull - String operator *(@nullCheck int times) { - if (0 >= times) return ''; - if (times == 1 || this.length == 0) return this; - if (times != JS('!', '# >>> 0', times)) { - // times >= 2^32. We can't create a string that big. - throw const OutOfMemoryError(); - } - var result = ''; - String s = this; - while (true) { - if (times & 1 == 1) result = s + result; - times = JS('!', '# >>> 1', times); - if (times == 0) break; - s += s; - } - return result; - } - - @notNull - String padLeft(@nullCheck int width, [String padding = ' ']) { - int delta = width - this.length; - if (delta <= 0) return this; - return padding * delta + this; - } - - @notNull - String padRight(@nullCheck int width, [String padding = ' ']) { - int delta = width - this.length; - if (delta <= 0) return this; - return this + padding * delta; - } - - @notNull - List get codeUnits => CodeUnits(this); - - @notNull - Runes get runes => Runes(this); - - @notNull - int indexOf(@nullCheck Pattern pattern, [@nullCheck int start = 0]) { - if (start < 0 || start > this.length) { - throw RangeError.range(start, 0, this.length); - } - if (pattern is String) { - return stringIndexOfStringUnchecked(this, pattern, start); - } - if (pattern is JSSyntaxRegExp) { - JSSyntaxRegExp re = pattern; - Match? match = firstMatchAfter(re, this, start); - return (match == null) ? -1 : match.start; - } - var length = this.length; - for (int i = start; i <= length; i++) { - if (pattern.matchAsPrefix(this, i) != null) return i; - } - return -1; - } - - @notNull - int lastIndexOf(@nullCheck Pattern pattern, [int? _start]) { - var length = this.length; - var start = _start ?? length; - if (start < 0 || start > length) { - throw RangeError.range(start, 0, length); - } - if (pattern is String) { - String other = pattern; - if (start + other.length > length) { - start = length - other.length; - } - return stringLastIndexOfUnchecked(this, other, start); - } - for (int i = start; i >= 0; i--) { - if (pattern.matchAsPrefix(this, i) != null) return i; - } - return -1; - } - - @notNull - bool contains(@nullCheck Pattern other, [@nullCheck int startIndex = 0]) { - if (startIndex < 0 || startIndex > this.length) { - throw RangeError.range(startIndex, 0, this.length); - } - return stringContainsUnchecked(this, other, startIndex); - } - - @notNull - bool get isEmpty => JS('!', '#.length', this) == 0; - - @notNull - bool get isNotEmpty => !isEmpty; - - @notNull - int compareTo(@nullCheck String other) { - return this == other ? 0 : JS('!', r'# < #', this, other) ? -1 : 1; - } - - // Note: if you change this, also change the function [S]. - @notNull - String toString() => this; - - /** - * This is the [Jenkins hash function][1] but using masking to keep - * values in SMI range. - * - * [1]: http://en.wikipedia.org/wiki/Jenkins_hash_function - */ - @notNull - int get hashCode { - // TODO(ahe): This method shouldn't have to use JS. Update when our - // optimizations are smarter. - int hash = 0; - int length = JS('!', '#.length', this); - for (int i = 0; i < length; i++) { - hash = 0x1fffffff & (hash + JS('!', r'#.charCodeAt(#)', this, i)); - hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10)); - hash = JS('!', '# ^ (# >> 6)', hash, hash); - } - hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3)); - hash = JS('!', '# ^ (# >> 11)', hash, hash); - return 0x1fffffff & (hash + ((0x00003fff & hash) << 15)); - } - - @notNull - Type get runtimeType => String; - - @notNull - int get length native; - - @notNull - String operator [](@nullCheck int index) { - if (index >= JS('!', '#.length', this) || index < 0) { - throw diagnoseIndexError(this, index); - } - return JS('!', '#[#]', this, index); - } -} diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/linked_hash_map.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/linked_hash_map.dart deleted file mode 100644 index f797ea49566..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/linked_hash_map.dart +++ /dev/null @@ -1,275 +0,0 @@ -// Copyright (c) 2017, 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. - -// Efficient JavaScript based implementation of a linked hash map used as a -// backing map for constant maps and the [LinkedHashMap] patch - -part of dart._js_helper; - -abstract class InternalMap extends MapBase - implements LinkedHashMap, HashMap { - @notNull - get _map; - - @notNull - int get _modifications; - - void forEach(void action(K key, V value)) { - int modifications = _modifications; - for (var entry in JS('Iterable', '#.entries()', _map)) { - action(JS('', '#[0]', entry), JS('', '#[1]', entry)); - if (modifications != _modifications) { - throw ConcurrentModificationError(this); - } - } - } -} - -/// A linked hash map implementation based on ES6 Map. -/// -/// Items that can use identity semantics are stored directly in the backing -/// map. -/// -/// Items that have a custom equality/hashCode are first canonicalized by -/// looking up the canonical key by its hashCode. -class LinkedMap extends InternalMap { - /// The backing store for this map. - /// - /// Keys that use identity equality are stored directly. For other types of - /// keys, we first look them up (by hashCode) in the [_keyMap] map, then - /// we lookup the key in this map. - @notNull - final _map = JS('', 'new Map()'); - - /// Items that use custom equality semantics. - /// - /// This maps from the item's hashCode to the canonical key, which is then - /// used to lookup the item in [_map]. Keeping the data in our primary backing - /// map gives us the ordering semantics requred by [LinkedHashMap], while - /// also providing convenient access to keys/values. - @notNull - final _keyMap = JS('', 'new Map()'); - - // We track the number of modifications done to the key set of the - // hash map to be able to throw when the map is modified while being - // iterated over. - // - // Value cycles after 2^30 modifications so that modification counts are - // always unboxed (Smi) values. Modification detection will be missed if you - // make exactly some multiple of 2^30 modifications between advances of an - // iterator. - @notNull - int _modifications = 0; - - LinkedMap(); - - /// Called by generated code for a map literal. - LinkedMap.from(JSArray entries) { - var map = _map; - var keyMap = _keyMap; - for (int i = 0, n = JS('!', '#.length', entries); i < n; i += 2) { - K key = JS('', '#[#]', entries, i); - V value = JS('', '#[#]', entries, i + 1); - if (key == null) { - key = JS('', 'null'); - } else if (JS('!', '#[#] !== #', key, - dart.extensionSymbol('_equals'), dart.identityEquals)) { - key = putLinkedMapKey(key, keyMap); - } - JS('', '#.set(#, #)', map, key, value); - } - } - - @notNull - int get length => JS('!', '#.size', _map); - - @notNull - bool get isEmpty => JS('!', '#.size == 0', _map); - - @notNull - bool get isNotEmpty => JS('!', '#.size != 0', _map); - - Iterable get keys => _JSMapIterable(this, true); - Iterable get values => _JSMapIterable(this, false); - - @notNull - bool containsKey(Object? key) { - if (key == null) { - key = JS('', 'null'); - } else if (JS('!', '#[#] !== #', key, dart.extensionSymbol('_equals'), - dart.identityEquals)) { - var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, key.hashCode); - if (buckets != null) { - for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) { - K k = JS('', '#[#]', buckets, i); - if (k == key) return true; - } - } - return false; - } - return JS('!', '#.has(#)', _map, key); - } - - bool containsValue(Object? value) { - for (var v in JS('', '#.values()', _map)) { - if (v == value) return true; - } - return false; - } - - void addAll(Map other) { - var map = _map; - int length = JS('', '#.size', map); - other.forEach((K key, V value) { - if (key == null) { - key = JS('', 'null'); - } else if (JS('!', '#[#] !== #', key, - dart.extensionSymbol('_equals'), dart.identityEquals)) { - key = putLinkedMapKey(key, _keyMap); - } - JS('', '#.set(#, #)', _map, key, value); - }); - if (length != JS('!', '#.size', map)) { - _modifications = (_modifications + 1) & 0x3ffffff; - } - } - - V? operator [](Object? key) { - if (key == null) { - key = JS('', 'null'); - } else if (JS('!', '#[#] !== #', key, dart.extensionSymbol('_equals'), - dart.identityEquals)) { - var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, key.hashCode); - if (buckets != null) { - for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) { - K k = JS('', '#[#]', buckets, i); - if (k == key) return JS('', '#.get(#)', _map, k); - } - } - return null; - } - V value = JS('', '#.get(#)', _map, key); - return value == null ? null : value; // coerce undefined to null. - } - - void operator []=(K key, V value) { - if (key == null) { - key = JS('', 'null'); - } else if (JS('!', '#[#] !== #', key, dart.extensionSymbol('_equals'), - dart.identityEquals)) { - key = putLinkedMapKey(key, _keyMap); - } - var map = _map; - int length = JS('', '#.size', map); - JS('', '#.set(#, #)', map, key, value); - if (length != JS('!', '#.size', map)) { - _modifications = (_modifications + 1) & 0x3ffffff; - } - } - - V putIfAbsent(K key, V ifAbsent()) { - var map = _map; - if (key == null) { - key = JS('', 'null'); - if (JS('!', '#.has(null)', map)) return JS('', '#.get(null)', map); - } else if (JS('!', '#[#] !== #', key, dart.extensionSymbol('_equals'), - dart.identityEquals)) { - @notNull - K k = key; - var hash = JS('!', '# & 0x3ffffff', k.hashCode); - var buckets = JS('', '#.get(#)', _keyMap, hash); - if (buckets == null) { - JS('', '#.set(#, [#])', _keyMap, hash, key); - } else { - for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) { - k = JS('', '#[#]', buckets, i); - if (k == key) return JS('', '#.get(#)', map, k); - } - JS('', '#.push(#)', buckets, key); - } - } else if (JS('!', '#.has(#)', map, key)) { - return JS('', '#.get(#)', map, key); - } - V value = ifAbsent(); - if (value == null) { - value = JS('', 'null'); - } - JS('', '#.set(#, #)', map, key, value); - _modifications = (_modifications + 1) & 0x3ffffff; - return value; - } - - V? remove(Object? key) { - if (key == null) { - key = JS('', 'null'); - } else if (JS('!', '#[#] !== #', key, dart.extensionSymbol('_equals'), - dart.identityEquals)) { - @notNull - var hash = JS('!', '# & 0x3ffffff', key.hashCode); - var buckets = JS('', '#.get(#)', _keyMap, hash); - if (buckets == null) return null; // not found - for (int i = 0, n = JS('!', '#.length', buckets);;) { - K k = JS('', '#[#]', buckets, i); - if (k == key) { - key = k; - if (n == 1) { - JS('', '#.delete(#)', _keyMap, hash); - } else { - JS('', '#.splice(#, 1)', buckets, i); - } - break; - } - if (++i >= n) return null; // not found - } - } - var map = _map; - V value = JS('', '#.get(#)', map, key); - if (JS('!', '#.delete(#)', map, key)) { - _modifications = (_modifications + 1) & 0x3ffffff; - } - return value == null ? null : value; // coerce undefined to null. - } - - void clear() { - var map = _map; - if (JS('!', '#.size', map) > 0) { - JS('', '#.clear()', map); - JS('', '#.clear()', _keyMap); - _modifications = (_modifications + 1) & 0x3ffffff; - } - } -} - -@NoReifyGeneric() -K putLinkedMapKey(@notNull K key, keyMap) { - var hash = JS('!', '# & 0x3ffffff', key.hashCode); - var buckets = JS('', '#.get(#)', keyMap, hash); - if (buckets == null) { - JS('', '#.set(#, [#])', keyMap, hash, key); - return key; - } - for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) { - @notNull - K k = JS('', '#[#]', buckets, i); - if (k == key) return k; - } - JS('', '#.push(#)', buckets, key); - return key; -} - -class ImmutableMap extends LinkedMap { - ImmutableMap.from(JSArray entries) : super.from(entries); - - void operator []=(K key, V value) { - throw _unsupported(); - } - - void addAll(Object other) => throw _unsupported(); - void clear() => throw _unsupported(); - V? remove(Object? key) => throw _unsupported(); - V putIfAbsent(K key, V ifAbsent()) => throw _unsupported(); - - static Error _unsupported() => - UnsupportedError("Cannot modify unmodifiable map"); -} diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/mirror_helper.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/mirror_helper.dart deleted file mode 100644 index 1b78136eb25..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/mirror_helper.dart +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) 2013, 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. - -/** - * Helps dealing with reflection in the case that the source code has been - * changed as a result of compiling with dart2dart. - */ -library dart._mirror_helper; diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/native_helper.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/native_helper.dart deleted file mode 100644 index cc214e81bc3..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/native_helper.dart +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) 2012, 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. - -part of dart._js_helper; - -// Obsolete in dart dev compiler. Added only so that the same version of -// dart:html can be used in dart2js an dev compiler. -F convertDartClosureToJS(F closure, int arity) { - return closure; -} - -// Warning: calls to these methods need to be removed before custom elements -// and cross-frame dom objects behave correctly in ddc -// https://github.com/dart-lang/sdk/issues/28326 -setNativeSubclassDispatchRecord(proto, interceptor) {} -findDispatchTagForInterceptorClass(interceptorClassConstructor) {} -makeLeafDispatchRecord(interceptor) {} diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/native_typed_data.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/native_typed_data.dart deleted file mode 100644 index 3a7f409444f..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/native_typed_data.dart +++ /dev/null @@ -1,1826 +0,0 @@ -// Copyright (c) 2013, 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. - -/// Specialized integers and floating point numbers, -/// with SIMD support and efficient lists. -library dart.typed_data.implementation; - -import 'dart:collection'; -import 'dart:_internal'; -import 'dart:_interceptors' show JSIndexable; -import 'dart:_js_helper' - show - Creates, - JavaScriptIndexingBehavior, - JSName, - Native, - Returns, - diagnoseIndexError, - diagnoseRangeError; -import 'dart:_foreign_helper' show JS; -import 'dart:math' as Math; - -import 'dart:typed_data'; - -@Native('ArrayBuffer') -class NativeByteBuffer implements ByteBuffer { - @JSName('byteLength') - external int get lengthInBytes; - - Type get runtimeType => ByteBuffer; - - Uint8List asUint8List([int offsetInBytes = 0, int? length]) { - return NativeUint8List.view(this, offsetInBytes, length); - } - - Int8List asInt8List([int offsetInBytes = 0, int? length]) { - return NativeInt8List.view(this, offsetInBytes, length); - } - - Uint8ClampedList asUint8ClampedList([int offsetInBytes = 0, int? length]) { - return NativeUint8ClampedList.view(this, offsetInBytes, length); - } - - Uint16List asUint16List([int offsetInBytes = 0, int? length]) { - return NativeUint16List.view(this, offsetInBytes, length); - } - - Int16List asInt16List([int offsetInBytes = 0, int? length]) { - return NativeInt16List.view(this, offsetInBytes, length); - } - - Uint32List asUint32List([int offsetInBytes = 0, int? length]) { - return NativeUint32List.view(this, offsetInBytes, length); - } - - Int32List asInt32List([int offsetInBytes = 0, int? length]) { - return NativeInt32List.view(this, offsetInBytes, length); - } - - Uint64List asUint64List([int offsetInBytes = 0, int? length]) { - throw UnsupportedError("Uint64List not supported by dart2js."); - } - - Int64List asInt64List([int offsetInBytes = 0, int? length]) { - throw UnsupportedError("Int64List not supported by dart2js."); - } - - Int32x4List asInt32x4List([int offsetInBytes = 0, int? length]) { - var storage = - this.asInt32List(offsetInBytes, length != null ? length * 4 : null); - return NativeInt32x4List._externalStorage(storage); - } - - Float32List asFloat32List([int offsetInBytes = 0, int? length]) { - return NativeFloat32List.view(this, offsetInBytes, length); - } - - Float64List asFloat64List([int offsetInBytes = 0, int? length]) { - return NativeFloat64List.view(this, offsetInBytes, length); - } - - Float32x4List asFloat32x4List([int offsetInBytes = 0, int? length]) { - var storage = - this.asFloat32List(offsetInBytes, length != null ? length * 4 : null); - return NativeFloat32x4List._externalStorage(storage); - } - - Float64x2List asFloat64x2List([int offsetInBytes = 0, int? length]) { - var storage = - this.asFloat64List(offsetInBytes, length != null ? length * 2 : null); - return NativeFloat64x2List._externalStorage(storage); - } - - ByteData asByteData([int offsetInBytes = 0, int? length]) { - return NativeByteData.view(this, offsetInBytes, length); - } -} - -/// A fixed-length list of Float32x4 numbers that is viewable as a -/// [TypedData]. For long lists, this implementation will be considerably more -/// space- and time-efficient than the default [List] implementation. -class NativeFloat32x4List extends Object - with ListMixin, FixedLengthListMixin - implements Float32x4List { - final Float32List _storage; - - /// Creates a [Float32x4List] of the specified length (in elements), - /// all of whose elements are initially zero. - NativeFloat32x4List(int length) : _storage = NativeFloat32List(length * 4); - - NativeFloat32x4List._externalStorage(this._storage); - - NativeFloat32x4List._slowFromList(List list) - : _storage = NativeFloat32List(list.length * 4) { - for (int i = 0; i < list.length; i++) { - var e = list[i]; - _storage[(i * 4) + 0] = e.x; - _storage[(i * 4) + 1] = e.y; - _storage[(i * 4) + 2] = e.z; - _storage[(i * 4) + 3] = e.w; - } - } - - Type get runtimeType => Float32x4List; - - /// Creates a [Float32x4List] with the same size as the [elements] list - /// and copies over the elements. - factory NativeFloat32x4List.fromList(List list) { - if (list is NativeFloat32x4List) { - return NativeFloat32x4List._externalStorage( - NativeFloat32List.fromList(list._storage)); - } else { - return NativeFloat32x4List._slowFromList(list); - } - } - - ByteBuffer get buffer => _storage.buffer; - - int get lengthInBytes => _storage.lengthInBytes; - - int get offsetInBytes => _storage.offsetInBytes; - - int get elementSizeInBytes => Float32x4List.bytesPerElement; - - int get length => _storage.length ~/ 4; - - Float32x4 operator [](int index) { - _checkValidIndex(index, this, this.length); - double _x = _storage[(index * 4) + 0]; - double _y = _storage[(index * 4) + 1]; - double _z = _storage[(index * 4) + 2]; - double _w = _storage[(index * 4) + 3]; - return NativeFloat32x4._truncated(_x, _y, _z, _w); - } - - void operator []=(int index, Float32x4 value) { - _checkValidIndex(index, this, this.length); - _storage[(index * 4) + 0] = value.x; - _storage[(index * 4) + 1] = value.y; - _storage[(index * 4) + 2] = value.z; - _storage[(index * 4) + 3] = value.w; - } - - Float32x4List sublist(int start, [int? end]) { - var stop = _checkValidRange(start, end, this.length); - return NativeFloat32x4List._externalStorage( - _storage.sublist(start * 4, stop * 4)); - } -} - -/// A fixed-length list of Int32x4 numbers that is viewable as a -/// [TypedData]. For long lists, this implementation will be considerably more -/// space- and time-efficient than the default [List] implementation. -class NativeInt32x4List extends Object - with ListMixin, FixedLengthListMixin - implements Int32x4List { - final Int32List _storage; - - /// Creates a [Int32x4List] of the specified length (in elements), - /// all of whose elements are initially zero. - NativeInt32x4List(int length) : _storage = NativeInt32List(length * 4); - - NativeInt32x4List._externalStorage(Int32List storage) : _storage = storage; - - NativeInt32x4List._slowFromList(List list) - : _storage = NativeInt32List(list.length * 4) { - for (int i = 0; i < list.length; i++) { - var e = list[i]; - _storage[(i * 4) + 0] = e.x; - _storage[(i * 4) + 1] = e.y; - _storage[(i * 4) + 2] = e.z; - _storage[(i * 4) + 3] = e.w; - } - } - - Type get runtimeType => Int32x4List; - - /// Creates a [Int32x4List] with the same size as the [elements] list - /// and copies over the elements. - factory NativeInt32x4List.fromList(List list) { - if (list is NativeInt32x4List) { - return NativeInt32x4List._externalStorage( - NativeInt32List.fromList(list._storage)); - } else { - return NativeInt32x4List._slowFromList(list); - } - } - - ByteBuffer get buffer => _storage.buffer; - - int get lengthInBytes => _storage.lengthInBytes; - - int get offsetInBytes => _storage.offsetInBytes; - - int get elementSizeInBytes => Int32x4List.bytesPerElement; - - int get length => _storage.length ~/ 4; - - Int32x4 operator [](int index) { - _checkValidIndex(index, this, this.length); - int _x = _storage[(index * 4) + 0]; - int _y = _storage[(index * 4) + 1]; - int _z = _storage[(index * 4) + 2]; - int _w = _storage[(index * 4) + 3]; - return NativeInt32x4._truncated(_x, _y, _z, _w); - } - - void operator []=(int index, Int32x4 value) { - _checkValidIndex(index, this, this.length); - _storage[(index * 4) + 0] = value.x; - _storage[(index * 4) + 1] = value.y; - _storage[(index * 4) + 2] = value.z; - _storage[(index * 4) + 3] = value.w; - } - - Int32x4List sublist(int start, [int? end]) { - var stop = _checkValidRange(start, end, this.length); - return NativeInt32x4List._externalStorage( - _storage.sublist(start * 4, stop * 4)); - } -} - -/// A fixed-length list of Float64x2 numbers that is viewable as a -/// [TypedData]. For long lists, this implementation will be considerably more -/// space- and time-efficient than the default [List] implementation. -class NativeFloat64x2List extends Object - with ListMixin, FixedLengthListMixin - implements Float64x2List { - final Float64List _storage; - - /// Creates a [Float64x2List] of the specified length (in elements), - /// all of whose elements are initially zero. - NativeFloat64x2List(int length) : _storage = NativeFloat64List(length * 2); - - NativeFloat64x2List._externalStorage(this._storage); - - NativeFloat64x2List._slowFromList(List list) - : _storage = NativeFloat64List(list.length * 2) { - for (int i = 0; i < list.length; i++) { - var e = list[i]; - _storage[(i * 2) + 0] = e.x; - _storage[(i * 2) + 1] = e.y; - } - } - - /// Creates a [Float64x2List] with the same size as the [elements] list - /// and copies over the elements. - factory NativeFloat64x2List.fromList(List list) { - if (list is NativeFloat64x2List) { - return NativeFloat64x2List._externalStorage( - NativeFloat64List.fromList(list._storage)); - } else { - return NativeFloat64x2List._slowFromList(list); - } - } - - Type get runtimeType => Float64x2List; - - ByteBuffer get buffer => _storage.buffer; - - int get lengthInBytes => _storage.lengthInBytes; - - int get offsetInBytes => _storage.offsetInBytes; - - int get elementSizeInBytes => Float64x2List.bytesPerElement; - - int get length => _storage.length ~/ 2; - - Float64x2 operator [](int index) { - _checkValidIndex(index, this, this.length); - double _x = _storage[(index * 2) + 0]; - double _y = _storage[(index * 2) + 1]; - return Float64x2(_x, _y); - } - - void operator []=(int index, Float64x2 value) { - _checkValidIndex(index, this, this.length); - _storage[(index * 2) + 0] = value.x; - _storage[(index * 2) + 1] = value.y; - } - - Float64x2List sublist(int start, [int? end]) { - var stop = _checkValidRange(start, end, this.length); - return NativeFloat64x2List._externalStorage( - _storage.sublist(start * 2, stop * 2)); - } -} - -@Native('ArrayBufferView') -class NativeTypedData implements TypedData { - /// Returns the byte buffer associated with this object. - @Creates('NativeByteBuffer') - @Returns('NativeByteBuffer') - external ByteBuffer get buffer; - - /// Returns the length of this view, in bytes. - @JSName('byteLength') - external int get lengthInBytes; - - /// Returns the offset in bytes into the underlying byte buffer of this view. - @JSName('byteOffset') - external int get offsetInBytes; - - /// Returns the number of bytes in the representation of each element in this - /// list. - @JSName('BYTES_PER_ELEMENT') - external int get elementSizeInBytes; - - void _invalidPosition(int position, int length, String name) { - if (position is! int) { - throw ArgumentError.value(position, name, 'Invalid list position'); - } else { - throw RangeError.range(position, 0, length, name); - } - } - - void _checkPosition(int position, int length, String name) { - if (JS('!', '(# >>> 0) !== #', position, position) || - JS('!', '#', position) > length) { - // 'int' guaranteed by above test. - _invalidPosition(position, length, name); - } - } -} - -// Validates the unnamed constructor length argument. Checking is necessary -// because passing unvalidated values to the native constructors can cause -// conversions or create views. -int _checkLength(length) { - if (length is! int) throw ArgumentError('Invalid length $length'); - return length; -} - -// Validates `.view` constructor arguments. Checking is necessary because -// passing unvalidated values to the native constructors can cause conversions -// (e.g. String arguments) or create typed data objects that are not actually -// views of the input. -void _checkViewArguments(buffer, offsetInBytes, length) { - if (buffer is! NativeByteBuffer) { - throw ArgumentError('Invalid view buffer'); - } - if (offsetInBytes is! int) { - throw ArgumentError('Invalid view offsetInBytes $offsetInBytes'); - } - if (length is! int?) { - throw ArgumentError('Invalid view length $length'); - } -} - -// Ensures that [list] is a JavaScript Array or a typed array. If necessary, -// returns a copy of the list. -List _ensureNativeList(List list) { - if (list is JSIndexable) return list; - List result = List.filled(list.length, null); - for (int i = 0; i < list.length; i++) { - result[i] = list[i]; - } - return result; -} - -@Native('DataView') -class NativeByteData extends NativeTypedData implements ByteData { - /// Creates a [ByteData] of the specified length (in elements), all of - /// whose elements are initially zero. - factory NativeByteData(int length) => _create1(_checkLength(length)); - - /// Creates an [ByteData] _view_ of the specified region in the specified - /// byte buffer. Changes in the [ByteData] will be visible in the byte - /// buffer and vice versa. If the [offsetInBytes] index of the region is not - /// specified, it defaults to zero (the first byte in the byte buffer). - /// If the length is not specified, it defaults to null, which indicates - /// that the view extends to the end of the byte buffer. - /// - /// Throws [RangeError] if [offsetInBytes] or [length] are negative, or - /// if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than - /// the length of [buffer]. - factory NativeByteData.view( - ByteBuffer buffer, int offsetInBytes, int? length) { - _checkViewArguments(buffer, offsetInBytes, length); - return length == null - ? _create2(buffer, offsetInBytes) - : _create3(buffer, offsetInBytes, length); - } - - Type get runtimeType => ByteData; - - int get elementSizeInBytes => 1; - - /// Returns the floating point number represented by the four bytes at - /// the specified [byteOffset] in this object, in IEEE 754 - /// single-precision binary floating-point format (binary32). - /// - /// Throws [RangeError] if [byteOffset] is negative, or - /// `byteOffset + 4` is greater than the length of this object. - double getFloat32(int byteOffset, [Endian endian = Endian.big]) => - _getFloat32(byteOffset, Endian.little == endian); - - @JSName('getFloat32') - @Returns('double') - double _getFloat32(int byteOffset, [bool? littleEndian]) native; - - /// Returns the floating point number represented by the eight bytes at - /// the specified [byteOffset] in this object, in IEEE 754 - /// double-precision binary floating-point format (binary64). - /// - /// Throws [RangeError] if [byteOffset] is negative, or - /// `byteOffset + 8` is greater than the length of this object. - double getFloat64(int byteOffset, [Endian endian = Endian.big]) => - _getFloat64(byteOffset, Endian.little == endian); - - @JSName('getFloat64') - @Returns('double') - double _getFloat64(int byteOffset, [bool? littleEndian]) native; - - /// Returns the (possibly negative) integer represented by the two bytes at - /// the specified [byteOffset] in this object, in two's complement binary - /// form. - /// The return value will be between 215 and 215 - 1, - /// inclusive. - /// - /// Throws [RangeError] if [byteOffset] is negative, or - /// `byteOffset + 2` is greater than the length of this object. - int getInt16(int byteOffset, [Endian endian = Endian.big]) => - _getInt16(byteOffset, Endian.little == endian); - - @JSName('getInt16') - @Returns('int') - int _getInt16(int byteOffset, [bool? littleEndian]) native; - - /// Returns the (possibly negative) integer represented by the four bytes at - /// the specified [byteOffset] in this object, in two's complement binary - /// form. - /// The return value will be between 231 and 231 - 1, - /// inclusive. - /// - /// Throws [RangeError] if [byteOffset] is negative, or - /// `byteOffset + 4` is greater than the length of this object. - int getInt32(int byteOffset, [Endian endian = Endian.big]) => - _getInt32(byteOffset, Endian.little == endian); - - @JSName('getInt32') - @Returns('int') - int _getInt32(int byteOffset, [bool? littleEndian]) native; - - /// Returns the (possibly negative) integer represented by the eight bytes at - /// the specified [byteOffset] in this object, in two's complement binary - /// form. - /// The return value will be between 263 and 263 - 1, - /// inclusive. - /// - /// Throws [RangeError] if [byteOffset] is negative, or - /// `byteOffset + 8` is greater than the length of this object. - int getInt64(int byteOffset, [Endian endian = Endian.big]) { - throw UnsupportedError('Int64 accessor not supported by dart2js.'); - } - - /// Returns the (possibly negative) integer represented by the byte at the - /// specified [byteOffset] in this object, in two's complement binary - /// representation. The return value will be between -128 and 127, inclusive. - /// - /// Throws [RangeError] if [byteOffset] is negative, or - /// greater than or equal to the length of this object. - int getInt8(int byteOffset) native; - - /// Returns the positive integer represented by the two bytes starting - /// at the specified [byteOffset] in this object, in unsigned binary - /// form. - /// The return value will be between 0 and 216 - 1, inclusive. - /// - /// Throws [RangeError] if [byteOffset] is negative, or - /// `byteOffset + 2` is greater than the length of this object. - int getUint16(int byteOffset, [Endian endian = Endian.big]) => - _getUint16(byteOffset, Endian.little == endian); - - @JSName('getUint16') - @Returns('int') - int _getUint16(int byteOffset, [bool? littleEndian]) native; - - /// Returns the positive integer represented by the four bytes starting - /// at the specified [byteOffset] in this object, in unsigned binary - /// form. - /// The return value will be between 0 and 232 - 1, inclusive. - /// - /// Throws [RangeError] if [byteOffset] is negative, or - /// `byteOffset + 4` is greater than the length of this object. - int getUint32(int byteOffset, [Endian endian = Endian.big]) => - _getUint32(byteOffset, Endian.little == endian); - - @JSName('getUint32') - @Returns('int') - int _getUint32(int byteOffset, [bool? littleEndian]) native; - - /// Returns the positive integer represented by the eight bytes starting - /// at the specified [byteOffset] in this object, in unsigned binary - /// form. - /// The return value will be between 0 and 264 - 1, inclusive. - /// - /// Throws [RangeError] if [byteOffset] is negative, or - /// `byteOffset + 8` is greater than the length of this object. - int getUint64(int byteOffset, [Endian endian = Endian.big]) { - throw UnsupportedError('Uint64 accessor not supported by dart2js.'); - } - - /// Returns the positive integer represented by the byte at the specified - /// [byteOffset] in this object, in unsigned binary form. The - /// return value will be between 0 and 255, inclusive. - /// - /// Throws [RangeError] if [byteOffset] is negative, or - /// greater than or equal to the length of this object. - int getUint8(int byteOffset) native; - - /// Sets the four bytes starting at the specified [byteOffset] in this - /// object to the IEEE 754 single-precision binary floating-point - /// (binary32) representation of the specified [value]. - /// - /// **Note that this method can lose precision.** The input [value] is - /// a 64-bit floating point value, which will be converted to 32-bit - /// floating point value by IEEE 754 rounding rules before it is stored. - /// If [value] cannot be represented exactly as a binary32, it will be - /// converted to the nearest binary32 value. If two binary32 values are - /// equally close, the one whose least significant bit is zero will be used. - /// Note that finite (but large) values can be converted to infinity, and - /// small non-zero values can be converted to zero. - /// - /// Throws [RangeError] if [byteOffset] is negative, or - /// `byteOffset + 4` is greater than the length of this object. - void setFloat32(int byteOffset, num value, [Endian endian = Endian.big]) => - _setFloat32(byteOffset, value, Endian.little == endian); - - @JSName('setFloat32') - void _setFloat32(int byteOffset, num value, [bool? littleEndian]) native; - - /// Sets the eight bytes starting at the specified [byteOffset] in this - /// object to the IEEE 754 double-precision binary floating-point - /// (binary64) representation of the specified [value]. - /// - /// Throws [RangeError] if [byteOffset] is negative, or - /// `byteOffset + 8` is greater than the length of this object. - void setFloat64(int byteOffset, num value, [Endian endian = Endian.big]) => - _setFloat64(byteOffset, value, Endian.little == endian); - - @JSName('setFloat64') - void _setFloat64(int byteOffset, num value, [bool? littleEndian]) native; - - /// Sets the two bytes starting at the specified [byteOffset] in this - /// object to the two's complement binary representation of the specified - /// [value], which must fit in two bytes. In other words, [value] must lie - /// between 215 and 215 - 1, inclusive. - /// - /// Throws [RangeError] if [byteOffset] is negative, or - /// `byteOffset + 2` is greater than the length of this object. - void setInt16(int byteOffset, int value, [Endian endian = Endian.big]) => - _setInt16(byteOffset, value, Endian.little == endian); - - @JSName('setInt16') - void _setInt16(int byteOffset, int value, [bool? littleEndian]) native; - - /// Sets the four bytes starting at the specified [byteOffset] in this - /// object to the two's complement binary representation of the specified - /// [value], which must fit in four bytes. In other words, [value] must lie - /// between 231 and 231 - 1, inclusive. - /// - /// Throws [RangeError] if [byteOffset] is negative, or - /// `byteOffset + 4` is greater than the length of this object. - void setInt32(int byteOffset, int value, [Endian endian = Endian.big]) => - _setInt32(byteOffset, value, Endian.little == endian); - - @JSName('setInt32') - void _setInt32(int byteOffset, int value, [bool? littleEndian]) native; - - /// Sets the eight bytes starting at the specified [byteOffset] in this - /// object to the two's complement binary representation of the specified - /// [value], which must fit in eight bytes. In other words, [value] must lie - /// between 263 and 263 - 1, inclusive. - /// - /// Throws [RangeError] if [byteOffset] is negative, or - /// `byteOffset + 8` is greater than the length of this object. - void setInt64(int byteOffset, int value, [Endian endian = Endian.big]) { - throw UnsupportedError('Int64 accessor not supported by dart2js.'); - } - - /// Sets the byte at the specified [byteOffset] in this object to the - /// two's complement binary representation of the specified [value], which - /// must fit in a single byte. In other words, [value] must be between - /// -128 and 127, inclusive. - /// - /// Throws [RangeError] if [byteOffset] is negative, or - /// greater than or equal to the length of this object. - void setInt8(int byteOffset, int value) native; - - /// Sets the two bytes starting at the specified [byteOffset] in this object - /// to the unsigned binary representation of the specified [value], - /// which must fit in two bytes. in other words, [value] must be between - /// 0 and 216 - 1, inclusive. - /// - /// Throws [RangeError] if [byteOffset] is negative, or - /// `byteOffset + 2` is greater than the length of this object. - void setUint16(int byteOffset, int value, [Endian endian = Endian.big]) => - _setUint16(byteOffset, value, Endian.little == endian); - - @JSName('setUint16') - void _setUint16(int byteOffset, int value, [bool? littleEndian]) native; - - /// Sets the four bytes starting at the specified [byteOffset] in this object - /// to the unsigned binary representation of the specified [value], - /// which must fit in four bytes. in other words, [value] must be between - /// 0 and 232 - 1, inclusive. - /// - /// Throws [RangeError] if [byteOffset] is negative, or - /// `byteOffset + 4` is greater than the length of this object. - void setUint32(int byteOffset, int value, [Endian endian = Endian.big]) => - _setUint32(byteOffset, value, Endian.little == endian); - - @JSName('setUint32') - void _setUint32(int byteOffset, int value, [bool? littleEndian]) native; - - /// Sets the eight bytes starting at the specified [byteOffset] in this object - /// to the unsigned binary representation of the specified [value], - /// which must fit in eight bytes. in other words, [value] must be between - /// 0 and 264 - 1, inclusive. - /// - /// Throws [RangeError] if [byteOffset] is negative, or - /// `byteOffset + 8` is greater than the length of this object. - void setUint64(int byteOffset, int value, [Endian endian = Endian.big]) { - throw UnsupportedError('Uint64 accessor not supported by dart2js.'); - } - - /// Sets the byte at the specified [byteOffset] in this object to the - /// unsigned binary representation of the specified [value], which must fit - /// in a single byte. in other words, [value] must be between 0 and 255, - /// inclusive. - /// - /// Throws [RangeError] if [byteOffset] is negative, - /// or greater than or equal to the length of this object. - void setUint8(int byteOffset, int value) native; - - static NativeByteData _create1(arg) => - JS('NativeByteData', 'new DataView(new ArrayBuffer(#))', arg); - - static NativeByteData _create2(arg1, arg2) => - JS('NativeByteData', 'new DataView(#, #)', arg1, arg2); - - static NativeByteData _create3(arg1, arg2, arg3) => - JS('NativeByteData', 'new DataView(#, #, #)', arg1, arg2, arg3); -} - -abstract class NativeTypedArray extends NativeTypedData - implements JavaScriptIndexingBehavior { - int get length; - - void _setRangeFast( - int start, int end, NativeTypedArray source, int skipCount) { - int targetLength = this.length; - _checkPosition(start, targetLength, "start"); - _checkPosition(end, targetLength, "end"); - if (start > end) throw RangeError.range(start, 0, end); - int count = end - start; - - if (skipCount < 0) throw ArgumentError(skipCount); - - int sourceLength = source.length; - if (sourceLength - skipCount < count) { - throw StateError('Not enough elements'); - } - - if (skipCount != 0 || sourceLength != count) { - // Create a view of the exact subrange that is copied from the source. - source = JS('', '#.subarray(#, #)', source, skipCount, skipCount + count); - } - JS('void', '#.set(#, #)', this, source, start); - } -} - -abstract class NativeTypedArrayOfDouble extends NativeTypedArray - with ListMixin, FixedLengthListMixin { - int get length => JS('!', '#.length', this); - - double operator [](int index) { - _checkValidIndex(index, this, this.length); - return JS('!', '#[#]', this, index); - } - - void operator []=(int index, num value) { - _checkValidIndex(index, this, this.length); - JS('void', '#[#] = #', this, index, value); - } - - void setRange(int start, int end, Iterable iterable, - [int skipCount = 0]) { - if (iterable is NativeTypedArrayOfDouble) { - _setRangeFast(start, end, iterable, skipCount); - return; - } - super.setRange(start, end, iterable, skipCount); - } -} - -abstract class NativeTypedArrayOfInt extends NativeTypedArray - with ListMixin, FixedLengthListMixin - implements List { - int get length => JS('!', '#.length', this); - - // operator[]() is not here since different versions have different return - // types - - void operator []=(int index, int value) { - _checkValidIndex(index, this, this.length); - JS('void', '#[#] = #', this, index, value); - } - - void setRange(int start, int end, Iterable iterable, - [int skipCount = 0]) { - if (iterable is NativeTypedArrayOfInt) { - _setRangeFast(start, end, iterable, skipCount); - return; - } - super.setRange(start, end, iterable, skipCount); - } -} - -@Native('Float32Array') -class NativeFloat32List extends NativeTypedArrayOfDouble - implements Float32List { - factory NativeFloat32List(int length) => _create1(_checkLength(length)); - - factory NativeFloat32List.fromList(List elements) => - _create1(_ensureNativeList(elements)); - - factory NativeFloat32List.view( - ByteBuffer buffer, int offsetInBytes, int? length) { - _checkViewArguments(buffer, offsetInBytes, length); - return length == null - ? _create2(buffer, offsetInBytes) - : _create3(buffer, offsetInBytes, length); - } - - Type get runtimeType => Float32List; - - Float32List sublist(int start, [int? end]) { - var stop = _checkValidRange(start, end, this.length); - var source = - JS('!', '#.subarray(#, #)', this, start, stop); - return _create1(source); - } - - static NativeFloat32List _create1(arg) => - JS('!', 'new Float32Array(#)', arg); - - static NativeFloat32List _create2(arg1, arg2) => - JS('!', 'new Float32Array(#, #)', arg1, arg2); - - static NativeFloat32List _create3(arg1, arg2, arg3) => - JS('!', 'new Float32Array(#, #, #)', arg1, arg2, arg3); -} - -@Native('Float64Array') -class NativeFloat64List extends NativeTypedArrayOfDouble - implements Float64List { - factory NativeFloat64List(int length) => _create1(_checkLength(length)); - - factory NativeFloat64List.fromList(List elements) => - _create1(_ensureNativeList(elements)); - - factory NativeFloat64List.view( - ByteBuffer buffer, int offsetInBytes, int? length) { - _checkViewArguments(buffer, offsetInBytes, length); - return length == null - ? _create2(buffer, offsetInBytes) - : _create3(buffer, offsetInBytes, length); - } - - Type get runtimeType => Float64List; - - Float64List sublist(int start, [int? end]) { - var stop = _checkValidRange(start, end, this.length); - var source = JS('NativeFloat64List', '#.subarray(#, #)', this, start, stop); - return _create1(source); - } - - static NativeFloat64List _create1(arg) => - JS('NativeFloat64List', 'new Float64Array(#)', arg); - - static NativeFloat64List _create2(arg1, arg2) => - JS('NativeFloat64List', 'new Float64Array(#, #)', arg1, arg2); - - static NativeFloat64List _create3(arg1, arg2, arg3) => - JS('NativeFloat64List', 'new Float64Array(#, #, #)', arg1, arg2, arg3); -} - -@Native('Int16Array') -class NativeInt16List extends NativeTypedArrayOfInt implements Int16List { - factory NativeInt16List(int length) => _create1(_checkLength(length)); - - factory NativeInt16List.fromList(List elements) => - _create1(_ensureNativeList(elements)); - - factory NativeInt16List.view( - NativeByteBuffer buffer, int offsetInBytes, int? length) { - _checkViewArguments(buffer, offsetInBytes, length); - return length == null - ? _create2(buffer, offsetInBytes) - : _create3(buffer, offsetInBytes, length); - } - - Type get runtimeType => Int16List; - - int operator [](int index) { - _checkValidIndex(index, this, this.length); - return JS('!', '#[#]', this, index); - } - - Int16List sublist(int start, [int? end]) { - var stop = _checkValidRange(start, end, this.length); - var source = JS('NativeInt16List', '#.subarray(#, #)', this, start, stop); - return _create1(source); - } - - static NativeInt16List _create1(arg) => - JS('NativeInt16List', 'new Int16Array(#)', arg); - - static NativeInt16List _create2(arg1, arg2) => - JS('NativeInt16List', 'new Int16Array(#, #)', arg1, arg2); - - static NativeInt16List _create3(arg1, arg2, arg3) => - JS('NativeInt16List', 'new Int16Array(#, #, #)', arg1, arg2, arg3); -} - -@Native('Int32Array') -class NativeInt32List extends NativeTypedArrayOfInt implements Int32List { - factory NativeInt32List(int length) => _create1(_checkLength(length)); - - factory NativeInt32List.fromList(List elements) => - _create1(_ensureNativeList(elements)); - - factory NativeInt32List.view( - ByteBuffer buffer, int offsetInBytes, int? length) { - _checkViewArguments(buffer, offsetInBytes, length); - return length == null - ? _create2(buffer, offsetInBytes) - : _create3(buffer, offsetInBytes, length); - } - - Type get runtimeType => Int32List; - - int operator [](int index) { - _checkValidIndex(index, this, this.length); - return JS('!', '#[#]', this, index); - } - - Int32List sublist(int start, [int? end]) { - var stop = _checkValidRange(start, end, this.length); - var source = - JS('!', '#.subarray(#, #)', this, start, stop); - return _create1(source); - } - - static NativeInt32List _create1(arg) => - JS('!', 'new Int32Array(#)', arg); - - static NativeInt32List _create2(arg1, arg2) => - JS('!', 'new Int32Array(#, #)', arg1, arg2); - - static NativeInt32List _create3(arg1, arg2, arg3) => - JS('!', 'new Int32Array(#, #, #)', arg1, arg2, arg3); -} - -@Native('Int8Array') -class NativeInt8List extends NativeTypedArrayOfInt implements Int8List { - factory NativeInt8List(int length) => _create1(_checkLength(length)); - - factory NativeInt8List.fromList(List elements) => - _create1(_ensureNativeList(elements)); - - factory NativeInt8List.view( - ByteBuffer buffer, int offsetInBytes, int? length) { - _checkViewArguments(buffer, offsetInBytes, length); - return length == null - ? _create2(buffer, offsetInBytes) - : _create3(buffer, offsetInBytes, length); - } - - Type get runtimeType => Int8List; - - int operator [](int index) { - _checkValidIndex(index, this, this.length); - return JS('!', '#[#]', this, index); - } - - Int8List sublist(int start, [int? end]) { - var stop = _checkValidRange(start, end, this.length); - var source = JS('!', '#.subarray(#, #)', this, start, stop); - return _create1(source); - } - - static NativeInt8List _create1(arg) => - JS('!', 'new Int8Array(#)', arg); - - static NativeInt8List _create2(arg1, arg2) => - JS('!', 'new Int8Array(#, #)', arg1, arg2); - - static NativeInt8List _create3(arg1, arg2, arg3) => - JS('!', 'new Int8Array(#, #, #)', arg1, arg2, arg3); -} - -@Native('Uint16Array') -class NativeUint16List extends NativeTypedArrayOfInt implements Uint16List { - factory NativeUint16List(int length) => _create1(_checkLength(length)); - - factory NativeUint16List.fromList(List list) => - _create1(_ensureNativeList(list)); - - factory NativeUint16List.view( - ByteBuffer buffer, int offsetInBytes, int? length) { - _checkViewArguments(buffer, offsetInBytes, length); - return length == null - ? _create2(buffer, offsetInBytes) - : _create3(buffer, offsetInBytes, length); - } - - Type get runtimeType => Uint16List; - - int operator [](int index) { - _checkValidIndex(index, this, this.length); - return JS('!', '#[#]', this, index); - } - - Uint16List sublist(int start, [int? end]) { - var stop = _checkValidRange(start, end, this.length); - var source = - JS('!', '#.subarray(#, #)', this, start, stop); - return _create1(source); - } - - static NativeUint16List _create1(arg) => - JS('!', 'new Uint16Array(#)', arg); - - static NativeUint16List _create2(arg1, arg2) => - JS('!', 'new Uint16Array(#, #)', arg1, arg2); - - static NativeUint16List _create3(arg1, arg2, arg3) => - JS('!', 'new Uint16Array(#, #, #)', arg1, arg2, arg3); -} - -@Native('Uint32Array') -class NativeUint32List extends NativeTypedArrayOfInt implements Uint32List { - factory NativeUint32List(int length) => _create1(_checkLength(length)); - - factory NativeUint32List.fromList(List elements) => - _create1(_ensureNativeList(elements)); - - factory NativeUint32List.view( - ByteBuffer buffer, int offsetInBytes, int? length) { - _checkViewArguments(buffer, offsetInBytes, length); - return length == null - ? _create2(buffer, offsetInBytes) - : _create3(buffer, offsetInBytes, length); - } - - Type get runtimeType => Uint32List; - - int operator [](int index) { - _checkValidIndex(index, this, this.length); - return JS('!', '#[#]', this, index); - } - - Uint32List sublist(int start, [int? end]) { - var stop = _checkValidRange(start, end, this.length); - var source = - JS('!', '#.subarray(#, #)', this, start, stop); - return _create1(source); - } - - static NativeUint32List _create1(arg) => - JS('!', 'new Uint32Array(#)', arg); - - static NativeUint32List _create2(arg1, arg2) => - JS('!', 'new Uint32Array(#, #)', arg1, arg2); - - static NativeUint32List _create3(arg1, arg2, arg3) => - JS('!', 'new Uint32Array(#, #, #)', arg1, arg2, arg3); -} - -@Native('Uint8ClampedArray,CanvasPixelArray') -class NativeUint8ClampedList extends NativeTypedArrayOfInt - implements Uint8ClampedList { - factory NativeUint8ClampedList(int length) => _create1(_checkLength(length)); - - factory NativeUint8ClampedList.fromList(List elements) => - _create1(_ensureNativeList(elements)); - - factory NativeUint8ClampedList.view( - ByteBuffer buffer, int offsetInBytes, int? length) { - _checkViewArguments(buffer, offsetInBytes, length); - return length == null - ? _create2(buffer, offsetInBytes) - : _create3(buffer, offsetInBytes, length); - } - - Type get runtimeType => Uint8ClampedList; - - int get length => JS('!', '#.length', this); - - int operator [](int index) { - _checkValidIndex(index, this, this.length); - return JS('!', '#[#]', this, index); - } - - Uint8ClampedList sublist(int start, [int? end]) { - var stop = _checkValidRange(start, end, this.length); - var source = - JS('!', '#.subarray(#, #)', this, start, stop); - return _create1(source); - } - - static NativeUint8ClampedList _create1(arg) => - JS('!', 'new Uint8ClampedArray(#)', arg); - - static NativeUint8ClampedList _create2(arg1, arg2) => - JS( - '!', 'new Uint8ClampedArray(#, #)', arg1, arg2); - - static NativeUint8ClampedList _create3(arg1, arg2, arg3) => JS( - 'NativeUint8ClampedList', - 'new Uint8ClampedArray(#, #, #)', - arg1, - arg2, - arg3); -} - -// On some browsers Uint8ClampedArray is a subtype of Uint8Array. Marking -// Uint8List as !nonleaf ensures that the native dispatch correctly handles -// the potential for Uint8ClampedArray to 'accidentally' pick up the -// dispatch record for Uint8List. -@Native('Uint8Array,!nonleaf') -class NativeUint8List extends NativeTypedArrayOfInt implements Uint8List { - factory NativeUint8List(int length) => _create1(_checkLength(length)); - - factory NativeUint8List.fromList(List elements) => - _create1(_ensureNativeList(elements)); - - factory NativeUint8List.view( - ByteBuffer buffer, int offsetInBytes, int? length) { - _checkViewArguments(buffer, offsetInBytes, length); - return length == null - ? _create2(buffer, offsetInBytes) - : _create3(buffer, offsetInBytes, length); - } - - Type get runtimeType => Uint8List; - - int get length => JS('!', '#.length', this); - - int operator [](int index) { - _checkValidIndex(index, this, this.length); - return JS('!', '#[#]', this, index); - } - - Uint8List sublist(int start, [int? end]) { - var stop = _checkValidRange(start, end, this.length); - var source = - JS('!', '#.subarray(#, #)', this, start, stop); - return _create1(source); - } - - static NativeUint8List _create1(arg) => - JS('!', 'new Uint8Array(#)', arg); - - static NativeUint8List _create2(arg1, arg2) => - JS('!', 'new Uint8Array(#, #)', arg1, arg2); - - static NativeUint8List _create3(arg1, arg2, arg3) => - JS('!', 'new Uint8Array(#, #, #)', arg1, arg2, arg3); -} - -/// Implementation of Dart Float32x4 immutable value type and operations. -/// Float32x4 stores 4 32-bit floating point values in "lanes". -/// The lanes are "x", "y", "z", and "w" respectively. -class NativeFloat32x4 implements Float32x4 { - final double x; - final double y; - final double z; - final double w; - - static final NativeFloat32List _list = NativeFloat32List(4); - static final Uint32List _uint32view = _list.buffer.asUint32List(); - - static _truncate(x) { - _list[0] = x; - return _list[0]; - } - - NativeFloat32x4(double x, double y, double z, double w) - : this.x = _truncate(x), - this.y = _truncate(y), - this.z = _truncate(z), - this.w = _truncate(w) { - // We would prefer to check for `double` but in dart2js we can't see the - // difference anyway. - if (x is! num) throw ArgumentError(x); - if (y is! num) throw ArgumentError(y); - if (z is! num) throw ArgumentError(z); - if (w is! num) throw ArgumentError(w); - } - - NativeFloat32x4.splat(double v) : this(v, v, v, v); - NativeFloat32x4.zero() : this._truncated(0.0, 0.0, 0.0, 0.0); - - /// Returns a bit-wise copy of [i] as a Float32x4. - factory NativeFloat32x4.fromInt32x4Bits(Int32x4 i) { - _uint32view[0] = i.x; - _uint32view[1] = i.y; - _uint32view[2] = i.z; - _uint32view[3] = i.w; - return NativeFloat32x4._truncated(_list[0], _list[1], _list[2], _list[3]); - } - - NativeFloat32x4.fromFloat64x2(Float64x2 v) - : this._truncated(_truncate(v.x), _truncate(v.y), 0.0, 0.0); - - /// Creates a new NativeFloat32x4. - /// - /// Does not verify if the given arguments are non-null. - NativeFloat32x4._doubles(double x, double y, double z, double w) - : this.x = _truncate(x), - this.y = _truncate(y), - this.z = _truncate(z), - this.w = _truncate(w); - - /// Creates a new NativeFloat32x4. - /// - /// The constructor does not truncate the arguments. They must already be in - /// the correct range. It does not verify the type of the given arguments, - /// either. - NativeFloat32x4._truncated(this.x, this.y, this.z, this.w); - - String toString() { - return '[$x, $y, $z, $w]'; - } - - /// Addition operator. - Float32x4 operator +(Float32x4 other) { - double _x = x + other.x; - double _y = y + other.y; - double _z = z + other.z; - double _w = w + other.w; - return NativeFloat32x4._doubles(_x, _y, _z, _w); - } - - /// Negate operator. - Float32x4 operator -() { - return NativeFloat32x4._truncated(-x, -y, -z, -w); - } - - /// Subtraction operator. - Float32x4 operator -(Float32x4 other) { - double _x = x - other.x; - double _y = y - other.y; - double _z = z - other.z; - double _w = w - other.w; - return NativeFloat32x4._doubles(_x, _y, _z, _w); - } - - /// Multiplication operator. - Float32x4 operator *(Float32x4 other) { - double _x = x * other.x; - double _y = y * other.y; - double _z = z * other.z; - double _w = w * other.w; - return NativeFloat32x4._doubles(_x, _y, _z, _w); - } - - /// Division operator. - Float32x4 operator /(Float32x4 other) { - double _x = x / other.x; - double _y = y / other.y; - double _z = z / other.z; - double _w = w / other.w; - return NativeFloat32x4._doubles(_x, _y, _z, _w); - } - - /// Relational less than. - Int32x4 lessThan(Float32x4 other) { - bool _cx = x < other.x; - bool _cy = y < other.y; - bool _cz = z < other.z; - bool _cw = w < other.w; - return NativeInt32x4._truncated( - _cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0); - } - - /// Relational less than or equal. - Int32x4 lessThanOrEqual(Float32x4 other) { - bool _cx = x <= other.x; - bool _cy = y <= other.y; - bool _cz = z <= other.z; - bool _cw = w <= other.w; - return NativeInt32x4._truncated( - _cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0); - } - - /// Relational greater than. - Int32x4 greaterThan(Float32x4 other) { - bool _cx = x > other.x; - bool _cy = y > other.y; - bool _cz = z > other.z; - bool _cw = w > other.w; - return NativeInt32x4._truncated( - _cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0); - } - - /// Relational greater than or equal. - Int32x4 greaterThanOrEqual(Float32x4 other) { - bool _cx = x >= other.x; - bool _cy = y >= other.y; - bool _cz = z >= other.z; - bool _cw = w >= other.w; - return NativeInt32x4._truncated( - _cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0); - } - - /// Relational equal. - Int32x4 equal(Float32x4 other) { - bool _cx = x == other.x; - bool _cy = y == other.y; - bool _cz = z == other.z; - bool _cw = w == other.w; - return NativeInt32x4._truncated( - _cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0); - } - - /// Relational not-equal. - Int32x4 notEqual(Float32x4 other) { - bool _cx = x != other.x; - bool _cy = y != other.y; - bool _cz = z != other.z; - bool _cw = w != other.w; - return NativeInt32x4._truncated( - _cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0); - } - - /// Returns a copy of [this] each lane being scaled by [s]. - Float32x4 scale(double s) { - double _x = s * x; - double _y = s * y; - double _z = s * z; - double _w = s * w; - return NativeFloat32x4._doubles(_x, _y, _z, _w); - } - - /// Returns the absolute value of this [Float32x4]. - Float32x4 abs() { - double _x = x.abs(); - double _y = y.abs(); - double _z = z.abs(); - double _w = w.abs(); - return NativeFloat32x4._truncated(_x, _y, _z, _w); - } - - /// Clamps [this] to be in the range [lowerLimit]-[upperLimit]. - Float32x4 clamp(Float32x4 lowerLimit, Float32x4 upperLimit) { - double _lx = lowerLimit.x; - double _ly = lowerLimit.y; - double _lz = lowerLimit.z; - double _lw = lowerLimit.w; - double _ux = upperLimit.x; - double _uy = upperLimit.y; - double _uz = upperLimit.z; - double _uw = upperLimit.w; - double _x = x; - double _y = y; - double _z = z; - double _w = w; - // MAX(MIN(self, upper), lower). - _x = _x > _ux ? _ux : _x; - _y = _y > _uy ? _uy : _y; - _z = _z > _uz ? _uz : _z; - _w = _w > _uw ? _uw : _w; - _x = _x < _lx ? _lx : _x; - _y = _y < _ly ? _ly : _y; - _z = _z < _lz ? _lz : _z; - _w = _w < _lw ? _lw : _w; - return NativeFloat32x4._truncated(_x, _y, _z, _w); - } - - /// Extract the sign bit from each lane return them in the first 4 bits. - int get signMask { - var view = _uint32view; - var mx, my, mz, mw; - _list[0] = x; - _list[1] = y; - _list[2] = z; - _list[3] = w; - // This is correct because dart2js uses the unsigned right shift. - mx = (view[0] & 0x80000000) >> 31; - my = (view[1] & 0x80000000) >> 30; - mz = (view[2] & 0x80000000) >> 29; - mw = (view[3] & 0x80000000) >> 28; - return mx | my | mz | mw; - } - - /// Shuffle the lane values. [mask] must be one of the 256 shuffle constants. - Float32x4 shuffle(int mask) { - if ((mask < 0) || (mask > 255)) { - throw RangeError.range(mask, 0, 255, "mask"); - } - _list[0] = x; - _list[1] = y; - _list[2] = z; - _list[3] = w; - - double _x = _list[mask & 0x3]; - double _y = _list[(mask >> 2) & 0x3]; - double _z = _list[(mask >> 4) & 0x3]; - double _w = _list[(mask >> 6) & 0x3]; - return NativeFloat32x4._truncated(_x, _y, _z, _w); - } - - /// Shuffle the lane values in [this] and [other]. The returned - /// Float32x4 will have XY lanes from [this] and ZW lanes from [other]. - /// Uses the same [mask] as [shuffle]. - Float32x4 shuffleMix(Float32x4 other, int mask) { - if ((mask < 0) || (mask > 255)) { - throw RangeError.range(mask, 0, 255, "mask"); - } - _list[0] = x; - _list[1] = y; - _list[2] = z; - _list[3] = w; - double _x = _list[mask & 0x3]; - double _y = _list[(mask >> 2) & 0x3]; - - _list[0] = other.x; - _list[1] = other.y; - _list[2] = other.z; - _list[3] = other.w; - double _z = _list[(mask >> 4) & 0x3]; - double _w = _list[(mask >> 6) & 0x3]; - return NativeFloat32x4._truncated(_x, _y, _z, _w); - } - - /// Copy [this] and replace the [x] lane. - Float32x4 withX(double newX) { - return NativeFloat32x4._truncated(_truncate(newX), y, z, w); - } - - /// Copy [this] and replace the [y] lane. - Float32x4 withY(double newY) { - return NativeFloat32x4._truncated(x, _truncate(newY), z, w); - } - - /// Copy [this] and replace the [z] lane. - Float32x4 withZ(double newZ) { - return NativeFloat32x4._truncated(x, y, _truncate(newZ), w); - } - - /// Copy [this] and replace the [w] lane. - Float32x4 withW(double newW) { - return NativeFloat32x4._truncated(x, y, z, _truncate(newW)); - } - - /// Returns the lane-wise minimum value in [this] or [other]. - Float32x4 min(Float32x4 other) { - double _x = x < other.x ? x : other.x; - double _y = y < other.y ? y : other.y; - double _z = z < other.z ? z : other.z; - double _w = w < other.w ? w : other.w; - return NativeFloat32x4._truncated(_x, _y, _z, _w); - } - - /// Returns the lane-wise maximum value in [this] or [other]. - Float32x4 max(Float32x4 other) { - double _x = x > other.x ? x : other.x; - double _y = y > other.y ? y : other.y; - double _z = z > other.z ? z : other.z; - double _w = w > other.w ? w : other.w; - return NativeFloat32x4._truncated(_x, _y, _z, _w); - } - - /// Returns the square root of [this]. - Float32x4 sqrt() { - double _x = Math.sqrt(x); - double _y = Math.sqrt(y); - double _z = Math.sqrt(z); - double _w = Math.sqrt(w); - return NativeFloat32x4._doubles(_x, _y, _z, _w); - } - - /// Returns the reciprocal of [this]. - Float32x4 reciprocal() { - double _x = 1.0 / x; - double _y = 1.0 / y; - double _z = 1.0 / z; - double _w = 1.0 / w; - return NativeFloat32x4._doubles(_x, _y, _z, _w); - } - - /// Returns the square root of the reciprocal of [this]. - Float32x4 reciprocalSqrt() { - double _x = Math.sqrt(1.0 / x); - double _y = Math.sqrt(1.0 / y); - double _z = Math.sqrt(1.0 / z); - double _w = Math.sqrt(1.0 / w); - return NativeFloat32x4._doubles(_x, _y, _z, _w); - } -} - -/// Interface of Dart Int32x4 and operations. -/// Int32x4 stores 4 32-bit bit-masks in "lanes". -/// The lanes are "x", "y", "z", and "w" respectively. -class NativeInt32x4 implements Int32x4 { - final int x; - final int y; - final int z; - final int w; - - static final _list = NativeInt32List(4); - - static _truncate(x) { - _list[0] = x; - return _list[0]; - } - - NativeInt32x4(int x, int y, int z, int w) - : this.x = _truncate(x), - this.y = _truncate(y), - this.z = _truncate(z), - this.w = _truncate(w) { - if (x != this.x && x is! int) throw ArgumentError(x); - if (y != this.y && y is! int) throw ArgumentError(y); - if (z != this.z && z is! int) throw ArgumentError(z); - if (w != this.w && w is! int) throw ArgumentError(w); - } - - NativeInt32x4.bool(bool x, bool y, bool z, bool w) - : this.x = x ? -1 : 0, - this.y = y ? -1 : 0, - this.z = z ? -1 : 0, - this.w = w ? -1 : 0; - - /// Returns a bit-wise copy of [f] as a Int32x4. - factory NativeInt32x4.fromFloat32x4Bits(Float32x4 f) { - NativeFloat32List floatList = NativeFloat32x4._list; - floatList[0] = f.x; - floatList[1] = f.y; - floatList[2] = f.z; - floatList[3] = f.w; - Int32List view = floatList.buffer.asInt32List(); - return NativeInt32x4._truncated(view[0], view[1], view[2], view[3]); - } - - NativeInt32x4._truncated(this.x, this.y, this.z, this.w); - - String toString() => '[$x, $y, $z, $w]'; - - /// The bit-wise or operator. - Int32x4 operator |(Int32x4 other) { - // Dart2js uses unsigned results for bit-operations. - // We use "JS" to fall back to the signed versions. - return NativeInt32x4._truncated( - JS("int", "# | #", x, other.x), - JS("int", "# | #", y, other.y), - JS("int", "# | #", z, other.z), - JS("int", "# | #", w, other.w)); - } - - /// The bit-wise and operator. - Int32x4 operator &(Int32x4 other) { - // Dart2js uses unsigned results for bit-operations. - // We use "JS" to fall back to the signed versions. - return NativeInt32x4._truncated( - JS("int", "# & #", x, other.x), - JS("int", "# & #", y, other.y), - JS("int", "# & #", z, other.z), - JS("int", "# & #", w, other.w)); - } - - /// The bit-wise xor operator. - Int32x4 operator ^(Int32x4 other) { - // Dart2js uses unsigned results for bit-operations. - // We use "JS" to fall back to the signed versions. - return NativeInt32x4._truncated( - JS("int", "# ^ #", x, other.x), - JS("int", "# ^ #", y, other.y), - JS("int", "# ^ #", z, other.z), - JS("int", "# ^ #", w, other.w)); - } - - Int32x4 operator +(Int32x4 other) { - // Avoid going through the typed array by "| 0" the result. - return NativeInt32x4._truncated( - JS("int", "(# + #) | 0", x, other.x), - JS("int", "(# + #) | 0", y, other.y), - JS("int", "(# + #) | 0", z, other.z), - JS("int", "(# + #) | 0", w, other.w)); - } - - Int32x4 operator -(Int32x4 other) { - // Avoid going through the typed array by "| 0" the result. - return NativeInt32x4._truncated( - JS("int", "(# - #) | 0", x, other.x), - JS("int", "(# - #) | 0", y, other.y), - JS("int", "(# - #) | 0", z, other.z), - JS("int", "(# - #) | 0", w, other.w)); - } - - Int32x4 operator -() { - // Avoid going through the typed array by "| 0" the result. - return NativeInt32x4._truncated( - JS("int", "(-#) | 0", x), - JS("int", "(-#) | 0", y), - JS("int", "(-#) | 0", z), - JS("int", "(-#) | 0", w)); - } - - /// Extract the top bit from each lane return them in the first 4 bits. - int get signMask { - int mx = (x & 0x80000000) >> 31; - int my = (y & 0x80000000) >> 31; - int mz = (z & 0x80000000) >> 31; - int mw = (w & 0x80000000) >> 31; - return mx | my << 1 | mz << 2 | mw << 3; - } - - /// Shuffle the lane values. [mask] must be one of the 256 shuffle constants. - Int32x4 shuffle(int mask) { - if ((mask < 0) || (mask > 255)) { - throw RangeError.range(mask, 0, 255, "mask"); - } - _list[0] = x; - _list[1] = y; - _list[2] = z; - _list[3] = w; - int _x = _list[mask & 0x3]; - int _y = _list[(mask >> 2) & 0x3]; - int _z = _list[(mask >> 4) & 0x3]; - int _w = _list[(mask >> 6) & 0x3]; - return NativeInt32x4._truncated(_x, _y, _z, _w); - } - - /// Shuffle the lane values in [this] and [other]. The returned - /// Int32x4 will have XY lanes from [this] and ZW lanes from [other]. - /// Uses the same [mask] as [shuffle]. - Int32x4 shuffleMix(Int32x4 other, int mask) { - if ((mask < 0) || (mask > 255)) { - throw RangeError.range(mask, 0, 255, "mask"); - } - _list[0] = x; - _list[1] = y; - _list[2] = z; - _list[3] = w; - int _x = _list[mask & 0x3]; - int _y = _list[(mask >> 2) & 0x3]; - - _list[0] = other.x; - _list[1] = other.y; - _list[2] = other.z; - _list[3] = other.w; - int _z = _list[(mask >> 4) & 0x3]; - int _w = _list[(mask >> 6) & 0x3]; - return NativeInt32x4._truncated(_x, _y, _z, _w); - } - - /// Returns a new [Int32x4] copied from [this] with a new x value. - Int32x4 withX(int x) { - int _x = _truncate(x); - return NativeInt32x4._truncated(_x, y, z, w); - } - - /// Returns a new [Int32x4] copied from [this] with a new y value. - Int32x4 withY(int y) { - int _y = _truncate(y); - return NativeInt32x4._truncated(x, _y, z, w); - } - - /// Returns a new [Int32x4] copied from [this] with a new z value. - Int32x4 withZ(int z) { - int _z = _truncate(z); - return NativeInt32x4._truncated(x, y, _z, w); - } - - /// Returns a new [Int32x4] copied from [this] with a new w value. - Int32x4 withW(int w) { - int _w = _truncate(w); - return NativeInt32x4._truncated(x, y, z, _w); - } - - /// Extracted x value. Returns `false` for 0, `true` for any other value. - bool get flagX => x != 0; - - /// Extracted y value. Returns `false` for 0, `true` for any other value. - bool get flagY => y != 0; - - /// Extracted z value. Returns `false` for 0, `true` for any other value. - bool get flagZ => z != 0; - - /// Extracted w value. Returns `false` for 0, `true` for any other value. - bool get flagW => w != 0; - - /// Returns a new [Int32x4] copied from [this] with a new x value. - Int32x4 withFlagX(bool flagX) { - int _x = flagX ? -1 : 0; - return NativeInt32x4._truncated(_x, y, z, w); - } - - /// Returns a new [Int32x4] copied from [this] with a new y value. - Int32x4 withFlagY(bool flagY) { - int _y = flagY ? -1 : 0; - return NativeInt32x4._truncated(x, _y, z, w); - } - - /// Returns a new [Int32x4] copied from [this] with a new z value. - Int32x4 withFlagZ(bool flagZ) { - int _z = flagZ ? -1 : 0; - return NativeInt32x4._truncated(x, y, _z, w); - } - - /// Returns a new [Int32x4] copied from [this] with a new w value. - Int32x4 withFlagW(bool flagW) { - int _w = flagW ? -1 : 0; - return NativeInt32x4._truncated(x, y, z, _w); - } - - /// Merge [trueValue] and [falseValue] based on [this]' bit mask: - /// Select bit from [trueValue] when bit in [this] is on. - /// Select bit from [falseValue] when bit in [this] is off. - Float32x4 select(Float32x4 trueValue, Float32x4 falseValue) { - var floatList = NativeFloat32x4._list; - var intView = NativeFloat32x4._uint32view; - - floatList[0] = trueValue.x; - floatList[1] = trueValue.y; - floatList[2] = trueValue.z; - floatList[3] = trueValue.w; - int stx = intView[0]; - int sty = intView[1]; - int stz = intView[2]; - int stw = intView[3]; - - floatList[0] = falseValue.x; - floatList[1] = falseValue.y; - floatList[2] = falseValue.z; - floatList[3] = falseValue.w; - int sfx = intView[0]; - int sfy = intView[1]; - int sfz = intView[2]; - int sfw = intView[3]; - int _x = (x & stx) | (~x & sfx); - int _y = (y & sty) | (~y & sfy); - int _z = (z & stz) | (~z & sfz); - int _w = (w & stw) | (~w & sfw); - intView[0] = _x; - intView[1] = _y; - intView[2] = _z; - intView[3] = _w; - return NativeFloat32x4._truncated( - floatList[0], floatList[1], floatList[2], floatList[3]); - } -} - -class NativeFloat64x2 implements Float64x2 { - final double x; - final double y; - - static NativeFloat64List _list = NativeFloat64List(2); - static Uint32List _uint32View = _list.buffer.asUint32List(); - - NativeFloat64x2(this.x, this.y) { - if (x is! num) throw ArgumentError(x); - if (y is! num) throw ArgumentError(y); - } - - NativeFloat64x2.splat(double v) : this(v, v); - - NativeFloat64x2.zero() : this.splat(0.0); - - NativeFloat64x2.fromFloat32x4(Float32x4 v) : this(v.x, v.y); - - /// Arguments [x] and [y] must be doubles. - NativeFloat64x2._doubles(this.x, this.y); - - String toString() => '[$x, $y]'; - - /// Addition operator. - Float64x2 operator +(Float64x2 other) { - return NativeFloat64x2._doubles(x + other.x, y + other.y); - } - - /// Negate operator. - Float64x2 operator -() { - return NativeFloat64x2._doubles(-x, -y); - } - - /// Subtraction operator. - Float64x2 operator -(Float64x2 other) { - return NativeFloat64x2._doubles(x - other.x, y - other.y); - } - - /// Multiplication operator. - Float64x2 operator *(Float64x2 other) { - return NativeFloat64x2._doubles(x * other.x, y * other.y); - } - - /// Division operator. - Float64x2 operator /(Float64x2 other) { - return NativeFloat64x2._doubles(x / other.x, y / other.y); - } - - /// Returns a copy of [this] each lane being scaled by [s]. - Float64x2 scale(double s) { - return NativeFloat64x2._doubles(x * s, y * s); - } - - /// Returns the absolute value of this [Float64x2]. - Float64x2 abs() { - return NativeFloat64x2._doubles(x.abs(), y.abs()); - } - - /// Clamps [this] to be in the range [lowerLimit]-[upperLimit]. - Float64x2 clamp(Float64x2 lowerLimit, Float64x2 upperLimit) { - double _lx = lowerLimit.x; - double _ly = lowerLimit.y; - double _ux = upperLimit.x; - double _uy = upperLimit.y; - double _x = x; - double _y = y; - // MAX(MIN(self, upper), lower). - _x = _x > _ux ? _ux : _x; - _y = _y > _uy ? _uy : _y; - _x = _x < _lx ? _lx : _x; - _y = _y < _ly ? _ly : _y; - return NativeFloat64x2._doubles(_x, _y); - } - - /// Extract the sign bits from each lane return them in the first 2 bits. - int get signMask { - var view = _uint32View; - _list[0] = x; - _list[1] = y; - var mx = (view[1] & 0x80000000) >> 31; - var my = (view[3] & 0x80000000) >> 31; - return mx | my << 1; - } - - /// Returns a new [Float64x2] copied from [this] with a new x value. - Float64x2 withX(double x) { - if (x is! num) throw ArgumentError(x); - return NativeFloat64x2._doubles(x, y); - } - - /// Returns a new [Float64x2] copied from [this] with a new y value. - Float64x2 withY(double y) { - if (y is! num) throw ArgumentError(y); - return NativeFloat64x2._doubles(x, y); - } - - /// Returns the lane-wise minimum value in [this] or [other]. - Float64x2 min(Float64x2 other) { - return NativeFloat64x2._doubles( - x < other.x ? x : other.x, y < other.y ? y : other.y); - } - - /// Returns the lane-wise maximum value in [this] or [other]. - Float64x2 max(Float64x2 other) { - return NativeFloat64x2._doubles( - x > other.x ? x : other.x, y > other.y ? y : other.y); - } - - /// Returns the lane-wise square root of [this]. - Float64x2 sqrt() { - return NativeFloat64x2._doubles(Math.sqrt(x), Math.sqrt(y)); - } -} - -/// Checks that the value is a Uint32. If not, it's not valid as an array -/// index or offset. Also ensures that the value is non-negative. -bool _isInvalidArrayIndex(int index) { - return (JS('!', '(# >>> 0 !== #)', index, index)); -} - -/// Checks that [index] is a valid index into [list] which has length [length]. -/// -/// That is, [index] is an integer in the range `0..length - 1`. -void _checkValidIndex(int index, List list, int length) { - if (_isInvalidArrayIndex(index) || JS('!', '#', index) >= length) { - throw diagnoseIndexError(list, index); - } -} - -/// Checks that [start] and [end] form a range of a list of length [length]. -/// -/// That is: `start` and `end` are integers with `0 <= start <= end <= length`. -/// If `end` is `null` in which case it is considered to be `length` -/// -/// Returns the actual value of `end`, which is `length` if `end` is `null`, and -/// the original value of `end` otherwise. -int _checkValidRange(int start, int? end, int length) { - if (_isInvalidArrayIndex(start) || // Ensures start is non-negative int. - ((end == null) - ? start > length - : (_isInvalidArrayIndex(end) || start > end || end > length))) { - throw diagnoseRangeError(start, end, length); - } - if (end == null) return length; - return end; -} diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/preambles/README b/sdk_nnbd/lib/_internal/js_dev_runtime/private/preambles/README deleted file mode 100644 index 7eb614ef625..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/preambles/README +++ /dev/null @@ -1,17 +0,0 @@ -The files in this directory polyfill some of the functionality that browsers -provide. When running command-line JS evaluators it is frequently necessary to -execute the preambles before executing the output of dart2js. - -=Usage= -- d8: - d8 /lib/_internal/compiler/js_lib/preambles/d8.js .js - -- jsshell: - jsshell -f /lib/_internal/compiler/js_lib/preambles/d8.js -f .js - -- node.js: - The d8 preamble file works for most programs. - - Unfortunately we are not aware of any easy way to provide multiple input files - to node. It seems to be necessary to concatenate the d8 preamble and the - dart2js output. diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/preambles/d8.js b/sdk_nnbd/lib/_internal/js_dev_runtime/private/preambles/d8.js deleted file mode 100644 index 0c432f514d0..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/preambles/d8.js +++ /dev/null @@ -1,291 +0,0 @@ -// Copyright (c) 2014, 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. - -// Javascript preamble, that lets the output of dart2js run on V8's d8 shell. - -// Node wraps files and provides them with a different `this`. The global -// `this` can be accessed through `global`. - -var self = this; -if (typeof global != "undefined") self = global; // Node.js. - -(function(self) { - // Using strict mode to avoid accidentally defining global variables. - "use strict"; // Should be first statement of this function. - - // Location (Uri.base) - - var workingDirectory; - // TODO(sgjesse): This does not work on Windows. - if (typeof os == "object" && "system" in os) { - // V8. - workingDirectory = os.system("pwd"); - var length = workingDirectory.length; - if (workingDirectory[length - 1] == '\n') { - workingDirectory = workingDirectory.substring(0, length - 1); - } - } else if (typeof process != "undefined" && - typeof process.cwd == "function") { - // Node.js. - workingDirectory = process.cwd(); - } - self.location = { href: "file://" + workingDirectory + "/" }; - - // Event loop. - // Task queue as cyclic list queue. - var taskQueue = new Array(8); // Length is power of 2. - var head = 0; - var tail = 0; - var mask = taskQueue.length - 1; - function addTask(elem) { - taskQueue[head] = elem; - head = (head + 1) & mask; - if (head == tail) _growTaskQueue(); - } - function removeTask() { - if (head == tail) return; - var result = taskQueue[tail]; - taskQueue[tail] = undefined; - tail = (tail + 1) & mask; - return result; - } - function _growTaskQueue() { - // head == tail. - var length = taskQueue.length; - var split = head; - taskQueue.length = length * 2; - if (split * 2 < length) { // split < length / 2 - for (var i = 0; i < split; i++) { - taskQueue[length + i] = taskQueue[i]; - taskQueue[i] = undefined; - } - head += length; - } else { - for (var i = split; i < length; i++) { - taskQueue[length + i] = taskQueue[i]; - taskQueue[i] = undefined; - } - tail += length; - } - mask = taskQueue.length - 1; - } - - // Mapping from timer id to timer function. - // The timer id is written on the function as .$timerId. - // That field is cleared when the timer is cancelled, but it is not returned - // from the queue until its time comes. - var timerIds = {}; - var timerIdCounter = 1; // Counter used to assign ids. - - // Zero-timer queue as simple array queue using push/shift. - var zeroTimerQueue = []; - - function addTimer(f, ms) { - var id = timerIdCounter++; - f.$timerId = id; - timerIds[id] = f; - if (ms == 0 && !isNextTimerDue()) { - zeroTimerQueue.push(f); - } else { - addDelayedTimer(f, ms); - } - return id; - } - - function nextZeroTimer() { - while (zeroTimerQueue.length > 0) { - var action = zeroTimerQueue.shift(); - if (action.$timerId !== undefined) return action; - } - } - - function nextEvent() { - var action = removeTask(); - if (action) { - return action; - } - do { - action = nextZeroTimer(); - if (action) break; - var nextList = nextDelayedTimerQueue(); - if (!nextList) { - return; - } - var newTime = nextList.shift(); - advanceTimeTo(newTime); - zeroTimerQueue = nextList; - } while (true) - var id = action.$timerId; - clearTimerId(action, id); - return action; - } - - // Mocking time. - var timeOffset = 0; - var now = function() { - // Install the mock Date object only once. - // Following calls to "now" will just use the new (mocked) Date.now - // method directly. - installMockDate(); - now = Date.now; - return Date.now(); - }; - var originalDate = Date; - var originalNow = originalDate.now; - function advanceTimeTo(time) { - var now = originalNow(); - if (timeOffset < time - now) { - timeOffset = time - now; - } - } - function installMockDate() { - var NewDate = function Date(Y, M, D, h, m, s, ms) { - if (this instanceof Date) { - // Assume a construct call. - switch (arguments.length) { - case 0: return new originalDate(originalNow() + timeOffset); - case 1: return new originalDate(Y); - case 2: return new originalDate(Y, M); - case 3: return new originalDate(Y, M, D); - case 4: return new originalDate(Y, M, D, h); - case 5: return new originalDate(Y, M, D, h, m); - case 6: return new originalDate(Y, M, D, h, m, s); - default: return new originalDate(Y, M, D, h, m, s, ms); - } - } - return new originalDate(originalNow() + timeOffset).toString(); - }; - NewDate.UTC = originalDate.UTC; - NewDate.parse = originalDate.parse; - NewDate.now = function now() { return originalNow() + timeOffset; }; - NewDate.prototype = originalDate.prototype; - originalDate.prototype.constructor = NewDate; - Date = NewDate; - } - - // Heap priority queue with key index. - // Each entry is list of [timeout, callback1 ... callbackn]. - var timerHeap = []; - var timerIndex = {}; - function addDelayedTimer(f, ms) { - var timeout = now() + ms; - var timerList = timerIndex[timeout]; - if (timerList == null) { - timerList = [timeout, f]; - timerIndex[timeout] = timerList; - var index = timerHeap.length; - timerHeap.length += 1; - bubbleUp(index, timeout, timerList); - } else { - timerList.push(f); - } - } - - function isNextTimerDue() { - if (timerHeap.length == 0) return false; - var head = timerHeap[0]; - return head[0] < originalNow() + timeOffset; - } - - function nextDelayedTimerQueue() { - if (timerHeap.length == 0) return null; - var result = timerHeap[0]; - var last = timerHeap.pop(); - if (timerHeap.length > 0) { - bubbleDown(0, last[0], last); - } - return result; - } - - function bubbleUp(index, key, value) { - while (index != 0) { - var parentIndex = (index - 1) >> 1; - var parent = timerHeap[parentIndex]; - var parentKey = parent[0]; - if (key > parentKey) break; - timerHeap[index] = parent; - index = parentIndex; - } - timerHeap[index] = value; - } - - function bubbleDown(index, key, value) { - while (true) { - var leftChildIndex = index * 2 + 1; - if (leftChildIndex >= timerHeap.length) break; - var minChildIndex = leftChildIndex; - var minChild = timerHeap[leftChildIndex]; - var minChildKey = minChild[0]; - var rightChildIndex = leftChildIndex + 1; - if (rightChildIndex < timerHeap.length) { - var rightChild = timerHeap[rightChildIndex]; - var rightKey = rightChild[0]; - if (rightKey < minChildKey) { - minChildIndex = rightChildIndex; - minChild = rightChild; - minChildKey = rightKey; - } - } - if (minChildKey > key) break; - timerHeap[index] = minChild; - index = minChildIndex; - } - timerHeap[index] = value; - } - - function addInterval(f, ms) { - var id = timerIdCounter++; - function repeat() { - // Reactivate with the same id. - repeat.$timerId = id; - timerIds[id] = repeat; - addDelayedTimer(repeat, ms); - f(); - } - repeat.$timerId = id; - timerIds[id] = repeat; - addDelayedTimer(repeat, ms); - return id; - } - - function cancelTimer(id) { - var f = timerIds[id]; - if (f == null) return; - clearTimerId(f, id); - } - - function clearTimerId(f, id) { - f.$timerId = undefined; - delete timerIds[id]; - } - - function eventLoop(action) { - while (action) { - try { - action(); - } catch (e) { - if (typeof onerror == "function") { - onerror(e, null, -1); - } else { - throw e; - } - } - action = nextEvent(); - } - } - - // Global properties. "self" refers to the global object, so adding a - // property to "self" defines a global variable. - self.dartMainRunner = function(main, args) { - // Initialize. - var action = function() { main(args); } - eventLoop(action); - }; - self.setTimeout = addTimer; - self.clearTimeout = cancelTimer; - self.setInterval = addInterval; - self.clearInterval = cancelTimer; - self.scheduleImmediate = addTask; - self.self = self; -})(self); diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/preambles/jsshell.js b/sdk_nnbd/lib/_internal/js_dev_runtime/private/preambles/jsshell.js deleted file mode 100644 index 8f13bcc8f28..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/preambles/jsshell.js +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) 2014, 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. - -// Javascript preamble, that lets the output of dart2js run on JSShell. - -(function(self) { - // Using strict mode to avoid accidentally defining global variables. - "use strict"; // Should be first statement of this function. - - // Location (Uri.base) - - var workingDirectory = environment["PWD"]; - self.location = { href: "file://" + workingDirectory + "/" }; - - // Global properties. "self" refers to the global object, so adding a - // property to "self" defines a global variable. - self.self = self; -})(this) diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/profile.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/profile.dart deleted file mode 100644 index ede43638034..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/profile.dart +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright (c) 2017, 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. - -/// This file supports profiling dynamic calls. -part of dart._debugger; - -class _MethodStats { - final String typeName; - final String frame; - double count = 0.0; - - _MethodStats(this.typeName, this.frame); -} - -class _CallMethodRecord { - var jsError; - var type; - - _CallMethodRecord(this.jsError, this.type); -} - -/// Size for the random sample of dynamic calls. -int _callRecordSampleSize = 5000; - -/// If the number of dynamic calls exceeds [_callRecordSampleSize] this list -/// will represent a random sample of the dynamic calls made. -var _callMethodRecords = <_CallMethodRecord>[]; - -/// If the number of dynamic calls exceeds [_callRecordSampleSize] this value -/// will be greater than [_callMethodRecords.length]. -int _totalCallRecords = 0; - -/// Minimum number of samples to consider a profile entry relevant. -/// This could be set a lot higher. We set this value so users are not -/// confused into thinking that a dynamic call that occurred once but was -/// randomly included in the sample is relevant. -num _minCount = 2; - -/// Cache mapping from raw stack frames to source mapped stack frames to -/// speedup lookup of source map frames when running the profiler. -/// The number of source map entries looked up makes caching more important -/// in this case than for typical source map use cases. -var _frameMappingCache = {}; - -List> getDynamicStats() { - // Process the accumulated method stats. This may be quite slow as processing - // stack traces is expensive. If there are performance blockers, we should - // switch to a sampling approach that caps the number of _callMethodRecords - // and uses random sampling to decide whether to add each additional record - // to the sample. Main change required is that we need to still show the total - // raw number of dynamic calls so that the magnitude of the dynamic call - // performance hit is clear to users. - - var callMethodStats = {}; - if (_callMethodRecords.length > 0) { - // Ratio between total record count and sampled records count. - var recordRatio = _totalCallRecords / _callMethodRecords.length; - for (var record in _callMethodRecords) { - String stackStr = JS('!', '#.stack', record.jsError); - var frames = stackStr.split('\n'); - // Skip first two lines as the first couple frames are from the dart - // runtime. - var src = frames - .skip(2) - .map((f) => _frameMappingCache.putIfAbsent( - f, () => stackTraceMapper!('\n$f'))) - .firstWhere((f) => !f.startsWith('dart:'), orElse: () => ''); - - var actualTypeName = dart.typeName(record.type); - callMethodStats - .putIfAbsent( - "$actualTypeName <$src>", () => _MethodStats(actualTypeName, src)) - .count += recordRatio; - } - - // filter out all calls that did not occur at least _minCount times in the - // random sample if we are dealing with a random sample instead of a - // complete profile. - if (_totalCallRecords != _callMethodRecords.length) { - for (var k in callMethodStats.keys.toList()) { - var stats = callMethodStats[k]!; - var threshold = _minCount * recordRatio; - if (stats.count + 0.001 < threshold) { - callMethodStats.remove(k); - } - } - } - } - _callMethodRecords.clear(); - _totalCallRecords = 0; - var keys = callMethodStats.keys.toList(); - keys.sort( - (a, b) => callMethodStats[b]!.count.compareTo(callMethodStats[a]!.count)); - var ret = >[]; - for (var key in keys) { - var stats = callMethodStats[key]!; - ret.add([stats.typeName, stats.frame, stats.count.round()]); - } - return ret; -} - -clearDynamicStats() { - _callMethodRecords.clear(); -} - -// We need to set this property while the sdk is only partially initialized -// so we cannot use a regular Dart field. -bool get _trackProfile => JS('!', 'dart.__trackProfile'); - -trackCall(obj) { - if (JS('!', '!#', _trackProfile)) return; - int index = -1; - _totalCallRecords++; - if (_callMethodRecords.length == _callRecordSampleSize) { - // Ensure that each sample has an equal - // _callRecordSampleSize / _totalCallRecords chance of inclusion - // by choosing to include the new record in the sample the with the - // appropriate probability randomly evicting one of the existing records. - // Unfortunately we can't use the excellent Random.nextInt method defined - // by Dart from within this library. - index = JS('!', 'Math.floor(Math.random() * #)', _totalCallRecords); - if (index >= _callMethodRecords.length) return; // don't sample - } - var record = - _CallMethodRecord(JS('', 'new Error()'), dart.getReifiedType(obj)); - if (index == -1) { - _callMethodRecords.add(record); - } else { - _callMethodRecords[index] = record; - } -} diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/regexp_helper.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/regexp_helper.dart deleted file mode 100644 index 6ce53ac45a6..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/regexp_helper.dart +++ /dev/null @@ -1,289 +0,0 @@ -// Copyright (c) 2012, 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. - -part of dart._js_helper; - -// Helper method used by internal libraries. -regExpGetNative(JSSyntaxRegExp regexp) => regexp._nativeRegExp; - -/** - * Returns a native version of the RegExp with the global flag set. - * - * The RegExp's `lastIndex` property is zero when it is returned. - * - * The returned regexp is shared, and its `lastIndex` property may be - * modified by other uses, so the returned regexp must be used immediately - * when it's returned, with no user-provided code run in between. - */ -regExpGetGlobalNative(JSSyntaxRegExp regexp) { - var nativeRegexp = regexp._nativeGlobalVersion; - JS("void", "#.lastIndex = 0", nativeRegexp); - return nativeRegexp; -} - -/** - * Computes the number of captures in a regexp. - * - * This currently involves creating a new RegExp object with a different - * source and running it against the empty string (the last part is usually - * fast). - * - * The JSSyntaxRegExp could cache the result, and set the cache any time - * it finds a match. - */ -int regExpCaptureCount(JSSyntaxRegExp regexp) { - var nativeAnchoredRegExp = regexp._nativeAnchoredVersion; - JSExtendableArray match = - JS('JSExtendableArray', "#.exec('')", nativeAnchoredRegExp); - // The native-anchored regexp always have one capture more than the original, - // and always matches the empty string. - return match.length - 2; -} - -class JSSyntaxRegExp implements RegExp { - final String pattern; - final _nativeRegExp; - var _nativeGlobalRegExp; - var _nativeAnchoredRegExp; - - String toString() => - 'RegExp/$pattern/' + JS('!', '#.flags', _nativeRegExp); - - JSSyntaxRegExp(String source, - {bool multiLine = false, - bool caseSensitive = true, - bool unicode = false, - bool dotAll = false}) - : this.pattern = source, - this._nativeRegExp = makeNative( - source, multiLine, caseSensitive, unicode, dotAll, false); - - get _nativeGlobalVersion { - if (_nativeGlobalRegExp != null) return _nativeGlobalRegExp; - return _nativeGlobalRegExp = makeNative( - pattern, _isMultiLine, _isCaseSensitive, _isUnicode, _isDotAll, true); - } - - get _nativeAnchoredVersion { - if (_nativeAnchoredRegExp != null) return _nativeAnchoredRegExp; - // An "anchored version" of a regexp is created by adding "|()" to the - // source. This means that the regexp always matches at the first position - // that it tries, and you can see if the original regexp matched, or it - // was the added zero-width match that matched, by looking at the last - // capture. If it is a String, the match participated, otherwise it didn't. - return _nativeAnchoredRegExp = makeNative("$pattern|()", _isMultiLine, - _isCaseSensitive, _isUnicode, _isDotAll, true); - } - - bool get _isMultiLine => JS("bool", "#.multiline", _nativeRegExp); - bool get _isCaseSensitive => JS("bool", "!#.ignoreCase", _nativeRegExp); - bool get _isUnicode => JS("bool", "#.unicode", _nativeRegExp); - // The "dotAll" property is not available on all browsers, but our internals - // currently assume this is non-null. Coerce to false if not present. - bool get _isDotAll => JS("bool", "#.dotAll == true", _nativeRegExp); - - static makeNative(@nullCheck String source, bool multiLine, - bool caseSensitive, bool unicode, bool dotAll, bool global) { - String m = multiLine ? 'm' : ''; - String i = caseSensitive ? '' : 'i'; - String u = unicode ? 'u' : ''; - String s = dotAll ? 's' : ''; - String g = global ? 'g' : ''; - // We're using the JavaScript's try catch instead of the Dart one - // to avoid dragging in Dart runtime support just because of using - // RegExp. - var regexp = JS( - '', - '(function() {' - 'try {' - 'return new RegExp(#, # + # + # + # + #);' - '} catch (e) {' - 'return e;' - '}' - '})()', - source, - m, - i, - u, - s, - g); - if (JS('!', '# instanceof RegExp', regexp)) return regexp; - // The returned value is the JavaScript exception. Turn it into a - // Dart exception. - String errorMessage = JS('!', r'String(#)', regexp); - throw FormatException("Illegal RegExp pattern: $source, $errorMessage"); - } - - RegExpMatch? firstMatch(@nullCheck String string) { - List? m = - JS('JSExtendableArray|Null', r'#.exec(#)', _nativeRegExp, string); - if (m == null) return null; - return _MatchImplementation(this, m); - } - - @notNull - bool hasMatch(@nullCheck String string) { - return JS('!', r'#.test(#)', _nativeRegExp, string); - } - - String? stringMatch(String string) { - var match = firstMatch(string); - if (match != null) return match.group(0); - return null; - } - - Iterable allMatches(@nullCheck String string, - [@nullCheck int start = 0]) { - if (start < 0 || start > string.length) { - throw RangeError.range(start, 0, string.length); - } - return _AllMatchesIterable(this, string, start); - } - - RegExpMatch? _execGlobal(String string, int start) { - Object regexp = _nativeGlobalVersion; - JS("void", "#.lastIndex = #", regexp, start); - List? match = - JS("JSExtendableArray|Null", "#.exec(#)", regexp, string); - if (match == null) return null; - return _MatchImplementation(this, match); - } - - RegExpMatch? _execAnchored(String string, int start) { - Object regexp = _nativeAnchoredVersion; - JS("void", "#.lastIndex = #", regexp, start); - List? match = - JS("JSExtendableArray|Null", "#.exec(#)", regexp, string); - if (match == null) return null; - // If the last capture group participated, the original regexp did not - // match at the start position. - if (match[match.length - 1] != null) return null; - match.length -= 1; - return _MatchImplementation(this, match); - } - - Match? matchAsPrefix(String string, [int start = 0]) { - if (start < 0 || start > string.length) { - throw RangeError.range(start, 0, string.length); - } - return _execAnchored(string, start); - } - - bool get isMultiLine => _isMultiLine; - bool get isCaseSensitive => _isCaseSensitive; - bool get isUnicode => _isUnicode; - bool get isDotAll => _isDotAll; -} - -class _MatchImplementation implements RegExpMatch { - final Pattern pattern; - // Contains a JS RegExp match object. - // It is an Array of String values with extra "index" and "input" properties. - final List _match; - - _MatchImplementation(this.pattern, this._match) { - assert(JS("var", "#.input", _match) is String); - assert(JS("var", "#.index", _match) is int); - } - - String get input => JS("String", "#.input", _match); - int get start => JS("int", "#.index", _match); - int get end => start + _match[0].length; - - String? group(int index) => _match[index]; - String? operator [](int index) => group(index); - int get groupCount => _match.length - 1; - - List groups(List groups) { - List out = []; - for (int i in groups) { - out.add(group(i)); - } - return out; - } - - String? namedGroup(String name) { - var groups = JS('Object|Null', '#.groups', _match); - if (groups != null) { - var result = JS('', '#[#]', groups, name); - if (result != null || JS('!', '# in #', name, groups)) { - return result; - } - } - throw ArgumentError.value(name, "name", "Not a capture group name"); - } - - Iterable get groupNames { - var groups = JS('Object|Null', '#.groups', _match); - if (groups != null) { - var keys = JSArray.of(JS('', 'Object.keys(#)', groups)); - return SubListIterable(keys, 0, null); - } - return Iterable.empty(); - } -} - -class _AllMatchesIterable extends IterableBase { - final JSSyntaxRegExp _re; - final String _string; - final int _start; - - _AllMatchesIterable(this._re, this._string, this._start); - - Iterator get iterator => - _AllMatchesIterator(_re, _string, _start); -} - -class _AllMatchesIterator implements Iterator { - final JSSyntaxRegExp _regExp; - String? _string; - int _nextIndex; - RegExpMatch? _current; - - _AllMatchesIterator(this._regExp, this._string, this._nextIndex); - - RegExpMatch get current => _current as RegExpMatch; - - static bool _isLeadSurrogate(int c) { - return c >= 0xd800 && c <= 0xdbff; - } - - static bool _isTrailSurrogate(int c) { - return c >= 0xdc00 && c <= 0xdfff; - } - - bool moveNext() { - var string = _string; - if (string == null) return false; - if (_nextIndex <= string.length) { - var match = _regExp._execGlobal(string, _nextIndex); - if (match != null) { - _current = match; - int nextIndex = match.end; - if (match.start == nextIndex) { - // Zero-width match. Advance by one more, unless the regexp - // is in unicode mode and it would put us within a surrogate - // pair. In that case, advance past the code point as a whole. - if (_regExp.isUnicode && - _nextIndex + 1 < string.length && - _isLeadSurrogate(string.codeUnitAt(_nextIndex)) && - _isTrailSurrogate(string.codeUnitAt(_nextIndex + 1))) { - nextIndex++; - } - nextIndex++; - } - _nextIndex = nextIndex; - return true; - } - } - _current = null; - _string = null; // Marks iteration as ended. - return false; - } -} - -/** Find the first match of [regExp] in [string] at or after [start]. */ -RegExpMatch? firstMatchAfter(JSSyntaxRegExp regExp, String string, int start) { - return regExp._execGlobal(string, start); -} diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/string_helper.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/string_helper.dart deleted file mode 100644 index 7a0de57baf9..00000000000 --- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/string_helper.dart +++ /dev/null @@ -1,297 +0,0 @@ -// Copyright (c) 2012, 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. - -part of dart._js_helper; - -@notNull -int stringIndexOfStringUnchecked(receiver, other, startIndex) { - return JS('!', '#.indexOf(#, #)', receiver, other, startIndex); -} - -@notNull -String substring1Unchecked(receiver, startIndex) { - return JS('!', '#.substring(#)', receiver, startIndex); -} - -@notNull -String substring2Unchecked(receiver, startIndex, endIndex) { - return JS('!', '#.substring(#, #)', receiver, startIndex, endIndex); -} - -@notNull -bool stringContainsStringUnchecked(receiver, other, startIndex) { - return stringIndexOfStringUnchecked(receiver, other, startIndex) >= 0; -} - -class StringMatch implements Match { - const StringMatch(int this.start, String this.input, String this.pattern); - - int get end => start + pattern.length; - String operator [](int g) => group(g); - int get groupCount => 0; - - String group(int group_) { - if (group_ != 0) { - throw RangeError.value(group_); - } - return pattern; - } - - List groups(List groups_) { - List result = []; - for (int g in groups_) { - result.add(group(g)); - } - return result; - } - - final int start; - final String input; - final String pattern; -} - -Iterable allMatchesInStringUnchecked( - String pattern, String string, int startIndex) { - return _StringAllMatchesIterable(string, pattern, startIndex); -} - -class _StringAllMatchesIterable extends Iterable { - final String _input; - final String _pattern; - final int _index; - - _StringAllMatchesIterable(this._input, this._pattern, this._index); - - Iterator get iterator => - _StringAllMatchesIterator(_input, _pattern, _index); - - Match get first { - int index = stringIndexOfStringUnchecked(_input, _pattern, _index); - if (index >= 0) { - return StringMatch(index, _input, _pattern); - } - throw IterableElementError.noElement(); - } -} - -class _StringAllMatchesIterator implements Iterator { - final String _input; - final String _pattern; - int _index; - Match? _current; - - _StringAllMatchesIterator(this._input, this._pattern, this._index); - - bool moveNext() { - if (_index + _pattern.length > _input.length) { - _current = null; - return false; - } - var index = stringIndexOfStringUnchecked(_input, _pattern, _index); - if (index < 0) { - _index = _input.length + 1; - _current = null; - return false; - } - int end = index + _pattern.length; - _current = StringMatch(index, _input, _pattern); - // Empty match, don't start at same location again. - if (end == _index) end++; - _index = end; - return true; - } - - Match get current => _current!; -} - -@notNull -bool stringContainsUnchecked( - @notNull String receiver, @notNull other, int startIndex) { - if (other is String) { - return stringContainsStringUnchecked(receiver, other, startIndex); - } else if (other is JSSyntaxRegExp) { - return other.hasMatch(receiver.substring(startIndex)); - } else { - var substr = receiver.substring(startIndex); - return other.allMatches(substr).isNotEmpty; - } -} - -@notNull -String stringReplaceJS(String receiver, replacer, String replacement) { - // The JavaScript String.replace method recognizes replacement - // patterns in the replacement string. Dart does not have that - // behavior. - replacement = JS('!', r'#.replace(/\$/g, "$$$$")', replacement); - return JS('!', r'#.replace(#, #)', receiver, replacer, replacement); -} - -@notNull -String stringReplaceFirstRE(@notNull String receiver, JSSyntaxRegExp regexp, - String replacement, int startIndex) { - var match = regexp._execGlobal(receiver, startIndex); - if (match == null) return receiver; - var start = match.start; - var end = match.end; - return stringReplaceRangeUnchecked(receiver, start, end, replacement); -} - -/// Returns a string for a RegExp pattern that matches [string]. This is done by -/// escaping all RegExp metacharacters. -@notNull -String quoteStringForRegExp(string) { - return JS('!', r'#.replace(/[[\]{}()*+?.\\^$|]/g, "\\$&")', string); -} - -@notNull -String stringReplaceAllUnchecked(@notNull String receiver, - @nullCheck Pattern pattern, @nullCheck String replacement) { - if (pattern is String) { - if (pattern == "") { - if (receiver == "") { - return replacement; - } else { - StringBuffer result = StringBuffer(); - int length = receiver.length; - result.write(replacement); - for (int i = 0; i < length; i++) { - result.write(receiver[i]); - result.write(replacement); - } - return result.toString(); - } - } else { - return JS( - '!', '#.split(#).join(#)', receiver, pattern, replacement); - } - } else if (pattern is JSSyntaxRegExp) { - var re = regExpGetGlobalNative(pattern); - return stringReplaceJS(receiver, re, replacement); - } else { - // TODO(floitsch): implement generic String.replace (with patterns). - throw "String.replaceAll(Pattern) UNIMPLEMENTED"; - } -} - -String _matchString(Match match) => match[0]!; -String _stringIdentity(String string) => string; - -@notNull -String stringReplaceAllFuncUnchecked( - String receiver, - @nullCheck Pattern pattern, - String Function(Match)? onMatch, - String Function(String)? onNonMatch) { - if (onMatch == null) onMatch = _matchString; - if (onNonMatch == null) onNonMatch = _stringIdentity; - if (pattern is String) { - return stringReplaceAllStringFuncUnchecked( - receiver, pattern, onMatch, onNonMatch); - } - StringBuffer buffer = StringBuffer(); - int startIndex = 0; - for (Match match in pattern.allMatches(receiver)) { - buffer.write(onNonMatch(receiver.substring(startIndex, match.start))); - buffer.write(onMatch(match)); - startIndex = match.end; - } - buffer.write(onNonMatch(receiver.substring(startIndex))); - return buffer.toString(); -} - -@notNull -String stringReplaceAllEmptyFuncUnchecked(String receiver, - String onMatch(Match match), String onNonMatch(String nonMatch)) { - // Pattern is the empty string. - StringBuffer buffer = StringBuffer(); - int length = receiver.length; - int i = 0; - buffer.write(onNonMatch("")); - while (i < length) { - buffer.write(onMatch(StringMatch(i, receiver, ""))); - // Special case to avoid splitting a surrogate pair. - int code = receiver.codeUnitAt(i); - if ((code & ~0x3FF) == 0xD800 && length > i + 1) { - // Leading surrogate; - code = receiver.codeUnitAt(i + 1); - if ((code & ~0x3FF) == 0xDC00) { - // Matching trailing surrogate. - buffer.write(onNonMatch(receiver.substring(i, i + 2))); - i += 2; - continue; - } - } - buffer.write(onNonMatch(receiver[i])); - i++; - } - buffer.write(onMatch(StringMatch(i, receiver, ""))); - buffer.write(onNonMatch("")); - return buffer.toString(); -} - -@notNull -String stringReplaceAllStringFuncUnchecked(String receiver, String pattern, - String onMatch(Match match), String onNonMatch(String nonMatch)) { - int patternLength = pattern.length; - if (patternLength == 0) { - return stringReplaceAllEmptyFuncUnchecked(receiver, onMatch, onNonMatch); - } - int length = receiver.length; - StringBuffer buffer = StringBuffer(); - int startIndex = 0; - while (startIndex < length) { - int position = stringIndexOfStringUnchecked(receiver, pattern, startIndex); - if (position == -1) { - break; - } - buffer.write(onNonMatch(receiver.substring(startIndex, position))); - buffer.write(onMatch(StringMatch(position, receiver, pattern))); - startIndex = position + patternLength; - } - buffer.write(onNonMatch(receiver.substring(startIndex))); - return buffer.toString(); -} - -@notNull -String stringReplaceFirstUnchecked(@notNull String receiver, - @nullCheck Pattern pattern, String replacement, int startIndex) { - if (pattern is String) { - int index = stringIndexOfStringUnchecked(receiver, pattern, startIndex); - if (index < 0) return receiver; - int end = index + pattern.length; - return stringReplaceRangeUnchecked(receiver, index, end, replacement); - } - if (pattern is JSSyntaxRegExp) { - return startIndex == 0 - ? stringReplaceJS(receiver, regExpGetNative(pattern), replacement) - : stringReplaceFirstRE(receiver, pattern, replacement, startIndex); - } - Iterator matches = pattern.allMatches(receiver, startIndex).iterator; - if (!matches.moveNext()) return receiver; - Match match = matches.current; - return receiver.replaceRange(match.start, match.end, replacement); -} - -@notNull -String stringReplaceFirstMappedUnchecked(String receiver, Pattern pattern, - String replace(Match current), int startIndex) { - Iterator matches = pattern.allMatches(receiver, startIndex).iterator; - if (!matches.moveNext()) return receiver; - Match match = matches.current; - String replacement = "${replace(match)}"; - return receiver.replaceRange(match.start, match.end, replacement); -} - -@notNull -String stringJoinUnchecked(array, separator) { - return JS('!', r'#.join(#)', array, separator); -} - -@notNull -String stringReplaceRangeUnchecked( - String receiver, int start, int end, String replacement) { - String prefix = JS('!', '#.substring(0, #)', receiver, start); - String suffix = JS('!', '#.substring(#)', receiver, end); - return "$prefix$replacement$suffix"; -} diff --git a/sdk_nnbd/lib/_internal/js_runtime/.packages b/sdk_nnbd/lib/_internal/js_runtime/.packages deleted file mode 100644 index adf8b36f0da..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/.packages +++ /dev/null @@ -1,2 +0,0 @@ -# Generated by pub on 2015-12-07 17:08:11.724. -js_runtime:lib/ diff --git a/sdk_nnbd/lib/_internal/js_runtime/interceptors_sources.gni b/sdk_nnbd/lib/_internal/js_runtime/interceptors_sources.gni deleted file mode 100644 index b3a8760d0e2..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/interceptors_sources.gni +++ /dev/null @@ -1,5 +0,0 @@ -# Copyright (c) 2019, 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. - -interceptors_sdk_sources = [ "lib/interceptors.dart" ] diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/annotations.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/annotations.dart deleted file mode 100644 index f53c5f3c238..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/lib/annotations.dart +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) 2013, 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. - -part of _js_helper; - -/// Marks a class as native and defines its JavaScript name(s). -class Native { - final String name; - const Native(this.name); -} - -class _Patch { - const _Patch(); -} - -/// Annotation that marks the declaration as a patch. -const _Patch patch = const _Patch(); diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/async_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/async_patch.dart deleted file mode 100644 index 45ed0c5c202..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/lib/async_patch.dart +++ /dev/null @@ -1,708 +0,0 @@ -// Copyright (c) 2012, 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. - -// Patch file for the dart:async library. - -import 'dart:_js_helper' - show - patch, - ExceptionAndStackTrace, - convertDartClosureToJS, - getTraceFromException, - requiresPreamble, - wrapException, - unwrapException; - -import 'dart:_foreign_helper' show JS, JS_GET_FLAG; - -import 'dart:_async_await_error_codes' as async_error_codes; - -import "dart:collection" show IterableBase; - -@patch -class _AsyncRun { - @patch - static void _scheduleImmediate(void callback()) { - _scheduleImmediateClosure(callback); - } - - // Lazily initialized. - static final Function _scheduleImmediateClosure = - _initializeScheduleImmediate(); - - static Function _initializeScheduleImmediate() { - requiresPreamble(); - if (JS('', 'self.scheduleImmediate') != null) { - return _scheduleImmediateJsOverride; - } - if (JS('', 'self.MutationObserver') != null && - JS('', 'self.document') != null) { - // Use mutationObservers. - var div = JS('', 'self.document.createElement("div")'); - var span = JS('', 'self.document.createElement("span")'); - var storedCallback; - - internalCallback(_) { - var f = storedCallback; - storedCallback = null; - f(); - } - - var observer = JS('', 'new self.MutationObserver(#)', - convertDartClosureToJS(internalCallback, 1)); - JS('', '#.observe(#, { childList: true })', observer, div); - - return (void callback()) { - assert(storedCallback == null); - storedCallback = callback; - // Because of a broken shadow-dom polyfill we have to change the - // children instead a cheap property. - JS('', '#.firstChild ? #.removeChild(#): #.appendChild(#)', div, div, - span, div, span); - }; - } else if (JS('', 'self.setImmediate') != null) { - return _scheduleImmediateWithSetImmediate; - } - // TODO(20055): We should use DOM promises when available. - return _scheduleImmediateWithTimer; - } - - static void _scheduleImmediateJsOverride(void callback()) { - internalCallback() { - callback(); - } - - JS('void', 'self.scheduleImmediate(#)', - convertDartClosureToJS(internalCallback, 0)); - } - - static void _scheduleImmediateWithSetImmediate(void callback()) { - internalCallback() { - callback(); - } - - JS('void', 'self.setImmediate(#)', - convertDartClosureToJS(internalCallback, 0)); - } - - static void _scheduleImmediateWithTimer(void callback()) { - Timer._createTimer(Duration.zero, callback); - } -} - -@patch -class DeferredLibrary { - @patch - Future load() { - throw 'DeferredLibrary not supported. ' - 'please use the `import "lib.dart" deferred as lib` syntax.'; - } -} - -@patch -class Timer { - @patch - static Timer _createTimer(Duration duration, void callback()) { - int milliseconds = duration.inMilliseconds; - if (milliseconds < 0) milliseconds = 0; - return new _TimerImpl(milliseconds, callback); - } - - @patch - static Timer _createPeriodicTimer( - Duration duration, void callback(Timer timer)) { - int milliseconds = duration.inMilliseconds; - if (milliseconds < 0) milliseconds = 0; - return new _TimerImpl.periodic(milliseconds, callback); - } -} - -class _TimerImpl implements Timer { - final bool _once; - int? _handle; - int _tick = 0; - - _TimerImpl(int milliseconds, void callback()) : _once = true { - if (_hasTimer()) { - void internalCallback() { - _handle = null; - this._tick = 1; - callback(); - } - - _handle = JS('int', 'self.setTimeout(#, #)', - convertDartClosureToJS(internalCallback, 0), milliseconds); - } else { - throw new UnsupportedError('`setTimeout()` not found.'); - } - } - - _TimerImpl.periodic(int milliseconds, void callback(Timer timer)) - : _once = false { - if (_hasTimer()) { - int start = JS('int', 'Date.now()'); - _handle = JS( - 'int', - 'self.setInterval(#, #)', - convertDartClosureToJS(() { - int tick = this._tick + 1; - if (milliseconds > 0) { - int duration = JS('int', 'Date.now()') - start; - if (duration > (tick + 1) * milliseconds) { - tick = duration ~/ milliseconds; - } - } - this._tick = tick; - callback(this); - }, 0), - milliseconds); - } else { - throw new UnsupportedError('Periodic timer.'); - } - } - - @override - bool get isActive => _handle != null; - - @override - int get tick => _tick; - - @override - void cancel() { - if (_hasTimer()) { - if (_handle == null) return; - if (_once) { - JS('void', 'self.clearTimeout(#)', _handle); - } else { - JS('void', 'self.clearInterval(#)', _handle); - } - _handle = null; - } else { - throw new UnsupportedError('Canceling a timer.'); - } - } -} - -bool _hasTimer() { - requiresPreamble(); - return JS('', 'self.setTimeout') != null; -} - -class _AsyncAwaitCompleter implements Completer { - final _future = new _Future(); - bool isSync; - - _AsyncAwaitCompleter() : isSync = false; - - void complete([FutureOr? value]) { - // All paths require that if value is null, null as T succeeds. - value = (value == null) ? value as T : value; - if (!isSync) { - _future._asyncComplete(value); - } else if (value is Future) { - assert(!_future._isComplete); - _future._chainFuture(value); - } else { - // TODO(40014): Remove cast when type promotion works. - // This would normally be `as T` but we use `as dynamic` to make the - // unneeded check be implict to match dart2js unsound optimizations in the - // user code. - _future._completeWithValue(value as dynamic); - } - } - - void completeError(Object e, [StackTrace? st]) { - st ??= AsyncError.defaultStackTrace(e); - if (isSync) { - _future._completeError(e, st); - } else { - _future._asyncCompleteError(e, st); - } - } - - Future get future => _future; - bool get isCompleted => !_future._mayComplete; -} - -/// Creates a Completer for an `async` function. -/// -/// Used as part of the runtime support for the async/await transformation. -Completer _makeAsyncAwaitCompleter() { - return new _AsyncAwaitCompleter(); -} - -/// Initiates the computation of an `async` function and starts the body -/// synchronously. -/// -/// Used as part of the runtime support for the async/await transformation. -/// -/// This function sets up the first call into the transformed [bodyFunction]. -/// Independently, it takes the [completer] and returns the future of the -/// completer for convenience of the transformed code. -dynamic _asyncStartSync( - _WrappedAsyncBody bodyFunction, _AsyncAwaitCompleter completer) { - bodyFunction(async_error_codes.SUCCESS, null); - completer.isSync = true; - return completer.future; -} - -/// Performs the `await` operation of an `async` function. -/// -/// Used as part of the runtime support for the async/await transformation. -/// -/// Arranges for [bodyFunction] to be called when the future or value [object] -/// is completed with a code [async_error_codes.SUCCESS] or -/// [async_error_codes.ERROR] depending on the success of the future. -dynamic _asyncAwait(dynamic object, _WrappedAsyncBody bodyFunction) { - _awaitOnObject(object, bodyFunction); -} - -/// Completes the future of an `async` function. -/// -/// Used as part of the runtime support for the async/await transformation. -/// -/// This function is used when the `async` function returns (explicitly or -/// implicitly). -dynamic _asyncReturn(dynamic object, Completer completer) { - completer.complete(object); -} - -/// Completes the future of an `async` function with an error. -/// -/// Used as part of the runtime support for the async/await transformation. -/// -/// This function is used when the `async` function re-throws an exception. -dynamic _asyncRethrow(dynamic object, Completer completer) { - // The error is a js-error. - completer.completeError( - unwrapException(object), getTraceFromException(object)); -} - -/// Awaits on the given [object]. -/// -/// If the [object] is a Future, registers on it, otherwise wraps it into a -/// future first. -/// -/// The [bodyFunction] argument is the continuation that should be invoked -/// when the future completes. -void _awaitOnObject(object, _WrappedAsyncBody bodyFunction) { - FutureOr Function(dynamic) thenCallback = - (result) => bodyFunction(async_error_codes.SUCCESS, result); - - Function errorCallback = (dynamic error, StackTrace stackTrace) { - ExceptionAndStackTrace wrappedException = - new ExceptionAndStackTrace(error, stackTrace); - bodyFunction(async_error_codes.ERROR, wrappedException); - }; - - if (object is _Future) { - // We can skip the zone registration, since the bodyFunction is already - // registered (see [_wrapJsFunctionForAsync]). - object._thenAwait(thenCallback, errorCallback); - } else if (object is Future) { - object.then(thenCallback, onError: errorCallback); - } else { - _Future future = new _Future().._setValue(object); - // We can skip the zone registration, since the bodyFunction is already - // registered (see [_wrapJsFunctionForAsync]). - future._thenAwait(thenCallback, errorCallback); - } -} - -typedef void _WrappedAsyncBody(int errorCode, dynamic result); - -_WrappedAsyncBody _wrapJsFunctionForAsync(dynamic /* js function */ function) { - var protected = JS( - '', - """ - (function (fn, ERROR) { - // Invokes [function] with [errorCode] and [result]. - // - // If (and as long as) the invocation throws, calls [function] again, - // with an error-code. - return function(errorCode, result) { - while (true) { - try { - fn(errorCode, result); - break; - } catch (error) { - result = error; - errorCode = ERROR; - } - } - } - })(#, #)""", - function, - async_error_codes.ERROR); - - return Zone.current.registerBinaryCallback((int errorCode, dynamic result) { - JS('', '#(#, #)', protected, errorCode, result); - }); -} - -/// Implements the runtime support for async* functions. -/// -/// Called by the transformed function for each original return, await, yield, -/// yield* and before starting the function. -/// -/// When the async* function wants to return it calls this function with -/// [asyncBody] == [async_error_codes.SUCCESS], the asyncStarHelper takes this -/// as signal to close the stream. -/// -/// When the async* function wants to signal that an uncaught error was thrown, -/// it calls this function with [asyncBody] == [async_error_codes.ERROR], -/// the streamHelper takes this as signal to addError [object] to the -/// [controller] and close it. -/// -/// If the async* function wants to do a yield or yield*, it calls this function -/// with [object] being an [IterationMarker]. -/// -/// In the case of a yield or yield*, if the stream subscription has been -/// canceled, schedules [asyncBody] to be called with -/// [async_error_codes.STREAM_WAS_CANCELED]. -/// -/// If [object] is a single-yield [IterationMarker], adds the value of the -/// [IterationMarker] to the stream. If the stream subscription has been -/// paused, return early. Otherwise schedule the helper function to be -/// executed again. -/// -/// If [object] is a yield-star [IterationMarker], starts listening to the -/// yielded stream, and adds all events and errors to our own controller (taking -/// care if the subscription has been paused or canceled) - when the sub-stream -/// is done, schedules [asyncBody] again. -/// -/// If the async* function wants to do an await it calls this function with -/// [object] not an [IterationMarker]. -/// -/// If [object] is not a [Future], it is wrapped in a `Future.value`. -/// The [asyncBody] is called on completion of the future (see [asyncHelper]. -void _asyncStarHelper( - dynamic object, - dynamic /* int | _WrappedAsyncBody */ bodyFunctionOrErrorCode, - _AsyncStarStreamController controller) { - if (identical(bodyFunctionOrErrorCode, async_error_codes.SUCCESS)) { - // This happens on return from the async* function. - if (controller.isCanceled) { - controller.cancelationFuture!._completeWithValue(null); - } else { - controller.close(); - } - return; - } else if (identical(bodyFunctionOrErrorCode, async_error_codes.ERROR)) { - // The error is a js-error. - if (controller.isCanceled) { - controller.cancelationFuture!._completeError( - unwrapException(object), getTraceFromException(object)); - } else { - controller.addError( - unwrapException(object), getTraceFromException(object)); - controller.close(); - } - return; - } - - if (object is _IterationMarker) { - if (controller.isCanceled) { - bodyFunctionOrErrorCode(async_error_codes.STREAM_WAS_CANCELED, null); - return; - } - if (object.state == _IterationMarker.YIELD_SINGLE) { - controller.add(object.value); - - scheduleMicrotask(() { - if (controller.isPaused) { - // We only suspend the thread inside the microtask in order to allow - // listeners on the output stream to pause in response to the just - // output value, and have the stream immediately stop producing. - controller.isSuspended = true; - return; - } - bodyFunctionOrErrorCode(null, async_error_codes.SUCCESS); - }); - return; - } else if (object.state == _IterationMarker.YIELD_STAR) { - Stream stream = object.value; - // Errors of [stream] are passed though to the main stream. (see - // [AsyncStreamController.addStream]). - // TODO(sigurdm): The spec is not very clear here. Clarify with Gilad. - controller.addStream(stream).then((_) { - // No check for isPaused here because the spec 17.16.2 only - // demands checks *before* each element in [stream] not after the last - // one. On the other hand we check for isCanceled, as that check happens - // after insertion of each element. - int errorCode = controller.isCanceled - ? async_error_codes.STREAM_WAS_CANCELED - : async_error_codes.SUCCESS; - bodyFunctionOrErrorCode(errorCode, null); - }); - return; - } - } - - _awaitOnObject(object, bodyFunctionOrErrorCode); -} - -Stream _streamOfController(_AsyncStarStreamController controller) { - return controller.stream; -} - -/// A wrapper around a [StreamController] that keeps track of the state of -/// the execution of an async* function. -/// It can be in 1 of 3 states: -/// -/// - running/scheduled -/// - suspended -/// - canceled -/// -/// If yielding while the subscription is paused it will become suspended. And -/// only resume after the subscription is resumed or canceled. -class _AsyncStarStreamController { - late StreamController controller; - Stream get stream => controller.stream; - - /// True when the async* function has yielded while being paused. - /// When true execution will only resume after a `onResume` or `onCancel` - /// event. - bool isSuspended = false; - - bool get isPaused => controller.isPaused; - - _Future? cancelationFuture = null; - - /// True after the StreamSubscription has been cancelled. - /// When this is true, errors thrown from the async* body should go to the - /// [cancelationFuture] instead of adding them to [controller], and - /// returning from the async function should complete [cancelationFuture]. - bool get isCanceled => cancelationFuture != null; - - add(event) => controller.add(event); - - addStream(Stream stream) { - return controller.addStream(stream, cancelOnError: false); - } - - addError(error, stackTrace) => controller.addError(error, stackTrace); - - close() => controller.close(); - - _AsyncStarStreamController(_WrappedAsyncBody body) { - _resumeBody() { - scheduleMicrotask(() { - body(async_error_codes.SUCCESS, null); - }); - } - - controller = new StreamController(onListen: () { - _resumeBody(); - }, onResume: () { - // Only schedule again if the async* function actually is suspended. - // Resume directly instead of scheduling, so that the sequence - // `pause-resume-pause` will result in one extra event produced. - if (isSuspended) { - isSuspended = false; - _resumeBody(); - } - }, onCancel: () { - // If the async* is finished we ignore cancel events. - if (!controller.isClosed) { - cancelationFuture = new _Future(); - if (isSuspended) { - // Resume the suspended async* function to run finalizers. - isSuspended = false; - scheduleMicrotask(() { - body(async_error_codes.STREAM_WAS_CANCELED, null); - }); - } - return cancelationFuture; - } - }); - } -} - -/// Creates a stream controller for an `async*` function. -/// -/// Used as part of the runtime support for the async/await transformation. -_makeAsyncStarStreamController(_WrappedAsyncBody body) { - return new _AsyncStarStreamController(body); -} - -class _IterationMarker { - static const YIELD_SINGLE = 0; - static const YIELD_STAR = 1; - static const ITERATION_ENDED = 2; - static const UNCAUGHT_ERROR = 3; - - final value; - final int state; - - const _IterationMarker._(this.state, this.value); - - static yieldStar(dynamic /* Iterable or Stream */ values) { - return new _IterationMarker._(YIELD_STAR, values); - } - - static endOfIteration() { - return const _IterationMarker._(ITERATION_ENDED, null); - } - - static yieldSingle(dynamic value) { - return new _IterationMarker._(YIELD_SINGLE, value); - } - - static uncaughtError(dynamic error) { - return new _IterationMarker._(UNCAUGHT_ERROR, error); - } - - toString() => "IterationMarker($state, $value)"; -} - -class _SyncStarIterator implements Iterator { - // _SyncStarIterator handles stepping a sync* generator body state machine. - // - // It also handles the stepping over 'nested' iterators to flatten yield* - // statements. For non-sync* iterators, [_nestedIterator] contains the - // iterator. We delegate to [_nestedIterator] when it is not `null`. - // - // For nested sync* iterators, [this] iterator acts on behalf of the innermost - // nested sync* iterator. The current state machine is suspended on a stack - // until the inner state machine ends. - - // The state machine for the innermost _SyncStarIterator. - dynamic _body; - - // The current value, unless iterating a non-sync* nested iterator. - T? _current = null; - - // This is the nested iterator when iterating a yield* of a non-sync iterator. - Iterator? _nestedIterator = null; - - // Stack of suspended state machines when iterating a yield* of a sync* - // iterator. - List? _suspendedBodies = null; - - _SyncStarIterator(this._body); - - T get current { - var nested = _nestedIterator; - if (nested == null) return _current as dynamic; // implicit: as T; - return nested.current; - } - - _runBody() { - // TODO(sra): Find a way to hard-wire SUCCESS and ERROR codes. - return JS( - '', - ''' - // Invokes [body] with [errorCode] and [result]. - // - // If (and as long as) the invocation throws, calls [function] again, - // with an error-code. - (function(body, SUCCESS, ERROR) { - var errorValue, errorCode = SUCCESS; - while (true) { - try { - return body(errorCode, errorValue); - } catch (error) { - errorValue = error; - errorCode = ERROR; - } - } - })(#, #, #)''', - _body, - async_error_codes.SUCCESS, - async_error_codes.ERROR); - } - - bool moveNext() { - while (true) { - if (_nestedIterator != null) { - if (_nestedIterator!.moveNext()) { - return true; - } else { - _nestedIterator = null; - } - } - var value = _runBody(); - if (value is _IterationMarker) { - int state = value.state; - if (state == _IterationMarker.ITERATION_ENDED) { - var suspendedBodies = _suspendedBodies; - if (suspendedBodies == null || suspendedBodies.isEmpty) { - _current = null; - // Rely on [_body] to repeatedly return `ITERATION_ENDED`. - return false; - } - // Resume the innermost suspended iterator. - _body = suspendedBodies.removeLast(); - continue; - } else if (state == _IterationMarker.UNCAUGHT_ERROR) { - // Rely on [_body] to repeatedly return `UNCAUGHT_ERROR`. - // This is a wrapped exception, so we use JavaScript throw to throw - // it. - JS('', 'throw #', value.value); - } else { - assert(state == _IterationMarker.YIELD_STAR); - Iterator inner = value.value.iterator; - if (inner is _SyncStarIterator) { - // The test needs to be 'is _SyncStarIterator' for promotion to - // work. However, that test is much more expensive, so we use an - // unsafe cast. - _SyncStarIterator innerSyncStarIterator = JS('', '#', inner); - // Suspend the current state machine and start acting on behalf of - // the nested state machine. - // - // TODO(sra): Recognize "tail yield*" statements and avoid - // suspending the current body when all it will do is step without - // effect to ITERATION_ENDED. - (_suspendedBodies ??= []).add(_body); - _body = innerSyncStarIterator._body; - continue; - } else { - _nestedIterator = inner; - // TODO(32956): Change to the following when strong-mode is the only - // option: - // - // _nestedIterator = JS>('','#', inner); - continue; - } - } - } else { - // TODO(32956): Remove this test. - _current = JS('', '#', value); - return true; - } - } - return false; // TODO(sra): Fix type inference so that this is not needed. - } -} - -/// Creates an Iterable for a `sync*` function. -/// -/// Used as part of the runtime support for the async/await transformation. -_SyncStarIterable _makeSyncStarIterable(body) { - return new _SyncStarIterable(body); -} - -/// An Iterable corresponding to a sync* method. -/// -/// Each invocation of a sync* method will return a new instance of this class. -class _SyncStarIterable extends IterableBase { - // This is a function that will return a helper function that does the - // iteration of the sync*. - // - // Each invocation should give a body with fresh state. - final dynamic /* js function */ _outerHelper; - - _SyncStarIterable(this._outerHelper); - - Iterator get iterator => - new _SyncStarIterator(JS('', '#()', _outerHelper)); -} - -@patch -void _rethrow(Object error, StackTrace stackTrace) { - error = wrapException(error); - JS('void', '#.stack = #', error, stackTrace.toString()); - JS('void', 'throw #', error); -} diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/collection_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/collection_patch.dart deleted file mode 100644 index a1d76bfe4ff..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/lib/collection_patch.dart +++ /dev/null @@ -1,1716 +0,0 @@ -// Copyright (c) 2013, 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. - -// Patch file for dart:collection classes. -import 'dart:_foreign_helper' show JS; -import 'dart:_js_helper' - show - fillLiteralMap, - fillLiteralSet, - InternalMap, - NoInline, - NoSideEffects, - NoThrows, - patch, - JsLinkedHashMap, - LinkedHashMapCell, - LinkedHashMapKeyIterable, - LinkedHashMapKeyIterator; - -import 'dart:_internal' hide Symbol; - -const _USE_ES6_MAPS = const bool.fromEnvironment("dart2js.use.es6.maps"); - -const int _mask30 = 0x3fffffff; // Low 30 bits. - -@patch -class HashMap { - @patch - factory HashMap( - {bool equals(K key1, K key2)?, - int hashCode(K key)?, - bool isValidKey(potentialKey)?}) { - if (isValidKey == null) { - if (hashCode == null) { - if (equals == null) { - return new _HashMap(); - } - hashCode = _defaultHashCode; - } else { - if (identical(identityHashCode, hashCode) && - identical(identical, equals)) { - return new _IdentityHashMap(); - } - if (equals == null) { - equals = _defaultEquals; - } - } - } else { - if (hashCode == null) { - hashCode = _defaultHashCode; - } - if (equals == null) { - equals = _defaultEquals; - } - } - return new _CustomHashMap(equals, hashCode, isValidKey); - } - - @patch - factory HashMap.identity() = _IdentityHashMap; -} - -class _HashMap extends MapBase implements HashMap { - int _length = 0; - - // The hash map contents are divided into three parts: one part for - // string keys, one for numeric keys, and one for the rest. String - // and numeric keys map directly to their values, but the rest of - // the entries are stored in bucket lists of the form: - // - // [key-0, value-0, key-1, value-1, ...] - // - // where all keys in the same bucket share the same hash code. - var _strings; - var _nums; - var _rest; - - // When iterating over the hash map, it is very convenient to have a - // list of all the keys. We cache that on the instance and clear the - // the cache whenever the key set changes. This is also used to - // guard against concurrent modifications. - List? _keys; - - _HashMap(); - - int get length => _length; - bool get isEmpty => _length == 0; - bool get isNotEmpty => !isEmpty; - - Iterable get keys { - return new _HashMapKeyIterable(this); - } - - Iterable get values { - return new MappedIterable(keys, (each) => this[each] as V); - } - - bool containsKey(Object? key) { - if (_isStringKey(key)) { - var strings = _strings; - return (strings == null) ? false : _hasTableEntry(strings, key); - } else if (_isNumericKey(key)) { - var nums = _nums; - return (nums == null) ? false : _hasTableEntry(nums, key); - } else { - return _containsKey(key); - } - } - - bool _containsKey(Object? key) { - var rest = _rest; - if (rest == null) return false; - var bucket = _getBucket(rest, key); - return _findBucketIndex(bucket, key) >= 0; - } - - bool containsValue(Object? value) { - return _computeKeys().any((each) => this[each] == value); - } - - void addAll(Map other) { - other.forEach((K key, V value) { - this[key] = value; - }); - } - - V? operator [](Object? key) { - if (_isStringKey(key)) { - var strings = _strings; - return JS('', '#', strings == null ? null : _getTableEntry(strings, key)); - } else if (_isNumericKey(key)) { - var nums = _nums; - return JS('', '#', nums == null ? null : _getTableEntry(nums, key)); - } else { - return _get(key); - } - } - - V? _get(Object? key) { - var rest = _rest; - if (rest == null) return null; - var bucket = _getBucket(rest, key); - int index = _findBucketIndex(bucket, key); - return (index < 0) ? null : JS('', '#[#]', bucket, index + 1); - } - - void operator []=(K key, V value) { - if (_isStringKey(key)) { - var strings = _strings; - if (strings == null) _strings = strings = _newHashTable(); - _addHashTableEntry(strings, key, value); - } else if (_isNumericKey(key)) { - var nums = _nums; - if (nums == null) _nums = nums = _newHashTable(); - _addHashTableEntry(nums, key, value); - } else { - _set(key, value); - } - } - - void _set(K key, V value) { - var rest = _rest; - if (rest == null) _rest = rest = _newHashTable(); - var hash = _computeHashCode(key); - var bucket = JS('var', '#[#]', rest, hash); - if (bucket == null) { - _setTableEntry(rest, hash, JS('var', '[#, #]', key, value)); - _length++; - _keys = null; - } else { - int index = _findBucketIndex(bucket, key); - if (index >= 0) { - JS('void', '#[#] = #', bucket, index + 1, value); - } else { - JS('void', '#.push(#, #)', bucket, key, value); - _length++; - _keys = null; - } - } - } - - V putIfAbsent(K key, V ifAbsent()) { - if (containsKey(key)) return this[key] as V; - V value = ifAbsent(); - this[key] = value; - return value; - } - - V? remove(Object? key) { - if (_isStringKey(key)) { - return _removeHashTableEntry(_strings, key); - } else if (_isNumericKey(key)) { - return _removeHashTableEntry(_nums, key); - } else { - return _remove(key); - } - } - - V? _remove(Object? key) { - var rest = _rest; - if (rest == null) return null; - var hash = _computeHashCode(key); - var bucket = JS('var', '#[#]', rest, hash); - int index = _findBucketIndex(bucket, key); - if (index < 0) return null; - _length--; - _keys = null; - // Use splice to remove the two [key, value] elements at the index and - // return the value. - V result = JS('', '#.splice(#, 2)[1]', bucket, index); - if (0 == JS('int', '#.length', bucket)) { - _deleteTableEntry(rest, hash); - } - return result; - } - - void clear() { - if (_length > 0) { - _strings = _nums = _rest = _keys = null; - _length = 0; - } - } - - void forEach(void action(K key, V value)) { - List keys = _computeKeys(); - for (int i = 0, length = keys.length; i < length; i++) { - var key = JS('var', '#[#]', keys, i); - action(key, this[key] as V); - if (JS('bool', '# !== #', keys, _keys)) { - throw new ConcurrentModificationError(this); - } - } - } - - List _computeKeys() { - var result = _keys; - if (result != null) return result; - result = List.filled(_length, null); - int index = 0; - - // Add all string keys to the list. - var strings = _strings; - if (strings != null) { - var names = JS('var', 'Object.getOwnPropertyNames(#)', strings); - int entries = JS('int', '#.length', names); - for (int i = 0; i < entries; i++) { - String key = JS('String', '#[#]', names, i); - JS('void', '#[#] = #', result, index, key); - index++; - } - } - - // Add all numeric keys to the list. - var nums = _nums; - if (nums != null) { - var names = JS('var', 'Object.getOwnPropertyNames(#)', nums); - int entries = JS('int', '#.length', names); - for (int i = 0; i < entries; i++) { - // Object.getOwnPropertyNames returns a list of strings, so we - // have to convert the keys back to numbers (+). - num key = JS('num', '+#[#]', names, i); - JS('void', '#[#] = #', result, index, key); - index++; - } - } - - // Add all the remaining keys to the list. - var rest = _rest; - if (rest != null) { - var names = JS('var', 'Object.getOwnPropertyNames(#)', rest); - int entries = JS('int', '#.length', names); - for (int i = 0; i < entries; i++) { - var key = JS('String', '#[#]', names, i); - var bucket = JS('var', '#[#]', rest, key); - int length = JS('int', '#.length', bucket); - for (int i = 0; i < length; i += 2) { - var key = JS('var', '#[#]', bucket, i); - JS('void', '#[#] = #', result, index, key); - index++; - } - } - } - assert(index == _length); - _keys = result; - return result; - } - - void _addHashTableEntry(var table, K key, V value) { - if (!_hasTableEntry(table, key)) { - _length++; - _keys = null; - } - _setTableEntry(table, key, value); - } - - V? _removeHashTableEntry(var table, Object? key) { - if (table != null && _hasTableEntry(table, key)) { - V value = _getTableEntry(table, key); - _deleteTableEntry(table, key); - _length--; - _keys = null; - return value; - } else { - return null; - } - } - - static bool _isStringKey(var key) { - return key is String && key != '__proto__'; - } - - static bool _isNumericKey(var key) { - // Only treat unsigned 30-bit integers as numeric keys. This way, - // we avoid converting them to strings when we use them as keys in - // the JavaScript hash table object. - return key is num && JS('bool', '(# & #) === #', key, _mask30, key); - } - - int _computeHashCode(var key) { - // We force the hash codes to be unsigned 30-bit integers to avoid - // issues with problematic keys like '__proto__'. Another option - // would be to throw an exception if the hash code isn't a number. - return JS('int', '# & #', key.hashCode, _mask30); - } - - static bool _hasTableEntry(var table, var key) { - var entry = JS('var', '#[#]', table, key); - // We take care to only store non-null entries in the table, so we - // can check if the table has an entry for the given key with a - // simple null check. - return entry != null; - } - - static _getTableEntry(var table, var key) { - var entry = JS('var', '#[#]', table, key); - // We store the table itself as the entry to signal that it really - // is a null value, so we have to map back to null here. - return JS('bool', '# === #', entry, table) ? null : entry; - } - - static void _setTableEntry(var table, var key, var value) { - // We only store non-null entries in the table, so we have to - // change null values to refer to the table itself. Such values - // will be recognized and mapped back to null on access. - if (value == null) { - // Do not update [value] with [table], otherwise our - // optimizations could be confused by this opaque object being - // now used for more things than storing and fetching from it. - JS('void', '#[#] = #', table, key, table); - } else { - JS('void', '#[#] = #', table, key, value); - } - } - - static void _deleteTableEntry(var table, var key) { - JS('void', 'delete #[#]', table, key); - } - - List _getBucket(var table, var key) { - var hash = _computeHashCode(key); - return JS('var', '#[#]', table, hash); - } - - int _findBucketIndex(var bucket, var key) { - if (bucket == null) return -1; - int length = JS('int', '#.length', bucket); - for (int i = 0; i < length; i += 2) { - if (JS('var', '#[#]', bucket, i) == key) return i; - } - return -1; - } - - static _newHashTable() { - // Create a new JavaScript object to be used as a hash table. Use - // Object.create to avoid the properties on Object.prototype - // showing up as entries. - var table = JS('var', 'Object.create(null)'); - // Attempt to force the hash table into 'dictionary' mode by - // adding a property to it and deleting it again. - var temporaryKey = ''; - _setTableEntry(table, temporaryKey, table); - _deleteTableEntry(table, temporaryKey); - return table; - } -} - -class _IdentityHashMap extends _HashMap { - int _computeHashCode(var key) { - // We force the hash codes to be unsigned 30-bit integers to avoid - // issues with problematic keys like '__proto__'. Another option - // would be to throw an exception if the hash code isn't a number. - return JS('int', '# & #', identityHashCode(key), _mask30); - } - - int _findBucketIndex(var bucket, var key) { - if (bucket == null) return -1; - int length = JS('int', '#.length', bucket); - for (int i = 0; i < length; i += 2) { - if (identical(JS('var', '#[#]', bucket, i), key)) return i; - } - return -1; - } -} - -class _CustomHashMap extends _HashMap { - final _Equality _equals; - final _Hasher _hashCode; - final _Predicate _validKey; - - _CustomHashMap(this._equals, this._hashCode, bool validKey(potentialKey)?) - : _validKey = (validKey != null) ? validKey : ((v) => v is K); - - V? operator [](Object? key) { - if (!_validKey(key)) return null; - return super._get(key); - } - - void operator []=(K key, V value) { - super._set(key, value); - } - - bool containsKey(Object? key) { - if (!_validKey(key)) return false; - return super._containsKey(key); - } - - V? remove(Object? key) { - if (!_validKey(key)) return null; - return super._remove(key); - } - - int _computeHashCode(var key) { - // We force the hash codes to be unsigned 30-bit integers to avoid - // issues with problematic keys like '__proto__'. Another option - // would be to throw an exception if the hash code isn't a number. - return JS('int', '# & #', _hashCode(key), _mask30); - } - - int _findBucketIndex(var bucket, var key) { - if (bucket == null) return -1; - int length = JS('int', '#.length', bucket); - for (int i = 0; i < length; i += 2) { - if (_equals(JS('var', '#[#]', bucket, i), key)) return i; - } - return -1; - } -} - -class _HashMapKeyIterable extends EfficientLengthIterable { - final _map; - _HashMapKeyIterable(this._map); - - int get length => _map._length; - bool get isEmpty => _map._length == 0; - - Iterator get iterator { - return new _HashMapKeyIterator(_map, _map._computeKeys()); - } - - bool contains(Object? element) { - return _map.containsKey(element); - } - - void forEach(void f(E element)) { - List keys = _map._computeKeys(); - for (int i = 0, length = JS('int', '#.length', keys); i < length; i++) { - f(JS('var', '#[#]', keys, i)); - if (JS('bool', '# !== #', keys, _map._keys)) { - throw new ConcurrentModificationError(_map); - } - } - } -} - -class _HashMapKeyIterator implements Iterator { - final _map; - final List _keys; - int _offset = 0; - E? _current; - - _HashMapKeyIterator(this._map, this._keys); - - E get current => _current as E; - - bool moveNext() { - var keys = _keys; - int offset = _offset; - if (JS('bool', '# !== #', keys, _map._keys)) { - throw new ConcurrentModificationError(_map); - } else if (offset >= JS('int', '#.length', keys)) { - _current = null; - return false; - } else { - _current = JS('var', '#[#]', keys, offset); - // TODO(kasperl): For now, we have to tell the type inferrer to - // treat the result of doing offset + 1 as an int. Otherwise, we - // get unnecessary bailout code. - _offset = JS('int', '#', offset + 1); - return true; - } - } -} - -@patch -class LinkedHashMap { - @patch - factory LinkedHashMap( - {bool equals(K key1, K key2)?, - int hashCode(K key)?, - bool isValidKey(potentialKey)?}) { - if (isValidKey == null) { - if (hashCode == null) { - if (equals == null) { - return new JsLinkedHashMap.es6(); - } - hashCode = _defaultHashCode; - } else { - if (identical(identityHashCode, hashCode) && - identical(identical, equals)) { - return new _LinkedIdentityHashMap.es6(); - } - if (equals == null) { - equals = _defaultEquals; - } - } - } else { - if (hashCode == null) { - hashCode = _defaultHashCode; - } - if (equals == null) { - equals = _defaultEquals; - } - } - return new _LinkedCustomHashMap(equals, hashCode, isValidKey); - } - - @patch - factory LinkedHashMap.identity() = _LinkedIdentityHashMap.es6; - - // Private factory constructor called by generated code for map literals. - @pragma('dart2js:noInline') - factory LinkedHashMap._literal(List keyValuePairs) { - return fillLiteralMap(keyValuePairs, new JsLinkedHashMap.es6()); - } - - // Private factory constructor called by generated code for map literals. - @pragma('dart2js:noThrows') - @pragma('dart2js:noInline') - @pragma('dart2js:noSideEffects') - factory LinkedHashMap._empty() { - return new JsLinkedHashMap.es6(); - } - - // Private factory static function called by generated code for map literals. - // This version is for map literals without type parameters. - @pragma('dart2js:noThrows') - @pragma('dart2js:noInline') - @pragma('dart2js:noSideEffects') - static _makeEmpty() => new JsLinkedHashMap(); - - // Private factory static function called by generated code for map literals. - // This version is for map literals without type parameters. - @pragma('dart2js:noInline') - static _makeLiteral(keyValuePairs) => - fillLiteralMap(keyValuePairs, new JsLinkedHashMap()); -} - -class _LinkedIdentityHashMap extends JsLinkedHashMap { - static bool get _supportsEs6Maps { - return JS('returns:bool;depends:none;effects:none;throws:never;gvn:true', - 'typeof Map != "undefined"'); - } - - factory _LinkedIdentityHashMap.es6() { - return (_USE_ES6_MAPS && _LinkedIdentityHashMap._supportsEs6Maps) - ? new _Es6LinkedIdentityHashMap() - : new _LinkedIdentityHashMap(); - } - - _LinkedIdentityHashMap(); - - int internalComputeHashCode(var key) { - // We force the hash codes to be unsigned 30-bit integers to avoid - // issues with problematic keys like '__proto__'. Another option - // would be to throw an exception if the hash code isn't a number. - return JS('int', '# & #', identityHashCode(key), _mask30); - } - - int internalFindBucketIndex(var bucket, var key) { - if (bucket == null) return -1; - int length = JS('int', '#.length', bucket); - for (int i = 0; i < length; i++) { - LinkedHashMapCell cell = JS('var', '#[#]', bucket, i); - if (identical(cell.hashMapCellKey, key)) return i; - } - return -1; - } -} - -class _Es6LinkedIdentityHashMap extends _LinkedIdentityHashMap - implements InternalMap { - final _map; - int _modifications = 0; - - _Es6LinkedIdentityHashMap() : _map = JS('var', 'new Map()'); - - int get length => JS('int', '#.size', _map); - bool get isEmpty => length == 0; - bool get isNotEmpty => !isEmpty; - - Iterable get keys => new _Es6MapIterable(this, true); - - Iterable get values => new _Es6MapIterable(this, false); - - bool containsKey(Object? key) { - return JS('bool', '#.has(#)', _map, key); - } - - bool containsValue(Object? value) { - return values.any((each) => each == value); - } - - void addAll(Map other) { - other.forEach((K key, V value) { - this[key] = value; - }); - } - - V? operator [](Object? key) { - return JS('var', '#.get(#)', _map, key); - } - - void operator []=(K key, V value) { - JS('var', '#.set(#, #)', _map, key, value); - _modified(); - } - - V putIfAbsent(K key, V ifAbsent()) { - if (containsKey(key)) return this[key] as V; - V value = ifAbsent(); - this[key] = value; - return value; - } - - V? remove(Object? key) { - V? value = this[key]; - JS('bool', '#.delete(#)', _map, key); - _modified(); - return value; - } - - void clear() { - JS('void', '#.clear()', _map); - _modified(); - } - - void forEach(void action(K key, V value)) { - var jsEntries = JS('var', '#.entries()', _map); - int modifications = _modifications; - while (true) { - var next = JS('var', '#.next()', jsEntries); - bool done = JS('bool', '#.done', next); - if (done) break; - var entry = JS('var', '#.value', next); - var key = JS('var', '#[0]', entry); - var value = JS('var', '#[1]', entry); - action(key, value); - if (modifications != _modifications) { - throw new ConcurrentModificationError(this); - } - } - } - - void _modified() { - // Value cycles after 2^30 modifications so that modification counts are - // always unboxed (Smi) values. Modification detection will be missed if you - // make exactly some multiple of 2^30 modifications between advances of an - // iterator. - _modifications = _mask30 & (_modifications + 1); - } -} - -class _Es6MapIterable extends EfficientLengthIterable { - final _map; - final bool _isKeys; - - _Es6MapIterable(this._map, this._isKeys); - - int get length => _map.length; - bool get isEmpty => _map.isEmpty; - - Iterator get iterator => - new _Es6MapIterator(_map, _map._modifications, _isKeys); - - bool contains(Object? element) => _map.containsKey(element); - - void forEach(void f(E element)) { - var jsIterator; - if (_isKeys) { - jsIterator = JS('var', '#.keys()', _map._map); - } else { - jsIterator = JS('var', '#.values()', _map._map); - } - int modifications = _map._modifications; - while (true) { - var next = JS('var', '#.next()', jsIterator); - bool done = JS('bool', '#.done', next); - if (done) break; - var value = JS('var', '#.value', next); - f(value); - if (modifications != _map._modifications) { - throw new ConcurrentModificationError(_map); - } - } - } -} - -class _Es6MapIterator implements Iterator { - final _map; - final int _modifications; - final bool _isKeys; - var _jsIterator; - var _next; - E? _current; - bool _done = false; - - _Es6MapIterator(this._map, this._modifications, this._isKeys) { - if (_isKeys) { - _jsIterator = JS('var', '#.keys()', _map._map); - } else { - _jsIterator = JS('var', '#.values()', _map._map); - } - } - - E get current => _current as E; - - bool moveNext() { - if (_modifications != _map._modifications) { - throw new ConcurrentModificationError(_map); - } - if (_done) return false; - _next = JS('var', '#.next()', _jsIterator); - bool done = JS('bool', '#.done', _next); - if (done) { - _current = null; - _done = true; - return false; - } else { - _current = JS('var', '#.value', _next); - return true; - } - } -} - -// TODO(floitsch): use ES6 maps when available. -class _LinkedCustomHashMap extends JsLinkedHashMap { - final _Equality _equals; - final _Hasher _hashCode; - final _Predicate _validKey; - - _LinkedCustomHashMap( - this._equals, this._hashCode, bool validKey(potentialKey)?) - : _validKey = (validKey != null) ? validKey : ((v) => v is K); - - V? operator [](Object? key) { - if (!_validKey(key)) return null; - return super.internalGet(key); - } - - void operator []=(K key, V value) { - super.internalSet(key, value); - } - - bool containsKey(Object? key) { - if (!_validKey(key)) return false; - return super.internalContainsKey(key); - } - - V? remove(Object? key) { - if (!_validKey(key)) return null; - return super.internalRemove(key); - } - - int internalComputeHashCode(var key) { - // We force the hash codes to be unsigned 30-bit integers to avoid - // issues with problematic keys like '__proto__'. Another option - // would be to throw an exception if the hash code isn't a number. - return JS('int', '# & #', _hashCode(key), _mask30); - } - - int internalFindBucketIndex(var bucket, var key) { - if (bucket == null) return -1; - int length = JS('int', '#.length', bucket); - for (int i = 0; i < length; i++) { - LinkedHashMapCell cell = JS('var', '#[#]', bucket, i); - if (_equals(cell.hashMapCellKey, key)) return i; - } - return -1; - } -} - -@patch -class HashSet { - @patch - factory HashSet( - {bool equals(E e1, E e2)?, - int hashCode(E e)?, - bool isValidKey(potentialKey)?}) { - if (isValidKey == null) { - if (hashCode == null) { - if (equals == null) { - return new _HashSet(); - } - hashCode = _defaultHashCode; - } else { - if (identical(identityHashCode, hashCode) && - identical(identical, equals)) { - return new _IdentityHashSet(); - } - if (equals == null) { - equals = _defaultEquals; - } - } - } else { - if (hashCode == null) { - hashCode = _defaultHashCode; - } - if (equals == null) { - equals = _defaultEquals; - } - } - return new _CustomHashSet(equals, hashCode, isValidKey); - } - - @patch - factory HashSet.identity() = _IdentityHashSet; -} - -class _HashSet extends _SetBase implements HashSet { - int _length = 0; - - // The hash set contents are divided into three parts: one part for - // string elements, one for numeric elements, and one for the - // rest. String and numeric elements map directly to a sentinel - // value, but the rest of the entries are stored in bucket lists of - // the form: - // - // [element-0, element-1, element-2, ...] - // - // where all elements in the same bucket share the same hash code. - var _strings; - var _nums; - var _rest; - - // When iterating over the hash set, it is very convenient to have a - // list of all the elements. We cache that on the instance and clear - // the cache whenever the set changes. This is also used to - // guard against concurrent modifications. - List? _elements; - - _HashSet(); - - Set _newSet() => new _HashSet(); - Set _newSimilarSet() => new _HashSet(); - - // Iterable. - Iterator get iterator { - return new _HashSetIterator(this, _computeElements()); - } - - int get length => _length; - bool get isEmpty => _length == 0; - bool get isNotEmpty => !isEmpty; - - bool contains(Object? object) { - if (_isStringElement(object)) { - var strings = _strings; - return (strings == null) ? false : _hasTableEntry(strings, object); - } else if (_isNumericElement(object)) { - var nums = _nums; - return (nums == null) ? false : _hasTableEntry(nums, object); - } else { - return _contains(object); - } - } - - bool _contains(Object? object) { - var rest = _rest; - if (rest == null) return false; - var bucket = _getBucket(rest, object); - return _findBucketIndex(bucket, object) >= 0; - } - - E? lookup(Object? object) { - if (_isStringElement(object) || _isNumericElement(object)) { - return this.contains(object) ? object as E : null; - } - return _lookup(object); - } - - E? _lookup(Object? object) { - var rest = _rest; - if (rest == null) return null; - var bucket = _getBucket(rest, object); - var index = _findBucketIndex(bucket, object); - if (index < 0) return null; - return bucket[index]; - } - - // Collection. - bool add(E element) { - if (_isStringElement(element)) { - var strings = _strings; - if (strings == null) _strings = strings = _newHashTable(); - return _addHashTableEntry(strings, element); - } else if (_isNumericElement(element)) { - var nums = _nums; - if (nums == null) _nums = nums = _newHashTable(); - return _addHashTableEntry(nums, element); - } else { - return _add(element); - } - } - - bool _add(E element) { - var rest = _rest; - if (rest == null) _rest = rest = _newHashTable(); - var hash = _computeHashCode(element); - var bucket = JS('var', '#[#]', rest, hash); - if (bucket == null) { - _setTableEntry(rest, hash, JS('var', '[#]', element)); - } else { - int index = _findBucketIndex(bucket, element); - if (index >= 0) return false; - JS('void', '#.push(#)', bucket, element); - } - _length++; - _elements = null; - return true; - } - - void addAll(Iterable objects) { - for (E each in objects) { - add(each); - } - } - - bool remove(Object? object) { - if (_isStringElement(object)) { - return _removeHashTableEntry(_strings, object); - } else if (_isNumericElement(object)) { - return _removeHashTableEntry(_nums, object); - } else { - return _remove(object); - } - } - - bool _remove(Object? object) { - var rest = _rest; - if (rest == null) return false; - var hash = _computeHashCode(object); - var bucket = JS('var', '#[#]', rest, hash); - int index = _findBucketIndex(bucket, object); - if (index < 0) return false; - // TODO(kasperl): Consider getting rid of the bucket list when - // the length reaches zero. - _length--; - _elements = null; - // TODO(kasperl): It would probably be faster to move the element to the end - // and reduce the length of the bucket list. - JS('void', '#.splice(#, 1)', bucket, index); - if (0 == JS('int', '#.length', bucket)) { - _deleteTableEntry(rest, hash); - } - return true; - } - - void clear() { - if (_length > 0) { - _strings = _nums = _rest = _elements = null; - _length = 0; - } - } - - List _computeElements() { - var result = _elements; - if (result != null) return result; - result = List.filled(_length, null); - int index = 0; - - // Add all string elements to the list. - var strings = _strings; - if (strings != null) { - var names = JS('var', 'Object.getOwnPropertyNames(#)', strings); - int entries = JS('int', '#.length', names); - for (int i = 0; i < entries; i++) { - String element = JS('String', '#[#]', names, i); - JS('void', '#[#] = #', result, index, element); - index++; - } - } - - // Add all numeric elements to the list. - var nums = _nums; - if (nums != null) { - var names = JS('var', 'Object.getOwnPropertyNames(#)', nums); - int entries = JS('int', '#.length', names); - for (int i = 0; i < entries; i++) { - // Object.getOwnPropertyNames returns a list of strings, so we - // have to convert the elements back to numbers (+). - num element = JS('num', '+#[#]', names, i); - JS('void', '#[#] = #', result, index, element); - index++; - } - } - - // Add all the remaining elements to the list. - var rest = _rest; - if (rest != null) { - var names = JS('var', 'Object.getOwnPropertyNames(#)', rest); - int entries = JS('int', '#.length', names); - for (int i = 0; i < entries; i++) { - var entry = JS('String', '#[#]', names, i); - var bucket = JS('var', '#[#]', rest, entry); - int length = JS('int', '#.length', bucket); - for (int i = 0; i < length; i++) { - JS('void', '#[#] = #[#]', result, index, bucket, i); - index++; - } - } - } - assert(index == _length); - _elements = result; - return result; - } - - bool _addHashTableEntry(var table, E element) { - if (_hasTableEntry(table, element)) return false; - _setTableEntry(table, element, 0); - _length++; - _elements = null; - return true; - } - - bool _removeHashTableEntry(var table, Object? element) { - if (table != null && _hasTableEntry(table, element)) { - _deleteTableEntry(table, element); - _length--; - _elements = null; - return true; - } else { - return false; - } - } - - static bool _isStringElement(var element) { - return element is String && element != '__proto__'; - } - - static bool _isNumericElement(var element) { - // Only treat unsigned 30-bit integers as numeric elements. This - // way, we avoid converting them to strings when we use them as - // keys in the JavaScript hash table object. - return element is num && - JS('bool', '(# & #) === #', element, _mask30, element); - } - - int _computeHashCode(var element) { - // We force the hash codes to be unsigned 30-bit integers to avoid - // issues with problematic elements like '__proto__'. Another - // option would be to throw an exception if the hash code isn't a - // number. - return JS('int', '# & #', element.hashCode, _mask30); - } - - static bool _hasTableEntry(var table, var key) { - var entry = JS('var', '#[#]', table, key); - // We take care to only store non-null entries in the table, so we - // can check if the table has an entry for the given key with a - // simple null check. - return entry != null; - } - - static void _setTableEntry(var table, var key, var value) { - assert(value != null); - JS('void', '#[#] = #', table, key, value); - } - - static void _deleteTableEntry(var table, var key) { - JS('void', 'delete #[#]', table, key); - } - - List _getBucket(var table, var element) { - var hash = _computeHashCode(element); - return JS('var', '#[#]', table, hash); - } - - int _findBucketIndex(var bucket, var element) { - if (bucket == null) return -1; - int length = JS('int', '#.length', bucket); - for (int i = 0; i < length; i++) { - if (JS('var', '#[#]', bucket, i) == element) return i; - } - return -1; - } - - static _newHashTable() { - // Create a new JavaScript object to be used as a hash table. Use - // Object.create to avoid the properties on Object.prototype - // showing up as entries. - var table = JS('var', 'Object.create(null)'); - // Attempt to force the hash table into 'dictionary' mode by - // adding a property to it and deleting it again. - var temporaryKey = ''; - _setTableEntry(table, temporaryKey, table); - _deleteTableEntry(table, temporaryKey); - return table; - } -} - -class _IdentityHashSet extends _HashSet { - Set _newSet() => new _IdentityHashSet(); - Set _newSimilarSet() => new _IdentityHashSet(); - - int _computeHashCode(var key) { - // We force the hash codes to be unsigned 30-bit integers to avoid - // issues with problematic keys like '__proto__'. Another option - // would be to throw an exception if the hash code isn't a number. - return JS('int', '# & #', identityHashCode(key), _mask30); - } - - int _findBucketIndex(var bucket, var element) { - if (bucket == null) return -1; - int length = JS('int', '#.length', bucket); - for (int i = 0; i < length; i++) { - if (identical(JS('var', '#[#]', bucket, i), element)) return i; - } - return -1; - } -} - -class _CustomHashSet extends _HashSet { - _Equality _equality; - _Hasher _hasher; - _Predicate _validKey; - _CustomHashSet(this._equality, this._hasher, bool validKey(potentialKey)?) - : _validKey = (validKey != null) ? validKey : ((x) => x is E); - - Set _newSet() => new _CustomHashSet(_equality, _hasher, _validKey); - Set _newSimilarSet() => new _HashSet(); - - int _findBucketIndex(var bucket, var element) { - if (bucket == null) return -1; - int length = JS('int', '#.length', bucket); - for (int i = 0; i < length; i++) { - if (_equality(JS('var', '#[#]', bucket, i), element)) return i; - } - return -1; - } - - int _computeHashCode(var element) { - // We force the hash codes to be unsigned 30-bit integers to avoid - // issues with problematic elements like '__proto__'. Another - // option would be to throw an exception if the hash code isn't a - // number. - return JS('int', '# & #', _hasher(element), _mask30); - } - - bool add(E object) => super._add(object); - - bool contains(Object? object) { - if (!_validKey(object)) return false; - return super._contains(object); - } - - E? lookup(Object? object) { - if (!_validKey(object)) return null; - return super._lookup(object); - } - - bool remove(Object? object) { - if (!_validKey(object)) return false; - return super._remove(object); - } -} - -// TODO(kasperl): Share this code with _HashMapKeyIterator? -class _HashSetIterator implements Iterator { - final _set; - final List _elements; - int _offset = 0; - E? _current; - - _HashSetIterator(this._set, this._elements); - - E get current => _current as E; - - bool moveNext() { - var elements = _elements; - int offset = _offset; - if (JS('bool', '# !== #', elements, _set._elements)) { - throw new ConcurrentModificationError(_set); - } else if (offset >= JS('int', '#.length', elements)) { - _current = null; - return false; - } else { - _current = JS('var', '#[#]', elements, offset); - // TODO(kasperl): For now, we have to tell the type inferrer to - // treat the result of doing offset + 1 as an int. Otherwise, we - // get unnecessary bailout code. - _offset = JS('int', '#', offset + 1); - return true; - } - } -} - -@patch -class LinkedHashSet { - @patch - factory LinkedHashSet( - {bool equals(E e1, E e2)?, - int hashCode(E e)?, - bool isValidKey(potentialKey)?}) { - if (isValidKey == null) { - if (hashCode == null) { - if (equals == null) { - return new _LinkedHashSet(); - } - hashCode = _defaultHashCode; - } else { - if (identical(identityHashCode, hashCode) && - identical(identical, equals)) { - return new _LinkedIdentityHashSet(); - } - if (equals == null) { - equals = _defaultEquals; - } - } - } else { - if (hashCode == null) { - hashCode = _defaultHashCode; - } - if (equals == null) { - equals = _defaultEquals; - } - } - return new _LinkedCustomHashSet(equals, hashCode, isValidKey); - } - - @patch - factory LinkedHashSet.identity() = _LinkedIdentityHashSet; - - // Private factory constructor called by generated code for set literals. - @pragma('dart2js:noThrows') - @pragma('dart2js:noInline') - @pragma('dart2js:noSideEffects') - factory LinkedHashSet._empty() => new _LinkedHashSet(); - - // Private factory constructor called by generated code for set literals. - @pragma('dart2js:noInline') - factory LinkedHashSet._literal(List values) => - fillLiteralSet(values, new _LinkedHashSet()); - - // Private factory static function called by generated code for set literals. - // This version is for set literals without type parameters. - @pragma('dart2js:noThrows') - @pragma('dart2js:noInline') - @pragma('dart2js:noSideEffects') - static _makeEmpty() => new _LinkedHashSet(); - - // Private factory static function called by generated code for set literals. - // This version is for set literals without type parameters. - @pragma('dart2js:noInline') - static _makeLiteral(List values) => - fillLiteralSet(values, new _LinkedHashSet()); -} - -class _LinkedHashSet extends _SetBase implements LinkedHashSet { - int _length = 0; - - // The hash set contents are divided into three parts: one part for - // string elements, one for numeric elements, and one for the - // rest. String and numeric elements map directly to their linked - // cells, but the rest of the entries are stored in bucket lists of - // the form: - // - // [cell-0, cell-1, ...] - // - // where all elements in the same bucket share the same hash code. - var _strings; - var _nums; - var _rest; - - // The elements are stored in cells that are linked together - // to form a double linked list. - _LinkedHashSetCell? _first; - _LinkedHashSetCell? _last; - - // We track the number of modifications done to the element set to - // be able to throw when the set is modified while being iterated - // over. - int _modifications = 0; - - _LinkedHashSet(); - - Set _newSet() => new _LinkedHashSet(); - Set _newSimilarSet() => new _LinkedHashSet(); - - void _unsupported(String operation) { - throw 'LinkedHashSet: unsupported $operation'; - } - - // Iterable. - Iterator get iterator { - return new _LinkedHashSetIterator(this, _modifications); - } - - int get length => _length; - bool get isEmpty => _length == 0; - bool get isNotEmpty => !isEmpty; - - bool contains(Object? object) { - if (_isStringElement(object)) { - var strings = _strings; - if (strings == null) return false; - _LinkedHashSetCell? cell = _getTableEntry(strings, object); - return cell != null; - } else if (_isNumericElement(object)) { - var nums = _nums; - if (nums == null) return false; - _LinkedHashSetCell? cell = _getTableEntry(nums, object); - return cell != null; - } else { - return _contains(object); - } - } - - bool _contains(Object? object) { - var rest = _rest; - if (rest == null) return false; - var bucket = _getBucket(rest, object); - return _findBucketIndex(bucket, object) >= 0; - } - - E? lookup(Object? object) { - if (_isStringElement(object) || _isNumericElement(object)) { - return this.contains(object) ? object as E : null; - } else { - return _lookup(object); - } - } - - E? _lookup(Object? object) { - var rest = _rest; - if (rest == null) return null; - var bucket = _getBucket(rest, object); - var index = _findBucketIndex(bucket, object); - if (index < 0) return null; - return bucket[index]._element; - } - - void forEach(void action(E element)) { - _LinkedHashSetCell? cell = _first; - int modifications = _modifications; - while (cell != null) { - action(cell._element); - if (modifications != _modifications) { - throw new ConcurrentModificationError(this); - } - cell = cell._next; - } - } - - E get first { - var first = _first; - if (first == null) throw new StateError("No elements"); - return first._element; - } - - E get last { - var last = _last; - if (last == null) throw new StateError("No elements"); - return last._element; - } - - // Collection. - bool add(E element) { - if (_isStringElement(element)) { - var strings = _strings; - if (strings == null) _strings = strings = _newHashTable(); - return _addHashTableEntry(strings, element); - } else if (_isNumericElement(element)) { - var nums = _nums; - if (nums == null) _nums = nums = _newHashTable(); - return _addHashTableEntry(nums, element); - } else { - return _add(element); - } - } - - bool _add(E element) { - var rest = _rest; - if (rest == null) _rest = rest = _newHashTable(); - var hash = _computeHashCode(element); - var bucket = JS('var', '#[#]', rest, hash); - if (bucket == null) { - _LinkedHashSetCell cell = _newLinkedCell(element); - _setTableEntry(rest, hash, JS('var', '[#]', cell)); - } else { - int index = _findBucketIndex(bucket, element); - if (index >= 0) return false; - _LinkedHashSetCell cell = _newLinkedCell(element); - JS('void', '#.push(#)', bucket, cell); - } - return true; - } - - bool remove(Object? object) { - if (_isStringElement(object)) { - return _removeHashTableEntry(_strings, object); - } else if (_isNumericElement(object)) { - return _removeHashTableEntry(_nums, object); - } else { - return _remove(object); - } - } - - bool _remove(Object? object) { - var rest = _rest; - if (rest == null) return false; - var hash = _computeHashCode(object); - var bucket = JS('var', '#[#]', rest, hash); - int index = _findBucketIndex(bucket, object); - if (index < 0) return false; - // Use splice to remove the [cell] element at the index and unlink it. - _LinkedHashSetCell cell = JS('var', '#.splice(#, 1)[0]', bucket, index); - if (0 == JS('int', '#.length', bucket)) { - _deleteTableEntry(rest, hash); - } - _unlinkCell(cell); - return true; - } - - void removeWhere(bool test(E element)) { - _filterWhere(test, true); - } - - void retainWhere(bool test(E element)) { - _filterWhere(test, false); - } - - void _filterWhere(bool test(E element), bool removeMatching) { - _LinkedHashSetCell? cell = _first; - while (cell != null) { - E element = cell._element; - _LinkedHashSetCell? next = cell._next; - int modifications = _modifications; - bool shouldRemove = (removeMatching == test(element)); - if (modifications != _modifications) { - throw new ConcurrentModificationError(this); - } - if (shouldRemove) remove(element); - cell = next; - } - } - - void clear() { - if (_length > 0) { - _strings = _nums = _rest = _first = _last = null; - _length = 0; - _modified(); - } - } - - bool _addHashTableEntry(var table, E element) { - _LinkedHashSetCell? cell = _getTableEntry(table, element); - if (cell != null) return false; - _setTableEntry(table, element, _newLinkedCell(element)); - return true; - } - - bool _removeHashTableEntry(var table, Object? element) { - if (table == null) return false; - _LinkedHashSetCell? cell = _getTableEntry(table, element); - if (cell == null) return false; - _unlinkCell(cell); - _deleteTableEntry(table, element); - return true; - } - - void _modified() { - // Value cycles after 2^30 modifications. If you keep hold of an - // iterator for that long, you might miss a modification - // detection, and iteration can go sour. Don't do that. - _modifications = _mask30 & (_modifications + 1); - } - - // Create a new cell and link it in as the last one in the list. - _LinkedHashSetCell _newLinkedCell(E element) { - _LinkedHashSetCell cell = new _LinkedHashSetCell(element); - if (_first == null) { - _first = _last = cell; - } else { - _LinkedHashSetCell last = _last!; - cell._previous = last; - _last = last._next = cell; - } - _length++; - _modified(); - return cell; - } - - // Unlink the given cell from the linked list of cells. - void _unlinkCell(_LinkedHashSetCell cell) { - _LinkedHashSetCell? previous = cell._previous; - _LinkedHashSetCell? next = cell._next; - if (previous == null) { - assert(cell == _first); - _first = next; - } else { - previous._next = next; - } - if (next == null) { - assert(cell == _last); - _last = previous; - } else { - next._previous = previous; - } - _length--; - _modified(); - } - - static bool _isStringElement(var element) { - return element is String && element != '__proto__'; - } - - static bool _isNumericElement(var element) { - // Only treat unsigned 30-bit integers as numeric elements. This - // way, we avoid converting them to strings when we use them as - // keys in the JavaScript hash table object. - return element is num && - JS('bool', '(# & #) === #', element, _mask30, element); - } - - int _computeHashCode(var element) { - // We force the hash codes to be unsigned 30-bit integers to avoid - // issues with problematic elements like '__proto__'. Another - // option would be to throw an exception if the hash code isn't a - // number. - return JS('int', '# & #', element.hashCode, _mask30); - } - - static _getTableEntry(var table, var key) { - return JS('var', '#[#]', table, key); - } - - static void _setTableEntry(var table, var key, var value) { - assert(value != null); - JS('void', '#[#] = #', table, key, value); - } - - static void _deleteTableEntry(var table, var key) { - JS('void', 'delete #[#]', table, key); - } - - List _getBucket(var table, var element) { - var hash = _computeHashCode(element); - return JS('var', '#[#]', table, hash); - } - - int _findBucketIndex(var bucket, var element) { - if (bucket == null) return -1; - int length = JS('int', '#.length', bucket); - for (int i = 0; i < length; i++) { - _LinkedHashSetCell cell = JS('var', '#[#]', bucket, i); - if (cell._element == element) return i; - } - return -1; - } - - static _newHashTable() { - // Create a new JavaScript object to be used as a hash table. Use - // Object.create to avoid the properties on Object.prototype - // showing up as entries. - var table = JS('var', 'Object.create(null)'); - // Attempt to force the hash table into 'dictionary' mode by - // adding a property to it and deleting it again. - var temporaryKey = ''; - _setTableEntry(table, temporaryKey, table); - _deleteTableEntry(table, temporaryKey); - return table; - } -} - -class _LinkedIdentityHashSet extends _LinkedHashSet { - Set _newSet() => new _LinkedIdentityHashSet(); - Set _newSimilarSet() => new _LinkedIdentityHashSet(); - - int _computeHashCode(var key) { - // We force the hash codes to be unsigned 30-bit integers to avoid - // issues with problematic keys like '__proto__'. Another option - // would be to throw an exception if the hash code isn't a number. - return JS('int', '# & #', identityHashCode(key), _mask30); - } - - int _findBucketIndex(var bucket, var element) { - if (bucket == null) return -1; - int length = JS('int', '#.length', bucket); - for (int i = 0; i < length; i++) { - _LinkedHashSetCell cell = JS('var', '#[#]', bucket, i); - if (identical(cell._element, element)) return i; - } - return -1; - } -} - -class _LinkedCustomHashSet extends _LinkedHashSet { - _Equality _equality; - _Hasher _hasher; - _Predicate _validKey; - _LinkedCustomHashSet( - this._equality, this._hasher, bool validKey(potentialKey)?) - : _validKey = (validKey != null) ? validKey : ((x) => x is E); - - Set _newSet() => - new _LinkedCustomHashSet(_equality, _hasher, _validKey); - Set _newSimilarSet() => new _LinkedHashSet(); - - int _findBucketIndex(var bucket, var element) { - if (bucket == null) return -1; - int length = JS('int', '#.length', bucket); - for (int i = 0; i < length; i++) { - _LinkedHashSetCell cell = JS('var', '#[#]', bucket, i); - if (_equality(cell._element, element)) return i; - } - return -1; - } - - int _computeHashCode(var element) { - // We force the hash codes to be unsigned 30-bit integers to avoid - // issues with problematic elements like '__proto__'. Another - // option would be to throw an exception if the hash code isn't a - // number. - return JS('int', '# & #', _hasher(element), _mask30); - } - - bool add(E element) => super._add(element); - - bool contains(Object? object) { - if (!_validKey(object)) return false; - return super._contains(object); - } - - E? lookup(Object? object) { - if (!_validKey(object)) return null; - return super._lookup(object); - } - - bool remove(Object? object) { - if (!_validKey(object)) return false; - return super._remove(object); - } - - bool containsAll(Iterable elements) { - for (Object? element in elements) { - if (!_validKey(element) || !this.contains(element)) return false; - } - return true; - } - - void removeAll(Iterable elements) { - for (Object? element in elements) { - if (_validKey(element)) { - super._remove(element); - } - } - } -} - -class _LinkedHashSetCell { - final _element; - - _LinkedHashSetCell? _next; - _LinkedHashSetCell? _previous; - - _LinkedHashSetCell(this._element); -} - -// TODO(kasperl): Share this code with LinkedHashMapKeyIterator? -class _LinkedHashSetIterator implements Iterator { - final _set; - final int _modifications; - _LinkedHashSetCell? _cell; - E? _current; - - _LinkedHashSetIterator(this._set, this._modifications) { - _cell = _set._first; - } - - E get current => _current as E; - - bool moveNext() { - var cell = _cell; - if (_modifications != _set._modifications) { - throw new ConcurrentModificationError(_set); - } else if (cell == null) { - _current = null; - return false; - } else { - _current = cell._element; - _cell = cell._next; - return true; - } - } -} diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/constant_map.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/constant_map.dart deleted file mode 100644 index 0f673d875ba..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/lib/constant_map.dart +++ /dev/null @@ -1,231 +0,0 @@ -// Copyright (c) 2012, 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. - -part of _js_helper; - -class ConstantMapView extends UnmodifiableMapView - implements ConstantMap { - ConstantMapView(Map base) : super(base); -} - -abstract class ConstantMap implements Map { - // Used to create unmodifiable maps from other maps. - factory ConstantMap.from(Map other) { - var keys = new List.from(other.keys); - bool allStrings = true; - for (var k in keys) { - if (k is! String) { - allStrings = false; - break; - } - } - if (allStrings) { - bool containsProto = false; - var protoValue = null; - var object = JS('=Object', '{}'); - int length = 0; - for (var k in keys) { - V v = other[k]; - if (k != '__proto__') { - if (!jsHasOwnProperty(object, k as String)) length++; - JS('void', '#[#] = #', object, k, v); - } else { - containsProto = true; - protoValue = v; - } - } - if (containsProto) { - length++; - return new ConstantProtoMap._(length, object, keys, protoValue); - } - return new ConstantStringMap._(length, object, keys); - } - // TODO(lrn): Make a proper unmodifiable map implementation. - return new ConstantMapView(new Map.from(other)); - } - - const ConstantMap._(); - - Map cast() => Map.castFrom(this); - bool get isEmpty => length == 0; - - bool get isNotEmpty => !isEmpty; - - String toString() => MapBase.mapToString(this); - - static Never _throwUnmodifiable() { - throw new UnsupportedError('Cannot modify unmodifiable Map'); - } - - void operator []=(K key, V val) { - _throwUnmodifiable(); - } - - V putIfAbsent(K key, V ifAbsent()) { - _throwUnmodifiable(); - } - - V? remove(Object? key) { - _throwUnmodifiable(); - } - - void clear() => _throwUnmodifiable(); - void addAll(Map other) => _throwUnmodifiable(); - - Iterable> get entries sync* { - for (var key in keys) yield new MapEntry(key, this[key]!); - } - - void addEntries(Iterable> entries) { - for (var entry in entries) this[entry.key] = entry.value; - } - - Map map(MapEntry transform(K key, V value)) { - var result = {}; - this.forEach((K key, V value) { - var entry = transform(key, value); - result[entry.key] = entry.value; - }); - return result; - } - - V update(K key, V update(V value), {V ifAbsent()?}) { - _throwUnmodifiable(); - } - - void updateAll(V update(K key, V value)) { - _throwUnmodifiable(); - } - - void removeWhere(bool test(K key, V value)) { - _throwUnmodifiable(); - } -} - -class ConstantStringMap extends ConstantMap { - // This constructor is not used for actual compile-time constants. - // The instantiation of constant maps is shortcut by the compiler. - const ConstantStringMap._(this._length, this._jsObject, this._keys) - : super._(); - - // TODO(18131): Ensure type inference knows the precise types of the fields. - final int _length; - // A constant map is backed by a JavaScript object. - final _jsObject; - final List _keys; - - int get length => JS('JSUInt31', '#', _length); - List get _keysArray => JS('JSUnmodifiableArray', '#', _keys); - - bool containsValue(Object? needle) { - return values.any((V value) => value == needle); - } - - bool containsKey(Object? key) { - if (key is! String) return false; - if ('__proto__' == key) return false; - return jsHasOwnProperty(_jsObject, key); - } - - V? operator [](Object? key) { - if (!containsKey(key)) return null; - return JS('', '#', _fetch(key)); - } - - // [_fetch] is the indexer for keys for which `containsKey(key)` is true. - _fetch(key) => jsPropertyAccess(_jsObject, key); - - void forEach(void f(K key, V value)) { - // Use a JS 'cast' to get efficient loop. Type inference doesn't get this - // since constant map representation is chosen after type inference and the - // instantiation is shortcut by the compiler. - var keys = _keysArray; - for (int i = 0; i < keys.length; i++) { - var key = keys[i]; - f(key, _fetch(key)); - } - } - - Iterable get keys { - return new _ConstantMapKeyIterable(this); - } - - Iterable get values { - return new MappedIterable(_keysArray, (key) => _fetch(key)); - } -} - -class ConstantProtoMap extends ConstantStringMap { - // This constructor is not used. The instantiation is shortcut by the - // compiler. It is here to make the uninitialized final fields legal. - ConstantProtoMap._(length, jsObject, keys, this._protoValue) - : super._(length, jsObject, keys); - - final V _protoValue; - - bool containsKey(Object? key) { - if (key is! String) return false; - if ('__proto__' == key) return true; - return jsHasOwnProperty(_jsObject, key); - } - - _fetch(key) => - '__proto__' == key ? _protoValue : jsPropertyAccess(_jsObject, key); -} - -class _ConstantMapKeyIterable extends Iterable { - ConstantStringMap _map; - _ConstantMapKeyIterable(this._map); - - Iterator get iterator => _map._keysArray.iterator; - - int get length => _map._keysArray.length; -} - -class GeneralConstantMap extends ConstantMap { - // This constructor is not used. The instantiation is shortcut by the - // compiler. It is here to make the uninitialized final fields legal. - GeneralConstantMap(this._jsData) : super._(); - - // [_jsData] holds a key-value pair list. - final _jsData; - - // We cannot create the backing map on creation since hashCode interceptors - // have not been defined when constants are created. - Map _getMap() { - LinkedHashMap? backingMap = JS('LinkedHashMap|Null', r'#.$map', this); - if (backingMap == null) { - backingMap = new JsLinkedHashMap(); - fillLiteralMap(_jsData, backingMap); - JS('', r'#.$map = #', this, backingMap); - } - return backingMap; - } - - bool containsValue(Object? needle) { - return _getMap().containsValue(needle); - } - - bool containsKey(Object? key) { - return _getMap().containsKey(key); - } - - V? operator [](Object? key) { - return _getMap()[key]; - } - - void forEach(void f(K key, V value)) { - _getMap().forEach(f); - } - - Iterable get keys { - return _getMap().keys; - } - - Iterable get values { - return _getMap().values; - } - - int get length => _getMap().length; -} diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/convert_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/convert_patch.dart deleted file mode 100644 index d7dfb5f6102..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/lib/convert_patch.dart +++ /dev/null @@ -1,484 +0,0 @@ -// Copyright (c) 2013, 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. - -// Patch file for dart:convert library. - -import 'dart:_js_helper' show argumentErrorValue, patch; -import 'dart:_foreign_helper' show JS; -import 'dart:_interceptors' show JSArray, JSExtendableArray; -import 'dart:_internal' show MappedIterable, ListIterable; -import 'dart:collection' show LinkedHashMap, MapBase; -import 'dart:_native_typed_data' show NativeUint8List; - -/// Parses [json] and builds the corresponding parsed JSON value. -/// -/// Parsed JSON values Nare of the types [num], [String], [bool], [Null], -/// [List]s of parsed JSON values or [Map]s from [String] to parsed -/// JSON values. -/// -/// The optional [reviver] function, if provided, is called once for each object -/// or list property parsed. The arguments are the property name ([String]) or -/// list index ([int]), and the value is the parsed value. The return value of -/// the reviver will be used as the value of that property instead of the parsed -/// value. The top level value is passed to the reviver with the empty string -/// as a key. -/// -/// Throws [FormatException] if the input is not valid JSON text. -@patch -_parseJson(String source, reviver(key, value)?) { - if (source is! String) throw argumentErrorValue(source); - - var parsed; - try { - parsed = JS('=Object|JSExtendableArray|Null|bool|num|String', - 'JSON.parse(#)', source); - } catch (e) { - throw FormatException(JS('String', 'String(#)', e)); - } - - if (reviver == null) { - return _convertJsonToDartLazy(parsed); - } else { - return _convertJsonToDart(parsed, reviver); - } -} - -/// Walks the raw JavaScript value [json], replacing JavaScript Objects with -/// Maps. [json] is expected to be freshly allocated so elements can be replaced -/// in-place. -_convertJsonToDart(json, reviver(Object? key, Object? value)) { - walk(e) { - // JavaScript null, string, number, bool are in the correct representation. - if (JS('bool', '# == null', e) || - JS('bool', 'typeof # != "object"', e)) { - return e; - } - - // This test is needed to avoid identifying '{"__proto__":[]}' as an Array. - // TODO(sra): Replace this test with cheaper '#.constructor === Array' when - // bug 621 below is fixed. - if (JS('bool', 'Object.getPrototypeOf(#) === Array.prototype', e)) { - // In-place update of the elements since JS Array is a Dart List. - for (int i = 0; i < JS('int', '#.length', e); i++) { - // Use JS indexing to avoid range checks. We know this is the only - // reference to the list, but the compiler will likely never be able to - // tell that this instance of the list cannot have its length changed by - // the reviver even though it later will be passed to the reviver at the - // outer level. - var item = JS('', '#[#]', e, i); - JS('', '#[#]=#', e, i, reviver(i, walk(item))); - } - return e; - } - - // Otherwise it is a plain object, so copy to a JSON map, so we process - // and revive all entries recursively. - _JsonMap map = _JsonMap(e); - var processed = map._processed; - List keys = map._computeKeys(); - for (int i = 0; i < keys.length; i++) { - String key = keys[i]; - var revived = reviver(key, walk(JS('', '#[#]', e, key))); - JS('', '#[#]=#', processed, key, revived); - } - - // Update the JSON map structure so future access is cheaper. - map._original = processed; // Don't keep two objects around. - return map; - } - - return reviver(null, walk(json)); -} - -_convertJsonToDartLazy(object) { - // JavaScript null and undefined are represented as null. - if (object == null) return null; - - // JavaScript string, number, bool already has the correct representation. - if (JS('bool', 'typeof # != "object"', object)) { - return object; - } - - // This test is needed to avoid identifying '{"__proto__":[]}' as an array. - // TODO(sra): Replace this test with cheaper '#.constructor === Array' when - // bug https://code.google.com/p/v8/issues/detail?id=621 is fixed. - if (JS( - 'bool', 'Object.getPrototypeOf(#) !== Array.prototype', object)) { - return _JsonMap(object); - } - - // Update the elements in place since JS arrays are Dart lists. - for (int i = 0; i < JS('int', '#.length', object); i++) { - // Use JS indexing to avoid range checks. We know this is the only - // reference to the list, but the compiler will likely never be able to - // tell that this instance of the list cannot have its length changed by - // the reviver even though it later will be passed to the reviver at the - // outer level. - var item = JS('', '#[#]', object, i); - JS('', '#[#]=#', object, i, _convertJsonToDartLazy(item)); - } - return object; -} - -class _JsonMap extends MapBase { - // The original JavaScript object remains unchanged until - // the map is eventually upgraded, in which case we null it - // out to reclaim the memory used by it. - var _original; - - // We keep track of the map entries that we have already - // processed by adding them to a separate JavaScript object. - var _processed = _newJavaScriptObject(); - - // If the data slot isn't null, it represents either the list - // of keys (for non-upgraded JSON maps) or the upgraded map. - var _data = null; - - _JsonMap(this._original); - - operator [](key) { - if (_isUpgraded) { - return _upgradedMap[key]; - } else if (key is! String) { - return null; - } else { - var result = _getProperty(_processed, key); - if (_isUnprocessed(result)) result = _process(key); - return result; - } - } - - int get length => _isUpgraded ? _upgradedMap.length : _computeKeys().length; - - bool get isEmpty => length == 0; - bool get isNotEmpty => length > 0; - - Iterable get keys { - if (_isUpgraded) return _upgradedMap.keys; - return _JsonMapKeyIterable(this); - } - - Iterable get values { - if (_isUpgraded) return _upgradedMap.values; - return MappedIterable(_computeKeys(), (each) => this[each]); - } - - operator []=(key, value) { - if (_isUpgraded) { - _upgradedMap[key] = value; - } else if (containsKey(key)) { - var processed = _processed; - _setProperty(processed, key, value); - var original = _original; - if (!identical(original, processed)) { - _setProperty(original, key, null); // Reclaim memory. - } - } else { - _upgrade()[key] = value; - } - } - - void addAll(Map other) { - other.forEach((key, value) { - this[key] = value; - }); - } - - bool containsValue(value) { - if (_isUpgraded) return _upgradedMap.containsValue(value); - List keys = _computeKeys(); - for (int i = 0; i < keys.length; i++) { - String key = keys[i]; - if (this[key] == value) return true; - } - return false; - } - - bool containsKey(key) { - if (_isUpgraded) return _upgradedMap.containsKey(key); - if (key is! String) return false; - return _hasProperty(_original, key); - } - - putIfAbsent(key, ifAbsent()) { - if (containsKey(key)) return this[key]; - var value = ifAbsent(); - this[key] = value; - return value; - } - - remove(Object? key) { - if (!_isUpgraded && !containsKey(key)) return null; - return _upgrade().remove(key); - } - - void clear() { - if (_isUpgraded) { - _upgradedMap.clear(); - } else { - if (_data != null) { - // Clear the list of keys to make sure we force - // a concurrent modification error if anyone is - // currently iterating over it. - _data.clear(); - } - _original = _processed = null; - _data = {}; - } - } - - void forEach(void f(String key, value)) { - if (_isUpgraded) return _upgradedMap.forEach(f); - List keys = _computeKeys(); - for (int i = 0; i < keys.length; i++) { - String key = keys[i]; - - // Compute the value under the assumption that the property - // is present but potentially not processed. - var value = _getProperty(_processed, key); - if (_isUnprocessed(value)) { - value = _convertJsonToDartLazy(_getProperty(_original, key)); - _setProperty(_processed, key, value); - } - - // Do the callback. - f(key, value); - - // Check if invoking the callback function changed - // the key set. If so, throw an exception. - if (!identical(keys, _data)) { - throw ConcurrentModificationError(this); - } - } - } - - // ------------------------------------------ - // Private helper methods. - // ------------------------------------------ - - bool get _isUpgraded => _processed == null; - - Map get _upgradedMap { - assert(_isUpgraded); - // 'cast' the union type to LinkedHashMap. It would be even better if we - // could 'cast' to the implementation type, since LinkedHashMap includes - // _JsonMap. - return JS('LinkedHashMap', '#', _data); - } - - List _computeKeys() { - assert(!_isUpgraded); - List? keys = _data; - if (keys == null) { - keys = _data = new JSArray.typed(_getPropertyNames(_original)); - } - return JS('JSExtendableArray', '#', keys); - } - - Map _upgrade() { - if (_isUpgraded) return _upgradedMap; - - // Copy all the (key, value) pairs to a freshly allocated - // linked hash map thus preserving the ordering. - var result = {}; - List keys = _computeKeys(); - for (int i = 0; i < keys.length; i++) { - String key = keys[i]; - result[key] = this[key]; - } - - // We only upgrade when we need to extend the map, so we can - // safely force a concurrent modification error in case - // someone is iterating over the map here. - if (keys.isEmpty) { - keys.add(""); - } else { - keys.clear(); - } - - // Clear out the associated JavaScript objects and mark the - // map as having been upgraded. - _original = _processed = null; - _data = result; - assert(_isUpgraded); - return result; - } - - _process(String key) { - if (!_hasProperty(_original, key)) return null; - var result = _convertJsonToDartLazy(_getProperty(_original, key)); - return _setProperty(_processed, key, result); - } - - // ------------------------------------------ - // Private JavaScript helper methods. - // ------------------------------------------ - - static bool _hasProperty(object, String key) => JS( - 'bool', 'Object.prototype.hasOwnProperty.call(#,#)', object, key); - static _getProperty(object, String key) => JS('', '#[#]', object, key); - static _setProperty(object, String key, value) => - JS('', '#[#]=#', object, key, value); - static List _getPropertyNames(object) => - JS('JSExtendableArray', 'Object.keys(#)', object); - static bool _isUnprocessed(object) => - JS('bool', 'typeof(#)=="undefined"', object); - static _newJavaScriptObject() => JS('=Object', 'Object.create(null)'); -} - -class _JsonMapKeyIterable extends ListIterable { - final _JsonMap _parent; - - _JsonMapKeyIterable(this._parent); - - int get length => _parent.length; - - String elementAt(int index) { - return _parent._isUpgraded - ? _parent.keys.elementAt(index) - : _parent._computeKeys()[index]; - } - - /// Although [ListIterable] defines its own iterator, we return the iterator - /// of the underlying list [_keys] in order to propagate - /// [ConcurrentModificationError]s. - Iterator get iterator { - return _parent._isUpgraded - ? _parent.keys.iterator - : _parent._computeKeys().iterator; - } - - /// Delegate to [parent.containsKey] to ensure the performance expected - /// from [Map.keys.containsKey]. - bool contains(Object? key) => _parent.containsKey(key); -} - -@patch -class JsonDecoder { - @patch - StringConversionSink startChunkedConversion(Sink sink) { - return _JsonDecoderSink(_reviver, sink); - } -} - -/// Implements the chunked conversion from a JSON string to its corresponding -/// object. -/// -/// The sink only creates one object, but its input can be chunked. -// TODO(floitsch): don't accumulate everything before starting to decode. -class _JsonDecoderSink extends _StringSinkConversionSink { - final Object? Function(Object? key, Object? value)? _reviver; - final Sink _sink; - - _JsonDecoderSink(this._reviver, this._sink) : super(StringBuffer('')); - - void close() { - super.close(); - String accumulated = _stringSink.toString(); - _stringSink.clear(); - Object? decoded = _parseJson(accumulated, _reviver); - _sink.add(decoded); - _sink.close(); - } -} - -@patch -class Utf8Decoder { - // Always fall back to the Dart implementation for strings shorter than this - // threshold, as there is a large, constant overhead for using TextDecoder. - static const int _shortInputThreshold = 15; - - @patch - Converter, T> fuse(Converter next) { - return super.fuse(next); - } - - @patch - static String? _convertIntercepted( - bool allowMalformed, List codeUnits, int start, int? end) { - // Test `codeUnits is NativeUint8List`. Dart's NativeUint8List is - // implemented by JavaScript's Uint8Array. - if (JS('bool', '# instanceof Uint8Array', codeUnits)) { - // JS 'cast' to avoid a downcast equivalent to the is-check we hand-coded. - NativeUint8List casted = - JS('NativeUint8List', '#', codeUnits); - // Always use Dart implementation for short strings. - end ??= casted.length; - if (end - start < _shortInputThreshold) { - return null; - } - String? result = - _convertInterceptedUint8List(allowMalformed, casted, start, end); - if (result != null && allowMalformed) { - // In principle, TextDecoder should have provided the correct result - // here, but some browsers deviate from the standard as to how many - // replacement characters they produce. Thus, we fall back to the Dart - // implementation if the result contains any replacement characters. - if (JS('int', r'#.indexOf(#)', result, '\uFFFD') >= 0) { - return null; - } - } - return result; - } - return null; // This call was not intercepted. - } - - static String? _convertInterceptedUint8List( - bool allowMalformed, NativeUint8List codeUnits, int start, int end) { - final decoder = allowMalformed ? _decoderNonfatal : _decoder; - if (decoder == null) return null; - if (0 == start && end == codeUnits.length) { - return _useTextDecoder(decoder, codeUnits); - } - - int length = codeUnits.length; - end = RangeError.checkValidRange(start, end, length); - - return _useTextDecoder( - decoder, - JS( - 'NativeUint8List', '#.subarray(#, #)', codeUnits, start, end)); - } - - static String? _useTextDecoder(decoder, NativeUint8List codeUnits) { - // If the input is malformed, catch the exception and return `null` to fall - // back on unintercepted decoder. The fallback will either succeed in - // decoding, or report the problem better than TextDecoder. - try { - return JS('String', '#.decode(#)', decoder, codeUnits); - } catch (e) {} - return null; - } - - // TextDecoder is not defined on some browsers and on the stand-alone d8 and - // jsshell engines. Use a lazy initializer to do feature detection once. - static final _decoder = () { - try { - return JS('', 'new TextDecoder("utf-8", {fatal: true})'); - } catch (e) {} - return null; - }(); - static final _decoderNonfatal = () { - try { - return JS('', 'new TextDecoder("utf-8", {fatal: false})'); - } catch (e) {} - return null; - }(); -} - -@patch -class _Utf8Decoder { - @patch - _Utf8Decoder(this.allowMalformed) : _state = beforeBom; - - @patch - String convertSingle(List codeUnits, int start, int? maybeEnd) { - return convertGeneral(codeUnits, start, maybeEnd, true); - } - - @patch - String convertChunked(List codeUnits, int start, int? maybeEnd) { - return convertGeneral(codeUnits, start, maybeEnd, false); - } -} diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/core_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/core_patch.dart deleted file mode 100644 index 6ffa92ea5fa..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/lib/core_patch.dart +++ /dev/null @@ -1,2952 +0,0 @@ -// Copyright (c) 2012, 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. - -// Patch file for dart:core classes. -import "dart:_internal" hide Symbol, LinkedList, LinkedListEntry; -import "dart:_internal" as _symbol_dev; -import 'dart:_interceptors'; -import 'dart:_js_helper' - show - checkInt, - Closure, - ConstantMap, - getRuntimeType, - JsLinkedHashMap, - jsonEncodeNative, - JSSyntaxRegExp, - NoInline, - objectHashCode, - patch, - Primitives, - quoteStringForRegExp, - stringJoinUnchecked, - getTraceFromException, - RuntimeError; - -import 'dart:_foreign_helper' show JS, JS_GET_FLAG; - -import 'dart:_native_typed_data' show NativeUint8List; - -import "dart:convert" show Encoding, utf8; - -import 'dart:typed_data' show Endian, Uint8List, Uint16List; - -String _symbolToString(Symbol symbol) => - _symbol_dev.Symbol.getName(symbol as _symbol_dev.Symbol); - -Map? _symbolMapToStringMap(Map? map) { - if (map == null) return null; - var result = new Map(); - map.forEach((Symbol key, value) { - result[_symbolToString(key)] = value; - }); - return result; -} - -@patch -int identityHashCode(Object? object) => objectHashCode(object); - -// Patch for Object implementation. -@patch -class Object { - @patch - bool operator ==(Object other) => identical(this, other); - - @patch - int get hashCode => Primitives.objectHashCode(this); - - @patch - String toString() => Primitives.objectToHumanReadableString(this); - - @patch - dynamic noSuchMethod(Invocation invocation) { - throw new NoSuchMethodError(this, invocation.memberName, - invocation.positionalArguments, invocation.namedArguments); - } - - @patch - Type get runtimeType => getRuntimeType(this); -} - -@patch -class Null { - @patch - int get hashCode => super.hashCode; -} - -// Patch for Function implementation. -@patch -class Function { - @patch - static apply(Function function, List? positionalArguments, - [Map? namedArguments]) { - return Primitives.applyFunction( - function, - positionalArguments, - // Use this form so that if namedArguments is always null, we can - // tree-shake _symbolMapToStringMap. - namedArguments == null ? null : _symbolMapToStringMap(namedArguments)); - } -} - -// Patch for Expando implementation. -@patch -class Expando { - static const String _EXPANDO_PROPERTY_NAME = 'expando\$values'; - - // Incremented to make unique keys. - static int _keyCount = 0; - - // Stores either a JS WeakMap or a "unique" string key. - final Object _jsWeakMapOrKey; - - @patch - Expando([String? name]) - : this.name = name, - _jsWeakMapOrKey = JS('bool', 'typeof WeakMap == "function"') - ? JS('=Object', 'new WeakMap()') - : _createKey(); - - @patch - T? operator [](Object object) { - if (_jsWeakMapOrKey is! String) { - _checkType(object); // WeakMap doesn't check on reading, only writing. - return JS('', '#.get(#)', _jsWeakMapOrKey, object); - } - return _getFromObject(_jsWeakMapOrKey as String, object) as T?; - } - - @patch - void operator []=(Object object, T? value) { - if (_jsWeakMapOrKey is! String) { - JS('void', '#.set(#, #)', _jsWeakMapOrKey, object, value); - } else { - _setOnObject(_jsWeakMapOrKey as String, object, value); - } - } - - static Object _getFromObject(String key, Object object) { - var values = Primitives.getProperty(object, _EXPANDO_PROPERTY_NAME); - return (values == null) ? null : Primitives.getProperty(values, key); - } - - static void _setOnObject(String key, Object object, Object? value) { - var values = Primitives.getProperty(object, _EXPANDO_PROPERTY_NAME); - if (values == null) { - values = new Object(); - Primitives.setProperty(object, _EXPANDO_PROPERTY_NAME, values); - } - Primitives.setProperty(values, key, value); - } - - static String _createKey() => "expando\$key\$${_keyCount++}"; - - static _checkType(object) { - if (object == null || object is bool || object is num || object is String) { - throw new ArgumentError.value(object, - "Expandos are not allowed on strings, numbers, booleans or null"); - } - } -} - -@patch -class int { - @patch - static int parse(String source, - {int? radix, @deprecated int onError(String source)?}) { - int? value = tryParse(source, radix: radix); - if (value != null) return value; - if (onError != null) return onError(source); - throw new FormatException(source); - } - - @patch - static int? tryParse(String source, {int? radix}) { - return Primitives.parseInt(source, radix); - } -} - -@patch -class double { - @patch - static double parse(String source, - [@deprecated double onError(String source)?]) { - double? value = tryParse(source); - if (value != null) return value; - if (onError != null) return onError(source); - throw new FormatException('Invalid double', source); - } - - @patch - static double? tryParse(String source) { - return Primitives.parseDouble(source); - } -} - -@patch -class BigInt implements Comparable { - @patch - static BigInt get zero => _BigIntImpl.zero; - @patch - static BigInt get one => _BigIntImpl.one; - @patch - static BigInt get two => _BigIntImpl.two; - - @patch - static BigInt parse(String source, {int? radix}) => - _BigIntImpl.parse(source, radix: radix); - - @patch - static BigInt? tryParse(String source, {int? radix}) => - _BigIntImpl._tryParse(source, radix: radix); - - @patch - factory BigInt.from(num value) = _BigIntImpl.from; -} - -@patch -class Error { - @patch - static String _objectToString(Object object) { - // Closures all have useful and safe toString methods. - if (object is Closure) return object.toString(); - return Primitives.objectToHumanReadableString(object); - } - - @patch - static String _stringToSafeString(String string) { - return jsonEncodeNative(string); - } - - @patch - StackTrace? get stackTrace => Primitives.extractStackTrace(this); -} - -@patch -class FallThroughError { - @patch - FallThroughError._create(String url, int line); - - @patch - String toString() => super.toString(); -} - -@patch -class AbstractClassInstantiationError { - @patch - String toString() => "Cannot instantiate abstract class: '$_className'"; -} - -// Patch for DateTime implementation. -@patch -class DateTime { - @patch - DateTime.fromMillisecondsSinceEpoch(int millisecondsSinceEpoch, - {bool isUtc: false}) - // `0 + millisecondsSinceEpoch` forces the inferred result to be non-null. - : this._withValue(0 + millisecondsSinceEpoch, isUtc: isUtc); - - @patch - DateTime.fromMicrosecondsSinceEpoch(int microsecondsSinceEpoch, - {bool isUtc: false}) - : this._withValue( - _microsecondInRoundedMilliseconds(microsecondsSinceEpoch), - isUtc: isUtc); - - @patch - DateTime._internal(int year, int month, int day, int hour, int minute, - int second, int millisecond, int microsecond, bool isUtc) - // checkBool is manually inlined here because dart2js doesn't inline it - // and [isUtc] is usually a constant. - : this.isUtc = isUtc is bool - ? isUtc - : throw new ArgumentError.value(isUtc, 'isUtc'), - _value = checkInt(Primitives.valueFromDecomposedDate( - year, - month, - day, - hour, - minute, - second, - millisecond + _microsecondInRoundedMilliseconds(microsecond), - isUtc)); - - @patch - DateTime._now() - : isUtc = false, - _value = Primitives.dateNow(); - - /// Rounds the given [microsecond] to the nearest milliseconds value. - /// - /// For example, invoked with argument `2600` returns `3`. - static int _microsecondInRoundedMilliseconds(int microsecond) { - return (microsecond / 1000).round(); - } - - @patch - static int? _brokenDownDateToValue(int year, int month, int day, int hour, - int minute, int second, int millisecond, int microsecond, bool isUtc) { - return Primitives.valueFromDecomposedDate( - year, - month, - day, - hour, - minute, - second, - millisecond + _microsecondInRoundedMilliseconds(microsecond), - isUtc); - } - - @patch - String get timeZoneName { - if (isUtc) return "UTC"; - return Primitives.getTimeZoneName(this); - } - - @patch - Duration get timeZoneOffset { - if (isUtc) return new Duration(); - return new Duration(minutes: Primitives.getTimeZoneOffsetInMinutes(this)); - } - - @patch - DateTime add(Duration duration) { - return new DateTime._withValue(_value + duration.inMilliseconds, - isUtc: isUtc); - } - - @patch - DateTime subtract(Duration duration) { - return new DateTime._withValue(_value - duration.inMilliseconds, - isUtc: isUtc); - } - - @patch - Duration difference(DateTime other) { - return new Duration(milliseconds: _value - other._value); - } - - @patch - int get millisecondsSinceEpoch => _value; - - @patch - int get microsecondsSinceEpoch => 1000 * _value; - - @patch - int get year => Primitives.getYear(this); - - @patch - int get month => Primitives.getMonth(this); - - @patch - int get day => Primitives.getDay(this); - - @patch - int get hour => Primitives.getHours(this); - - @patch - int get minute => Primitives.getMinutes(this); - - @patch - int get second => Primitives.getSeconds(this); - - @patch - int get millisecond => Primitives.getMilliseconds(this); - - @patch - int get microsecond => 0; - - @patch - int get weekday => Primitives.getWeekday(this); - - @patch - bool operator ==(Object other) => - other is DateTime && - _value == other.millisecondsSinceEpoch && - isUtc == other.isUtc; - - @patch - bool isBefore(DateTime other) => _value < other.millisecondsSinceEpoch; - - @patch - bool isAfter(DateTime other) => _value > other.millisecondsSinceEpoch; - - @patch - bool isAtSameMomentAs(DateTime other) => - _value == other.millisecondsSinceEpoch; - - @patch - int compareTo(DateTime other) => - _value.compareTo(other.millisecondsSinceEpoch); -} - -// Patch for Stopwatch implementation. -@patch -class Stopwatch { - @patch - static int _initTicker() { - Primitives.initTicker(); - return Primitives.timerFrequency; - } - - @patch - static int _now() => Primitives.timerTicks(); - - @patch - int get elapsedMicroseconds { - int ticks = elapsedTicks; - if (_frequency == 1000000) return ticks; - assert(_frequency == 1000); - return ticks * 1000; - } - - @patch - int get elapsedMilliseconds { - int ticks = elapsedTicks; - if (_frequency == 1000) return ticks; - assert(_frequency == 1000000); - return ticks ~/ 1000; - } -} - -// Patch for List implementation. -@patch -class List { - @patch - factory List([int? length]) = JSArray.list; - - @patch - factory List.filled(int length, E fill, {bool growable: false}) { - var result = growable - ? new JSArray.growable(length) - : new JSArray.fixed(length); - if (length != 0 && fill != null) { - // TODO(sra): Consider using `Array.fill`. - for (int i = 0; i < result.length; i++) { - // Unchecked assignment equivalent to `result[i] = fill`; - // `fill` is checked statically at call site. - JS('', '#[#] = #', result, i, fill); - } - } - return result; - } - - @patch - factory List.empty({bool growable: false}) { - return growable ? new JSArray.growable(0) : new JSArray.fixed(0); - } - - @patch - factory List.from(Iterable elements, {bool growable: true}) { - List list = []; - for (E e in elements) { - list.add(e); - } - if (growable) return list; - return makeListFixedLength(list); - } - - @patch - factory List.of(Iterable elements, {bool growable: true}) { - // TODO(32937): Specialize to benefit from known element type. - return List.from(elements, growable: growable); - } - - @patch - factory List.generate(int length, E generator(int index), - {bool growable = true}) { - final result = growable - ? new JSArray.growable(length) - : new JSArray.fixed(length); - for (int i = 0; i < length; i++) { - result[i] = generator(i); - } - return result; - } - - @patch - factory List.unmodifiable(Iterable elements) { - var result = List.from(elements, growable: false); - return makeFixedListUnmodifiable(result); - } -} - -@patch -class Map { - @patch - factory Map.unmodifiable(Map other) = ConstantMap.from; - - @patch - factory Map() = JsLinkedHashMap.es6; -} - -@patch -class String { - @patch - factory String.fromCharCodes(Iterable charCodes, - [int start = 0, int? end]) { - if (charCodes is JSArray) { - // Type promotion doesn't work unless the check is `is JSArray`, - // which is more expensive. - // TODO(41383): Optimize `is JSArray` rather than do weird 'casts'. - JSArray array = JS('JSArray', '#', charCodes); - return _stringFromJSArray(array, start, end); - } - if (charCodes is NativeUint8List) { - return _stringFromUint8List(charCodes, start, end); - } - return _stringFromIterable(charCodes, start, end); - } - - @patch - factory String.fromCharCode(int charCode) { - return Primitives.stringFromCharCode(charCode); - } - - static String _stringFromJSArray(JSArray list, int start, int? endOrNull) { - int len = list.length; - int end = RangeError.checkValidRange(start, endOrNull, len); - if (start > 0 || end < len) { - list = JS('JSArray', '#.slice(#, #)', list, start, end); - } - return Primitives.stringFromCharCodes(list); - } - - static String _stringFromUint8List( - NativeUint8List charCodes, int start, int? endOrNull) { - int len = charCodes.length; - int end = RangeError.checkValidRange(start, endOrNull, len); - return Primitives.stringFromNativeUint8List(charCodes, start, end); - } - - static String _stringFromIterable( - Iterable charCodes, int start, int? end) { - if (start < 0) throw new RangeError.range(start, 0, charCodes.length); - if (end != null && end < start) { - throw new RangeError.range(end, start, charCodes.length); - } - var it = charCodes.iterator; - for (int i = 0; i < start; i++) { - if (!it.moveNext()) { - throw new RangeError.range(start, 0, i); - } - } - var list = []; - if (end == null) { - while (it.moveNext()) list.add(it.current); - } else { - for (int i = start; i < end; i++) { - if (!it.moveNext()) { - throw new RangeError.range(end, start, i); - } - list.add(it.current); - } - } - return Primitives.stringFromCharCodes(list); - } -} - -@patch -class bool { - @patch - int get hashCode => super.hashCode; -} - -@patch -class RegExp { - @pragma('dart2js:noInline') - @patch - factory RegExp(String source, - {bool multiLine: false, - bool caseSensitive: true, - bool unicode: false, - bool dotAll: false}) => - new JSSyntaxRegExp(source, - multiLine: multiLine, - caseSensitive: caseSensitive, - unicode: unicode, - dotAll: dotAll); - - @patch - static String escape(String text) => quoteStringForRegExp(text); -} - -// Patch for 'identical' function. -@pragma( - 'dart2js:noInline') // No inlining since we recognize the call in optimizer. -@patch -bool identical(Object? a, Object? b) { - return JS('bool', '(# == null ? # == null : # === #)', a, b, a, b); -} - -@patch -class StringBuffer { - String _contents; - - @patch - StringBuffer([Object content = ""]) : _contents = '$content'; - - @patch - int get length => _contents.length; - - @patch - void write(Object? obj) { - _writeString('$obj'); - } - - @patch - void writeCharCode(int charCode) { - _writeString(new String.fromCharCode(charCode)); - } - - @patch - void writeAll(Iterable objects, [String separator = ""]) { - _contents = _writeAll(_contents, objects, separator); - } - - @patch - void writeln([Object? obj = ""]) { - _writeString('$obj\n'); - } - - @patch - void clear() { - _contents = ""; - } - - @patch - String toString() => Primitives.flattenString(_contents); - - void _writeString(String str) { - _contents = Primitives.stringConcatUnchecked(_contents, str); - } - - static String _writeAll(String string, Iterable objects, String separator) { - Iterator iterator = objects.iterator; - if (!iterator.moveNext()) return string; - if (separator.isEmpty) { - do { - string = _writeOne(string, iterator.current); - } while (iterator.moveNext()); - } else { - string = _writeOne(string, iterator.current); - while (iterator.moveNext()) { - string = _writeOne(string, separator); - string = _writeOne(string, iterator.current); - } - } - return string; - } - - static String _writeOne(String string, Object? obj) { - return Primitives.stringConcatUnchecked(string, '$obj'); - } -} - -@patch -class NoSuchMethodError { - final Object? _receiver; - final Symbol _memberName; - final List? _arguments; - final Map? _namedArguments; - final List? _existingArgumentNames; - - @patch - NoSuchMethodError.withInvocation(Object? receiver, Invocation invocation) - : this(receiver, invocation.memberName, invocation.positionalArguments, - invocation.namedArguments); - - @patch - NoSuchMethodError(Object? receiver, Symbol memberName, - List? positionalArguments, Map? namedArguments, - [List? existingArgumentNames = null]) - : _receiver = receiver, - _memberName = memberName, - _arguments = positionalArguments, - _namedArguments = namedArguments, - _existingArgumentNames = existingArgumentNames; - - @patch - String toString() { - StringBuffer sb = StringBuffer(''); - String comma = ''; - var arguments = _arguments; - if (arguments != null) { - for (var argument in arguments) { - sb.write(comma); - sb.write(Error.safeToString(argument)); - comma = ', '; - } - } - var namedArguments = _namedArguments; - if (namedArguments != null) { - namedArguments.forEach((Symbol key, var value) { - sb.write(comma); - sb.write(_symbolToString(key)); - sb.write(": "); - sb.write(Error.safeToString(value)); - comma = ', '; - }); - } - String memberName = _symbolToString(_memberName); - String receiverText = Error.safeToString(_receiver); - String actualParameters = '$sb'; - var existingArgumentNames = _existingArgumentNames; - if (existingArgumentNames == null) { - return "NoSuchMethodError: method not found: '$memberName'\n" - "Receiver: ${receiverText}\n" - "Arguments: [$actualParameters]"; - } else { - String formalParameters = existingArgumentNames.join(', '); - return "NoSuchMethodError: incorrect number of arguments passed to " - "method named '$memberName'\n" - "Receiver: ${receiverText}\n" - "Tried calling: $memberName($actualParameters)\n" - "Found: $memberName($formalParameters)"; - } - } -} - -class _CompileTimeError extends Error { - final String _errorMsg; - // TODO(sigmund): consider calling `JS('', 'debugger')`. - _CompileTimeError(this._errorMsg); - String toString() => _errorMsg; -} - -@patch -class Uri { - @patch - static Uri get base { - String? uri = Primitives.currentUri(); - if (uri != null) return Uri.parse(uri); - throw new UnsupportedError("'Uri.base' is not supported"); - } -} - -@patch -class _Uri { - @patch - static bool get _isWindows => _isWindowsCached; - - static final bool _isWindowsCached = JS( - 'bool', - 'typeof process != "undefined" && ' - 'Object.prototype.toString.call(process) == "[object process]" && ' - 'process.platform == "win32"'); - - // Matches a String that _uriEncodes to itself regardless of the kind of - // component. This corresponds to [_unreservedTable], i.e. characters that - // are not encoded by any encoding table. - static final RegExp _needsNoEncoding = new RegExp(r'^[\-\.0-9A-Z_a-z~]*$'); - - /// This is the internal implementation of JavaScript's encodeURI function. - /// It encodes all characters in the string [text] except for those - /// that appear in [canonicalTable], and returns the escaped string. - @patch - static String _uriEncode(List canonicalTable, String text, - Encoding encoding, bool spaceToPlus) { - if (identical(encoding, utf8) && _needsNoEncoding.hasMatch(text)) { - return text; - } - - // Encode the string into bytes then generate an ASCII only string - // by percent encoding selected bytes. - StringBuffer result = new StringBuffer(''); - var bytes = encoding.encode(text); - for (int i = 0; i < bytes.length; i++) { - int byte = bytes[i]; - if (byte < 128 && - ((canonicalTable[byte >> 4] & (1 << (byte & 0x0f))) != 0)) { - result.writeCharCode(byte); - } else if (spaceToPlus && byte == _SPACE) { - result.write('+'); - } else { - const String hexDigits = '0123456789ABCDEF'; - result.write('%'); - result.write(hexDigits[(byte >> 4) & 0x0f]); - result.write(hexDigits[byte & 0x0f]); - } - } - return result.toString(); - } -} - -bool _hasErrorStackProperty = JS('bool', 'new Error().stack != void 0'); - -@patch -class StackTrace { - @patch - @pragma('dart2js:noInline') - static StackTrace get current { - if (_hasErrorStackProperty) { - return getTraceFromException(JS('', 'new Error()')); - } - // Fallback if new Error().stack does not exist. - // Currently only required for IE 11. - try { - throw ''; - } catch (_, stackTrace) { - return stackTrace; - } - } -} - -// Called from kernel generated code. -_malformedTypeError(message) => new RuntimeError(message); - -// Called from kernel generated code. -_genericNoSuchMethod(receiver, memberName, positionalArguments, namedArguments, - existingArguments) { - return new NoSuchMethodError( - receiver, memberName, positionalArguments, namedArguments); -} - -// Called from kernel generated code. -_unresolvedConstructorError(receiver, memberName, positionalArguments, - namedArguments, existingArguments) { - // TODO(sra): Generate an error that reads: - // - // No constructor '$memberName' declared in class '$receiver'. - - return new NoSuchMethodError( - receiver, memberName, positionalArguments, namedArguments); -} - -// Called from kernel generated code. -_unresolvedStaticGetterError(receiver, memberName, positionalArguments, - namedArguments, existingArguments) { - // TODO(sra): Generate customized message. - return new NoSuchMethodError( - receiver, memberName, positionalArguments, namedArguments); -} - -// Called from kernel generated code. -_unresolvedStaticSetterError(receiver, memberName, positionalArguments, - namedArguments, existingArguments) { - // TODO(sra): Generate customized message. - return new NoSuchMethodError( - receiver, memberName, positionalArguments, namedArguments); -} - -// Called from kernel generated code. -_unresolvedStaticMethodError(receiver, memberName, positionalArguments, - namedArguments, existingArguments) { - // TODO(sra): Generate customized message. - return new NoSuchMethodError( - receiver, memberName, positionalArguments, namedArguments); -} - -// Called from kernel generated code. -_unresolvedTopLevelGetterError(receiver, memberName, positionalArguments, - namedArguments, existingArguments) { - // TODO(sra): Generate customized message. - return new NoSuchMethodError( - receiver, memberName, positionalArguments, namedArguments); -} - -// Called from kernel generated code. -_unresolvedTopLevelSetterError(receiver, memberName, positionalArguments, - namedArguments, existingArguments) { - // TODO(sra): Generate customized message. - return new NoSuchMethodError( - receiver, memberName, positionalArguments, namedArguments); -} - -// Called from kernel generated code. -_unresolvedTopLevelMethodError(receiver, memberName, positionalArguments, - namedArguments, existingArguments) { - // TODO(sra): Generate customized message. - return new NoSuchMethodError( - receiver, memberName, positionalArguments, namedArguments); -} - -/// Used by Fasta to report a runtime error when a final field with an -/// initializer is also initialized in a generative constructor. -/// -/// Note: in strong mode, this is a compile-time error and this class becomes -/// obsolete. -class _DuplicatedFieldInitializerError extends Error { - final String _name; - - _DuplicatedFieldInitializerError(this._name); - - toString() => "Error: field '$_name' is already initialized."; -} - -// TODO(sra): The rest of this core_patch.dart source should reside in an -// included part file instead of being inlined. However, part files are not -// properly supported here. - -// Copyright (c) 2017, 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. - -// part of dart.core; - -int _max(int a, int b) => a > b ? a : b; -int _min(int a, int b) => a < b ? a : b; - -/// Empty list used as an initializer for local variables in the `_BigIntImpl`. -final _dummyList = new Uint16List(0); - -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -/* - * Copyright (c) 2003-2005 Tom Wu - * Copyright (c) 2012 Adam Singer (adam@solvr.io) - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL, - * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER - * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF - * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * In addition, the following condition applies: - * - * All redistributions must retain an intact copy of this copyright notice - * and disclaimer. - */ - -/// An implementation for the arbitrarily large integer. -/// -/// The integer number is represented by a sign, an array of 16-bit unsigned -/// integers in little endian format, and a number of used digits in that array. -class _BigIntImpl implements BigInt { - // Bits per digit. - static const int _digitBits = 16; - static const int _digitBase = 1 << _digitBits; - static const int _digitMask = (1 << _digitBits) - 1; - - static final _BigIntImpl zero = new _BigIntImpl._fromInt(0); - static final _BigIntImpl one = new _BigIntImpl._fromInt(1); - static final _BigIntImpl two = new _BigIntImpl._fromInt(2); - - static final _BigIntImpl _minusOne = -one; - static final _BigIntImpl _bigInt10000 = new _BigIntImpl._fromInt(10000); - - // Result cache for last _divRem call. - // Result cache for last _divRem call. - static Uint16List? _lastDividendDigits; - static int? _lastDividendUsed; - static Uint16List? _lastDivisorDigits; - static int? _lastDivisorUsed; - static late Uint16List _lastQuoRemDigits; - static late int _lastQuoRemUsed; - static late int _lastRemUsed; - static late int _lastRem_nsh; - - /// Whether this bigint is negative. - final bool _isNegative; - - /// The unsigned digits of this bigint. - /// - /// The least significant digit is in slot 0. - /// The list may have more digits than needed. That is, `_digits.length` may - /// be strictly greater than `_used`. - final Uint16List _digits; - - /// The number of used entries in [_digits]. - /// - /// To avoid reallocating [Uint16List]s, lists that are too big are not - /// replaced. - final int _used; - - /// Parses [source] as a, possibly signed, integer literal and returns its - /// value. - /// - /// The [source] must be a non-empty sequence of base-[radix] digits, - /// optionally prefixed with a minus or plus sign ('-' or '+'). - /// - /// The [radix] must be in the range 2..36. The digits used are - /// first the decimal digits 0..9, and then the letters 'a'..'z' with - /// values 10 through 35. Also accepts upper-case letters with the same - /// values as the lower-case ones. - /// - /// If no [radix] is given then it defaults to 10. In this case, the [source] - /// digits may also start with `0x`, in which case the number is interpreted - /// as a hexadecimal literal, which effectively means that the `0x` is ignored - /// and the radix is instead set to 16. - /// - /// For any int `n` and radix `r`, it is guaranteed that - /// `n == int.parse(n.toRadixString(r), radix: r)`. - /// - /// Throws a [FormatException] if the [source] is not a valid integer literal, - /// optionally prefixed by a sign. - static _BigIntImpl parse(String source, {int? radix}) { - var result = _tryParse(source, radix: radix); - if (result == null) { - throw new FormatException("Could not parse BigInt", source); - } - return result; - } - - /// Parses a decimal bigint literal. - /// - /// The [source] must not contain leading or trailing whitespace. - static _BigIntImpl _parseDecimal(String source, bool isNegative) { - const _0 = 48; - - int part = 0; - _BigIntImpl result = zero; - // Read in the source 4 digits at a time. - // The first part may have a few leading virtual '0's to make the remaining - // parts all have exactly 4 digits. - var digitInPartCount = 4 - source.length.remainder(4); - if (digitInPartCount == 4) digitInPartCount = 0; - for (int i = 0; i < source.length; i++) { - part = part * 10 + source.codeUnitAt(i) - _0; - if (++digitInPartCount == 4) { - result = result * _bigInt10000 + new _BigIntImpl._fromInt(part); - part = 0; - digitInPartCount = 0; - } - } - if (isNegative) return -result; - return result; - } - - /// Returns the value of a given source digit. - /// - /// Source digits between "0" and "9" (inclusive) return their decimal value. - /// - /// Source digits between "a" and "z", or "A" and "Z" (inclusive) return - /// 10 + their position in the ASCII alphabet. - /// - /// The incoming [codeUnit] must be an ASCII code-unit. - static int _codeUnitToRadixValue(int codeUnit) { - // We know that the characters must be ASCII as otherwise the - // regexp wouldn't have matched. Lowercasing by doing `| 0x20` is thus - // guaranteed to be a safe operation, since it preserves digits - // and lower-cases ASCII letters. - const int _0 = 48; - const int _9 = 57; - const int _a = 97; - if (_0 <= codeUnit && codeUnit <= _9) return codeUnit - _0; - codeUnit |= 0x20; - var result = codeUnit - _a + 10; - return result; - } - - /// Parses the given [source] string, starting at [startPos], as a hex - /// literal. - /// - /// If [isNegative] is true, negates the result before returning it. - /// - /// The [source] (substring) must be a valid hex literal. - static _BigIntImpl? _parseHex(String source, int startPos, bool isNegative) { - int hexDigitsPerChunk = _digitBits ~/ 4; - int sourceLength = source.length - startPos; - int chunkCount = (sourceLength / hexDigitsPerChunk).ceil(); - var digits = new Uint16List(chunkCount); - - int lastDigitLength = sourceLength - (chunkCount - 1) * hexDigitsPerChunk; - int digitIndex = digits.length - 1; - int i = startPos; - int chunk = 0; - for (int j = 0; j < lastDigitLength; j++) { - var digitValue = _codeUnitToRadixValue(source.codeUnitAt(i++)); - if (digitValue >= 16) return null; - chunk = chunk * 16 + digitValue; - } - digits[digitIndex--] = chunk; - - while (i < source.length) { - chunk = 0; - for (int j = 0; j < hexDigitsPerChunk; j++) { - var digitValue = _codeUnitToRadixValue(source.codeUnitAt(i++)); - if (digitValue >= 16) return null; - chunk = chunk * 16 + digitValue; - } - digits[digitIndex--] = chunk; - } - if (digits.length == 1 && digits[0] == 0) return zero; - return new _BigIntImpl._(isNegative, digits.length, digits); - } - - /// Parses the given [source] as a [radix] literal. - /// - /// The [source] will be checked for invalid characters. If it is invalid, - /// this function returns `null`. - static _BigIntImpl? _parseRadix(String source, int radix, bool isNegative) { - var result = zero; - var base = new _BigIntImpl._fromInt(radix); - for (int i = 0; i < source.length; i++) { - var digitValue = _codeUnitToRadixValue(source.codeUnitAt(i)); - if (digitValue >= radix) return null; - result = result * base + new _BigIntImpl._fromInt(digitValue); - } - if (isNegative) return -result; - return result; - } - - /// Tries to parse the given [source] as a [radix] literal. - /// - /// Returns the parsed big integer, or `null` if it failed. - /// - /// If the [radix] is `null` accepts decimal literals or `0x` hex literals. - static _BigIntImpl? _tryParse(String source, {int? radix}) { - if (source == "") return null; - - var match = _parseRE.firstMatch(source); - int signIndex = 1; - int hexIndex = 3; - int decimalIndex = 4; - int nonDecimalHexIndex = 5; - if (match == null) return null; - - bool isNegative = match[signIndex] == "-"; - - String? decimalMatch = match[decimalIndex]; - String? hexMatch = match[hexIndex]; - String? nonDecimalMatch = match[nonDecimalHexIndex]; - - if (radix == null) { - if (decimalMatch != null) { - // Cannot fail because we know that the digits are all decimal. - return _parseDecimal(decimalMatch, isNegative); - } - if (hexMatch != null) { - // Cannot fail because we know that the digits are all hex. - return _parseHex(hexMatch, 2, isNegative); - } - return null; - } - - if (radix is! int) { - throw new ArgumentError.value(radix, 'radix', 'is not an integer'); - } - if (radix < 2 || radix > 36) { - throw new RangeError.range(radix, 2, 36, 'radix'); - } - if (radix == 10 && decimalMatch != null) { - return _parseDecimal(decimalMatch, isNegative); - } - if (radix == 16 && (decimalMatch != null || nonDecimalMatch != null)) { - return _parseHex(decimalMatch ?? nonDecimalMatch!, 0, isNegative); - } - - return _parseRadix( - decimalMatch ?? nonDecimalMatch ?? hexMatch!, radix, isNegative); - } - - static RegExp _parseRE = RegExp( - r'^\s*([+-]?)((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$', - caseSensitive: false); - - /// Finds the amount significant digits in the provided [digits] array. - static int _normalize(int used, Uint16List digits) { - while (used > 0 && digits[used - 1] == 0) used--; - return 0 + used; // force inferred result to be non-null. - } - - /// Factory returning an instance initialized with the given field values. - /// If the [digits] array contains leading 0s, the [used] value is adjusted - /// accordingly. The [digits] array is not modified. - _BigIntImpl._(bool isNegative, int used, Uint16List digits) - : this._normalized(isNegative, _normalize(used, digits), digits); - - _BigIntImpl._normalized(bool isNegative, this._used, this._digits) - : _isNegative = _used == 0 ? false : isNegative; - - /// Whether this big integer is zero. - bool get _isZero => _used == 0; - - /// Allocates an array of the given [length] and copies the [digits] in the - /// range [from] to [to-1], starting at index 0, followed by leading zero - /// digits. - static Uint16List _cloneDigits( - Uint16List digits, int from, int to, int length) { - var resultDigits = new Uint16List(length); - var n = to - from; - for (var i = 0; i < n; i++) { - resultDigits[i] = digits[from + i]; - } - return resultDigits; - } - - /// Allocates a big integer from the provided [value] number. - factory _BigIntImpl.from(num value) { - if (value == 0) return zero; - if (value == 1) return one; - if (value == 2) return two; - - // Given this order dart2js will use the `_fromInt` for smaller value and - // then use the bit-manipulating `_fromDouble` for all other values. - if (value.abs() < 0x100000000) - return new _BigIntImpl._fromInt(value.toInt()); - if (value is double) return new _BigIntImpl._fromDouble(value); - return new _BigIntImpl._fromInt(value as int); - } - - factory _BigIntImpl._fromInt(int value) { - bool isNegative = value < 0; - assert(_digitBits == 16); - if (isNegative) { - // Handle the min 64-bit value differently, since its negation is not - // positive. - const int minInt64 = -0x80000000 * 0x100000000; - if (value == minInt64) { - var digits = new Uint16List(4); - digits[3] = 0x8000; - return new _BigIntImpl._(true, 4, digits); - } - value = -value; - } - if (value < _digitBase) { - var digits = new Uint16List(1); - digits[0] = value; - return new _BigIntImpl._(isNegative, 1, digits); - } - if (value <= 0xFFFFFFFF) { - var digits = new Uint16List(2); - digits[0] = value & _digitMask; - digits[1] = value >> _digitBits; - return new _BigIntImpl._(isNegative, 2, digits); - } - - var bits = value.bitLength; - var digits = new Uint16List((bits - 1) ~/ _digitBits + 1); - var i = 0; - while (value != 0) { - digits[i++] = value & _digitMask; - value = value ~/ _digitBase; - } - return new _BigIntImpl._(isNegative, digits.length, digits); - } - - /// An 8-byte Uint8List we can reuse for [_fromDouble] to avoid generating - /// garbage. - static final Uint8List _bitsForFromDouble = new Uint8List(8); - - factory _BigIntImpl._fromDouble(double value) { - const int exponentBias = 1075; - - if (value.isNaN || value.isInfinite) { - throw new ArgumentError("Value must be finite: $value"); - } - bool isNegative = value < 0; - if (isNegative) value = -value; - - value = value.floorToDouble(); - if (value == 0) return zero; - - var bits = _bitsForFromDouble; - for (int i = 0; i < 8; i++) { - bits[i] = 0; - } - bits.buffer.asByteData().setFloat64(0, value, Endian.little); - // The exponent is in bits 53..63. - var biasedExponent = (bits[7] << 4) + (bits[6] >> 4); - var exponent = biasedExponent - exponentBias; - - assert(_digitBits == 16); - // The significant bits are in 0 .. 52. - var unshiftedDigits = new Uint16List(4); - unshiftedDigits[0] = (bits[1] << 8) + bits[0]; - unshiftedDigits[1] = (bits[3] << 8) + bits[2]; - unshiftedDigits[2] = (bits[5] << 8) + bits[4]; - // Don't forget to add the hidden bit. - unshiftedDigits[3] = 0x10 | (bits[6] & 0xF); - - var unshiftedBig = new _BigIntImpl._normalized(false, 4, unshiftedDigits); - _BigIntImpl absResult = unshiftedBig; - if (exponent < 0) { - absResult = unshiftedBig >> -exponent; - } else if (exponent > 0) { - absResult = unshiftedBig << exponent; - } - if (isNegative) return -absResult; - return absResult; - } - - /// Return the negative value of this integer. - /// - /// The result of negating an integer always has the opposite sign, except - /// for zero, which is its own negation. - _BigIntImpl operator -() { - if (_used == 0) return this; - return new _BigIntImpl._(!_isNegative, _used, _digits); - } - - /// Returns the absolute value of this integer. - /// - /// For any integer `x`, the result is the same as `x < 0 ? -x : x`. - _BigIntImpl abs() => _isNegative ? -this : this; - - /// Returns this << n *_DIGIT_BITS. - _BigIntImpl _dlShift(int n) { - final used = _used; - if (used == 0) { - return zero; - } - final resultUsed = used + n; - final digits = _digits; - final resultDigits = new Uint16List(resultUsed); - for (int i = used - 1; i >= 0; i--) { - resultDigits[i + n] = digits[i]; - } - return new _BigIntImpl._(_isNegative, resultUsed, resultDigits); - } - - /// Same as [_dlShift] but works on the decomposed big integers. - /// - /// Returns `resultUsed`. - /// - /// `resultDigits[0..resultUsed-1] = xDigits[0..xUsed-1] << n*_DIGIT_BITS`. - static int _dlShiftDigits( - Uint16List xDigits, int xUsed, int n, Uint16List resultDigits) { - if (xUsed == 0) { - return 0; - } - if (n == 0 && identical(resultDigits, xDigits)) { - return xUsed; - } - final resultUsed = xUsed + n; - for (int i = xUsed - 1; i >= 0; i--) { - resultDigits[i + n] = xDigits[i]; - } - for (int i = n - 1; i >= 0; i--) { - resultDigits[i] = 0; - } - return resultUsed; - } - - /// Returns `this >> n*_DIGIT_BITS`. - _BigIntImpl _drShift(int n) { - final used = _used; - if (used == 0) { - return zero; - } - final resultUsed = used - n; - if (resultUsed <= 0) { - return _isNegative ? _minusOne : zero; - } - final digits = _digits; - final resultDigits = new Uint16List(resultUsed); - for (var i = n; i < used; i++) { - resultDigits[i - n] = digits[i]; - } - final result = new _BigIntImpl._(_isNegative, resultUsed, resultDigits); - if (_isNegative) { - // Round down if any bit was shifted out. - for (var i = 0; i < n; i++) { - if (digits[i] != 0) { - return result - one; - } - } - } - return result; - } - - /// Shifts the digits of [xDigits] into the right place in [resultDigits]. - /// - /// `resultDigits[ds..xUsed+ds] = xDigits[0..xUsed-1] << (n % _DIGIT_BITS)` - /// where `ds = n ~/ _DIGIT_BITS` - /// - /// Does *not* clear digits below ds. - static void _lsh( - Uint16List xDigits, int xUsed, int n, Uint16List resultDigits) { - assert(xUsed > 0); - final digitShift = n ~/ _digitBits; - final bitShift = n % _digitBits; - final carryBitShift = _digitBits - bitShift; - final bitMask = (1 << carryBitShift) - 1; - var carry = 0; - for (int i = xUsed - 1; i >= 0; i--) { - final digit = xDigits[i]; - resultDigits[i + digitShift + 1] = (digit >> carryBitShift) | carry; - carry = (digit & bitMask) << bitShift; - } - resultDigits[digitShift] = carry; - } - - /// Shift the bits of this integer to the left by [shiftAmount]. - /// - /// Shifting to the left makes the number larger, effectively multiplying - /// the number by `pow(2, shiftIndex)`. - /// - /// There is no limit on the size of the result. It may be relevant to - /// limit intermediate values by using the "and" operator with a suitable - /// mask. - /// - /// It is an error if [shiftAmount] is negative. - _BigIntImpl operator <<(int shiftAmount) { - if (shiftAmount < 0) { - throw new ArgumentError("shift-amount must be posititve $shiftAmount"); - } - if (_isZero) return this; - final digitShift = shiftAmount ~/ _digitBits; - final bitShift = shiftAmount % _digitBits; - if (bitShift == 0) { - return _dlShift(digitShift); - } - var resultUsed = _used + digitShift + 1; - var resultDigits = new Uint16List(resultUsed); - _lsh(_digits, _used, shiftAmount, resultDigits); - return new _BigIntImpl._(_isNegative, resultUsed, resultDigits); - } - - // resultDigits[0..resultUsed-1] = xDigits[0..xUsed-1] << n. - // Returns resultUsed. - static int _lShiftDigits( - Uint16List xDigits, int xUsed, int n, Uint16List resultDigits) { - final digitsShift = n ~/ _digitBits; - final bitShift = n % _digitBits; - if (bitShift == 0) { - return _dlShiftDigits(xDigits, xUsed, digitsShift, resultDigits); - } - var resultUsed = xUsed + digitsShift + 1; - _lsh(xDigits, xUsed, n, resultDigits); - var i = digitsShift; - while (--i >= 0) { - resultDigits[i] = 0; - } - if (resultDigits[resultUsed - 1] == 0) { - resultUsed--; // Clamp result. - } - return resultUsed; - } - - // resultDigits[0..resultUsed-1] = xDigits[0..xUsed-1] >> n. - static void _rsh( - Uint16List xDigits, int xUsed, int n, Uint16List resultDigits) { - assert(xUsed > 0); - final digitsShift = n ~/ _digitBits; - final bitShift = n % _digitBits; - final carryBitShift = _digitBits - bitShift; - final bitMask = (1 << bitShift) - 1; - var carry = xDigits[digitsShift] >> bitShift; - final last = xUsed - digitsShift - 1; - for (var i = 0; i < last; i++) { - final digit = xDigits[i + digitsShift + 1]; - resultDigits[i] = ((digit & bitMask) << carryBitShift) | carry; - carry = digit >> bitShift; - } - resultDigits[last] = carry; - } - - /// Shift the bits of this integer to the right by [shiftAmount]. - /// - /// Shifting to the right makes the number smaller and drops the least - /// significant bits, effectively doing an integer division by - /// `pow(2, shiftIndex)`. - /// - /// It is an error if [shiftAmount] is negative. - _BigIntImpl operator >>(int shiftAmount) { - if (shiftAmount < 0) { - throw new ArgumentError("shift-amount must be posititve $shiftAmount"); - } - if (_isZero) return this; - final digitShift = shiftAmount ~/ _digitBits; - final bitShift = shiftAmount % _digitBits; - if (bitShift == 0) { - return _drShift(digitShift); - } - final used = _used; - final resultUsed = used - digitShift; - if (resultUsed <= 0) { - return _isNegative ? _minusOne : zero; - } - final digits = _digits; - final resultDigits = new Uint16List(resultUsed); - _rsh(digits, used, shiftAmount, resultDigits); - final result = new _BigIntImpl._(_isNegative, resultUsed, resultDigits); - if (_isNegative) { - // Round down if any bit was shifted out. - if ((digits[digitShift] & ((1 << bitShift) - 1)) != 0) { - return result - one; - } - for (var i = 0; i < digitShift; i++) { - if (digits[i] != 0) { - return result - one; - } - } - } - return result; - } - - /// Compares this to [other] taking the absolute value of both operands. - /// - /// Returns 0 if abs(this) == abs(other); a positive number if - /// abs(this) > abs(other); and a negative number if abs(this) < abs(other). - int _absCompare(_BigIntImpl other) { - return _compareDigits(_digits, _used, other._digits, other._used); - } - - /// Compares this to `other`. - /// - /// Returns a negative number if `this` is less than `other`, zero if they are - /// equal, and a positive number if `this` is greater than `other`. - int compareTo(covariant _BigIntImpl other) { - if (_isNegative == other._isNegative) { - var result = _absCompare(other); - // Use 0 - result to avoid negative zero in JavaScript. - return _isNegative ? 0 - result : result; - } - return _isNegative ? -1 : 1; - } - - /// Compares `digits[0..used-1]` with `otherDigits[0..otherUsed-1]`. - /// - /// Returns 0 if equal; a positive number if larger; - /// and a negative number if smaller. - static int _compareDigits( - Uint16List digits, int used, Uint16List otherDigits, int otherUsed) { - var result = used - otherUsed; - if (result == 0) { - for (int i = used - 1; i >= 0; i--) { - result = digits[i] - otherDigits[i]; - if (result != 0) return result; - } - } - return result; - } - - // resultDigits[0..used] = digits[0..used-1] + otherDigits[0..otherUsed-1]. - // used >= otherUsed > 0. - static void _absAdd(Uint16List digits, int used, Uint16List otherDigits, - int otherUsed, Uint16List resultDigits) { - assert(used >= otherUsed && otherUsed > 0); - var carry = 0; - for (var i = 0; i < otherUsed; i++) { - carry += digits[i] + otherDigits[i]; - resultDigits[i] = carry & _digitMask; - carry >>= _digitBits; - } - for (var i = otherUsed; i < used; i++) { - carry += digits[i]; - resultDigits[i] = carry & _digitMask; - carry >>= _digitBits; - } - resultDigits[used] = carry; - } - - // resultDigits[0..used-1] = digits[0..used-1] - otherDigits[0..otherUsed-1]. - // used >= otherUsed > 0. - static void _absSub(Uint16List digits, int used, Uint16List otherDigits, - int otherUsed, Uint16List resultDigits) { - assert(used >= otherUsed && otherUsed > 0); - - var carry = 0; - for (var i = 0; i < otherUsed; i++) { - carry += digits[i] - otherDigits[i]; - resultDigits[i] = carry & _digitMask; - // Dart2js only supports unsigned shifts. - // Since the carry can only be -1 or 0 use this hack. - carry = 0 - ((carry >> _digitBits) & 1); - } - for (var i = otherUsed; i < used; i++) { - carry += digits[i]; - resultDigits[i] = carry & _digitMask; - // Dart2js only supports unsigned shifts. - // Since the carry can only be -1 or 0 use this hack. - carry = 0 - ((carry >> _digitBits) & 1); - } - } - - /// Returns `abs(this) + abs(other)` with sign set according to [isNegative]. - _BigIntImpl _absAddSetSign(_BigIntImpl other, bool isNegative) { - var used = _used; - var otherUsed = other._used; - if (used < otherUsed) { - return other._absAddSetSign(this, isNegative); - } - if (used == 0) { - assert(!isNegative); - return zero; - } - if (otherUsed == 0) { - return _isNegative == isNegative ? this : -this; - } - var resultUsed = used + 1; - var resultDigits = new Uint16List(resultUsed); - _absAdd(_digits, used, other._digits, otherUsed, resultDigits); - return new _BigIntImpl._(isNegative, resultUsed, resultDigits); - } - - /// Returns `abs(this) - abs(other)` with sign set according to [isNegative]. - /// - /// Requirement: `abs(this) >= abs(other)`. - _BigIntImpl _absSubSetSign(_BigIntImpl other, bool isNegative) { - assert(_absCompare(other) >= 0); - var used = _used; - if (used == 0) { - assert(!isNegative); - return zero; - } - var otherUsed = other._used; - if (otherUsed == 0) { - return _isNegative == isNegative ? this : -this; - } - var resultDigits = new Uint16List(used); - _absSub(_digits, used, other._digits, otherUsed, resultDigits); - return new _BigIntImpl._(isNegative, used, resultDigits); - } - - /// Returns `abs(this) & abs(other)` with sign set according to [isNegative]. - _BigIntImpl _absAndSetSign(_BigIntImpl other, bool isNegative) { - var resultUsed = _min(_used, other._used); - var digits = _digits; - var otherDigits = other._digits; - var resultDigits = new Uint16List(resultUsed); - for (var i = 0; i < resultUsed; i++) { - resultDigits[i] = digits[i] & otherDigits[i]; - } - return new _BigIntImpl._(isNegative, resultUsed, resultDigits); - } - - /// Returns `abs(this) &~ abs(other)` with sign set according to [isNegative]. - _BigIntImpl _absAndNotSetSign(_BigIntImpl other, bool isNegative) { - var resultUsed = _used; - var digits = _digits; - var otherDigits = other._digits; - var resultDigits = new Uint16List(resultUsed); - var m = _min(resultUsed, other._used); - for (var i = 0; i < m; i++) { - resultDigits[i] = digits[i] & ~otherDigits[i]; - } - for (var i = m; i < resultUsed; i++) { - resultDigits[i] = digits[i]; - } - return new _BigIntImpl._(isNegative, resultUsed, resultDigits); - } - - /// Returns `abs(this) | abs(other)` with sign set according to [isNegative]. - _BigIntImpl _absOrSetSign(_BigIntImpl other, bool isNegative) { - var used = _used; - var otherUsed = other._used; - var resultUsed = _max(used, otherUsed); - var digits = _digits; - var otherDigits = other._digits; - var resultDigits = new Uint16List(resultUsed); - _BigIntImpl l; - int m; - if (used < otherUsed) { - l = other; - m = used; - } else { - l = this; - m = otherUsed; - } - for (var i = 0; i < m; i++) { - resultDigits[i] = digits[i] | otherDigits[i]; - } - var lDigits = l._digits; - for (var i = m; i < resultUsed; i++) { - resultDigits[i] = lDigits[i]; - } - return new _BigIntImpl._(isNegative, resultUsed, resultDigits); - } - - /// Returns `abs(this) ^ abs(other)` with sign set according to [isNegative]. - _BigIntImpl _absXorSetSign(_BigIntImpl other, bool isNegative) { - var used = _used; - var otherUsed = other._used; - var resultUsed = _max(used, otherUsed); - var digits = _digits; - var otherDigits = other._digits; - var resultDigits = new Uint16List(resultUsed); - _BigIntImpl l; - int m; - if (used < otherUsed) { - l = other; - m = used; - } else { - l = this; - m = otherUsed; - } - for (var i = 0; i < m; i++) { - resultDigits[i] = digits[i] ^ otherDigits[i]; - } - var lDigits = l._digits; - for (var i = m; i < resultUsed; i++) { - resultDigits[i] = lDigits[i]; - } - return new _BigIntImpl._(isNegative, resultUsed, resultDigits); - } - - /// Bit-wise and operator. - /// - /// Treating both `this` and [other] as sufficiently large two's component - /// integers, the result is a number with only the bits set that are set in - /// both `this` and [other] - /// - /// Of both operands are negative, the result is negative, otherwise - /// the result is non-negative. - _BigIntImpl operator &(covariant _BigIntImpl other) { - if (_isZero || other._isZero) return zero; - if (_isNegative == other._isNegative) { - if (_isNegative) { - // (-this) & (-other) == ~(this-1) & ~(other-1) - // == ~((this-1) | (other-1)) - // == -(((this-1) | (other-1)) + 1) - _BigIntImpl this1 = _absSubSetSign(one, true); - _BigIntImpl other1 = other._absSubSetSign(one, true); - // Result cannot be zero if this and other are negative. - return this1._absOrSetSign(other1, true)._absAddSetSign(one, true); - } - return _absAndSetSign(other, false); - } - // _isNegative != other._isNegative - _BigIntImpl p, n; - if (_isNegative) { - p = other; - n = this; - } else { - // & is symmetric. - p = this; - n = other; - } - // p & (-n) == p & ~(n-1) == p &~ (n-1) - var n1 = n._absSubSetSign(one, false); - return p._absAndNotSetSign(n1, false); - } - - /// Bit-wise or operator. - /// - /// Treating both `this` and [other] as sufficiently large two's component - /// integers, the result is a number with the bits set that are set in either - /// of `this` and [other] - /// - /// If both operands are non-negative, the result is non-negative, - /// otherwise the result us negative. - _BigIntImpl operator |(covariant _BigIntImpl other) { - if (_isZero) return other; - if (other._isZero) return this; - if (_isNegative == other._isNegative) { - if (_isNegative) { - // (-this) | (-other) == ~(this-1) | ~(other-1) - // == ~((this-1) & (other-1)) - // == -(((this-1) & (other-1)) + 1) - var this1 = _absSubSetSign(one, true); - var other1 = other._absSubSetSign(one, true); - // Result cannot be zero if this and a are negative. - return this1._absAndSetSign(other1, true)._absAddSetSign(one, true); - } - return _absOrSetSign(other, false); - } - // _neg != a._neg - _BigIntImpl p, n; - if (_isNegative) { - p = other; - n = this; - } else { - // | is symmetric. - p = this; - n = other; - } - // p | (-n) == p | ~(n-1) == ~((n-1) &~ p) == -(~((n-1) &~ p) + 1) - var n1 = n._absSubSetSign(one, true); - // Result cannot be zero if only one of this or a is negative. - return n1._absAndNotSetSign(p, true)._absAddSetSign(one, true); - } - - /// Bit-wise exclusive-or operator. - /// - /// Treating both `this` and [other] as sufficiently large two's component - /// integers, the result is a number with the bits set that are set in one, - /// but not both, of `this` and [other] - /// - /// If the operands have the same sign, the result is non-negative, - /// otherwise the result is negative. - _BigIntImpl operator ^(covariant _BigIntImpl other) { - if (_isZero) return other; - if (other._isZero) return this; - if (_isNegative == other._isNegative) { - if (_isNegative) { - // (-this) ^ (-other) == ~(this-1) ^ ~(other-1) == (this-1) ^ (other-1) - var this1 = _absSubSetSign(one, true); - var other1 = other._absSubSetSign(one, true); - return this1._absXorSetSign(other1, false); - } - return _absXorSetSign(other, false); - } - // _isNegative != a._isNegative - _BigIntImpl p, n; - if (_isNegative) { - p = other; - n = this; - } else { - // ^ is symmetric. - p = this; - n = other; - } - // p ^ (-n) == p ^ ~(n-1) == ~(p ^ (n-1)) == -((p ^ (n-1)) + 1) - var n1 = n._absSubSetSign(one, true); - // Result cannot be zero if only one of this or a is negative. - return p._absXorSetSign(n1, true)._absAddSetSign(one, true); - } - - /// The bit-wise negate operator. - /// - /// Treating `this` as a sufficiently large two's component integer, - /// the result is a number with the opposite bits set. - /// - /// This maps any integer `x` to `-x - 1`. - _BigIntImpl operator ~() { - if (_isZero) return _minusOne; - if (_isNegative) { - // ~(-this) == ~(~(this-1)) == this-1 - return _absSubSetSign(one, false); - } - // ~this == -this-1 == -(this+1) - // Result cannot be zero if this is positive. - return _absAddSetSign(one, true); - } - - /// Addition operator. - _BigIntImpl operator +(covariant _BigIntImpl other) { - if (_isZero) return other; - if (other._isZero) return this; - var isNegative = _isNegative; - if (isNegative == other._isNegative) { - // this + other == this + other - // (-this) + (-other) == -(this + other) - return _absAddSetSign(other, isNegative); - } - // this + (-other) == this - other == -(this - other) - // (-this) + other == other - this == -(this - other) - if (_absCompare(other) >= 0) { - return _absSubSetSign(other, isNegative); - } - return other._absSubSetSign(this, !isNegative); - } - - /// Subtraction operator. - _BigIntImpl operator -(covariant _BigIntImpl other) { - if (_isZero) return -other; - if (other._isZero) return this; - var isNegative = _isNegative; - if (isNegative != other._isNegative) { - // this - (-other) == this + other - // (-this) - other == -(this + other) - return _absAddSetSign(other, isNegative); - } - // this - other == this - a == -(this - other) - // (-this) - (-other) == other - this == -(this - other) - if (_absCompare(other) >= 0) { - return _absSubSetSign(other, isNegative); - } - return other._absSubSetSign(this, !isNegative); - } - - /// Multiplies [x] with [multiplicandDigits] and adds the result to - /// [accumulatorDigits]. - /// - /// The [multiplicandDigits] in the range [i] to [i]+[n]-1 are the - /// multiplicand digits. - /// - /// The [acculumatorDigits] in the range [j] to [j]+[n]-1 are the accumulator - /// digits. - /// - /// Adds the result of the multiplicand-digits * [x] to the accumulator. - /// - /// Concretely: `accumulatorDigits[j..j+n] += x * m_digits[i..i+n-1]`. - static void _mulAdd(int x, Uint16List multiplicandDigits, int i, - Uint16List accumulatorDigits, int j, int n) { - if (x == 0) { - // No-op if x is 0. - return; - } - int c = 0; - while (--n >= 0) { - int product = x * multiplicandDigits[i++]; - int combined = product + accumulatorDigits[j] + c; - accumulatorDigits[j++] = combined & _digitMask; - // Note that this works with 53 bits, as the division will not lose - // bits. - c = combined ~/ _digitBase; - } - while (c != 0) { - int l = accumulatorDigits[j] + c; - accumulatorDigits[j++] = l & _digitMask; - c = l ~/ _digitBase; - } - } - - /// Multiplication operator. - _BigIntImpl operator *(covariant _BigIntImpl other) { - var used = _used; - var otherUsed = other._used; - if (used == 0 || otherUsed == 0) { - return zero; - } - var resultUsed = used + otherUsed; - var digits = _digits; - var otherDigits = other._digits; - var resultDigits = new Uint16List(resultUsed); - var i = 0; - while (i < otherUsed) { - _mulAdd(otherDigits[i], digits, 0, resultDigits, i, used); - i++; - } - return new _BigIntImpl._( - _isNegative != other._isNegative, resultUsed, resultDigits); - } - - // r_digits[0..rUsed-1] = xDigits[0..xUsed-1]*otherDigits[0..otherUsed-1]. - // Return resultUsed = xUsed + otherUsed. - static int _mulDigits(Uint16List xDigits, int xUsed, Uint16List otherDigits, - int otherUsed, Uint16List resultDigits) { - var resultUsed = xUsed + otherUsed; - var i = resultUsed; - assert(resultDigits.length >= i); - while (--i >= 0) { - resultDigits[i] = 0; - } - i = 0; - while (i < otherUsed) { - _mulAdd(otherDigits[i], xDigits, 0, resultDigits, i, xUsed); - i++; - } - return resultUsed; - } - - /// Returns an estimate of `digits[i-1..i] ~/ topDigitDivisor`. - static int _estimateQuotientDigit( - int topDigitDivisor, Uint16List digits, int i) { - if (digits[i] == topDigitDivisor) return _digitMask; - var quotientDigit = - (digits[i] << _digitBits | digits[i - 1]) ~/ topDigitDivisor; - if (quotientDigit > _digitMask) return _digitMask; - return quotientDigit; - } - - /// Returns `trunc(this / other)`, with `other != 0`. - _BigIntImpl _div(_BigIntImpl other) { - assert(other._used > 0); - if (_used < other._used) { - return zero; - } - _divRem(other); - // Return quotient, i.e. - // _lastQuoRem_digits[_lastRem_used.._lastQuoRem_used-1] with proper sign. - var lastQuo_used = _lastQuoRemUsed - _lastRemUsed; - var quo_digits = _cloneDigits( - _lastQuoRemDigits, _lastRemUsed, _lastQuoRemUsed, lastQuo_used); - var quo = new _BigIntImpl._(false, lastQuo_used, quo_digits); - if ((_isNegative != other._isNegative) && (quo._used > 0)) { - quo = -quo; - } - return quo; - } - - /// Returns `this - other * trunc(this / other)`, with `other != 0`. - _BigIntImpl _rem(_BigIntImpl other) { - assert(other._used > 0); - if (_used < other._used) { - return this; - } - _divRem(other); - // Return remainder, i.e. - // denormalized _lastQuoRem_digits[0.._lastRem_used-1] with proper sign. - var remDigits = - _cloneDigits(_lastQuoRemDigits, 0, _lastRemUsed, _lastRemUsed); - var rem = new _BigIntImpl._(false, _lastRemUsed, remDigits); - if (_lastRem_nsh > 0) { - rem = rem >> _lastRem_nsh; // Denormalize remainder. - } - if (_isNegative && (rem._used > 0)) { - rem = -rem; - } - return rem; - } - - /// Computes this ~/ other and this.remainder(other). - /// - /// Stores the result in [_lastQuoRemDigits], [_lastQuoRemUsed] and - /// [_lastRemUsed]. The [_lastQuoRemDigits] contains the digits of *both*, the - /// quotient and the remainder. - /// - /// Caches the input to avoid doing the work again when users write - /// `a ~/ b` followed by a `a % b`. - void _divRem(_BigIntImpl other) { - // Check if result is already cached. - if ((this._used == _lastDividendUsed) && - (other._used == _lastDivisorUsed) && - identical(this._digits, _lastDividendDigits) && - identical(other._digits, _lastDivisorDigits)) { - return; - } - assert(_used >= other._used); - - var nsh = _digitBits - other._digits[other._used - 1].bitLength; - // Concatenated positive quotient and normalized positive remainder. - // The resultDigits can have at most one more digit than the dividend. - Uint16List resultDigits; - int resultUsed; - // Normalized positive divisor. - // The normalized divisor has the most-significant bit of its most - // significant digit set. - // This makes estimating the quotient easier. - Uint16List yDigits; - int yUsed; - if (nsh > 0) { - yDigits = new Uint16List(other._used + 5); - yUsed = _lShiftDigits(other._digits, other._used, nsh, yDigits); - resultDigits = new Uint16List(_used + 5); - resultUsed = _lShiftDigits(_digits, _used, nsh, resultDigits); - } else { - yDigits = other._digits; - yUsed = other._used; - resultDigits = _cloneDigits(_digits, 0, _used, _used + 2); - resultUsed = _used; - } - var topDigitDivisor = yDigits[yUsed - 1]; - var i = resultUsed; - var j = i - yUsed; - // tmpDigits is a temporary array of i (resultUsed) digits. - var tmpDigits = new Uint16List(i); - var tmpUsed = _dlShiftDigits(yDigits, yUsed, j, tmpDigits); - // Explicit first division step in case normalized dividend is larger or - // equal to shifted normalized divisor. - if (_compareDigits(resultDigits, resultUsed, tmpDigits, tmpUsed) >= 0) { - assert(i == resultUsed); - resultDigits[resultUsed++] = 1; // Quotient = 1. - // Subtract divisor from remainder. - _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits); - } else { - // Account for possible carry in _mulAdd step. - resultDigits[resultUsed++] = 0; - } - - // Negate y so we can later use _mulAdd instead of non-existent _mulSub. - var nyDigits = new Uint16List(yUsed + 2); - nyDigits[yUsed] = 1; - _absSub(nyDigits, yUsed + 1, yDigits, yUsed, nyDigits); - // nyDigits is read-only and has yUsed digits (possibly including several - // leading zeros). - // resultDigits is modified during iteration. - // resultDigits[0..yUsed-1] is the current remainder. - // resultDigits[yUsed..resultUsed-1] is the current quotient. - --i; - - while (j > 0) { - var estimatedQuotientDigit = - _estimateQuotientDigit(topDigitDivisor, resultDigits, i); - j--; - _mulAdd(estimatedQuotientDigit, nyDigits, 0, resultDigits, j, yUsed); - if (resultDigits[i] < estimatedQuotientDigit) { - // Reusing the already existing tmpDigits array. - var tmpUsed = _dlShiftDigits(nyDigits, yUsed, j, tmpDigits); - _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits); - while (resultDigits[i] < --estimatedQuotientDigit) { - _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits); - } - } - i--; - } - // Cache result. - _lastDividendDigits = _digits; - _lastDividendUsed = _used; - _lastDivisorDigits = other._digits; - _lastDivisorUsed = other._used; - _lastQuoRemDigits = resultDigits; - _lastQuoRemUsed = resultUsed; - _lastRemUsed = yUsed; - _lastRem_nsh = nsh; - } - - int get hashCode { - // This is the [Jenkins hash function][1] but using masking to keep - // values in SMI range. - // - // [1]: http://en.wikipedia.org/wiki/Jenkins_hash_function - - int combine(int hash, int value) { - hash = 0x1fffffff & (hash + value); - hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10)); - return hash ^ (hash >> 6); - } - - int finish(int hash) { - hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3)); - hash = hash ^ (hash >> 11); - return 0x1fffffff & (hash + ((0x00003fff & hash) << 15)); - } - - if (_isZero) return 6707; // Just a random number. - var hash = _isNegative ? 83585 : 429689; // Also random. - for (int i = 0; i < _used; i++) { - hash = combine(hash, _digits[i]); - } - return finish(hash); - } - - /// Test whether this value is numerically equal to `other`. - /// - /// If [other] is a [_BigIntImpl] returns whether the two operands have the - /// same value. - /// - /// Returns false if `other` is not a [_BigIntImpl]. - bool operator ==(Object other) => - other is _BigIntImpl && compareTo(other) == 0; - - /// Returns the minimum number of bits required to store this big integer. - /// - /// The number of bits excludes the sign bit, which gives the natural length - /// for non-negative (unsigned) values. Negative values are complemented to - /// return the bit position of the first bit that differs from the sign bit. - /// - /// To find the number of bits needed to store the value as a signed value, - /// add one, i.e. use `x.bitLength + 1`. - /// - /// ``` - /// x.bitLength == (-x-1).bitLength - /// - /// new BigInt.from(3).bitLength == 2; // 00000011 - /// new BigInt.from(2).bitLength == 2; // 00000010 - /// new BigInt.from(1).bitLength == 1; // 00000001 - /// new BigInt.from(0).bitLength == 0; // 00000000 - /// new BigInt.from(-1).bitLength == 0; // 11111111 - /// new BigInt.from(-2).bitLength == 1; // 11111110 - /// new BigInt.from(-3).bitLength == 2; // 11111101 - /// new BigInt.from(-4).bitLength == 2; // 11111100 - /// ``` - int get bitLength { - if (_used == 0) return 0; - if (_isNegative) return (~this).bitLength; - return _digitBits * (_used - 1) + _digits[_used - 1].bitLength; - } - - /// Truncating division operator. - /// - /// Performs a truncating integer division, where the remainder is discarded. - /// - /// The remainder can be computed using the [remainder] method. - /// - /// Examples: - /// ``` - /// var seven = new BigInt.from(7); - /// var three = new BigInt.from(3); - /// seven ~/ three; // => 2 - /// (-seven) ~/ three; // => -2 - /// seven ~/ -three; // => -2 - /// seven.remainder(three); // => 1 - /// (-seven).remainder(three); // => -1 - /// seven.remainder(-three); // => 1 - /// ``` - _BigIntImpl operator ~/(covariant _BigIntImpl other) { - if (other._used == 0) { - throw const IntegerDivisionByZeroException(); - } - return _div(other); - } - - /// Returns the remainder of the truncating division of `this` by [other]. - /// - /// The result `r` of this operation satisfies: - /// `this == (this ~/ other) * other + r`. - /// As a consequence the remainder `r` has the same sign as the divider - /// `this`. - _BigIntImpl remainder(covariant _BigIntImpl other) { - if (other._used == 0) { - throw const IntegerDivisionByZeroException(); - } - return _rem(other); - } - - /// Division operator. - double operator /(BigInt other) => this.toDouble() / other.toDouble(); - - /// Relational less than operator. - bool operator <(covariant _BigIntImpl other) => compareTo(other) < 0; - - /// Relational less than or equal operator. - bool operator <=(covariant _BigIntImpl other) => compareTo(other) <= 0; - - /// Relational greater than operator. - bool operator >(covariant _BigIntImpl other) => compareTo(other) > 0; - - /// Relational greater than or equal operator. - bool operator >=(covariant _BigIntImpl other) => compareTo(other) >= 0; - - /// Euclidean modulo operator. - /// - /// Returns the remainder of the Euclidean division. The Euclidean division of - /// two integers `a` and `b` yields two integers `q` and `r` such that - /// `a == b * q + r` and `0 <= r < b.abs()`. - /// - /// The sign of the returned value `r` is always positive. - /// - /// See [remainder] for the remainder of the truncating division. - _BigIntImpl operator %(covariant _BigIntImpl other) { - if (other._used == 0) { - throw const IntegerDivisionByZeroException(); - } - var result = _rem(other); - if (result._isNegative) { - if (other._isNegative) { - result = result - other; - } else { - result = result + other; - } - } - return result; - } - - /// Returns the sign of this big integer. - /// - /// Returns 0 for zero, -1 for values less than zero and - /// +1 for values greater than zero. - int get sign { - if (_used == 0) return 0; - return _isNegative ? -1 : 1; - } - - /// Whether this big integer is even. - bool get isEven => _used == 0 || (_digits[0] & 1) == 0; - - /// Whether this big integer is odd. - bool get isOdd => !isEven; - - /// Whether this number is negative. - bool get isNegative => _isNegative; - - _BigIntImpl pow(int exponent) { - if (exponent < 0) { - throw new ArgumentError("Exponent must not be negative: $exponent"); - } - if (exponent == 0) return one; - - // Exponentiation by squaring. - var result = one; - var base = this; - while (exponent != 0) { - if ((exponent & 1) == 1) { - result *= base; - } - exponent >>= 1; - // Skip unnecessary operation. - if (exponent != 0) { - base *= base; - } - } - return result; - } - - /// Returns this integer to the power of [exponent] modulo [modulus]. - /// - /// The [exponent] must be non-negative and [modulus] must be - /// positive. - _BigIntImpl modPow( - covariant _BigIntImpl exponent, covariant _BigIntImpl modulus) { - if (exponent._isNegative) { - throw new ArgumentError("exponent must be positive: $exponent"); - } - if (modulus <= zero) { - throw new ArgumentError("modulus must be strictly positive: $modulus"); - } - if (exponent._isZero) return one; - - final modulusUsed = modulus._used; - final modulusUsed2p4 = 2 * modulusUsed + 4; - final exponentBitlen = exponent.bitLength; - if (exponentBitlen <= 0) return one; - _BigIntReduction z = new _BigIntClassic(modulus); - var resultDigits = new Uint16List(modulusUsed2p4); - var result2Digits = new Uint16List(modulusUsed2p4); - var gDigits = new Uint16List(modulusUsed); - var gUsed = z.convert(this, gDigits); - // Initialize result with g. - // Copy leading zero if any. - for (int j = gUsed - 1; j >= 0; j--) { - resultDigits[j] = gDigits[j]; - } - var resultUsed = gUsed; - int result2Used; - for (int i = exponentBitlen - 2; i >= 0; i--) { - result2Used = z.sqr(resultDigits, resultUsed, result2Digits); - if (!(exponent & (one << i))._isZero) { - resultUsed = - z.mul(result2Digits, result2Used, gDigits, gUsed, resultDigits); - } else { - // Swap result and result2. - var tmpDigits = resultDigits; - var tmpUsed = resultUsed; - resultDigits = result2Digits; - resultUsed = result2Used; - result2Digits = tmpDigits; - result2Used = tmpUsed; - } - } - return z.revert(resultDigits, resultUsed); - } - - // If inv is false, returns gcd(x, y). - // If inv is true and gcd(x, y) = 1, returns d, so that c*x + d*y = 1. - // If inv is true and gcd(x, y) != 1, throws Exception("Not coprime"). - static _BigIntImpl _binaryGcd(_BigIntImpl x, _BigIntImpl y, bool inv) { - var xDigits = x._digits; - var yDigits = y._digits; - var xUsed = x._used; - var yUsed = y._used; - var maxUsed = xUsed > yUsed ? xUsed : yUsed; - var unshiftedMaxUsed = maxUsed; // Keep - xDigits = _cloneDigits(xDigits, 0, xUsed, maxUsed); - yDigits = _cloneDigits(yDigits, 0, yUsed, maxUsed); - int shiftAmount = 0; - if (inv) { - if ((yUsed == 1) && (yDigits[0] == 1)) return one; - if ((yUsed == 0) || (yDigits[0].isEven && xDigits[0].isEven)) { - throw new Exception("Not coprime"); - } - } else { - if (x._isZero) { - throw new ArgumentError.value(0, "this", "must not be zero"); - } - if (y._isZero) { - throw new ArgumentError.value(0, "other", "must not be zero"); - } - if (((xUsed == 1) && (xDigits[0] == 1)) || - ((yUsed == 1) && (yDigits[0] == 1))) return one; - while (((xDigits[0] & 1) == 0) && ((yDigits[0] & 1) == 0)) { - _rsh(xDigits, xUsed, 1, xDigits); - _rsh(yDigits, yUsed, 1, yDigits); - shiftAmount++; - } - if (shiftAmount >= _digitBits) { - var digitShiftAmount = shiftAmount ~/ _digitBits; - xUsed -= digitShiftAmount; - yUsed -= digitShiftAmount; - maxUsed -= digitShiftAmount; - } - if ((yDigits[0] & 1) == 1) { - // Swap x and y. - var tmpDigits = xDigits; - var tmpUsed = xUsed; - xDigits = yDigits; - xUsed = yUsed; - yDigits = tmpDigits; - yUsed = tmpUsed; - } - } - var uDigits = _cloneDigits(xDigits, 0, xUsed, unshiftedMaxUsed); - var vDigits = - _cloneDigits(yDigits, 0, yUsed, unshiftedMaxUsed + 2); // +2 for lsh. - final bool ac = (xDigits[0] & 1) == 0; - - // Variables a, b, c, and d require one more digit. - final abcdUsed = maxUsed + 1; - final abcdLen = abcdUsed + 2; // +2 to satisfy _absAdd. - var aDigits = _dummyList; - var aIsNegative = false; - var cDigits = _dummyList; - var cIsNegative = false; - if (ac) { - aDigits = new Uint16List(abcdLen); - aDigits[0] = 1; - cDigits = new Uint16List(abcdLen); - } - var bDigits = new Uint16List(abcdLen); - var bIsNegative = false; - var dDigits = new Uint16List(abcdLen); - var dIsNegative = false; - dDigits[0] = 1; - - while (true) { - while ((uDigits[0] & 1) == 0) { - _rsh(uDigits, maxUsed, 1, uDigits); - if (ac) { - if (((aDigits[0] & 1) == 1) || ((bDigits[0] & 1) == 1)) { - // a += y - if (aIsNegative) { - if ((aDigits[maxUsed] != 0) || - (_compareDigits(aDigits, maxUsed, yDigits, maxUsed)) > 0) { - _absSub(aDigits, abcdUsed, yDigits, maxUsed, aDigits); - } else { - _absSub(yDigits, maxUsed, aDigits, maxUsed, aDigits); - aIsNegative = false; - } - } else { - _absAdd(aDigits, abcdUsed, yDigits, maxUsed, aDigits); - } - // b -= x - if (bIsNegative) { - _absAdd(bDigits, abcdUsed, xDigits, maxUsed, bDigits); - } else if ((bDigits[maxUsed] != 0) || - (_compareDigits(bDigits, maxUsed, xDigits, maxUsed) > 0)) { - _absSub(bDigits, abcdUsed, xDigits, maxUsed, bDigits); - } else { - _absSub(xDigits, maxUsed, bDigits, maxUsed, bDigits); - bIsNegative = true; - } - } - _rsh(aDigits, abcdUsed, 1, aDigits); - } else if ((bDigits[0] & 1) == 1) { - // b -= x - if (bIsNegative) { - _absAdd(bDigits, abcdUsed, xDigits, maxUsed, bDigits); - } else if ((bDigits[maxUsed] != 0) || - (_compareDigits(bDigits, maxUsed, xDigits, maxUsed) > 0)) { - _absSub(bDigits, abcdUsed, xDigits, maxUsed, bDigits); - } else { - _absSub(xDigits, maxUsed, bDigits, maxUsed, bDigits); - bIsNegative = true; - } - } - _rsh(bDigits, abcdUsed, 1, bDigits); - } - while ((vDigits[0] & 1) == 0) { - _rsh(vDigits, maxUsed, 1, vDigits); - if (ac) { - if (((cDigits[0] & 1) == 1) || ((dDigits[0] & 1) == 1)) { - // c += y - if (cIsNegative) { - if ((cDigits[maxUsed] != 0) || - (_compareDigits(cDigits, maxUsed, yDigits, maxUsed) > 0)) { - _absSub(cDigits, abcdUsed, yDigits, maxUsed, cDigits); - } else { - _absSub(yDigits, maxUsed, cDigits, maxUsed, cDigits); - cIsNegative = false; - } - } else { - _absAdd(cDigits, abcdUsed, yDigits, maxUsed, cDigits); - } - // d -= x - if (dIsNegative) { - _absAdd(dDigits, abcdUsed, xDigits, maxUsed, dDigits); - } else if ((dDigits[maxUsed] != 0) || - (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) { - _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits); - } else { - _absSub(xDigits, maxUsed, dDigits, maxUsed, dDigits); - dIsNegative = true; - } - } - _rsh(cDigits, abcdUsed, 1, cDigits); - } else if ((dDigits[0] & 1) == 1) { - // d -= x - if (dIsNegative) { - _absAdd(dDigits, abcdUsed, xDigits, maxUsed, dDigits); - } else if ((dDigits[maxUsed] != 0) || - (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) { - _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits); - } else { - _absSub(xDigits, maxUsed, dDigits, maxUsed, dDigits); - dIsNegative = true; - } - } - _rsh(dDigits, abcdUsed, 1, dDigits); - } - if (_compareDigits(uDigits, maxUsed, vDigits, maxUsed) >= 0) { - // u -= v - _absSub(uDigits, maxUsed, vDigits, maxUsed, uDigits); - if (ac) { - // a -= c - if (aIsNegative == cIsNegative) { - var a_cmp_c = _compareDigits(aDigits, abcdUsed, cDigits, abcdUsed); - if (a_cmp_c > 0) { - _absSub(aDigits, abcdUsed, cDigits, abcdUsed, aDigits); - } else { - _absSub(cDigits, abcdUsed, aDigits, abcdUsed, aDigits); - aIsNegative = !aIsNegative && (a_cmp_c != 0); - } - } else { - _absAdd(aDigits, abcdUsed, cDigits, abcdUsed, aDigits); - } - } - // b -= d - if (bIsNegative == dIsNegative) { - var b_cmp_d = _compareDigits(bDigits, abcdUsed, dDigits, abcdUsed); - if (b_cmp_d > 0) { - _absSub(bDigits, abcdUsed, dDigits, abcdUsed, bDigits); - } else { - _absSub(dDigits, abcdUsed, bDigits, abcdUsed, bDigits); - bIsNegative = !bIsNegative && (b_cmp_d != 0); - } - } else { - _absAdd(bDigits, abcdUsed, dDigits, abcdUsed, bDigits); - } - } else { - // v -= u - _absSub(vDigits, maxUsed, uDigits, maxUsed, vDigits); - if (ac) { - // c -= a - if (cIsNegative == aIsNegative) { - var c_cmp_a = _compareDigits(cDigits, abcdUsed, aDigits, abcdUsed); - if (c_cmp_a > 0) { - _absSub(cDigits, abcdUsed, aDigits, abcdUsed, cDigits); - } else { - _absSub(aDigits, abcdUsed, cDigits, abcdUsed, cDigits); - cIsNegative = !cIsNegative && (c_cmp_a != 0); - } - } else { - _absAdd(cDigits, abcdUsed, aDigits, abcdUsed, cDigits); - } - } - // d -= b - if (dIsNegative == bIsNegative) { - var d_cmp_b = _compareDigits(dDigits, abcdUsed, bDigits, abcdUsed); - if (d_cmp_b > 0) { - _absSub(dDigits, abcdUsed, bDigits, abcdUsed, dDigits); - } else { - _absSub(bDigits, abcdUsed, dDigits, abcdUsed, dDigits); - dIsNegative = !dIsNegative && (d_cmp_b != 0); - } - } else { - _absAdd(dDigits, abcdUsed, bDigits, abcdUsed, dDigits); - } - } - // Exit loop if u == 0. - var i = maxUsed; - while ((i > 0) && (uDigits[i - 1] == 0)) --i; - if (i == 0) break; - } - if (!inv) { - if (shiftAmount > 0) { - maxUsed = _lShiftDigits(vDigits, maxUsed, shiftAmount, vDigits); - } - return new _BigIntImpl._(false, maxUsed, vDigits); - } - // No inverse if v != 1. - var i = maxUsed - 1; - while ((i > 0) && (vDigits[i] == 0)) --i; - if ((i != 0) || (vDigits[0] != 1)) { - throw new Exception("Not coprime"); - } - - if (dIsNegative) { - while ((dDigits[maxUsed] != 0) || - (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) { - // d += x, d still negative - _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits); - } - // d += x - _absSub(xDigits, maxUsed, dDigits, maxUsed, dDigits); - dIsNegative = false; - } else { - while ((dDigits[maxUsed] != 0) || - (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) >= 0)) { - // d -= x - _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits); - } - } - return new _BigIntImpl._(false, maxUsed, dDigits); - } - - /// Returns the modular multiplicative inverse of this big integer - /// modulo [modulus]. - /// - /// The [modulus] must be positive. - /// - /// It is an error if no modular inverse exists. - // Returns 1/this % modulus, with modulus > 0. - _BigIntImpl modInverse(covariant _BigIntImpl modulus) { - if (modulus <= zero) { - throw new ArgumentError("Modulus must be strictly positive: $modulus"); - } - if (modulus == one) return zero; - var tmp = this; - if (tmp._isNegative || (tmp._absCompare(modulus) >= 0)) { - tmp %= modulus; - } - return _binaryGcd(modulus, tmp, true); - } - - /// Returns the greatest common divisor of this big integer and [other]. - /// - /// If either number is non-zero, the result is the numerically greatest - /// integer dividing both `this` and `other`. - /// - /// The greatest common divisor is independent of the order, - /// so `x.gcd(y)` is always the same as `y.gcd(x)`. - /// - /// For any integer `x`, `x.gcd(x)` is `x.abs()`. - /// - /// If both `this` and `other` is zero, the result is also zero. - _BigIntImpl gcd(covariant _BigIntImpl other) { - if (_isZero) return other.abs(); - if (other._isZero) return this.abs(); - return _binaryGcd(this, other, false); - } - - /// Returns the least significant [width] bits of this big integer as a - /// non-negative number (i.e. unsigned representation). The returned value - /// has zeros in all bit positions higher than [width]. - /// - /// ``` - /// new BigInt.from(-1).toUnsigned(5) == 31 // 11111111 -> 00011111 - /// ``` - /// - /// This operation can be used to simulate arithmetic from low level - /// languages. For example, to increment an 8 bit quantity: - /// - /// ``` - /// q = (q + 1).toUnsigned(8); - /// ``` - /// - /// `q` will count from `0` up to `255` and then wrap around to `0`. - /// - /// If the input fits in [width] bits without truncation, the result is the - /// same as the input. The minimum width needed to avoid truncation of `x` is - /// given by `x.bitLength`, i.e. - /// - /// ``` - /// x == x.toUnsigned(x.bitLength); - /// ``` - _BigIntImpl toUnsigned(int width) { - return this & ((one << width) - one); - } - - /// Returns the least significant [width] bits of this integer, extending the - /// highest retained bit to the sign. This is the same as truncating the - /// value to fit in [width] bits using an signed 2-s complement - /// representation. The returned value has the same bit value in all - /// positions higher than [width]. - /// - /// ``` - /// var big15 = new BigInt.from(15); - /// var big16 = new BigInt.from(16); - /// var big239 = new BigInt.from(239); - /// V--sign bit-V - /// big16.toSigned(5) == -big16 // 00010000 -> 11110000 - /// big239.toSigned(5) == big15 // 11101111 -> 00001111 - /// ^ ^ - /// ``` - /// - /// This operation can be used to simulate arithmetic from low level - /// languages. For example, to increment an 8 bit signed quantity: - /// - /// ``` - /// q = (q + 1).toSigned(8); - /// ``` - /// - /// `q` will count from `0` up to `127`, wrap to `-128` and count back up to - /// `127`. - /// - /// If the input value fits in [width] bits without truncation, the result is - /// the same as the input. The minimum width needed to avoid truncation of - /// `x` is `x.bitLength + 1`, i.e. - /// - /// ``` - /// x == x.toSigned(x.bitLength + 1); - /// ``` - _BigIntImpl toSigned(int width) { - // The value of binary number weights each bit by a power of two. The - // twos-complement value weights the sign bit negatively. We compute the - // value of the negative weighting by isolating the sign bit with the - // correct power of two weighting and subtracting it from the value of the - // lower bits. - var signMask = one << (width - 1); - return (this & (signMask - one)) - (this & signMask); - } - - // Maximum number of digits that always fit in mantissa. - static const _simpleValidIntDigits = 53 ~/ _digitBits; - - bool get isValidInt { - if (_used <= _simpleValidIntDigits) return true; - var asInt = toInt(); - if (!asInt.toDouble().isFinite) return false; - return this == new _BigIntImpl._fromInt(asInt); - } - - int toInt() { - var result = 0; - for (int i = _used - 1; i >= 0; i--) { - result = result * _digitBase + _digits[i]; - } - return _isNegative ? -result : result; - } - - /// Returns this [_BigIntImpl] as a [double]. - /// - /// If the number is not representable as a [double], an - /// approximation is returned. For numerically large integers, the - /// approximation may be infinite. - double toDouble() { - const int exponentBias = 1075; - // There are 11 bits for the exponent. - // 2047 (all bits set to 1) is reserved for infinity and NaN. - // When storing the exponent in the 11 bits, it is biased by exponentBias - // to support negative exponents. - const int maxDoubleExponent = 2046 - exponentBias; - if (_isZero) return 0.0; - - // We fill the 53 bits little-endian. - var resultBits = new Uint8List(8); - - var length = _digitBits * (_used - 1) + _digits[_used - 1].bitLength; - if (length > maxDoubleExponent + 53) { - return _isNegative ? double.negativeInfinity : double.infinity; - } - - // The most significant bit is for the sign. - if (_isNegative) resultBits[7] = 0x80; - - // Write the exponent into bits 1..12: - var biasedExponent = length - 53 + exponentBias; - resultBits[6] = (biasedExponent & 0xF) << 4; - resultBits[7] |= biasedExponent >> 4; - - int cachedBits = 0; - int cachedBitsLength = 0; - int digitIndex = _used - 1; - int readBits(int n) { - // Ensure that we have enough bits in [cachedBits]. - while (cachedBitsLength < n) { - int nextDigit; - int nextDigitLength = _digitBits; // May get updated. - if (digitIndex < 0) { - nextDigit = 0; - digitIndex--; - } else { - nextDigit = _digits[digitIndex]; - if (digitIndex == _used - 1) nextDigitLength = nextDigit.bitLength; - digitIndex--; - } - cachedBits = (cachedBits << nextDigitLength) + nextDigit; - cachedBitsLength += nextDigitLength; - } - // Read the top [n] bits. - var result = cachedBits >> (cachedBitsLength - n); - // Remove the bits from the cache. - cachedBits -= result << (cachedBitsLength - n); - cachedBitsLength -= n; - return result; - } - - // The first leading 1 bit is implicit in the double-representation and can - // be discarded. - var leadingBits = readBits(5) & 0xF; - resultBits[6] |= leadingBits; - - for (int i = 5; i >= 0; i--) { - // Get the remaining 48 bits. - resultBits[i] = readBits(8); - } - - void roundUp() { - // Simply consists of adding 1 to the whole 64 bit "number". - // It will update the exponent, if necessary. - // It might even round up to infinity (which is what we want). - var carry = 1; - for (int i = 0; i < 8; i++) { - if (carry == 0) break; - var sum = resultBits[i] + carry; - resultBits[i] = sum & 0xFF; - carry = sum >> 8; - } - } - - if (readBits(1) == 1) { - if (resultBits[0].isOdd) { - // Rounds to even all the time. - roundUp(); - } else { - // Round up, if there is at least one other digit that is not 0. - if (cachedBits != 0) { - // There is already one in the cachedBits. - roundUp(); - } else { - for (int i = digitIndex; i >= 0; i--) { - if (_digits[i] != 0) { - roundUp(); - break; - } - } - } - } - } - return resultBits.buffer.asByteData().getFloat64(0, Endian.little); - } - - /// Returns a String-representation of this integer. - /// - /// The returned string is parsable by [parse]. - /// For any `_BigIntImpl` `i`, it is guaranteed that - /// `i == _BigIntImpl.parse(i.toString())`. - String toString() { - if (_used == 0) return "0"; - if (_used == 1) { - if (_isNegative) return (-_digits[0]).toString(); - return _digits[0].toString(); - } - - // Generate in chunks of 4 digits. - // The chunks are in reversed order. - var decimalDigitChunks = []; - var rest = isNegative ? -this : this; - while (rest._used > 1) { - var digits4 = rest.remainder(_bigInt10000).toString(); - decimalDigitChunks.add(digits4); - if (digits4.length == 1) decimalDigitChunks.add("000"); - if (digits4.length == 2) decimalDigitChunks.add("00"); - if (digits4.length == 3) decimalDigitChunks.add("0"); - rest = rest ~/ _bigInt10000; - } - decimalDigitChunks.add(rest._digits[0].toString()); - if (_isNegative) decimalDigitChunks.add("-"); - return decimalDigitChunks.reversed.join(); - } - - int _toRadixCodeUnit(int digit) { - const int _0 = 48; - const int _a = 97; - if (digit < 10) return _0 + digit; - return _a + digit - 10; - } - - /// Converts [this] to a string representation in the given [radix]. - /// - /// In the string representation, lower-case letters are used for digits above - /// '9', with 'a' being 10 an 'z' being 35. - /// - /// The [radix] argument must be an integer in the range 2 to 36. - String toRadixString(int radix) { - if (radix > 36) throw new RangeError.range(radix, 2, 36); - - if (_used == 0) return "0"; - - if (_used == 1) { - var digitString = _digits[0].toRadixString(radix); - if (_isNegative) return "-" + digitString; - return digitString; - } - - if (radix == 16) return _toHexString(); - - var base = new _BigIntImpl._fromInt(radix); - var reversedDigitCodeUnits = []; - var rest = this.abs(); - while (!rest._isZero) { - var digit = rest.remainder(base).toInt(); - rest = rest ~/ base; - reversedDigitCodeUnits.add(_toRadixCodeUnit(digit)); - } - var digitString = new String.fromCharCodes(reversedDigitCodeUnits.reversed); - if (_isNegative) return "-" + digitString; - return digitString; - } - - String _toHexString() { - var chars = []; - for (int i = 0; i < _used - 1; i++) { - int chunk = _digits[i]; - for (int j = 0; j < (_digitBits ~/ 4); j++) { - chars.add(_toRadixCodeUnit(chunk & 0xF)); - chunk >>= 4; - } - } - var msbChunk = _digits[_used - 1]; - while (msbChunk != 0) { - chars.add(_toRadixCodeUnit(msbChunk & 0xF)); - msbChunk >>= 4; - } - if (_isNegative) { - const _dash = 45; - chars.add(_dash); - } - return new String.fromCharCodes(chars.reversed); - } -} - -// Interface for modular reduction. -abstract class _BigIntReduction { - // Return the number of digits used by r_digits. - int convert(_BigIntImpl x, Uint16List r_digits); - int mul(Uint16List xDigits, int xUsed, Uint16List yDigits, int yUsed, - Uint16List resultDigits); - int sqr(Uint16List xDigits, int xUsed, Uint16List resultDigits); - - // Return x reverted to _BigIntImpl. - _BigIntImpl revert(Uint16List xDigits, int xUsed); -} - -// Modular reduction using "classic" algorithm. -class _BigIntClassic implements _BigIntReduction { - final _BigIntImpl _modulus; // Modulus. - final _BigIntImpl _normalizedModulus; // Normalized _modulus. - - _BigIntClassic(this._modulus) - : _normalizedModulus = _modulus << - (_BigIntImpl._digitBits - - _modulus._digits[_modulus._used - 1].bitLength); - - int convert(_BigIntImpl x, Uint16List resultDigits) { - Uint16List digits; - int used; - if (x._isNegative || x._absCompare(_modulus) >= 0) { - var remainder = x._rem(_modulus); - if (x._isNegative && remainder._used > 0) { - assert(remainder._isNegative); - remainder += _modulus; - } - assert(!remainder._isNegative); - used = remainder._used; - digits = remainder._digits; - } else { - used = x._used; - digits = x._digits; - } - var i = used; // Copy leading zero if any. - while (--i >= 0) { - resultDigits[i] = digits[i]; - } - return used; - } - - _BigIntImpl revert(Uint16List xDigits, int xUsed) { - return new _BigIntImpl._(false, xUsed, xDigits); - } - - int _reduce(Uint16List xDigits, int xUsed) { - if (xUsed < _modulus._used) { - return xUsed; - } - var reverted = revert(xDigits, xUsed); - var rem = reverted._rem(_normalizedModulus); - return convert(rem, xDigits); - } - - int sqr(Uint16List xDigits, int xUsed, Uint16List resultDigits) { - var b = new _BigIntImpl._(false, xUsed, xDigits); - var b2 = b * b; - for (int i = 0; i < b2._used; i++) { - resultDigits[i] = b2._digits[i]; - } - for (int i = b2._used; i < 2 * xUsed; i++) { - resultDigits[i] = 0; - } - return _reduce(resultDigits, 2 * xUsed); - } - - int mul(Uint16List xDigits, int xUsed, Uint16List yDigits, int yUsed, - Uint16List resultDigits) { - var resultUsed = - _BigIntImpl._mulDigits(xDigits, xUsed, yDigits, yUsed, resultDigits); - return _reduce(resultDigits, resultUsed); - } -} - -/// Creates an invocation object used in noSuchMethod forwarding stubs. -/// -/// The signature is hardwired to the kernel nodes generated in the -/// `Dart2jsTarget` and read in the `KernelSsaGraphBuilder`. -external Invocation _createInvocationMirror( - String memberName, - List typeArguments, - List positionalArguments, - Map namedArguments, - int kind); diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/developer_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/developer_patch.dart deleted file mode 100644 index aff3f5572bb..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/lib/developer_patch.dart +++ /dev/null @@ -1,157 +0,0 @@ -// 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. - -// Patch file for dart:developer library. - -import 'dart:_js_helper' show patch, ForceInline; -import 'dart:_foreign_helper' show JS; -import 'dart:async' show Zone; -import 'dart:isolate'; - -@patch -@pragma('dart2js:tryInline') -bool debugger({bool when = true, String? message}) { - if (when) { - JS('', 'debugger'); - } - return when; -} - -@patch -Object? inspect(Object? object) { - return object; -} - -@patch -void log(String message, - {DateTime? time, - int? sequenceNumber, - int level = 0, - String name = '', - Zone? zone, - Object? error, - StackTrace? stackTrace}) { - // TODO. -} - -final _extensions = {}; - -@patch -ServiceExtensionHandler? _lookupExtension(String method) { - return _extensions[method]; -} - -@patch -_registerExtension(String method, ServiceExtensionHandler handler) { - _extensions[method] = handler; -} - -@patch -void _postEvent(String eventKind, String eventData) { - // TODO. -} - -@patch -bool _isDartStreamEnabled() { - return false; -} - -@patch -int _getTraceClock() { - // TODO. - return _clockValue++; -} - -int _clockValue = 0; - -@patch -void _reportFlowEvent( - String category, String name, int type, int id, String argumentsAsJson) { - // TODO. -} - -@patch -void _reportInstantEvent(String category, String name, String argumentsAsJson) { - // TODO. -} - -@patch -int _getNextAsyncId() { - return 0; -} - -@patch -void _reportTaskEvent(int taskId, String phase, String category, String name, - String argumentsAsJson) { - // TODO. -} - -@patch -int _getServiceMajorVersion() { - return 0; -} - -@patch -int _getServiceMinorVersion() { - return 0; -} - -@patch -void _getServerInfo(SendPort sendPort) { - sendPort.send(null); -} - -@patch -void _webServerControl(SendPort sendPort, bool enable) { - sendPort.send(null); -} - -@patch -String? _getIsolateIDFromSendPort(SendPort sendPort) { - return null; -} - -@patch -class UserTag { - @patch - factory UserTag(String label) = _FakeUserTag; - - @patch - static UserTag get defaultTag => _FakeUserTag._defaultTag; -} - -class _FakeUserTag implements UserTag { - static final _instances = {}; - - _FakeUserTag.real(this.label); - - factory _FakeUserTag(String label) { - // Canonicalize by name. - var existingTag = _instances[label]; - if (existingTag != null) { - return existingTag; - } - // Throw an exception if we've reached the maximum number of user tags. - if (_instances.length == UserTag.MAX_USER_TAGS) { - throw UnsupportedError( - 'UserTag instance limit (${UserTag.MAX_USER_TAGS}) reached.'); - } - return _instances[label] = _FakeUserTag.real(label); - } - - final String label; - - UserTag makeCurrent() { - var old = _currentTag; - _currentTag = this; - return old; - } - - static final UserTag _defaultTag = new _FakeUserTag('Default'); -} - -var _currentTag = _FakeUserTag._defaultTag; - -@patch -UserTag getCurrentTag() => _currentTag; diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/foreign_helper.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/foreign_helper.dart deleted file mode 100644 index 88ca3d2a9e0..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/lib/foreign_helper.dart +++ /dev/null @@ -1,279 +0,0 @@ -// Copyright (c) 2012, 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 _foreign_helper; - -import 'dart:_js_embedded_names' show JsGetName, JsBuiltin; -import 'dart:_rti' show Rti; - -/// Emits a JavaScript code fragment parametrized by arguments. -/// -/// Hash characters `#` in the [codeTemplate] are replaced in left-to-right -/// order with expressions that contain the values of, or evaluate to, the -/// arguments. The number of hash marks must match the number or arguments. -/// Although declared with arguments [arg0] through [arg2], the form actually -/// has no limit on the number of arguments. -/// -/// The [typeDescription] argument is interpreted as a description of the -/// behavior of the JavaScript code. Currently it describes the side effects -/// types that may be returned by the expression, with the additional behavior -/// that the returned values may be fresh instances of the types. The type -/// information must be correct as it is trusted by the compiler in -/// optimizations, and it must be precise as possible since it is used for -/// native live type analysis to tree-shake large parts of the DOM libraries. -/// If poorly written, the [typeDescription] will cause unnecessarily bloated -/// programs. (You can check for this by compiling with `--verbose`; there is -/// an info message describing the number of native (DOM) types that can be -/// removed, which usually should be greater than zero.) -/// -/// The [typeDescription] must be a [String]. Two forms of it are supported: -/// -/// 1) a union of types separated by vertical bar `|` symbols, e.g. -/// `"num|String"` describes the union of numbers and Strings. There is no -/// type in Dart that is this precise. The Dart alternative would be -/// `Object` or `dynamic`, but these types imply that the JS-code might also -/// be creating instances of all the DOM types. -/// -/// If `null` is possible, it must be specified explicitly, e.g. -/// `"String|Null"`. [typeDescription] has several extensions to help -/// describe the behavior more accurately. In addition to the union type -/// already described: -/// -/// + `=Object` is a plain JavaScript object. Some DOM methods return -/// instances that have no corresponding Dart type (e.g. cross-frame -/// documents), `=Object` can be used to describe these untyped' values. -/// -/// + `var` or empty string. If the entire [typeDescription] is `var` (or -/// empty string) then the type is `dynamic` but the code is known to not -/// create any instances. -/// -/// Examples: -/// -/// // Parent window might be an opaque cross-frame window. -/// var thing = JS('=Object|Window', '#.parent', myWindow); -/// -/// 2) a sequence of the form `:;` where `` is one of -/// `creates`, `returns`, `effects` or `depends`. -/// -/// The first two tags are used to specify the created and returned types of -/// the expression. The value of `creates` and `returns` is a type string as -/// defined in 1). -/// -/// The tags `effects` and `depends` encode the side effects of this call. -/// They can be omitted, in which case the expression is parsed and a safe -/// conservative side-effect estimation is computed. -/// -/// The values of `effects` and `depends` may be 'all', 'none' or a -/// comma-separated list of 'no-index', 'no-instance' and 'no-static'. -/// -/// The value 'all' indicates that the call affects/depends on every -/// side-effect. The flag 'none' signals that the call does not affect -/// (resp. depends on) anything. -/// -/// The value 'no-index' indicates that the call does *not* do (resp. depends -/// on) any array index-store. The flag 'no-instance' indicates that the call -/// does not modify (resp. depends on) any instance variable. Similarly, -/// the 'no-static' value indicates that the call does not modify (resp. -/// depends on) any static variable. -/// -/// The `effects` and `depends` flag must be used in tandem. Either both are -/// specified or none is. -/// -/// Each tag (including the type tags) may only occur once in the sequence. -/// -/// Guidelines: -/// -/// + Do not use any parameter, local, method or field names in the -/// [codeTemplate]. These names are all subject to arbitrary renaming by the -/// compiler. Pass the values in via `#` substition, and test with the -/// `--minify` dart2js command-line option. -/// -/// + The substituted expressions are values, not locations. -/// -/// JS('void', '# += "x"', this.field); -/// -/// `this.field` might not be a substituted as a reference to the field. The -/// generated code might accidentally work as intended, but it also might be -/// -/// var t1 = this.field; -/// t1 += "x"; -/// -/// or -/// -/// this.get$field() += "x"; -/// -/// The remedy in this case is to expand the `+=` operator, leaving all -/// references to the Dart field as Dart code: -/// -/// this.field = JS('String', '# + "x"', this.field); -/// -/// + Never use `#` in function bodies. -/// -/// This is a variation on the previous guideline. Since `#` is replaced -/// with an *expression* and the expression is only valid in the immediate -/// context, `#` should never appear in a function body. Doing so might -/// defer the evaluation of the expression, and its side effects, until the -/// function is called. -/// -/// For example, -/// -/// var value = foo(); -/// var f = JS('', 'function(){return #}', value) -/// -/// might result in no immediate call to `foo` and a call to `foo` on every -/// call to the JavaScript function bound to `f`. This is better: -/// -/// var f = JS('', -/// '(function(val) { return function(){return val}; })(#)', value); -/// -/// Since `#` occurs in the immediately evaluated expression, the expression -/// is immediately evaluated and bound to `val` in the immediate call. -/// -/// -/// Type argument. -/// -/// In Dart 2.0, the type argument additionally constrains the returned type. -/// So, with type inference filling in the type argumemnt, -/// -/// String s = JS('', 'JSON.stringify(#)', x); -/// -/// will be the same as the current meaning of -/// -/// var s = JS('String|Null', 'JSON.stringify(#)', x); -/// -/// -/// Additional notes. -/// -/// In the future we may extend [typeDescription] to include other aspects of -/// the behavior, for example, separating the returned types from the -/// instantiated types to allow the compiler to perform more optimizations -/// around the code. -/// -/// This might be an extension of [JS] or a new function similar to [JS] with -/// additional arguments for the new information. -// Add additional optional arguments if needed. The method is treated internally -// as a variable argument method. -external T JS(String typeDescription, String codeTemplate, - [arg0, - arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - arg7, - arg8, - arg9, - arg10, - arg11, - arg12, - arg13, - arg14, - arg51, - arg16, - arg17, - arg18, - arg19]); - -/// Converts the Dart closure [function] into a JavaScript closure. -/// -/// Warning: This is no different from [RAW_DART_FUNCTION_REF] which means care -/// must be taken to store the current isolate. -external DART_CLOSURE_TO_JS(Function function); - -/// Returns a raw reference to the JavaScript function which implements -/// [function]. -/// -/// Warning: this is dangerous, you should probably use -/// [DART_CLOSURE_TO_JS] instead. The returned object is not a valid -/// Dart closure, does not store the isolate context or arity. -/// -/// A valid example of where this can be used is as the second argument -/// to V8's Error.captureStackTrace. See -/// https://code.google.com/p/v8/wiki/JavaScriptStackTraceApi. -external RAW_DART_FUNCTION_REF(Function function); - -/// Sets the current static state to [staticState]. -external void JS_SET_STATIC_STATE(staticState); - -/// Returns the interceptor for class [type]. The interceptor is the type's -/// constructor's `prototype` property. [type] will typically be the class, not -/// an interface, e.g. `JS_INTERCEPTOR_CONSTANT(JSInt)`, not -/// `JS_INTERCEPTOR_CONSTANT(int)`. -external JS_INTERCEPTOR_CONSTANT(Type type); - -/// Returns the interceptor for [object]. -/// -/// Calls are replaced with the [HInterceptor] SSA instruction. -external getInterceptor(object); - -/// Returns the Rti object for the type for JavaScript arrays via JS-interop. -/// -/// Calls are replaced with a [HLoadType] SSA instruction. -external Object getJSArrayInteropRti(); - -/// Returns the object corresponding to Namer.staticStateHolder. -external JS_GET_STATIC_STATE(); - -/// Returns the JS name for [name] from the Namer. -external String JS_GET_NAME(JsGetName name); - -/// Reads an embedded global. -/// -/// The [name] should be a constant defined in the `_embedded_names` library. -external JS_EMBEDDED_GLOBAL(String typeDescription, String name); - -/// Instructs the compiler to execute the [builtinName] action at the call-site. -/// -/// The [builtin] should be a constant defined in the `_embedded_names` -/// library. -// Add additional optional arguments if needed. The method is treated internally -// as a variable argument method. -external JS_BUILTIN(String typeDescription, JsBuiltin builtin, - [arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11]); - -/// Returns the state of a flag that is determined by the state of the compiler -/// when the program has been analyzed. -external bool JS_GET_FLAG(String name); - -/// Returns a TypeReference to [T]. -external Rti TYPE_REF(); - -/// Returns a TypeReference to [T]*. -external Rti LEGACY_TYPE_REF(); - -/// Pretend [code] is executed. Generates no executable code. This is used to -/// model effects at some other point in external code. For example, the -/// following models an assignment to foo with an unknown value. -/// -/// var foo; -/// -/// main() { -/// JS_EFFECT((_){ foo = _; }) -/// } -/// -/// TODO(sra): Replace this hack with something to mark the volatile or -/// externally initialized elements. -void JS_EFFECT(Function code) { - code(null); -} - -/// Use this class for creating constants that hold JavaScript code. -/// For example: -/// -/// const constant = JS_CONST('typeof window != "undefined"); -/// -/// This code will generate: -/// $.JS_CONST_1 = typeof window != "undefined"; -class JS_CONST { - final String code; - const JS_CONST(this.code); -} - -/// JavaScript string concatenation. Inputs must be Strings. Corresponds to the -/// HStringConcat SSA instruction and may be constant-folded. -String JS_STRING_CONCAT(String a, String b) { - // This body is unused, only here for type analysis. - return JS('String', '# + #', a, b); -} diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/instantiation.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/instantiation.dart deleted file mode 100644 index da3fcbdef60..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/lib/instantiation.dart +++ /dev/null @@ -1,330 +0,0 @@ -// Copyright (c) 2018, 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. - -part of _js_helper; - -/// Support class for generic function type instantiation (binding of types). -/// -abstract class Instantiation extends Closure { - final Closure _genericClosure; - Instantiation(this._genericClosure) { - // TODO(sra): Copy some metadata used by Function.apply. - - // Mark support code as used. The JS condition is inscrutable to dart2js, - // so the 'if (false)' is in the final program. - // TODO(sra): Find a better way to do this. Generating the signature methods - // earlier as SSA on the instantiation closures should achieve this. - if (JS('bool', 'false')) { - // [instantiatedGenericFunctionType] is called from injected $signature - // methods with runtime type representations. - newRti.instantiatedGenericFunctionType(JS('', '0'), JS('', '0')); - } - } - - /// Returns a list of the bound types. - List get _types; - - String toString() { - var types = "<${_types.join(', ')}>"; - // TODO(sra): Refactor Closure formatting to place type arguments inside, - // e.g. "Closure 'map' of Instance of 'JSArray'". - return '$_genericClosure with $types'; - } -} - -/// Instantiation classes are subclasses of [Instantiation]. For now we have a -/// fixed number of subclasses. Later we might generate the classes on demand. -class Instantiation1 extends Instantiation { - Instantiation1(Closure f) : super(f); - List get _types => [T1]; -} - -class Instantiation2 extends Instantiation { - Instantiation2(Closure f) : super(f); - List get _types => [T1, T2]; -} - -class Instantiation3 extends Instantiation { - Instantiation3(Closure f) : super(f); - List get _types => [T1, T2, T3]; -} - -class Instantiation4 extends Instantiation { - Instantiation4(Closure f) : super(f); - List get _types => [T1, T2, T3, T4]; -} - -class Instantiation5 extends Instantiation { - Instantiation5(Closure f) : super(f); - List get _types => [T1, T2, T3, T4, T5]; -} - -class Instantiation6 extends Instantiation { - Instantiation6(Closure f) : super(f); - List get _types => [T1, T2, T3, T4, T5, T6]; -} - -class Instantiation7 extends Instantiation { - Instantiation7(Closure f) : super(f); - List get _types => [T1, T2, T3, T4, T5, T6, T7]; -} - -class Instantiation8 extends Instantiation { - Instantiation8(Closure f) : super(f); - List get _types => [T1, T2, T3, T4, T5, T6, T7, T8]; -} - -class Instantiation9 extends Instantiation { - Instantiation9(Closure f) : super(f); - List get _types => [T1, T2, T3, T4, T5, T6, T7, T8, T9]; -} - -class Instantiation10 - extends Instantiation { - Instantiation10(Closure f) : super(f); - List get _types => [T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]; -} - -class Instantiation11 - extends Instantiation { - Instantiation11(Closure f) : super(f); - List get _types => [T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]; -} - -class Instantiation12 - extends Instantiation { - Instantiation12(Closure f) : super(f); - List get _types => [T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]; -} - -class Instantiation13 - extends Instantiation { - Instantiation13(Closure f) : super(f); - List get _types => [T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]; -} - -class Instantiation14 extends Instantiation { - Instantiation14(Closure f) : super(f); - List get _types => - [T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]; -} - -class Instantiation15 extends Instantiation { - Instantiation15(Closure f) : super(f); - List get _types => - [T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]; -} - -class Instantiation16 extends Instantiation { - Instantiation16(Closure f) : super(f); - List get _types => - [T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16]; -} - -class Instantiation17 extends Instantiation { - Instantiation17(Closure f) : super(f); - List get _types => [ - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17 - ]; -} - -class Instantiation18 extends Instantiation { - Instantiation18(Closure f) : super(f); - List get _types => [ - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18 - ]; -} - -class Instantiation19 extends Instantiation { - Instantiation19(Closure f) : super(f); - List get _types => [ - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19 - ]; -} - -class Instantiation20 extends Instantiation { - Instantiation20(Closure f) : super(f); - List get _types => [ - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20 - ]; -} - -Instantiation instantiate1(Closure f) { - return new Instantiation1(f); -} - -Instantiation instantiate2(Closure f) { - return new Instantiation2(f); -} - -Instantiation instantiate3(Closure f) { - return new Instantiation3(f); -} - -Instantiation instantiate4(Closure f) { - return new Instantiation4(f); -} - -Instantiation instantiate5(Closure f) { - return new Instantiation5(f); -} - -Instantiation instantiate6(Closure f) { - return new Instantiation6(f); -} - -Instantiation instantiate7(Closure f) { - return new Instantiation7(f); -} - -Instantiation instantiate8(Closure f) { - return new Instantiation8(f); -} - -Instantiation instantiate9(Closure f) { - return new Instantiation9(f); -} - -Instantiation instantiate10( - Closure f) { - return new Instantiation10(f); -} - -Instantiation instantiate11( - Closure f) { - return new Instantiation11(f); -} - -Instantiation instantiate12( - Closure f) { - return new Instantiation12( - f); -} - -Instantiation - instantiate13( - Closure f) { - return new Instantiation13(f); -} - -Instantiation - instantiate14( - Closure f) { - return new Instantiation14(f); -} - -Instantiation instantiate15(Closure f) { - return new Instantiation15(f); -} - -Instantiation instantiate16(Closure f) { - return new Instantiation16(f); -} - -Instantiation instantiate17(Closure f) { - return new Instantiation17(f); -} - -Instantiation instantiate18(Closure f) { - return new Instantiation18(f); -} - -Instantiation instantiate19(Closure f) { - return new Instantiation19(f); -} - -Instantiation instantiate20(Closure f) { - return new Instantiation20(f); -} diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/interceptors.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/interceptors.dart deleted file mode 100644 index fc97282b896..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/lib/interceptors.dart +++ /dev/null @@ -1,447 +0,0 @@ -// Copyright (c) 2012, 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 _interceptors; - -import 'dart:_js_embedded_names' - show DISPATCH_PROPERTY_NAME, TYPE_TO_INTERCEPTOR_MAP; - -import 'dart:collection' hide LinkedList, LinkedListEntry; -import 'dart:_internal' hide Symbol; -import "dart:_internal" as _symbol_dev show Symbol; -import 'dart:_js_helper' - show - allMatchesInStringUnchecked, - JSSyntaxRegExp, - Primitives, - argumentErrorValue, - checkBool, - checkInt, - checkNull, - checkNum, - checkString, - defineProperty, - diagnoseIndexError, - getIsolateAffinityTag, - getRuntimeType, - initNativeDispatch, - initNativeDispatchFlag, - regExpGetNative, - regExpCaptureCount, - stringContainsUnchecked, - stringIndexOfStringUnchecked, - stringLastIndexOfUnchecked, - stringReplaceAllFuncUnchecked, - stringReplaceAllUnchecked, - stringReplaceFirstUnchecked, - stringReplaceFirstMappedUnchecked, - stringReplaceRangeUnchecked, - stringSplitUnchecked, - throwConcurrentModificationError, - lookupAndCacheInterceptor, - StringMatch, - firstMatchAfter, - NoInline; - -import 'dart:_foreign_helper' - show - getInterceptor, - JS, - JS_EFFECT, - JS_EMBEDDED_GLOBAL, - JS_INTERCEPTOR_CONSTANT, - JS_STRING_CONCAT; -import 'dart:math' show Random, ln2; - -part 'js_array.dart'; -part 'js_number.dart'; -part 'js_string.dart'; - -final String DART_CLOSURE_PROPERTY_NAME = - getIsolateAffinityTag(r'_$dart_dartClosure'); - -getDispatchProperty(object) { - return JS( - '', '#[#]', object, JS_EMBEDDED_GLOBAL('String', DISPATCH_PROPERTY_NAME)); -} - -setDispatchProperty(object, value) { - defineProperty( - object, JS_EMBEDDED_GLOBAL('String', DISPATCH_PROPERTY_NAME), value); -} - -// Avoid inlining this method because inlining gives us multiple allocation -// points for records which is bad because it leads to polymorphic access. -@pragma('dart2js:noInline') -makeDispatchRecord(interceptor, proto, extension, indexability) { - // Dispatch records are stored in the prototype chain, and in some cases, on - // instances. - // - // The record layout and field usage is designed to minimize the number of - // operations on the common paths. - // - // [interceptor] is the interceptor - a holder of methods for the object, - // i.e. the prototype of the interceptor class. - // - // [proto] is usually the prototype, used to check that the dispatch record - // matches the object and is not the dispatch record of a superclass. Other - // values: - // - `false` for leaf classes that need no check. - // - `true` for Dart classes where the object is its own interceptor (unused) - // - a function used to continue matching. - // - // [extension] is used for irregular cases. - // - // [indexability] is used to cache whether or not the object - // implements JavaScriptIndexingBehavior. - // - // proto interceptor extension action - // ----- ----------- --------- ------ - // false I use interceptor I - // true - use object - // P I if object's prototype is P, use I - // F - P if object's prototype is P, call F - - return JS('', '{i: #, p: #, e: #, x: #}', interceptor, proto, extension, - indexability); -} - -dispatchRecordInterceptor(record) => JS('', '#.i', record); -dispatchRecordProto(record) => JS('', '#.p', record); -dispatchRecordExtension(record) => JS('', '#.e', record); -bool? dispatchRecordIndexability(record) => JS('bool|Null', '#.x', record); - -/// Returns the interceptor for a native class instance. Used by -/// [getInterceptor]. -getNativeInterceptor(object) { - var record = getDispatchProperty(object); - - if (record == null) { - if (initNativeDispatchFlag == null) { - initNativeDispatch(); - record = getDispatchProperty(object); - } - } - - if (record != null) { - var proto = dispatchRecordProto(record); - if (false == proto) return dispatchRecordInterceptor(record); - if (true == proto) return object; - var objectProto = JS('', 'Object.getPrototypeOf(#)', object); - if (JS('bool', '# === #', proto, objectProto)) { - return dispatchRecordInterceptor(record); - } - - var extension = dispatchRecordExtension(record); - if (JS('bool', '# === #', extension, objectProto)) { - // TODO(sra): The discriminator returns a tag. The tag is an uncached or - // instance-cached tag, defaulting to instance-cached if caching - // unspecified. - var discriminatedTag = JS('', '(#)(#, #)', proto, object, record); - throw new UnimplementedError('Return interceptor for $discriminatedTag'); - } - } - - // Check for cached UnknownJavaScriptObject. This avoids doing the slow - // dispatch-record based lookup for repeated js-interop classes. - var constructor = JS('', '#.constructor', object); - var interceptor = lookupInterceptorByConstructor(constructor); - if (interceptor != null) return interceptor; - - // This takes care of dispatch-record based caching, but not constructor based - // caching of [UnknownJavaScriptObject]s. - interceptor = lookupAndCacheInterceptor(object); - if (interceptor != null) return interceptor; - - // JavaScript Objects created via object literals and `Object.create(null)` - // are 'plain' Objects. This test could be simplified and the dispatch path - // be faster if Object.prototype was pre-patched with a non-leaf dispatch - // record. - if (JS('bool', 'typeof # == "function"', object)) { - interceptor = JS_INTERCEPTOR_CONSTANT(JavaScriptFunction); - // TODO(sra): Investigate caching on `Function`. It might be impossible if - // some HTML embedded objects on some browsers are (still) JS functions. - return interceptor; - } - var proto = JS('', 'Object.getPrototypeOf(#)', object); - if (JS('bool', '# == null', proto)) { - // Nowhere to cache output. - return JS_INTERCEPTOR_CONSTANT(PlainJavaScriptObject); - } - interceptor = JS_INTERCEPTOR_CONSTANT(UnknownJavaScriptObject); - if (JS('bool', '# === Object.prototype', proto)) { - interceptor = JS_INTERCEPTOR_CONSTANT(PlainJavaScriptObject); - // TODO(sra): Investigate caching on 'Object'. It might be impossible if - // some native class is plain Object (e.g. like Firefox's ImageData). - return interceptor; - } - if (JS('bool', 'typeof # == "function"', constructor)) { - cacheInterceptorOnConstructor(constructor, interceptor); - return interceptor; - } - return JS_INTERCEPTOR_CONSTANT(UnknownJavaScriptObject); -} - -// A JS String or Symbol. -dynamic _JS_INTEROP_INTERCEPTOR_TAG = null; -get JS_INTEROP_INTERCEPTOR_TAG { - return _JS_INTEROP_INTERCEPTOR_TAG ??= getIsolateAffinityTag(r'_$dart_js'); -} - -lookupInterceptorByConstructor(constructor) { - return constructor == null - ? null - : JS('', '#[#]', constructor, JS_INTEROP_INTERCEPTOR_TAG); -} - -void cacheInterceptorOnConstructor(constructor, interceptor) { - defineProperty(constructor, JS_INTEROP_INTERCEPTOR_TAG, interceptor); -} - -var constructorToInterceptor = - JS('', 'typeof(self.WeakMap) == "undefined" ? new Map() : new WeakMap()'); - -XlookupInterceptorByConstructor(constructor) { - return JS('', '#.get(#)', constructorToInterceptor, constructor); -} - -void XcacheInterceptorOnConstructor(constructor, interceptor) { - JS('', '#.set(#, #)', constructorToInterceptor, constructor, interceptor); -} - -/// Data structure used to map a [Type] to the [Interceptor] and constructors -/// for that type. It is JavaScript array of 3N entries of adjacent slots -/// containing a [Type], followed by an [Interceptor] class for the type, -/// followed by a JavaScript object map for the constructors. -/// -/// The value of this variable is set by the compiler and contains only types -/// that are user extensions of native classes where the type occurs as a -/// constant in the program. -/// -/// The compiler, in CustomElementsAnalysis, assumes that [typeToInterceptorMap] -/// is accessed only by code that also calls [findIndexForWebComponentType]. If -/// this assumption is invalidated, the compiler will have to be updated. -get typeToInterceptorMap { - return JS_EMBEDDED_GLOBAL('', TYPE_TO_INTERCEPTOR_MAP); -} - -int? findIndexForNativeSubclassType(Type? type) { - if (JS('bool', '# == null', typeToInterceptorMap)) return null; - List map = JS('JSFixedArray', '#', typeToInterceptorMap); - for (int i = 0; i + 1 < map.length; i += 3) { - if (type == map[i]) { - return i; - } - } - return null; -} - -findInterceptorConstructorForType(Type? type) { - var index = findIndexForNativeSubclassType(type); - if (index == null) return null; - List map = JS('JSFixedArray', '#', typeToInterceptorMap); - return map[index + 1]; -} - -/// Returns a JavaScript function that runs the constructor on its argument, or -/// `null` if there is no such constructor. -/// -/// The returned function takes one argument, the web component object. -findConstructorForNativeSubclassType(Type? type, String name) { - var index = findIndexForNativeSubclassType(type); - if (index == null) return null; - List map = JS('JSFixedArray', '#', typeToInterceptorMap); - var constructorMap = map[index + 2]; - var constructorFn = JS('', '#[#]', constructorMap, name); - return constructorFn; -} - -findInterceptorForType(Type? type) { - var constructor = findInterceptorConstructorForType(type); - if (constructor == null) return null; - return JS('', '#.prototype', constructor); -} - -/// The base interceptor class. -/// -/// The code `r.foo(a)` is compiled to `getInterceptor(r).foo$1(r, a)`. The -/// value returned by [getInterceptor] holds the methods separately from the -/// state of the instance. The compiler converts the methods on an interceptor -/// to take the Dart `this` argument as an explicit `receiver` argument. The -/// JavaScript `this` parameter is bound to the interceptor. -/// -/// In order to have uniform call sites, if a method is defined on an -/// interceptor, methods of that name on plain unintercepted classes also use -/// the interceptor calling convention. The plain classes are -/// _self-interceptors_, and for them, `getInterceptor(r)` returns `r`. Methods -/// on plain unintercepted classes have a redundant `receiver` argument and, to -/// enable some optimizations, must ignore `receiver` in favour of `this`. -/// -/// In the case of mixins, a method may be placed on both an intercepted class -/// and an unintercepted class. In this case, the method must use the -/// `receiver` parameter. -/// -/// -/// There are various optimizations of the general call pattern. -/// -/// When the interceptor can be statically determined, it can be used directly: -/// -/// CONSTANT_INTERCEPTOR.foo$1(r, a) -/// -/// If there are only a few classes, [getInterceptor] can be specialized with a -/// more efficient dispatch: -/// -/// getInterceptor$specialized(r).foo$1(r, a) -/// -/// If it can be determined that the receiver is an unintercepted class, it can -/// be called directly: -/// -/// r.foo$1(r, a) -/// -/// If, further, it is known that the call site cannot call a foo that is -/// mixed-in to a native class, then it is known that the explicit receiver is -/// ignored, and space-saving dummy value can be passed instead: -/// -/// r.foo$1(0, a) -/// -/// This class defines implementations of *all* methods on [Object] so no -/// interceptor inherits an implementation from [Object]. This enables the -/// implementations on Object to ignore the explicit receiver argument, which -/// allows dummy receiver optimization. -abstract class Interceptor { - const Interceptor(); - - bool operator ==(other) => identical(this, other); - - int get hashCode => Primitives.objectHashCode(this); - - String toString() => Primitives.objectToHumanReadableString(this); - - // [Interceptor.noSuchMethod] is identical to [Object.noSuchMethod]. However, - // each copy is compiled differently. The presence of the method on an - // Interceptor class forces [noSuchMethod] to use interceptor calling - // convention. In the [Interceptor] version, `this` is the explicit receiver - // argument. In the [Object] version, as Object is not an intercepted class, - // `this` is the JavaScript receiver, and the explicit receiver is ignored. - // The noSuchMethod stubs for selectors that use the interceptor calling - // convention do not know the calling convention and forward `this` and - // `receiver` to one of these noSuchMethod implementations which selects the - // correct Dart receiver. - // - // We don't allow [noSuchMethod] on intercepted classes (that would force all - // calls to use interceptor calling convention). If we did allow it, the - // interceptor context would select the correct `this`. - dynamic noSuchMethod(Invocation invocation) { - throw new NoSuchMethodError(this, invocation.memberName, - invocation.positionalArguments, invocation.namedArguments); - } - - Type get runtimeType => getRuntimeType(this); -} - -/// The interceptor class for [bool]. -class JSBool extends Interceptor implements bool { - const JSBool(); - - // Note: if you change this, also change the function [S]. - String toString() => JS('String', r'String(#)', this); - - bool operator &(bool other) => JS('bool', "# && #", checkBool(other), this); - - bool operator |(bool other) => JS('bool', "# || #", checkBool(other), this); - - bool operator ^(bool other) => !identical(this, checkBool(other)); - - // The values here are SMIs, co-prime and differ about half of the bit - // positions, including the low bit, so they are different mod 2^k. - int get hashCode => this ? (2 * 3 * 23 * 3761) : (269 * 811); - - Type get runtimeType => bool; -} - -/// The interceptor class for [Null]. -/// -/// This class defines implementations for *all* methods on [Object] since -/// the methods on Object assume the receiver is non-null. This means that -/// JSNull will always be in the interceptor set for methods defined on Object. -class JSNull extends Interceptor implements Null { - const JSNull(); - - bool operator ==(other) => identical(null, other); - - // Note: if you change this, also change the function [S]. - String toString() => 'null'; - - int get hashCode => 0; - - // The spec guarantees that `null` is the singleton instance of the `Null` - // class. In the mirrors library we also have to patch the `type` getter to - // special case `null`. - Type get runtimeType => Null; - - dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); -} - -/// The supertype for JSString and JSArray. Used by the backend as to -/// have a type mask that contains the objects that we can use the -/// native JS [] operator and length on. -abstract class JSIndexable { - int get length; - E operator [](int index); -} - -/// The supertype for JSMutableArray and -/// JavaScriptIndexingBehavior. Used by the backend to have a type mask -/// that contains the objects we can use the JS []= operator on. -abstract class JSMutableIndexable extends JSIndexable { - operator []=(int index, E value); -} - -/// The interface implemented by JavaScript objects. These are methods in -/// addition to the regular Dart Object methods like [Object.hashCode]. -/// -/// This is the type that should be exported by a JavaScript interop library. -abstract class JSObject {} - -/// Interceptor base class for JavaScript objects not recognized as some more -/// specific native type. -class JavaScriptObject extends Interceptor implements JSObject { - const JavaScriptObject(); - - // It would be impolite to stash a property on the object. - int get hashCode => 0; - - Type get runtimeType => JSObject; - - /// Returns the result of the JavaScript objects `toString` method. - String toString() => JS('String', 'String(#)', this); -} - -/// Interceptor for plain JavaScript objects created as JavaScript object -/// literals or `new Object()`. -class PlainJavaScriptObject extends JavaScriptObject { - const PlainJavaScriptObject(); -} - -/// Interceptor for unclassified JavaScript objects, typically objects with a -/// non-trivial prototype chain. -/// -/// This class also serves as a fallback for unknown JavaScript exceptions. -class UnknownJavaScriptObject extends JavaScriptObject { - const UnknownJavaScriptObject(); -} - -/// Interceptor for JavaScript function objects and Dart functions that have -/// been converted to JavaScript functions. -/// These interceptor methods are not always used as the JavaScript function -/// object has also been mangled to support Dart function calling conventions. -class JavaScriptFunction extends JavaScriptObject implements Function { - const JavaScriptFunction(); - - String toString() { - var dartClosure = JS('', '#.#', this, DART_CLOSURE_PROPERTY_NAME); - if (dartClosure == null) return super.toString(); - return 'JavaScript function for ${dartClosure.toString()}'; - } -} diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/internal_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/internal_patch.dart deleted file mode 100644 index e2922cade2e..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/lib/internal_patch.dart +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 2013, 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 'dart:core' hide Symbol; -import 'dart:core' as core show Symbol; -import 'dart:_js_primitives' show printString; -import 'dart:_js_helper' show patch; -import 'dart:_interceptors' show JSArray; -import 'dart:_foreign_helper' show JS, JS_GET_FLAG; - -@patch -@pragma('dart2js:tryInline') -bool typeAcceptsNull() { - bool isLegacySubtyping = JS_GET_FLAG('LEGACY'); - return isLegacySubtyping || null is T; -} - -@patch -class Symbol implements core.Symbol { - @patch - const Symbol(String name) : this._name = name; - - @patch - int get hashCode { - int? hash = JS('int|Null', '#._hashCode', this); - if (hash != null) return hash; - const arbitraryPrime = 664597; - hash = 0x1fffffff & (arbitraryPrime * _name.hashCode); - JS('', '#._hashCode = #', this, hash); - return hash; - } - - @patch - toString() => 'Symbol("$_name")'; - - @patch - static String computeUnmangledName(Symbol symbol) { - throw "unsupported operation"; - } -} - -@patch -void printToConsole(String line) { - printString('$line'); -} - -@patch -List makeListFixedLength(List growableList) { - return JSArray.markFixedList(growableList); -} - -@patch -List makeFixedListUnmodifiable(List fixedLengthList) { - return JSArray.markUnmodifiableList(fixedLengthList); -} - -@patch -@pragma('dart2js:noInline') -Object extractTypeArguments(T instance, Function extract) { - // This function is recognized and replaced with calls to js_runtime. - - // This call to [extract] is required to model that the function is called and - // the returned value flows to the result of extractTypeArguments. - return extract(); -} diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/io_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/io_patch.dart deleted file mode 100644 index 77a253027ff..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/lib/io_patch.dart +++ /dev/null @@ -1,707 +0,0 @@ -// Copyright (c) 2013, 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 'dart:_js_helper' show patch; -import 'dart:_internal' hide Symbol; -import 'dart:async'; -import 'dart:convert'; -import 'dart:isolate'; -import 'dart:typed_data'; - -@patch -class _Directory { - @patch - static _current(_Namespace namespace) { - throw new UnsupportedError("Directory._current"); - } - - @patch - static _setCurrent(_Namespace namespace, Uint8List path) { - throw new UnsupportedError("Directory_SetCurrent"); - } - - @patch - static _createTemp(_Namespace namespace, Uint8List path) { - throw new UnsupportedError("Directory._createTemp"); - } - - @patch - static String _systemTemp(_Namespace namespace) { - throw new UnsupportedError("Directory._systemTemp"); - } - - @patch - static _exists(_Namespace namespace, Uint8List path) { - throw new UnsupportedError("Directory._exists"); - } - - @patch - static _create(_Namespace namespace, Uint8List path) { - throw new UnsupportedError("Directory._create"); - } - - @patch - static _deleteNative(_Namespace namespace, Uint8List path, bool recursive) { - throw new UnsupportedError("Directory._deleteNative"); - } - - @patch - static _rename(_Namespace namespace, Uint8List path, String newPath) { - throw new UnsupportedError("Directory._rename"); - } - - @patch - static void _fillWithDirectoryListing( - _Namespace namespace, - List list, - Uint8List path, - bool recursive, - bool followLinks) { - throw new UnsupportedError("Directory._fillWithDirectoryListing"); - } -} - -@patch -class _AsyncDirectoryListerOps { - @patch - factory _AsyncDirectoryListerOps(int pointer) { - throw new UnsupportedError("Directory._list"); - } -} - -@patch -class _EventHandler { - @patch - static void _sendData(Object? sender, SendPort sendPort, int data) { - throw new UnsupportedError("EventHandler._sendData"); - } -} - -@patch -class FileStat { - @patch - static _statSync(_Namespace namespace, String path) { - throw new UnsupportedError("FileStat.stat"); - } -} - -@patch -class FileSystemEntity { - @patch - static _getTypeNative( - _Namespace namespace, Uint8List path, bool followLinks) { - throw new UnsupportedError("FileSystemEntity._getType"); - } - - @patch - static _identicalNative(_Namespace namespace, String path1, String path2) { - throw new UnsupportedError("FileSystemEntity._identical"); - } - - @patch - static _resolveSymbolicLinks(_Namespace namespace, Uint8List path) { - throw new UnsupportedError("FileSystemEntity._resolveSymbolicLinks"); - } -} - -@patch -class _File { - @patch - static _exists(_Namespace namespace, Uint8List path) { - throw new UnsupportedError("File._exists"); - } - - @patch - static _create(_Namespace namespace, Uint8List path) { - throw new UnsupportedError("File._create"); - } - - @patch - static _createLink(_Namespace namespace, Uint8List path, String target) { - throw new UnsupportedError("File._createLink"); - } - - @patch - static _linkTarget(_Namespace namespace, Uint8List path) { - throw new UnsupportedError("File._linkTarget"); - } - - @patch - static _deleteNative(_Namespace namespace, Uint8List path) { - throw new UnsupportedError("File._deleteNative"); - } - - @patch - static _deleteLinkNative(_Namespace namespace, Uint8List path) { - throw new UnsupportedError("File._deleteLinkNative"); - } - - @patch - static _rename(_Namespace namespace, Uint8List oldPath, String newPath) { - throw new UnsupportedError("File._rename"); - } - - @patch - static _renameLink(_Namespace namespace, Uint8List oldPath, String newPath) { - throw new UnsupportedError("File._renameLink"); - } - - @patch - static _copy(_Namespace namespace, Uint8List oldPath, String newPath) { - throw new UnsupportedError("File._copy"); - } - - @patch - static _lengthFromPath(_Namespace namespace, Uint8List path) { - throw new UnsupportedError("File._lengthFromPath"); - } - - @patch - static _lastModified(_Namespace namespace, Uint8List path) { - throw new UnsupportedError("File._lastModified"); - } - - @patch - static _lastAccessed(_Namespace namespace, Uint8List path) { - throw new UnsupportedError("File._lastAccessed"); - } - - @patch - static _setLastModified(_Namespace namespace, Uint8List path, int millis) { - throw new UnsupportedError("File._setLastModified"); - } - - @patch - static _setLastAccessed(_Namespace namespace, Uint8List path, int millis) { - throw new UnsupportedError("File._setLastAccessed"); - } - - @patch - static _open(_Namespace namespace, Uint8List path, int mode) { - throw new UnsupportedError("File._open"); - } - - @patch - static int _openStdio(int fd) { - throw new UnsupportedError("File._openStdio"); - } -} - -@patch -class _Namespace { - @patch - static void _setupNamespace(var namespace) { - throw new UnsupportedError("_Namespace"); - } - - @patch - static _Namespace get _namespace { - throw new UnsupportedError("_Namespace"); - } - - @patch - static int get _namespacePointer { - throw new UnsupportedError("_Namespace"); - } -} - -@patch -class _RandomAccessFileOps { - @patch - factory _RandomAccessFileOps(int pointer) { - throw new UnsupportedError("RandomAccessFile"); - } -} - -@patch -bool _isDirectIOCapableTypedList(List buffer) { - throw UnsupportedError("_isDirectIOCapableTypedList"); -} - -@patch -class _IOCrypto { - @patch - static Uint8List getRandomBytes(int count) { - throw new UnsupportedError("_IOCrypto.getRandomBytes"); - } -} - -@patch -class _Platform { - @patch - static int _numberOfProcessors() { - throw new UnsupportedError("Platform._numberOfProcessors"); - } - - @patch - static String _pathSeparator() { - throw new UnsupportedError("Platform._pathSeparator"); - } - - @patch - static String _operatingSystem() { - throw new UnsupportedError("Platform._operatingSystem"); - } - - @patch - static _operatingSystemVersion() { - throw new UnsupportedError("Platform._operatingSystemVersion"); - } - - @patch - static _localHostname() { - throw new UnsupportedError("Platform._localHostname"); - } - - @patch - static _executable() { - throw new UnsupportedError("Platform._executable"); - } - - @patch - static _resolvedExecutable() { - throw new UnsupportedError("Platform._resolvedExecutable"); - } - - @patch - static List _executableArguments() { - throw new UnsupportedError("Platform._executableArguments"); - } - - @patch - static String _packageRoot() { - throw new UnsupportedError("Platform._packageRoot"); - } - - @patch - static String _packageConfig() { - throw new UnsupportedError("Platform._packageConfig"); - } - - @patch - static _environment() { - throw new UnsupportedError("Platform._environment"); - } - - @patch - static String _version() { - throw new UnsupportedError("Platform._version"); - } - - @patch - static String _localeName() { - throw new UnsupportedError("Platform._localeName"); - } - - @patch - static Uri _script() { - throw new UnsupportedError("Platform._script"); - } -} - -@patch -class _ProcessUtils { - @patch - static Never _exit(int status) { - throw new UnsupportedError("ProcessUtils._exit"); - } - - @patch - static void _setExitCode(int status) { - throw new UnsupportedError("ProcessUtils._setExitCode"); - } - - @patch - static int _getExitCode() { - throw new UnsupportedError("ProcessUtils._getExitCode"); - } - - @patch - static void _sleep(int millis) { - throw new UnsupportedError("ProcessUtils._sleep"); - } - - @patch - static int _pid(Process? process) { - throw new UnsupportedError("ProcessUtils._pid"); - } - - @patch - static Stream _watchSignal(ProcessSignal signal) { - throw new UnsupportedError("ProcessUtils._watchSignal"); - } -} - -@patch -class ProcessInfo { - @patch - static int get currentRss { - throw new UnsupportedError("ProcessInfo.currentRss"); - } - - @patch - static int get maxRss { - throw new UnsupportedError("ProcessInfo.maxRss"); - } -} - -@patch -class Process { - @patch - static Future start(String executable, List arguments, - {String? workingDirectory, - Map? environment, - bool includeParentEnvironment: true, - bool runInShell: false, - ProcessStartMode mode: ProcessStartMode.normal}) { - throw new UnsupportedError("Process.start"); - } - - @patch - static Future run(String executable, List arguments, - {String? workingDirectory, - Map? environment, - bool includeParentEnvironment: true, - bool runInShell: false, - Encoding stdoutEncoding: systemEncoding, - Encoding stderrEncoding: systemEncoding}) { - throw new UnsupportedError("Process.run"); - } - - @patch - static ProcessResult runSync(String executable, List arguments, - {String? workingDirectory, - Map? environment, - bool includeParentEnvironment: true, - bool runInShell: false, - Encoding stdoutEncoding: systemEncoding, - Encoding stderrEncoding: systemEncoding}) { - throw new UnsupportedError("Process.runSync"); - } - - @patch - static bool killPid(int pid, [ProcessSignal signal = ProcessSignal.sigterm]) { - throw new UnsupportedError("Process.killPid"); - } -} - -@patch -class InternetAddress { - @patch - static InternetAddress get LOOPBACK_IP_V4 { - throw new UnsupportedError("InternetAddress.LOOPBACK_IP_V4"); - } - - @patch - static InternetAddress get LOOPBACK_IP_V6 { - throw new UnsupportedError("InternetAddress.LOOPBACK_IP_V6"); - } - - @patch - static InternetAddress get ANY_IP_V4 { - throw new UnsupportedError("InternetAddress.ANY_IP_V4"); - } - - @patch - static InternetAddress get ANY_IP_V6 { - throw new UnsupportedError("InternetAddress.ANY_IP_V6"); - } - - @patch - factory InternetAddress(String address, {InternetAddressType? type}) { - throw new UnsupportedError("InternetAddress"); - } - - @patch - factory InternetAddress.fromRawAddress(Uint8List rawAddress, - {InternetAddressType? type}) { - throw new UnsupportedError("InternetAddress.fromRawAddress"); - } - - @patch - static Future> lookup(String host, - {InternetAddressType type: InternetAddressType.any}) { - throw new UnsupportedError("InternetAddress.lookup"); - } - - @patch - static InternetAddress _cloneWithNewHost( - InternetAddress address, String host) { - throw new UnsupportedError("InternetAddress._cloneWithNewHost"); - } - - @patch - static InternetAddress? tryParse(String address) { - throw UnsupportedError("InternetAddress.tryParse"); - } -} - -@patch -class NetworkInterface { - @patch - static bool get listSupported { - throw new UnsupportedError("NetworkInterface.listSupported"); - } - - @patch - static Future> list( - {bool includeLoopback: false, - bool includeLinkLocal: false, - InternetAddressType type: InternetAddressType.any}) { - throw new UnsupportedError("NetworkInterface.list"); - } -} - -@patch -class RawServerSocket { - @patch - static Future bind(address, int port, - {int backlog: 0, bool v6Only: false, bool shared: false}) { - throw new UnsupportedError("RawServerSocket.bind"); - } -} - -@patch -class ServerSocket { - @patch - static Future _bind(address, int port, - {int backlog: 0, bool v6Only: false, bool shared: false}) { - throw new UnsupportedError("ServerSocket.bind"); - } -} - -@patch -class RawSocket { - @patch - static Future connect(dynamic host, int port, - {dynamic sourceAddress, Duration? timeout}) { - throw new UnsupportedError("RawSocket constructor"); - } - - @patch - static Future> startConnect(dynamic host, int port, - {dynamic sourceAddress}) { - throw new UnsupportedError("RawSocket constructor"); - } -} - -@patch -class Socket { - @patch - static Future _connect(dynamic host, int port, - {dynamic sourceAddress, Duration? timeout}) { - throw new UnsupportedError("Socket constructor"); - } - - @patch - static Future> _startConnect(dynamic host, int port, - {dynamic sourceAddress}) { - throw new UnsupportedError("Socket constructor"); - } -} - -@patch -class SecureSocket { - @patch - factory SecureSocket._(RawSecureSocket rawSocket) { - throw new UnsupportedError("SecureSocket constructor"); - } -} - -@patch -class RawSynchronousSocket { - @patch - static RawSynchronousSocket connectSync(dynamic host, int port) { - throw new UnsupportedError("RawSynchronousSocket.connectSync"); - } -} - -@patch -class RawSocketOption { - @patch - static int _getOptionValue(int key) { - throw UnsupportedError("RawSocketOption._getOptionValue"); - } -} - -@patch -class SecurityContext { - @patch - factory SecurityContext({bool withTrustedRoots: false}) { - throw new UnsupportedError("SecurityContext constructor"); - } - - @patch - static SecurityContext get defaultContext { - throw new UnsupportedError("default SecurityContext getter"); - } - - @patch - static bool get alpnSupported { - throw new UnsupportedError("SecurityContext alpnSupported getter"); - } -} - -@patch -class X509Certificate { - @patch - factory X509Certificate._() { - throw new UnsupportedError("X509Certificate constructor"); - } -} - -@patch -class RawDatagramSocket { - @patch - static Future bind(dynamic host, int port, - {bool reuseAddress: true, bool reusePort: false, int ttl: 1}) { - throw new UnsupportedError("RawDatagramSocket.bind"); - } -} - -@patch -class _SecureFilter { - @patch - factory _SecureFilter._() { - throw new UnsupportedError("_SecureFilter._SecureFilter"); - } -} - -@patch -class _StdIOUtils { - @patch - static Stdin _getStdioInputStream(int fd) { - throw new UnsupportedError("StdIOUtils._getStdioInputStream"); - } - - @patch - static _getStdioOutputStream(int fd) { - throw new UnsupportedError("StdIOUtils._getStdioOutputStream"); - } - - @patch - static int _socketType(Socket socket) { - throw new UnsupportedError("StdIOUtils._socketType"); - } - - @patch - static _getStdioHandleType(int fd) { - throw new UnsupportedError("StdIOUtils._getStdioHandleType"); - } -} - -@patch -class _WindowsCodePageDecoder { - @patch - static String _decodeBytes(List bytes) { - throw new UnsupportedError("_WindowsCodePageDecoder._decodeBytes"); - } -} - -@patch -class _WindowsCodePageEncoder { - @patch - static List _encodeString(String string) { - throw new UnsupportedError("_WindowsCodePageEncoder._encodeString"); - } -} - -@patch -class RawZLibFilter { - @patch - static RawZLibFilter _makeZLibDeflateFilter( - bool gzip, - int level, - int windowBits, - int memLevel, - int strategy, - List? dictionary, - bool raw) { - throw new UnsupportedError("_newZLibDeflateFilter"); - } - - @patch - static RawZLibFilter _makeZLibInflateFilter( - int windowBits, List? dictionary, bool raw) { - throw new UnsupportedError("_newZLibInflateFilter"); - } -} - -@patch -class Stdin { - @patch - int readByteSync() { - throw new UnsupportedError("Stdin.readByteSync"); - } - - @patch - bool get echoMode { - throw new UnsupportedError("Stdin.echoMode"); - } - - @patch - void set echoMode(bool enabled) { - throw new UnsupportedError("Stdin.echoMode"); - } - - @patch - bool get lineMode { - throw new UnsupportedError("Stdin.lineMode"); - } - - @patch - void set lineMode(bool enabled) { - throw new UnsupportedError("Stdin.lineMode"); - } - - @patch - bool get supportsAnsiEscapes { - throw new UnsupportedError("Stdin.supportsAnsiEscapes"); - } -} - -@patch -class Stdout { - @patch - bool _hasTerminal(int fd) { - throw new UnsupportedError("Stdout.hasTerminal"); - } - - @patch - int _terminalColumns(int fd) { - throw new UnsupportedError("Stdout.terminalColumns"); - } - - @patch - int _terminalLines(int fd) { - throw new UnsupportedError("Stdout.terminalLines"); - } - - @patch - static bool _supportsAnsiEscapes(int fd) { - throw new UnsupportedError("Stdout.supportsAnsiEscapes"); - } -} - -@patch -class _FileSystemWatcher { - @patch - static Stream _watch( - String path, int events, bool recursive) { - throw new UnsupportedError("_FileSystemWatcher.watch"); - } - - @patch - static bool get isSupported { - throw new UnsupportedError("_FileSystemWatcher.isSupported"); - } -} - -@patch -class _IOService { - @patch - static Future _dispatch(int request, List data) { - throw new UnsupportedError("_IOService._dispatch"); - } -} diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/isolate_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/isolate_patch.dart deleted file mode 100644 index 4c7f5c5f395..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/lib/isolate_patch.dart +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright (c) 2012, 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. - -// Patch file for the dart:isolate library. - -import "dart:async"; -import 'dart:_foreign_helper' show JS; -import 'dart:_js_helper' show patch; -import "dart:typed_data" show TypedData; - -@patch -class Isolate { - @patch - static Isolate get current { - throw new UnsupportedError("Isolate.current"); - } - - @patch - String? get debugName { - throw new UnsupportedError("Isolate.debugName"); - } - - @patch - static Future get packageRoot { - throw new UnsupportedError("Isolate.packageRoot"); - } - - @patch - static Future get packageConfig { - throw new UnsupportedError("Isolate.packageConfig"); - } - - @patch - static Future resolvePackageUri(Uri packageUri) { - throw new UnsupportedError("Isolate.resolvePackageUri"); - } - - @patch - static Future spawn(void entryPoint(T message), T message, - {bool paused = false, - bool errorsAreFatal = true, - SendPort? onExit, - SendPort? onError}) { - throw new UnsupportedError("Isolate.spawn"); - } - - @patch - static Future spawnUri(Uri uri, List args, var message, - {bool paused = false, - SendPort? onExit, - SendPort? onError, - bool errorsAreFatal = true, - bool? checked, - Map? environment, - Uri? packageRoot, - Uri? packageConfig, - bool automaticPackageResolution = false, - String? debugName}) { - throw new UnsupportedError("Isolate.spawnUri"); - } - - @patch - void _pause(Capability resumeCapability) { - throw new UnsupportedError("Isolate._pause"); - } - - @patch - void resume(Capability resumeCapability) { - throw new UnsupportedError("Isolate.resume"); - } - - @patch - void addOnExitListener(SendPort responsePort, {Object? response}) { - throw new UnsupportedError("Isolate.addOnExitListener"); - } - - @patch - void removeOnExitListener(SendPort responsePort) { - throw new UnsupportedError("Isolate.removeOnExitListener"); - } - - @patch - void setErrorsFatal(bool errorsAreFatal) { - throw new UnsupportedError("Isolate.setErrorsFatal"); - } - - @patch - void kill({int priority = beforeNextEvent}) { - throw new UnsupportedError("Isolate.kill"); - } - - @patch - void ping(SendPort responsePort, - {Object? response, int priority = immediate}) { - throw new UnsupportedError("Isolate.ping"); - } - - @patch - void addErrorListener(SendPort port) { - throw new UnsupportedError("Isolate.addErrorListener"); - } - - @patch - void removeErrorListener(SendPort port) { - throw new UnsupportedError("Isolate.removeErrorListener"); - } -} - -@patch -class ReceivePort { - @patch - factory ReceivePort() = _ReceivePortImpl; - - @patch - factory ReceivePort.fromRawReceivePort(RawReceivePort rawPort) { - throw new UnsupportedError('new ReceivePort.fromRawReceivePort'); - } -} - -class _ReceivePortImpl extends Stream implements ReceivePort { - StreamSubscription listen(void Function(dynamic)? onData, - {Function? onError, - void Function()? onDone, - bool? cancelOnError = true}) { - throw new UnsupportedError("ReceivePort.listen"); - } - - void close() {} - - SendPort get sendPort => throw new UnsupportedError("ReceivePort.sendPort"); -} - -@patch -class RawReceivePort { - @patch - factory RawReceivePort([Function? handler]) { - throw new UnsupportedError('new RawReceivePort'); - } -} - -@patch -class Capability { - @patch - factory Capability() { - throw new UnsupportedError('new Capability'); - } -} - -@patch -abstract class TransferableTypedData { - @patch - factory TransferableTypedData.fromList(List list) { - throw new UnsupportedError('TransferableTypedData.fromList'); - } -} diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/js_array.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/js_array.dart deleted file mode 100644 index d13165860bb..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/lib/js_array.dart +++ /dev/null @@ -1,727 +0,0 @@ -// Copyright (c) 2012, 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. - -part of _interceptors; - -class _Growable { - const _Growable(); -} - -const _ListConstructorSentinel = const _Growable(); - -/// The interceptor class for [List]. The compiler recognizes this -/// class as an interceptor, and changes references to [:this:] to -/// actually use the receiver of the method, which is generated as an extra -/// argument added to each member. -class JSArray extends Interceptor implements List, JSIndexable { - const JSArray(); - - // This factory constructor is the redirection target of the List() factory - // constructor. [length] has no type to permit the sentinel value. - factory JSArray.list([length = _ListConstructorSentinel]) { - if (_ListConstructorSentinel == length) { - return new JSArray.emptyGrowable(); - } - return new JSArray.fixed(length); - } - - /// Returns a fresh JavaScript Array, marked as fixed-length. - /// - /// [length] must be a non-negative integer. - factory JSArray.fixed(int length) { - // Explicit type test is necessary to guard against JavaScript conversions - // in unchecked mode, and against `new Array(null)` which creates a single - // element Array containing `null`. - if (length is! int) { - throw new ArgumentError.value(length, 'length', 'is not an integer'); - } - // The JavaScript Array constructor with one argument throws if - // the value is not a UInt32. Give a better error message. - int maxJSArrayLength = 0xFFFFFFFF; - if (length < 0 || length > maxJSArrayLength) { - throw new RangeError.range(length, 0, maxJSArrayLength, 'length'); - } - return new JSArray.markFixed(JS('', 'new Array(#)', length)); - } - - /// Returns a fresh growable JavaScript Array of zero length length. - factory JSArray.emptyGrowable() => new JSArray.markGrowable(JS('', '[]')); - - /// Returns a fresh growable JavaScript Array with initial length. - /// - /// [validatedLength] must be a non-negative integer. - factory JSArray.growable(int length) { - // Explicit type test is necessary to guard against JavaScript conversions - // in unchecked mode. - if ((length is! int) || (length < 0)) { - throw new ArgumentError('Length must be a non-negative integer: $length'); - } - return new JSArray.markGrowable(JS('', 'new Array(#)', length)); - } - - /// Constructor for adding type parameters to an existing JavaScript Array. - /// The compiler specially recognizes this constructor. - /// - /// var a = new JSArray.typed(JS('JSExtendableArray', '[]')); - /// a is List --> true - /// a is List --> false - /// - /// Usually either the [JSArray.markFixed] or [JSArray.markGrowable] - /// constructors is used instead. - /// - /// The input must be a JavaScript Array. The JS form is just a re-assertion - /// to help type analysis when the input type is sloppy. - factory JSArray.typed(allocation) => JS('JSArray', '#', allocation); - - factory JSArray.markFixed(allocation) => - JS('JSFixedArray', '#', markFixedList(new JSArray.typed(allocation))); - - factory JSArray.markGrowable(allocation) => - JS('JSExtendableArray', '#', new JSArray.typed(allocation)); - - static List markFixedList(List list) { - // Functions are stored in the hidden class and not as properties in - // the object. We never actually look at the value, but only want - // to know if the property exists. - JS('void', r'#.fixed$length = Array', list); - return JS('JSFixedArray', '#', list); - } - - static List markUnmodifiableList(List list) { - // Functions are stored in the hidden class and not as properties in - // the object. We never actually look at the value, but only want - // to know if the property exists. - JS('void', r'#.fixed$length = Array', list); - JS('void', r'#.immutable$list = Array', list); - return JS('JSUnmodifiableArray', '#', list); - } - - static bool isFixedLength(JSArray a) { - return !JS('bool', r'!#.fixed$length', a); - } - - static bool isUnmodifiable(JSArray a) { - return !JS('bool', r'!#.immutable$list', a); - } - - static bool isGrowable(JSArray a) { - return !isFixedLength(a); - } - - static bool isMutable(JSArray a) { - return !isUnmodifiable(a); - } - - checkMutable(String reason) { - if (!isMutable(this)) { - throw UnsupportedError(reason); - } - } - - checkGrowable(String reason) { - if (!isGrowable(this)) { - throw UnsupportedError(reason); - } - } - - List cast() => List.castFrom(this); - void add(E value) { - checkGrowable('add'); - JS('void', r'#.push(#)', this, value); - } - - E removeAt(int index) { - checkGrowable('removeAt'); - if (index is! int) throw argumentErrorValue(index); - if (index < 0 || index >= length) { - throw new RangeError.value(index); - } - return JS('', r'#.splice(#, 1)[0]', this, index); - } - - void insert(int index, E value) { - checkGrowable('insert'); - if (index is! int) throw argumentErrorValue(index); - if (index < 0 || index > length) { - throw new RangeError.value(index); - } - JS('void', r'#.splice(#, 0, #)', this, index, value); - } - - void insertAll(int index, Iterable iterable) { - checkGrowable('insertAll'); - RangeError.checkValueInInterval(index, 0, this.length, 'index'); - if (iterable is! EfficientLengthIterable) { - iterable = iterable.toList(); - } - int insertionLength = iterable.length; - this.length += insertionLength; - int end = index + insertionLength; - this.setRange(end, this.length, this, index); - this.setRange(index, end, iterable); - } - - void setAll(int index, Iterable iterable) { - checkMutable('setAll'); - RangeError.checkValueInInterval(index, 0, this.length, 'index'); - for (var element in iterable) { - this[index++] = element; - } - } - - E removeLast() { - checkGrowable('removeLast'); - if (length == 0) throw diagnoseIndexError(this, -1); - return JS('', r'#.pop()', this); - } - - bool remove(Object? element) { - checkGrowable('remove'); - for (int i = 0; i < this.length; i++) { - if (this[i] == element) { - JS('', r'#.splice(#, 1)', this, i); - return true; - } - } - return false; - } - - /// Removes elements matching [test] from [this] List. - void removeWhere(bool test(E element)) { - checkGrowable('removeWhere'); - _removeWhere(test, true); - } - - void retainWhere(bool test(E element)) { - checkGrowable('retainWhere'); - _removeWhere(test, false); - } - - void _removeWhere(bool test(E element), bool removeMatching) { - // Performed in two steps, to avoid exposing an inconsistent state - // to the [test] function. First the elements to retain are found, and then - // the original list is updated to contain those elements. - - // TODO(sra): Replace this algorithm with one that retains a list of ranges - // to be removed. Most real uses remove 0, 1 or a few clustered elements. - - List retained = []; - int end = this.length; - for (int i = 0; i < end; i++) { - // TODO(22407): Improve bounds check elimination to allow this JS code to - // be replaced by indexing. - var element = JS('', '#[#]', this, i); - // !test() ensures bool conversion in checked mode. - if (!test(element) == removeMatching) { - retained.add(element); - } - if (this.length != end) throw new ConcurrentModificationError(this); - } - if (retained.length == end) return; - this.length = retained.length; - for (int i = 0; i < retained.length; i++) { - // We don't need a bounds check or an element type check. - JS('', '#[#] = #', this, i, retained[i]); - } - } - - Iterable where(bool f(E element)) { - return new WhereIterable(this, f); - } - - Iterable expand(Iterable f(E element)) { - return new ExpandIterable(this, f); - } - - void addAll(Iterable collection) { - int i = this.length; - checkGrowable('addAll'); - for (E e in collection) { - assert( - i++ == this.length || (throw new ConcurrentModificationError(this))); - JS('void', r'#.push(#)', this, e); - } - } - - void clear() { - length = 0; - } - - void forEach(void f(E element)) { - int end = this.length; - for (int i = 0; i < end; i++) { - // TODO(22407): Improve bounds check elimination to allow this JS code to - // be replaced by indexing. - var element = JS('', '#[#]', this, i); - f(element); - if (this.length != end) throw new ConcurrentModificationError(this); - } - } - - Iterable map(T f(E element)) { - return new MappedListIterable(this, f); - } - - String join([String separator = '']) { - var list = List.filled(this.length, ""); - for (int i = 0; i < this.length; i++) { - list[i] = '${this[i]}'; - } - return JS('String', '#.join(#)', list, separator); - } - - Iterable take(int n) { - return new SubListIterable(this, 0, n); - } - - Iterable takeWhile(bool test(E value)) { - return new TakeWhileIterable(this, test); - } - - Iterable skip(int n) { - return new SubListIterable(this, n, null); - } - - Iterable skipWhile(bool test(E value)) { - return new SkipWhileIterable(this, test); - } - - E reduce(E combine(E previousValue, E element)) { - int length = this.length; - if (length == 0) throw IterableElementError.noElement(); - E value = this[0]; - for (int i = 1; i < length; i++) { - // TODO(22407): Improve bounds check elimination to allow this JS code to - // be replaced by indexing. - var element = JS('', '#[#]', this, i); - value = combine(value, element); - if (length != this.length) throw new ConcurrentModificationError(this); - } - return value; - } - - T fold(T initialValue, T combine(T previousValue, E element)) { - var value = initialValue; - int length = this.length; - for (int i = 0; i < length; i++) { - // TODO(22407): Improve bounds check elimination to allow this JS code to - // be replaced by indexing. - var element = JS('', '#[#]', this, i); - value = combine(value, element); - if (this.length != length) throw new ConcurrentModificationError(this); - } - return value; - } - - E firstWhere(bool Function(E) test, {E Function()? orElse}) { - var end = this.length; - for (int i = 0; i < end; ++i) { - // TODO(22407): Improve bounds check elimination to allow this JS code to - // be replaced by indexing. - var element = JS('', '#[#]', this, i); - if (test(element)) return element; - if (this.length != end) throw new ConcurrentModificationError(this); - } - if (orElse != null) return orElse(); - throw IterableElementError.noElement(); - } - - E lastWhere(bool Function(E) test, {E Function()? orElse}) { - int length = this.length; - for (int i = length - 1; i >= 0; i--) { - // TODO(22407): Improve bounds check elimination to allow this JS code to - // be replaced by indexing. - var element = JS('', '#[#]', this, i); - if (test(element)) return element; - if (length != this.length) { - throw new ConcurrentModificationError(this); - } - } - if (orElse != null) return orElse(); - throw IterableElementError.noElement(); - } - - E singleWhere(bool Function(E) test, {E Function()? orElse}) { - int length = this.length; - E? match = null; - bool matchFound = false; - for (int i = 0; i < length; i++) { - // TODO(22407): Improve bounds check elimination to allow this JS code to - // be replaced by indexing. - var element = JS('', '#[#]', this, i); - if (test(element)) { - if (matchFound) { - throw IterableElementError.tooMany(); - } - matchFound = true; - match = element; - } - if (length != this.length) { - throw new ConcurrentModificationError(this); - } - } - if (matchFound) return match as E; - if (orElse != null) return orElse(); - throw IterableElementError.noElement(); - } - - E elementAt(int index) { - return this[index]; - } - - List sublist(int start, [int? end]) { - checkNull(start); // TODO(ahe): This is not specified but co19 tests it. - if (start is! int) throw argumentErrorValue(start); - if (start < 0 || start > length) { - throw new RangeError.range(start, 0, length, 'start'); - } - if (end == null) { - end = length; - } else { - if (end is! int) throw argumentErrorValue(end); - if (end < start || end > length) { - throw new RangeError.range(end, start, length, 'end'); - } - } - if (start == end) return []; - return new JSArray.markGrowable( - JS('', r'#.slice(#, #)', this, start, end)); - } - - Iterable getRange(int start, int end) { - RangeError.checkValidRange(start, end, this.length); - return new SubListIterable(this, start, end); - } - - E get first { - if (length > 0) return this[0]; - throw IterableElementError.noElement(); - } - - E get last { - if (length > 0) return this[length - 1]; - throw IterableElementError.noElement(); - } - - E get single { - if (length == 1) return this[0]; - if (length == 0) throw IterableElementError.noElement(); - throw IterableElementError.tooMany(); - } - - void removeRange(int start, int end) { - checkGrowable('removeRange'); - RangeError.checkValidRange(start, end, this.length); - int deleteCount = end - start; - JS('', '#.splice(#, #)', this, start, deleteCount); - } - - void setRange(int start, int end, Iterable iterable, [int skipCount = 0]) { - checkMutable('setRange'); - - RangeError.checkValidRange(start, end, this.length); - int length = end - start; - if (length == 0) return; - RangeError.checkNotNegative(skipCount, 'skipCount'); - - List otherList; - int otherStart; - // TODO(floitsch): Make this accept more. - if (iterable is List) { - otherList = JS>('', '#', iterable); - otherStart = skipCount; - } else { - otherList = iterable.skip(skipCount).toList(growable: false); - otherStart = 0; - } - if (otherStart + length > otherList.length) { - throw IterableElementError.tooFew(); - } - if (otherStart < start) { - // Copy backwards to ensure correct copy if [from] is this. - // TODO(sra): If [from] is the same Array as [this], we can copy without - // type annotation checks on the stores. - for (int i = length - 1; i >= 0; i--) { - // Use JS to avoid bounds check (the bounds check elimination - // optimzation is too weak). The 'E' type annotation is a store type - // check - we can't rely on iterable, it could be List. - E element = otherList[otherStart + i]; - JS('', '#[#] = #', this, start + i, element); - } - } else { - for (int i = 0; i < length; i++) { - E element = otherList[otherStart + i]; - JS('', '#[#] = #', this, start + i, element); - } - } - } - - void fillRange(int start, int end, [E? fillValue]) { - checkMutable('fill range'); - RangeError.checkValidRange(start, end, this.length); - E checkedFillValue = fillValue as E; - for (int i = start; i < end; i++) { - // Store is safe since [checkedFillValue] type has been checked as - // parameter and for null. - JS('', '#[#] = #', this, i, checkedFillValue); - } - } - - void replaceRange(int start, int end, Iterable replacement) { - checkGrowable('replaceRange'); - RangeError.checkValidRange(start, end, this.length); - if (replacement is! EfficientLengthIterable) { - replacement = replacement.toList(); - } - int removeLength = end - start; - int insertLength = replacement.length; - if (removeLength >= insertLength) { - int delta = removeLength - insertLength; - int insertEnd = start + insertLength; - int newLength = this.length - delta; - this.setRange(start, insertEnd, replacement); - if (delta != 0) { - this.setRange(insertEnd, newLength, this, end); - this.length = newLength; - } - } else { - int delta = insertLength - removeLength; - int newLength = this.length + delta; - int insertEnd = start + insertLength; // aka. end + delta. - this.length = newLength; - this.setRange(insertEnd, newLength, this, end); - this.setRange(start, insertEnd, replacement); - } - } - - bool any(bool test(E element)) { - int end = this.length; - for (int i = 0; i < end; i++) { - // TODO(22407): Improve bounds check elimination to allow this JS code to - // be replaced by indexing. - var element = JS('', '#[#]', this, i); - if (test(element)) return true; - if (this.length != end) throw new ConcurrentModificationError(this); - } - return false; - } - - bool every(bool test(E element)) { - int end = this.length; - for (int i = 0; i < end; i++) { - // TODO(22407): Improve bounds check elimination to allow this JS code to - // be replaced by indexing. - var element = JS('', '#[#]', this, i); - if (!test(element)) return false; - if (this.length != end) throw new ConcurrentModificationError(this); - } - return true; - } - - Iterable get reversed => new ReversedListIterable(this); - - void sort([int Function(E, E)? compare]) { - checkMutable('sort'); - Sort.sort(this, compare ?? _compareAny); - } - - static int _compareAny(a, b) { - return Comparable.compare(a, b); - } - - void shuffle([Random? random]) { - checkMutable('shuffle'); - if (random == null) random = new Random(); - int length = this.length; - while (length > 1) { - int pos = random.nextInt(length); - length -= 1; - var tmp = this[length]; - this[length] = this[pos]; - this[pos] = tmp; - } - } - - int indexOf(Object? element, [int start = 0]) { - int length = this.length; - if (start >= length) { - return -1; - } - if (start < 0) { - start = 0; - } - for (int i = start; i < length; i++) { - if (this[i] == element) { - return i; - } - } - return -1; - } - - int lastIndexOf(Object? element, [int? startIndex]) { - int start = startIndex ?? this.length - 1; - if (start < 0) { - return -1; - } - if (start >= this.length) { - start = this.length - 1; - } - for (int i = start; i >= 0; i--) { - if (this[i] == element) { - return i; - } - } - return -1; - } - - bool contains(Object? other) { - for (int i = 0; i < length; i++) { - E element = JS('', '#[#]', this, i); - if (element == other) return true; - } - return false; - } - - bool get isEmpty => length == 0; - - bool get isNotEmpty => !isEmpty; - - String toString() => ListBase.listToString(this); - - List toList({bool growable: true}) => - growable ? _toListGrowable() : _toListFixed(); - - List _toListGrowable() => - // slice(0) is slightly faster than slice() - new JSArray.markGrowable(JS('', '#.slice(0)', this)); - - List _toListFixed() => - new JSArray.markFixed(JS('', '#.slice(0)', this)); - - Set toSet() => new Set.from(this); - - Iterator get iterator => new ArrayIterator(this); - - int get hashCode => Primitives.objectHashCode(this); - - int get length => JS('JSUInt32', r'#.length', this); - - set length(int newLength) { - checkGrowable('set length'); - if (newLength is! int) { - throw new ArgumentError.value(newLength, 'newLength'); - } - // TODO(sra): Remove this test and let JavaScript throw an error. - if (newLength < 0) { - throw new RangeError.range(newLength, 0, null, 'newLength'); - } - // JavaScript with throw a RangeError for numbers that are too big. The - // message does not contain the value. - JS('void', r'#.length = #', this, newLength); - } - - E operator [](int index) { - if (index is! int) throw diagnoseIndexError(this, index); - if (index >= length || index < 0) throw diagnoseIndexError(this, index); - return JS('', '#[#]', this, index); - } - - void operator []=(int index, E value) { - checkMutable('indexed set'); - if (index is! int) throw diagnoseIndexError(this, index); - if (index >= length || index < 0) throw diagnoseIndexError(this, index); - JS('void', r'#[#] = #', this, index, value); - } - - Map asMap() { - return new ListMapView(this); - } - - Iterable followedBy(Iterable other) => - new FollowedByIterable.firstEfficient(this, other); - - Iterable whereType() => new WhereTypeIterable(this); - - List operator +(List other) => [...this, ...other]; - - int indexWhere(bool test(E element), [int start = 0]) { - if (start >= this.length) return -1; - if (start < 0) start = 0; - for (int i = start; i < this.length; i++) { - if (test(this[i])) return i; - } - return -1; - } - - int lastIndexWhere(bool test(E element), [int? start]) { - if (start == null) start = this.length - 1; - if (start < 0) return -1; - for (int i = start; i >= 0; i--) { - if (test(this[i])) return i; - } - return -1; - } - - void set first(E element) { - if (this.isEmpty) throw IterableElementError.noElement(); - this[0] = element; - } - - void set last(E element) { - if (this.isEmpty) throw IterableElementError.noElement(); - this[this.length - 1] = element; - } -} - -/// Dummy subclasses that allow the backend to track more precise -/// information about arrays through their type. The CPA type inference -/// relies on the fact that these classes do not override [] nor []=. -/// -/// These classes are really a fiction, and can have no methods, since -/// getInterceptor always returns JSArray. We should consider pushing the -/// 'isGrowable' and 'isMutable' checks into the getInterceptor implementation -/// so these classes can have specialized implementations. Doing so will -/// challenge many assumptions in the JS backend. -class JSMutableArray extends JSArray implements JSMutableIndexable {} - -class JSFixedArray extends JSMutableArray {} - -class JSExtendableArray extends JSMutableArray {} - -class JSUnmodifiableArray extends JSArray {} // Already is JSIndexable. - -/// An [Iterator] that iterates a JSArray. -/// -class ArrayIterator implements Iterator { - final JSArray _iterable; - final int _length; - int _index; - E? _current; - - ArrayIterator(JSArray iterable) - : _iterable = iterable, - _length = iterable.length, - _index = 0; - - E get current => _current as E; - - bool moveNext() { - int length = _iterable.length; - - // We have to do the length check even on fixed length Arrays. If we can - // inline moveNext() we might be able to GVN the length and eliminate this - // check on known fixed length JSArray. - if (_length != length) { - throw throwConcurrentModificationError(_iterable); - } - - if (_index >= length) { - _current = null; - return false; - } - _current = _iterable[_index]; - _index++; - return true; - } -} diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/js_helper.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/js_helper.dart deleted file mode 100644 index db4ef1bed05..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/lib/js_helper.dart +++ /dev/null @@ -1,3253 +0,0 @@ -// Copyright (c) 2013, 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 _js_helper; - -import 'dart:_js_embedded_names' - show - ARRAY_RTI_PROPERTY, - CURRENT_SCRIPT, - DEFERRED_LIBRARY_PARTS, - DEFERRED_PART_URIS, - DEFERRED_PART_HASHES, - GET_TYPE_FROM_NAME, - GET_ISOLATE_TAG, - INITIALIZE_LOADED_HUNK, - INTERCEPTED_NAMES, - INTERCEPTORS_BY_TAG, - IS_HUNK_LOADED, - IS_HUNK_INITIALIZED, - JsBuiltin, - JsGetName, - LEAF_TAGS, - NATIVE_SUPERCLASS_TAG_NAME, - STATIC_FUNCTION_NAME_PROPERTY_NAME; - -import 'dart:collection'; - -import 'dart:async' show Completer, DeferredLoadException, Future; - -import 'dart:_foreign_helper' - show - DART_CLOSURE_TO_JS, - getInterceptor, - JS, - JS_BUILTIN, - JS_CONST, - JS_EFFECT, - JS_EMBEDDED_GLOBAL, - JS_GET_FLAG, - JS_GET_NAME, - JS_INTERCEPTOR_CONSTANT, - JS_STRING_CONCAT, - RAW_DART_FUNCTION_REF; - -import 'dart:_interceptors'; -import 'dart:_internal' as _symbol_dev; -import 'dart:_internal' - show - EfficientLengthIterable, - MappedIterable, - IterableElementError, - SubListIterable; - -import 'dart:_native_typed_data'; - -import 'dart:_js_names' - show - extractKeys, - unmangleGlobalNameIfPreservedAnyways, - unmangleAllIdentifiersIfPreservedAnyways; - -import 'dart:_rti' as newRti - show - createRuntimeType, - evalInInstance, - getRuntimeType, - getTypeFromTypesTable, - instanceTypeName, - instantiatedGenericFunctionType, - throwTypeError; - -part 'annotations.dart'; -part 'constant_map.dart'; -part 'instantiation.dart'; -part 'native_helper.dart'; -part 'regexp_helper.dart'; -part 'string_helper.dart'; -part 'js_rti.dart'; -part 'linked_hash_map.dart'; - -/// Marks the internal map in dart2js, so that internal libraries can is-check -/// them. -abstract class InternalMap {} - -/// Extracts the JavaScript-constructor name from the given isCheckProperty. -// TODO(floitsch): move this to foreign_helper.dart or similar. -@pragma('dart2js:tryInline') -String isCheckPropertyToJsConstructorName(String isCheckProperty) { - return JS_BUILTIN('returns:String;depends:none;effects:none', - JsBuiltin.isCheckPropertyToJsConstructorName, isCheckProperty); -} - -/// Returns true if the given [type] is a function type object. -// TODO(floitsch): move this to foreign_helper.dart or similar. -@pragma('dart2js:tryInline') -bool isDartFunctionType(Object type) { - // Function type test is using the `in` operator which doesn't work on - // primitive types. - assert(!(type == null || type is num || type is String)); - return JS_BUILTIN( - 'returns:bool;effects:none;depends:none', JsBuiltin.isFunctionType, type); -} - -/// Returns true if the given [type] is a FutureOr type object. -// TODO(floitsch): move this to foreign_helper.dart or similar. -@pragma('dart2js:tryInline') -bool isDartFutureOrType(Object type) { - // FutureOr test is using the `in` operator which doesn't work on primitive - // types. - assert(!(type == null || type is num || type is String)); - return JS_BUILTIN( - 'returns:bool;effects:none;depends:none', JsBuiltin.isFutureOrType, type); -} - -@pragma('dart2js:tryInline') -bool isDartVoidTypeRti(Object type) { - return JS_BUILTIN( - 'returns:bool;effects:none;depends:none', JsBuiltin.isVoidType, type); -} - -/// Retrieves the class name from type information stored on the constructor of -/// [type]. -// TODO(floitsch): move this to foreign_helper.dart or similar. -@pragma('dart2js:tryInline') -String rawRtiToJsConstructorName(Object rti) { - return JS_BUILTIN('String', JsBuiltin.rawRtiToJsConstructorName, rti); -} - -/// Given a raw constructor name, return the unminified name, if available, -/// otherwise tag the name with `minified:`. -String unminifyOrTag(String rawClassName) { - String? preserved = unmangleGlobalNameIfPreservedAnyways(rawClassName); - if (preserved != null) return preserved; - if (JS_GET_FLAG('MINIFIED')) return 'minified:${rawClassName}'; - return rawClassName; -} - -/// Returns the rti from the given [constructorName]. -// TODO(floitsch): make this a builtin. -jsConstructorNameToRti(String constructorName) { - var getTypeFromName = JS_EMBEDDED_GLOBAL('', GET_TYPE_FROM_NAME); - return JS('', '#(#)', getTypeFromName, constructorName); -} - -/// Returns the raw runtime type of the given object [o]. -/// -/// The argument [o] must be the interceptor for primitive types. If -/// necessary run it through [getInterceptor] first. -// TODO(floitsch): move this to foreign_helper.dart or similar. -// TODO(floitsch): we should call getInterceptor ourselves, but currently -// getInterceptor is not GVNed. -@pragma('dart2js:tryInline') -Object getRawRuntimeType(Object o) { - return JS_BUILTIN('', JsBuiltin.rawRuntimeType, o); -} - -/// Returns whether the given [type] is a subtype of [other]. -/// -/// The argument [other] is the name of the other type, as computed by -/// [runtimeTypeToString]. -@pragma('dart2js:tryInline') -bool builtinIsSubtype(type, String other) { - return JS_BUILTIN('returns:bool;effects:none;depends:none', - JsBuiltin.isSubtype, other, type); -} - -/// Returns true if the given [type] is _the_ `Function` type. -// TODO(floitsch): move this to foreign_helper.dart or similar. -@pragma('dart2js:tryInline') -bool isDartFunctionTypeRti(Object type) { - return JS_BUILTIN( - 'returns:bool;effects:none;depends:none', - JsBuiltin.isGivenTypeRti, - type, - JS_GET_NAME(JsGetName.FUNCTION_CLASS_TYPE_NAME)); -} - -/// Returns true if the given [type] is _the_ `Null` type. -@pragma('dart2js:tryInline') -bool isNullType(Object type) { - return JS_BUILTIN( - 'returns:bool;effects:none;depends:none', - JsBuiltin.isGivenTypeRti, - type, - JS_GET_NAME(JsGetName.NULL_CLASS_TYPE_NAME)); -} - -/// Returns whether the given type is the dynamic type. -// TODO(floitsch): move this to foreign_helper.dart or similar. -@pragma('dart2js:tryInline') -bool isDartDynamicTypeRti(type) { - return JS_BUILTIN( - 'returns:bool;effects:none;depends:none', JsBuiltin.isDynamicType, type); -} - -@pragma('dart2js:tryInline') -bool isDartJsInteropTypeArgumentRti(type) { - return JS_BUILTIN('returns:bool;effects:none;depends:none', - JsBuiltin.isJsInteropTypeArgument, type); -} - -/// Returns whether the given type is _the_ Dart Object type. -// TODO(floitsch): move this to foreign_helper.dart or similar. -@pragma('dart2js:tryInline') -bool isDartObjectTypeRti(type) { - return JS_BUILTIN( - 'returns:bool;effects:none;depends:none', - JsBuiltin.isGivenTypeRti, - type, - JS_GET_NAME(JsGetName.OBJECT_CLASS_TYPE_NAME)); -} - -/// Returns whether the given type is _the_ null type. -// TODO(floitsch): move this to foreign_helper.dart or similar. -@pragma('dart2js:tryInline') -bool isNullTypeRti(type) { - return JS_BUILTIN( - 'returns:bool;effects:none;depends:none', - JsBuiltin.isGivenTypeRti, - type, - JS_GET_NAME(JsGetName.NULL_CLASS_TYPE_NAME)); -} - -/// Returns the metadata of the given [index]. -// TODO(floitsch): move this to foreign_helper.dart or similar. -@pragma('dart2js:tryInline') -getMetadata(int index) { - return JS_BUILTIN( - 'returns:var;effects:none;depends:none', JsBuiltin.getMetadata, index); -} - -/// Returns the type of the given [index]. -// TODO(floitsch): move this to foreign_helper.dart or similar. -@pragma('dart2js:tryInline') -getType(int index) { - return JS_BUILTIN( - 'returns:var;effects:none;depends:none', JsBuiltin.getType, index); -} - -/// No-op method that is called to inform the compiler that preambles might -/// be needed when executing the resulting JS file in a command-line -/// JS engine. -requiresPreamble() {} - -bool isJsIndexable(var object, var record) { - if (record != null) { - var result = dispatchRecordIndexability(record); - if (result != null) return result; - } - return object is JavaScriptIndexingBehavior; -} - -String S(value) { - if (value is String) return value; - if (value is num) { - if (value != 0) { - // ""+x is faster than String(x) for integers on most browsers. - return JS('String', r'"" + (#)', value); - } - } else if (true == value) { - return 'true'; - } else if (false == value) { - return 'false'; - } else if (value == null) { - return 'null'; - } - var res = value.toString(); - if (res is! String) throw argumentErrorValue(value); - return res; -} - -// Called from generated code. -createInvocationMirror( - String name, internalName, kind, arguments, argumentNames, types) { - // TODO(sra): [types] (the number of type arguments) could be omitted in the - // generated stub code to save an argument. Then we would use `types ?? 0`. - return new JSInvocationMirror( - name, internalName, kind, arguments, argumentNames, types); -} - -createUnmangledInvocationMirror( - Symbol symbol, internalName, kind, arguments, argumentNames, types) { - return new JSInvocationMirror( - symbol, internalName, kind, arguments, argumentNames, types); -} - -void throwInvalidReflectionError(String memberName) { - throw new UnsupportedError("Can't use '$memberName' in reflection " - "because it is not included in a @MirrorsUsed annotation."); -} - -/// Helper used to instrument calls when the compiler is invoked with -/// `--experiment-call-instrumentation`. -/// -/// By default, whenever a method is invoked for the first time, it prints an id -/// and the method name to the console. This can be overriden by adding a top -/// level `dartCallInstrumentation` hook in JavaScript. -@pragma('dart2js:noInline') -void traceHelper(dynamic /*int*/ id, dynamic /*String*/ qualifiedName) { - // Note: this method is written mostly in JavaScript to prevent a stack - // overflow. In particular, we use dynamic argument types because with with - // types, traceHelper would include type checks for the parameter types, those - // checks (intTypeCheck, stringTypeCheck) are themselves calls that end up - // invoking this traceHelper and produce a stack overflow. Similarly if we - // had Dart code below using, for example, string interpolation, we would - // include extra calls to the Dart runtime that could also trigger a stack - // overflow. This approach here is simpler than making the compiler smart - // about how to generate traceHelper calls more carefully. - JS( - '', - r''' - (function (id, name) { - var hook = self.dartCallInstrumentation; - if (typeof hook === "function") { - hook(id, name); - return; - } - if (!this.callInstrumentationCache) { - this.callInstrumentationCache = Object.create(null); - } - if (!this.callInstrumentationCache[id]) { - console.log(id, name); - this.callInstrumentationCache[id] = true; - } - })(#, #)''', - id, - qualifiedName); -} - -class JSInvocationMirror implements Invocation { - static const METHOD = 0; - static const GETTER = 1; - static const SETTER = 2; - - /// When [_memberName] is a String, it holds the mangled name of this - /// invocation. When it is a Symbol, it holds the unmangled name. - var /* String or Symbol */ _memberName; - final String _internalName; - final int _kind; - final List _arguments; - final List _namedArgumentNames; - final int _typeArgumentCount; - - JSInvocationMirror(this._memberName, this._internalName, this._kind, - this._arguments, this._namedArgumentNames, this._typeArgumentCount); - - Symbol get memberName { - if (_memberName is Symbol) return _memberName; - return _memberName = new _symbol_dev.Symbol.unvalidated(_memberName); - } - - bool get isMethod => _kind == METHOD; - bool get isGetter => _kind == GETTER; - bool get isSetter => _kind == SETTER; - bool get isAccessor => _kind != METHOD; - - List get typeArguments { - if (_typeArgumentCount == 0) return const []; - int start = _arguments.length - _typeArgumentCount; - var list = []; - for (int index = 0; index < _typeArgumentCount; index++) { - list.add(newRti.createRuntimeType(_arguments[start + index])); - } - return JSArray.markUnmodifiableList(list); - } - - List get positionalArguments { - if (isGetter) return const []; - var argumentCount = - _arguments.length - _namedArgumentNames.length - _typeArgumentCount; - if (argumentCount == 0) return const []; - var list = []; - for (var index = 0; index < argumentCount; index++) { - list.add(_arguments[index]); - } - return JSArray.markUnmodifiableList(list); - } - - Map get namedArguments { - if (isAccessor) return const {}; - int namedArgumentCount = _namedArgumentNames.length; - int namedArgumentsStartIndex = - _arguments.length - namedArgumentCount - _typeArgumentCount; - if (namedArgumentCount == 0) return const {}; - var map = new Map(); - for (int i = 0; i < namedArgumentCount; i++) { - map[new _symbol_dev.Symbol.unvalidated(_namedArgumentNames[i])] = - _arguments[namedArgumentsStartIndex + i]; - } - return new ConstantMapView(map); - } -} - -class Primitives { - static int objectHashCode(object) { - int? hash = JS('int|Null', r'#.$identityHash', object); - if (hash == null) { - hash = JS('int', '(Math.random() * 0x3fffffff) | 0'); - JS('void', r'#.$identityHash = #', object, hash); - } - return JS('int', '#', hash); - } - - static int? parseInt(String source, int? radix) { - checkString(source); - var re = JS('', r'/^\s*[+-]?((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$/i'); - var match = JS('JSExtendableArray|Null', '#.exec(#)', re, source); - int digitsIndex = 1; - int hexIndex = 2; - int decimalIndex = 3; - if (match == null) { - // TODO(sra): It might be that the match failed due to unrecognized U+0085 - // spaces. We could replace them with U+0020 spaces and try matching - // again. - return null; - } - Object? decimalMatch = match[decimalIndex]; - if (radix == null) { - if (decimalMatch != null) { - // Cannot fail because we know that the digits are all decimal. - return JS('int', r'parseInt(#, 10)', source); - } - if (match[hexIndex] != null) { - // Cannot fail because we know that the digits are all hex. - return JS('int', r'parseInt(#, 16)', source); - } - return null; - } - - if (radix is! int) { - throw new ArgumentError.value(radix, 'radix', 'is not an integer'); - } - if (radix < 2 || radix > 36) { - throw new RangeError.range(radix, 2, 36, 'radix'); - } - if (radix == 10 && decimalMatch != null) { - // Cannot fail because we know that the digits are all decimal. - return JS('int', r'parseInt(#, 10)', source); - } - // If radix >= 10 and we have only decimal digits the string is safe. - // Otherwise we need to check the digits. - if (radix < 10 || decimalMatch == null) { - // We know that the characters must be ASCII as otherwise the - // regexp wouldn't have matched. Lowercasing by doing `| 0x20` is thus - // guaranteed to be a safe operation, since it preserves digits - // and lower-cases ASCII letters. - int maxCharCode; - if (radix <= 10) { - // Allow all digits less than the radix. For example 0, 1, 2 for - // radix 3. - // "0".codeUnitAt(0) + radix - 1; - maxCharCode = (0x30 - 1) + radix; - } else { - // Letters are located after the digits in ASCII. Therefore we - // only check for the character code. The regexp above made already - // sure that the string does not contain anything but digits or - // letters. - // "a".codeUnitAt(0) + (radix - 10) - 1; - maxCharCode = (0x61 - 10 - 1) + radix; - } - assert(match[digitsIndex] is String); - String digitsPart = JS('String', '#[#]', match, digitsIndex); - for (int i = 0; i < digitsPart.length; i++) { - int characterCode = digitsPart.codeUnitAt(i) | 0x20; - if (characterCode > maxCharCode) { - return null; - } - } - } - // The above matching and checks ensures the source has at least one digits - // and all digits are suitable for the radix, so parseInt cannot return NaN. - return JS('int', r'parseInt(#, #)', source, radix); - } - - static double? parseDouble(String source) { - checkString(source); - // Notice that JS parseFloat accepts garbage at the end of the string. - // Accept only: - // - [+/-]NaN - // - [+/-]Infinity - // - a Dart double literal - // We do allow leading or trailing whitespace. - if (!JS( - 'bool', - r'/^\s*[+-]?(?:Infinity|NaN|' - r'(?:\.\d+|\d+(?:\.\d*)?)(?:[eE][+-]?\d+)?)\s*$/.test(#)', - source)) { - return null; - } - var result = JS('num', r'parseFloat(#)', source); - if (result.isNaN) { - var trimmed = source.trim(); - if (trimmed == 'NaN' || trimmed == '+NaN' || trimmed == '-NaN') { - return result; - } - return null; - } - return result; - } - - /// [: r"$".codeUnitAt(0) :] - static const int DOLLAR_CHAR_VALUE = 36; - - /// Returns the type of [object] as a string (including type arguments). - /// Tries to return a sensible name for non-Dart objects. - /// - /// In minified mode, uses the unminified names if available, otherwise tags - /// them with 'minified:'. - @pragma('dart2js:noInline') - static String objectTypeName(Object object) { - return _objectTypeNameNewRti(object); - } - - static String _objectClassName(Object object) { - var interceptor = getInterceptor(object); - // The interceptor is either an object (self-intercepting plain Dart class), - // the prototype of the constructor for an Interceptor class (like - // `JSString.prototype`, `JSNull.prototype`), or an Interceptor object - // instance (`const JSString()`, should use `JSString.prototype`). - // - // These all should have a `constructor` property with a `name` property. - String? name; - var interceptorConstructor = JS('', '#.constructor', interceptor); - if (JS('bool', 'typeof # == "function"', interceptorConstructor)) { - var interceptorConstructorName = JS('', '#.name', interceptorConstructor); - if (interceptorConstructorName is String) { - name = interceptorConstructorName; - } - } - - if (name == null || - identical(interceptor, JS_INTERCEPTOR_CONSTANT(Interceptor)) || - object is UnknownJavaScriptObject) { - // Try to do better. If we do not find something better, leave the name - // as 'UnknownJavaScriptObject' or 'Interceptor' (or the minified name). - // - // When we get here via the UnknownJavaScriptObject test (for JavaScript - // objects from outside the program), the object's constructor has a - // better name that 'UnknownJavaScriptObject'. - // - // When we get here the Interceptor test (for Native classes that are - // declared in the Dart program but have been 'folded' into Interceptor), - // the native class's constructor name is better than the generic - // 'Interceptor' (an abstract class). - - // Try the [constructorNameFallback]. This gets the constructor name for - // any browser (used by [getNativeInterceptor]). - String dispatchName = constructorNameFallback(object); - name ??= dispatchName; - if (dispatchName == 'Object') { - // Try to decompile the constructor by turning it into a string and get - // the name out of that. If the decompiled name is a string containing - // an identifier, we use that instead of the very generic 'Object'. - var objectConstructor = JS('', '#.constructor', object); - if (JS('bool', 'typeof # == "function"', objectConstructor)) { - var match = JS('var', r'#.match(/^\s*function\s*([\w$]*)\s*\(/)', - JS('var', r'String(#)', objectConstructor)); - var decompiledName = match == null ? null : JS('var', r'#[1]', match); - if (decompiledName is String && - JS('bool', r'/^\w+$/.test(#)', decompiledName)) { - name = decompiledName; - } - } - } - return JS('String', '#', name); - } - - // Type inference does not understand that [name] is now always a non-null - // String. (There is some imprecision in the negation of the disjunction.) - name = JS('String', '#', name); - - // TODO(kasperl): If the namer gave us a fresh global name, we may - // want to remove the numeric suffix that makes it unique too. - if (name.length > 1 && identical(name.codeUnitAt(0), DOLLAR_CHAR_VALUE)) { - name = name.substring(1); - } - return unminifyOrTag(name); - } - - /// Returns the type of [object] as a string (including type arguments). - /// Tries to return a sensible name for non-Dart objects. - /// - /// In minified mode, uses the unminified names if available, otherwise tags - /// them with 'minified:'. - static String _objectTypeNameNewRti(Object object) { - var dartObjectConstructor = JS_BUILTIN( - 'depends:none;effects:none;', JsBuiltin.dartObjectConstructor); - if (JS('bool', '# instanceof #', object, dartObjectConstructor)) { - return newRti.instanceTypeName(object); - } - - var interceptor = getInterceptor(object); - if (identical(interceptor, JS_INTERCEPTOR_CONSTANT(Interceptor)) || - object is UnknownJavaScriptObject) { - // Try to do better. If we do not find something better, fallthrough to - // Dart-type based name that leave the name as 'UnknownJavaScriptObject' - // or 'Interceptor' (or the minified versions thereof). - // - // When we get here via the UnknownJavaScriptObject test (for JavaScript - // objects from outside the program), the object's constructor has a - // better name that 'UnknownJavaScriptObject'. - // - // When we get here the Interceptor test (for Native classes that are - // declared in the Dart program but have been 'folded' into Interceptor), - // the native class's constructor name is better than the generic - // 'Interceptor' (an abstract class). - - // Try the [constructorNameFallback]. This gets the constructor name for - // any browser (used by [getNativeInterceptor]). - String dispatchName = constructorNameFallback(object); - if (_saneNativeClassName(dispatchName)) return dispatchName; - var constructor = JS('', '#.constructor', object); - if (JS('bool', 'typeof # == "function"', constructor)) { - var constructorName = JS('', '#.name', constructor); - if (constructorName is String && - _saneNativeClassName(constructorName)) { - return constructorName; - } - } - } - - return newRti.instanceTypeName(object); - } - - static bool _saneNativeClassName(name) => - name != null && name != 'Object' && name != ''; - - /// In minified mode, uses the unminified names if available. - static String objectToHumanReadableString(Object object) { - String name = objectTypeName(object); - return "Instance of '$name'"; - } - - static int dateNow() => JS('int', r'Date.now()'); - - static void initTicker() { - if (timerFrequency != 0) return; - // Start with low-resolution. We overwrite the fields if we find better. - timerFrequency = 1000; - if (JS('bool', 'typeof window == "undefined"')) return; - var window = JS('var', 'window'); - if (window == null) return; - var performance = JS('var', '#.performance', window); - if (performance == null) return; - if (JS('bool', 'typeof #.now != "function"', performance)) return; - timerFrequency = 1000000; - timerTicks = () => (1000 * JS('num', '#.now()', performance)).floor(); - } - - static int timerFrequency = 0; - static int Function() timerTicks = dateNow; // Low-resolution version. - - static String? currentUri() { - requiresPreamble(); - // In a browser return self.location.href. - if (JS('bool', '!!self.location')) { - return JS('String', 'self.location.href'); - } - - return null; - } - - /// Version of `String.fromCharCode.apply` that chunks the conversion to avoid - /// stack overflows due to very large argument arrays. - /// - /// [array] is pre-validated as a JSArray of int values but is not typed as - /// so it can be called with any JSArray. - static String _fromCharCodeApply(List array) { - const kMaxApply = 500; - int end = array.length; - if (end <= kMaxApply) { - return JS('String', r'String.fromCharCode.apply(null, #)', array); - } - String result = ''; - for (int i = 0; i < end; i += kMaxApply) { - int chunkEnd = (i + kMaxApply < end) ? i + kMaxApply : end; - result = JS( - 'String', - r'# + String.fromCharCode.apply(null, #.slice(#, #))', - result, - array, - i, - chunkEnd); - } - return result; - } - - static String stringFromCodePoints(codePoints) { - List a = []; - for (var i in codePoints) { - if (i is! int) throw argumentErrorValue(i); - if (i <= 0xffff) { - a.add(i); - } else if (i <= 0x10ffff) { - a.add(0xd800 + ((((i - 0x10000) >> 10) & 0x3ff))); - a.add(0xdc00 + (i & 0x3ff)); - } else { - throw argumentErrorValue(i); - } - } - return _fromCharCodeApply(a); - } - - static String stringFromCharCodes(charCodes) { - for (var i in charCodes) { - if (i is! int) throw argumentErrorValue(i); - if (i < 0) throw argumentErrorValue(i); - if (i > 0xffff) return stringFromCodePoints(charCodes); - } - return _fromCharCodeApply(charCodes); - } - - // [start] and [end] are validated. - static String stringFromNativeUint8List( - NativeUint8List charCodes, int start, int end) { - const kMaxApply = 500; - if (end <= kMaxApply && start == 0 && end == charCodes.length) { - return JS('String', r'String.fromCharCode.apply(null, #)', charCodes); - } - String result = ''; - for (int i = start; i < end; i += kMaxApply) { - int chunkEnd = (i + kMaxApply < end) ? i + kMaxApply : end; - result = JS( - 'String', - r'# + String.fromCharCode.apply(null, #.subarray(#, #))', - result, - charCodes, - i, - chunkEnd); - } - return result; - } - - static String stringFromCharCode(charCode) { - if (0 <= charCode) { - if (charCode <= 0xffff) { - return JS('returns:String;effects:none;depends:none', - 'String.fromCharCode(#)', charCode); - } - if (charCode <= 0x10ffff) { - var bits = charCode - 0x10000; - var low = 0xDC00 | (bits & 0x3ff); - var high = 0xD800 | (bits >> 10); - return JS('returns:String;effects:none;depends:none', - 'String.fromCharCode(#, #)', high, low); - } - } - throw new RangeError.range(charCode, 0, 0x10ffff); - } - - static String stringConcatUnchecked(String string1, String string2) { - return JS_STRING_CONCAT(string1, string2); - } - - static String flattenString(String str) { - return JS('returns:String;depends:none;effects:none;throws:never;gvn:true', - '#.charCodeAt(0) == 0 ? # : #', str, str, str); - } - - static String getTimeZoneName(DateTime receiver) { - // Firefox and Chrome emit the timezone in parenthesis. - // Example: "Wed May 16 2012 21:13:00 GMT+0200 (CEST)". - // We extract this name using a regexp. - var d = lazyAsJsDate(receiver); - List? match = JS('JSArray|Null', r'/\((.*)\)/.exec(#.toString())', d); - if (match != null) return match[1]; - - // Internet Explorer 10+ emits the zone name without parenthesis: - // Example: Thu Oct 31 14:07:44 PDT 2013 - match = JS( - 'JSArray|Null', - // Thu followed by a space. - r'/^[A-Z,a-z]{3}\s' - // Oct 31 followed by space. - r'[A-Z,a-z]{3}\s\d+\s' - // Time followed by a space. - r'\d{2}:\d{2}:\d{2}\s' - // The time zone name followed by a space. - r'([A-Z]{3,5})\s' - // The year. - r'\d{4}$/' - '.exec(#.toString())', - d); - if (match != null) return match[1]; - - // IE 9 and Opera don't provide the zone name. We fall back to emitting the - // UTC/GMT offset. - // Example (IE9): Wed Nov 20 09:51:00 UTC+0100 2013 - // (Opera): Wed Nov 20 2013 11:03:38 GMT+0100 - match = JS('JSArray|Null', r'/(?:GMT|UTC)[+-]\d{4}/.exec(#.toString())', d); - if (match != null) return match[0]; - return ''; - } - - static int getTimeZoneOffsetInMinutes(DateTime receiver) { - // Note that JS and Dart disagree on the sign of the offset. - // Subtract to avoid -0.0 - return 0 - JS('int', r'#.getTimezoneOffset()', lazyAsJsDate(receiver)) - as int; - } - - static int? valueFromDecomposedDate( - years, month, day, hours, minutes, seconds, milliseconds, isUtc) { - final int MAX_MILLISECONDS_SINCE_EPOCH = 8640000000000000; - checkInt(years); - checkInt(month); - checkInt(day); - checkInt(hours); - checkInt(minutes); - checkInt(seconds); - checkInt(milliseconds); - checkBool(isUtc); - var jsMonth = month - 1; - // The JavaScript Date constructor 'corrects' year NN to 19NN. Sidestep that - // correction by adjusting years out of that range and compensating with an - // adjustment of months. This hack should not be sensitive to leap years but - // use 400 just in case. - if (0 <= years && years < 100) { - years += 400; - jsMonth -= 400 * 12; - } - var value; - if (isUtc) { - value = JS('num', r'Date.UTC(#, #, #, #, #, #, #)', years, jsMonth, day, - hours, minutes, seconds, milliseconds); - } else { - value = JS('num', r'new Date(#, #, #, #, #, #, #).valueOf()', years, - jsMonth, day, hours, minutes, seconds, milliseconds); - } - if (value.isNaN || - value < -MAX_MILLISECONDS_SINCE_EPOCH || - value > MAX_MILLISECONDS_SINCE_EPOCH) { - return null; - } - return JS('int', '#', value); - } - - // Lazily keep a JS Date stored in the JS object. - static lazyAsJsDate(DateTime receiver) { - if (JS('bool', r'#.date === (void 0)', receiver)) { - JS('void', r'#.date = new Date(#)', receiver, - receiver.millisecondsSinceEpoch); - } - return JS('var', r'#.date', receiver); - } - - // The getters for date and time parts below add a positive integer to ensure - // that the result is really an integer, because the JavaScript implementation - // may return -0.0 instead of 0. - // - // They are marked as @pragma('dart2js:noThrows') because `receiver` comes from a receiver of - // a method on DateTime (i.e. is not `null`). - - // TODO(sra): These methods are GVN-able. dart2js should implement an - // annotation for that. - - // TODO(sra): These methods often occur in groups (e.g. day, month and - // year). Is it possible to factor them so that the `Date` is visible and can - // be GVN-ed without a lot of code bloat? - - @pragma('dart2js:noSideEffects') - @pragma('dart2js:noThrows') - @pragma('dart2js:noInline') - static getYear(DateTime receiver) { - return (receiver.isUtc) - ? JS('int', r'(#.getUTCFullYear() + 0)', lazyAsJsDate(receiver)) - : JS('int', r'(#.getFullYear() + 0)', lazyAsJsDate(receiver)); - } - - @pragma('dart2js:noSideEffects') - @pragma('dart2js:noThrows') - @pragma('dart2js:noInline') - static getMonth(DateTime receiver) { - return (receiver.isUtc) - ? JS('JSUInt31', r'#.getUTCMonth() + 1', lazyAsJsDate(receiver)) - : JS('JSUInt31', r'#.getMonth() + 1', lazyAsJsDate(receiver)); - } - - @pragma('dart2js:noSideEffects') - @pragma('dart2js:noThrows') - @pragma('dart2js:noInline') - static getDay(DateTime receiver) { - return (receiver.isUtc) - ? JS('JSUInt31', r'(#.getUTCDate() + 0)', lazyAsJsDate(receiver)) - : JS('JSUInt31', r'(#.getDate() + 0)', lazyAsJsDate(receiver)); - } - - @pragma('dart2js:noSideEffects') - @pragma('dart2js:noThrows') - @pragma('dart2js:noInline') - static getHours(DateTime receiver) { - return (receiver.isUtc) - ? JS('JSUInt31', r'(#.getUTCHours() + 0)', lazyAsJsDate(receiver)) - : JS('JSUInt31', r'(#.getHours() + 0)', lazyAsJsDate(receiver)); - } - - @pragma('dart2js:noSideEffects') - @pragma('dart2js:noThrows') - @pragma('dart2js:noInline') - static getMinutes(DateTime receiver) { - return (receiver.isUtc) - ? JS('JSUInt31', r'(#.getUTCMinutes() + 0)', lazyAsJsDate(receiver)) - : JS('JSUInt31', r'(#.getMinutes() + 0)', lazyAsJsDate(receiver)); - } - - @pragma('dart2js:noSideEffects') - @pragma('dart2js:noThrows') - @pragma('dart2js:noInline') - static getSeconds(DateTime receiver) { - return (receiver.isUtc) - ? JS('JSUInt31', r'(#.getUTCSeconds() + 0)', lazyAsJsDate(receiver)) - : JS('JSUInt31', r'(#.getSeconds() + 0)', lazyAsJsDate(receiver)); - } - - @pragma('dart2js:noSideEffects') - @pragma('dart2js:noThrows') - @pragma('dart2js:noInline') - static getMilliseconds(DateTime receiver) { - return (receiver.isUtc) - ? JS( - 'JSUInt31', r'(#.getUTCMilliseconds() + 0)', lazyAsJsDate(receiver)) - : JS('JSUInt31', r'(#.getMilliseconds() + 0)', lazyAsJsDate(receiver)); - } - - @pragma('dart2js:noSideEffects') - @pragma('dart2js:noThrows') - @pragma('dart2js:noInline') - static getWeekday(DateTime receiver) { - int weekday = (receiver.isUtc) - ? JS('int', r'#.getUTCDay() + 0', lazyAsJsDate(receiver)) - : JS('int', r'#.getDay() + 0', lazyAsJsDate(receiver)); - // Adjust by one because JS weeks start on Sunday. - return (weekday + 6) % 7 + 1; - } - - static valueFromDateString(str) { - if (str is! String) throw argumentErrorValue(str); - var value = JS('num', r'Date.parse(#)', str); - if (value.isNaN) throw argumentErrorValue(str); - return value; - } - - static getProperty(object, key) { - if (object == null || object is bool || object is num || object is String) { - throw argumentErrorValue(object); - } - return JS('var', '#[#]', object, key); - } - - static void setProperty(object, key, value) { - if (object == null || object is bool || object is num || object is String) { - throw argumentErrorValue(object); - } - JS('void', '#[#] = #', object, key, value); - } - - static functionNoSuchMethod(function, List? positionalArguments, - Map? namedArguments) { - int argumentCount = 0; - List arguments = []; - List namedArgumentList = []; - - if (positionalArguments != null) { - argumentCount += positionalArguments.length; - arguments.addAll(positionalArguments); - } - - String names = ''; - if (namedArguments != null && !namedArguments.isEmpty) { - namedArguments.forEach((String name, argument) { - names = '$names\$$name'; - namedArgumentList.add(name); - arguments.add(argument); - argumentCount++; - }); - } - - String selectorName = - '${JS_GET_NAME(JsGetName.CALL_PREFIX)}\$$argumentCount$names'; - - return function.noSuchMethod(createUnmangledInvocationMirror( - #call, - selectorName, - JSInvocationMirror.METHOD, - arguments, - namedArgumentList, - 0)); - } - - /// Implements [Function.apply] for the lazy and startup emitters. - /// - /// There are two types of closures that can reach this function: - /// - /// 1. tear-offs (including tear-offs of static functions). - /// 2. anonymous closures. - /// - /// They are treated differently (although there are lots of similarities). - /// Both have in common that they have - /// a [JsGetName.CALL_CATCH_ALL] and - /// a [JsGetName.REQUIRED_PARAMETER_PROPERTY] property. - /// - /// If the closure supports optional parameters, then they also feature - /// a [JsGetName.DEFAULT_VALUES_PROPERTY] property. - /// - /// The catch-all property is a method that takes all arguments (including - /// all optional positional or named arguments). If the function accepts - /// optional arguments, then the default-values property stores (potentially - /// wrapped in a function) the default values for the optional arguments. If - /// the function accepts optional positional arguments, then the value is a - /// JavaScript array with the default values. Otherwise, when the function - /// accepts optional named arguments, it is a JavaScript object. - /// - /// The default-values property may either contain the value directly, or - /// it can be a function that returns the default-values when invoked. - /// - /// If the function is an anonymous closure, then the catch-all property - /// only contains a string pointing to the property that should be used - /// instead. For example, if the catch-all property contains the string - /// "call$4", then the object's "call$4" property should be used as if it was - /// the value of the catch-all property. - static applyFunction(Function function, List? positionalArguments, - Map? namedArguments) { - // Fast shortcut for the common case. - if (JS('bool', '# instanceof Array', positionalArguments) && - (namedArguments == null || namedArguments.isEmpty)) { - // Let the compiler know that we did a type-test. - List arguments = (JS('JSArray', '#', positionalArguments)); - int argumentCount = arguments.length; - if (argumentCount == 0) { - String selectorName = JS_GET_NAME(JsGetName.CALL_PREFIX0); - if (JS('bool', '!!#[#]', function, selectorName)) { - return JS('', '#[#]()', function, selectorName); - } - } else if (argumentCount == 1) { - String selectorName = JS_GET_NAME(JsGetName.CALL_PREFIX1); - if (JS('bool', '!!#[#]', function, selectorName)) { - return JS('', '#[#](#[0])', function, selectorName, arguments); - } - } else if (argumentCount == 2) { - String selectorName = JS_GET_NAME(JsGetName.CALL_PREFIX2); - if (JS('bool', '!!#[#]', function, selectorName)) { - return JS('', '#[#](#[0],#[1])', function, selectorName, arguments, - arguments); - } - } else if (argumentCount == 3) { - String selectorName = JS_GET_NAME(JsGetName.CALL_PREFIX3); - if (JS('bool', '!!#[#]', function, selectorName)) { - return JS('', '#[#](#[0],#[1],#[2])', function, selectorName, - arguments, arguments, arguments); - } - } else if (argumentCount == 4) { - String selectorName = JS_GET_NAME(JsGetName.CALL_PREFIX4); - if (JS('bool', '!!#[#]', function, selectorName)) { - return JS('', '#[#](#[0],#[1],#[2],#[3])', function, selectorName, - arguments, arguments, arguments, arguments); - } - } else if (argumentCount == 5) { - String selectorName = JS_GET_NAME(JsGetName.CALL_PREFIX5); - if (JS('bool', '!!#[#]', function, selectorName)) { - return JS( - '', - '#[#](#[0],#[1],#[2],#[3],#[4])', - function, - selectorName, - arguments, - arguments, - arguments, - arguments, - arguments); - } - } - String selectorName = - '${JS_GET_NAME(JsGetName.CALL_PREFIX)}\$$argumentCount'; - var jsStub = JS('var', r'#[#]', function, selectorName); - if (jsStub != null) { - return JS('var', '#.apply(#, #)', jsStub, function, arguments); - } - } - - return _genericApplyFunction2( - function, positionalArguments, namedArguments); - } - - static _genericApplyFunction2(Function function, List? positionalArguments, - Map? namedArguments) { - List arguments; - if (positionalArguments != null) { - if (JS('bool', '# instanceof Array', positionalArguments)) { - arguments = JS('JSArray', '#', positionalArguments); - } else { - arguments = new List.from(positionalArguments); - } - } else { - arguments = []; - } - - int argumentCount = arguments.length; - - int requiredParameterCount = JS('int', r'#[#]', function, - JS_GET_NAME(JsGetName.REQUIRED_PARAMETER_PROPERTY)); - - if (argumentCount < requiredParameterCount) { - return functionNoSuchMethod(function, arguments, namedArguments); - } - - var defaultValuesClosure = JS('var', r'#[#]', function, - JS_GET_NAME(JsGetName.DEFAULT_VALUES_PROPERTY)); - - bool acceptsOptionalArguments = defaultValuesClosure != null; - - // Default values are stored inside a JavaScript closure to avoid - // accessing them too early. - var defaultValues = - acceptsOptionalArguments ? JS('', '#()', defaultValuesClosure) : null; - - var interceptor = getInterceptor(function); - var jsFunction = - JS('', '#[#]', interceptor, JS_GET_NAME(JsGetName.CALL_CATCH_ALL)); - if (jsFunction is String) { - // Anonymous closures redirect to the catch-all property instead of - // storing the catch-all method directly in the catch-all property. - jsFunction = JS('', '#[#]', interceptor, jsFunction); - } - - if (!acceptsOptionalArguments) { - if (namedArguments != null && namedArguments.isNotEmpty) { - // Tried to invoke a function that takes a fixed number of arguments - // with named (optional) arguments. - return functionNoSuchMethod(function, arguments, namedArguments); - } - if (argumentCount == requiredParameterCount) { - return JS('var', r'#.apply(#, #)', jsFunction, function, arguments); - } - return functionNoSuchMethod(function, arguments, namedArguments); - } - - bool acceptsPositionalArguments = - JS('bool', '# instanceof Array', defaultValues); - - if (acceptsPositionalArguments) { - if (namedArguments != null && namedArguments.isNotEmpty) { - // Tried to invoke a function that takes optional positional arguments - // with named arguments. - return functionNoSuchMethod(function, arguments, namedArguments); - } - - int defaultsLength = JS('int', '#.length', defaultValues); - int maxArguments = requiredParameterCount + defaultsLength; - if (argumentCount > maxArguments) { - // The function expects fewer arguments. - return functionNoSuchMethod(function, arguments, null); - } - List missingDefaults = JS('JSArray', '#.slice(#)', defaultValues, - argumentCount - requiredParameterCount); - arguments.addAll(missingDefaults); - return JS('var', '#.apply(#, #)', jsFunction, function, arguments); - } else { - // Handle named arguments. - - if (argumentCount > requiredParameterCount) { - // Tried to invoke a function that takes named parameters with - // too many positional arguments. - return functionNoSuchMethod(function, arguments, namedArguments); - } - - List keys = JS('JSArray', r'Object.keys(#)', defaultValues); - if (namedArguments == null) { - for (String key in keys) { - var defaultValue = JS('var', '#[#]', defaultValues, key); - if (isRequired(defaultValue)) { - return functionNoSuchMethod(function, arguments, namedArguments); - } - arguments.add(defaultValue); - } - } else { - int used = 0; - for (String key in keys) { - if (namedArguments.containsKey(key)) { - used++; - arguments.add(namedArguments[key]); - } else { - var defaultValue = JS('var', '#[#]', defaultValues, key); - if (isRequired(defaultValue)) { - return functionNoSuchMethod(function, arguments, namedArguments); - } - arguments.add(defaultValue); - } - } - if (used != namedArguments.length) { - return functionNoSuchMethod(function, arguments, namedArguments); - } - } - return JS('var', r'#.apply(#, #)', jsFunction, function, arguments); - } - } - - static StackTrace extractStackTrace(Error error) { - return getTraceFromException(JS('', r'#.$thrownJsError', error)); - } -} - -/// Helper class for allocating and using JS object literals as caches. -class JsCache { - /// Returns a JavaScript object suitable for use as a cache. - static allocate() { - var result = JS('=Object', 'Object.create(null)'); - // Deleting a property makes V8 assume that it shouldn't create a hidden - // class for [result] and map transitions. Although these map transitions - // pay off if there are many cache hits for the same keys, it becomes - // really slow when there aren't many repeated hits. - JS('void', '#.x=0', result); - JS('void', 'delete #.x', result); - return result; - } - - static fetch(cache, String key) { - return JS('', '#[#]', cache, key); - } - - static void update(cache, String key, value) { - JS('void', '#[#] = #', cache, key, value); - } -} - -/// Called by generated code to throw an illegal-argument exception, -/// for example, if a non-integer index is given to an optimized -/// indexed access. -@pragma('dart2js:noInline') -iae(argument) { - throw argumentErrorValue(argument); -} - -/// Called by generated code to throw an index-out-of-range exception, for -/// example, if a bounds check fails in an optimized indexed access. This may -/// also be called when the index is not an integer, in which case it throws an -/// illegal-argument exception instead, like [iae], or when the receiver is -/// null. -@pragma('dart2js:noInline') -ioore(receiver, index) { - if (receiver == null) receiver.length; // Force a NoSuchMethodError. - throw diagnoseIndexError(receiver, index); -} - -/// Diagnoses an indexing error. Returns the ArgumentError or RangeError that -/// describes the problem. -@pragma('dart2js:noInline') -Error diagnoseIndexError(indexable, index) { - if (index is! int) return new ArgumentError.value(index, 'index'); - int length = indexable.length; - // The following returns the same error that would be thrown by calling - // [RangeError.checkValidIndex] with no optional parameters provided. - if (index < 0 || index >= length) { - return new RangeError.index(index, indexable, 'index', null, length); - } - // The above should always match, but if it does not, use the following. - return new RangeError.value(index, 'index'); -} - -/// Diagnoses a range error. Returns the ArgumentError or RangeError that -/// describes the problem. -@pragma('dart2js:noInline') -Error diagnoseRangeError(start, end, length) { - if (start is! int) { - return new ArgumentError.value(start, 'start'); - } - if (start < 0 || start > length) { - return new RangeError.range(start, 0, length, 'start'); - } - if (end != null) { - if (end is! int) { - return new ArgumentError.value(end, 'end'); - } - if (end < start || end > length) { - return new RangeError.range(end, start, length, 'end'); - } - } - // The above should always match, but if it does not, use the following. - return new ArgumentError.value(end, 'end'); -} - -stringLastIndexOfUnchecked(receiver, element, start) => - JS('int', r'#.lastIndexOf(#, #)', receiver, element, start); - -/// 'factory' for constructing ArgumentError.value to keep the call sites small. -@pragma('dart2js:noInline') -ArgumentError argumentErrorValue(object) { - return new ArgumentError.value(object); -} - -checkNull(object) { - if (object == null) throw argumentErrorValue(object); - return object; -} - -@pragma('dart2js:noInline') -num checkNum(value) { - if (value is! num) throw argumentErrorValue(value); - return value; -} - -int checkInt(value) { - if (value is! int) throw argumentErrorValue(value); - return value; -} - -bool checkBool(value) { - if (value is! bool) throw argumentErrorValue(value); - return value; -} - -String checkString(value) { - if (value is! String) throw argumentErrorValue(value); - return value; -} - -/// Wrap the given Dart object and record a stack trace. -/// -/// The code in [unwrapException] deals with getting the original Dart -/// object out of the wrapper again. -@pragma('dart2js:noInline') -wrapException(ex) { - if (ex == null) ex = new NullThrownError(); - var wrapper = JS('', 'new Error()'); - // [unwrapException] looks for the property 'dartException'. - JS('void', '#.dartException = #', wrapper, ex); - - if (JS('bool', '"defineProperty" in Object')) { - // Define a JavaScript getter for 'message'. This is to work around V8 bug - // (https://code.google.com/p/v8/issues/detail?id=2519). The default - // toString on Error returns the value of 'message' if 'name' is - // empty. Setting toString directly doesn't work, see the bug. - JS('void', 'Object.defineProperty(#, "message", { get: # })', wrapper, - DART_CLOSURE_TO_JS(toStringWrapper)); - JS('void', '#.name = ""', wrapper); - } else { - // In the unlikely event the browser doesn't support Object.defineProperty, - // hope that it just calls toString. - JS('void', '#.toString = #', wrapper, DART_CLOSURE_TO_JS(toStringWrapper)); - } - - return wrapper; -} - -/// Do not call directly. -toStringWrapper() { - // This method gets installed as toString on a JavaScript object. Due to the - // weird scope rules of JavaScript, JS 'this' will refer to that object. - return JS('', r'this.dartException').toString(); -} - -/// This wraps the exception and does the throw. It is possible to call this in -/// a JS expression context, where the throw statement is not allowed. Helpers -/// are never inlined, so we don't risk inlining the throw statement into an -/// expression context. -throwExpression(ex) { - JS('void', 'throw #', wrapException(ex)); -} - -throwRuntimeError(message) { - throw new RuntimeError(message); -} - -throwUnsupportedError(message) { - throw new UnsupportedError(message); -} - -throwAbstractClassInstantiationError(className) { - throw new AbstractClassInstantiationError(className); -} - -// This is used in open coded for-in loops on arrays. -// -// checkConcurrentModificationError(a.length == startLength, a) -// -// is replaced in codegen by: -// -// a.length == startLength || throwConcurrentModificationError(a) -// -// TODO(sra): We would like to annotate this as @pragma('dart2js:noSideEffects') so that loops -// with no other effects can recognize that the array length does not -// change. However, in the usual case where the loop does have other effects, -// that causes the length in the loop condition to be phi(startLength,a.length), -// which causes confusion in range analysis and the insertion of a bounds check. -@pragma('dart2js:noInline') -checkConcurrentModificationError(sameLength, collection) { - if (true != sameLength) { - throwConcurrentModificationError(collection); - } -} - -@pragma('dart2js:noInline') -throwConcurrentModificationError(collection) { - throw new ConcurrentModificationError(collection); -} - -/// Helper class for building patterns recognizing native type errors. -class TypeErrorDecoder { - // Field names are private to help tree-shaking. - - /// A regular expression which matches is matched against an error message. - final String _pattern; - - /// The group index of "arguments" in [_pattern], or -1 if _pattern has no - /// match for "arguments". - final int _arguments; - - /// The group index of "argumentsExpr" in [_pattern], or -1 if _pattern has - /// no match for "argumentsExpr". - final int _argumentsExpr; - - /// The group index of "expr" in [_pattern], or -1 if _pattern has no match - /// for "expr". - final int _expr; - - /// The group index of "method" in [_pattern], or -1 if _pattern has no match - /// for "method". - final int _method; - - /// The group index of "receiver" in [_pattern], or -1 if _pattern has no - /// match for "receiver". - final int _receiver; - - /// Pattern used to recognize a NoSuchMethodError error (and - /// possibly extract the method name). - static final TypeErrorDecoder noSuchMethodPattern = - extractPattern(provokeCallErrorOn(buildJavaScriptObject())); - - /// Pattern used to recognize an "object not a closure" error (and - /// possibly extract the method name). - static final TypeErrorDecoder notClosurePattern = - extractPattern(provokeCallErrorOn(buildJavaScriptObjectWithNonClosure())); - - /// Pattern used to recognize a NoSuchMethodError on JavaScript null - /// call. - static final TypeErrorDecoder nullCallPattern = - extractPattern(provokeCallErrorOn(JS('', 'null'))); - - /// Pattern used to recognize a NoSuchMethodError on JavaScript literal null - /// call. - static final TypeErrorDecoder nullLiteralCallPattern = - extractPattern(provokeCallErrorOnNull()); - - /// Pattern used to recognize a NoSuchMethodError on JavaScript - /// undefined call. - static final TypeErrorDecoder undefinedCallPattern = - extractPattern(provokeCallErrorOn(JS('', 'void 0'))); - - /// Pattern used to recognize a NoSuchMethodError on JavaScript literal - /// undefined call. - static final TypeErrorDecoder undefinedLiteralCallPattern = - extractPattern(provokeCallErrorOnUndefined()); - - /// Pattern used to recognize a NoSuchMethodError on JavaScript null - /// property access. - static final TypeErrorDecoder nullPropertyPattern = - extractPattern(provokePropertyErrorOn(JS('', 'null'))); - - /// Pattern used to recognize a NoSuchMethodError on JavaScript literal null - /// property access. - static final TypeErrorDecoder nullLiteralPropertyPattern = - extractPattern(provokePropertyErrorOnNull()); - - /// Pattern used to recognize a NoSuchMethodError on JavaScript - /// undefined property access. - static final TypeErrorDecoder undefinedPropertyPattern = - extractPattern(provokePropertyErrorOn(JS('', 'void 0'))); - - /// Pattern used to recognize a NoSuchMethodError on JavaScript literal - /// undefined property access. - static final TypeErrorDecoder undefinedLiteralPropertyPattern = - extractPattern(provokePropertyErrorOnUndefined()); - - TypeErrorDecoder(this._arguments, this._argumentsExpr, this._expr, - this._method, this._receiver, this._pattern); - - /// Returns a JavaScript object literal (map) with at most the - /// following keys: - /// - /// * arguments: The arguments as formatted by the JavaScript - /// engine. No browsers are known to provide this information. - /// - /// * argumentsExpr: The syntax of the arguments (JavaScript source - /// code). No browsers are known to provide this information. - /// - /// * expr: The syntax of the receiver expression (JavaScript source - /// code). Firefox provides this information, for example: "$expr$.$method$ - /// is not a function". - /// - /// * method: The name of the called method (mangled name). At least Firefox - /// and Chrome/V8 provides this information, for example, "Object [object - /// Object] has no method '$method$'". - /// - /// * receiver: The string representation of the receiver. Chrome/V8 - /// used to provide this information (by calling user-defined - /// JavaScript toString on receiver), but it has degenerated into - /// "[object Object]" in recent versions. - matchTypeError(message) { - var match = JS( - 'JSExtendableArray|Null', 'new RegExp(#).exec(#)', _pattern, message); - if (match == null) return null; - var result = JS('', 'Object.create(null)'); - if (_arguments != -1) { - JS('', '#.arguments = #[# + 1]', result, match, _arguments); - } - if (_argumentsExpr != -1) { - JS('', '#.argumentsExpr = #[# + 1]', result, match, _argumentsExpr); - } - if (_expr != -1) { - JS('', '#.expr = #[# + 1]', result, match, _expr); - } - if (_method != -1) { - JS('', '#.method = #[# + 1]', result, match, _method); - } - if (_receiver != -1) { - JS('', '#.receiver = #[# + 1]', result, match, _receiver); - } - - return result; - } - - /// Builds a JavaScript Object with a toString method saying - /// r"$receiver$". - static buildJavaScriptObject() { - return JS('', r'{ toString: function() { return "$receiver$"; } }'); - } - - /// Builds a JavaScript Object with a toString method saying - /// r"$receiver$". The property "$method" is defined, but is not a function. - static buildJavaScriptObjectWithNonClosure() { - return JS( - '', - r'{ $method$: null, ' - r'toString: function() { return "$receiver$"; } }'); - } - - /// Extract a pattern from a JavaScript TypeError message. - /// - /// The patterns are extracted by forcing TypeErrors on known - /// objects thus forcing known strings into the error message. The - /// known strings are then replaced with wildcards which in theory - /// makes it possible to recognize the desired information even if - /// the error messages are reworded or translated. - static extractPattern(String message) { - // Some JavaScript implementations (V8 at least) include a - // representation of the receiver in the error message, however, - // this representation is not always [: receiver.toString() :], - // sometimes it is [: Object.prototype.toString(receiver) :], and - // sometimes it is an implementation specific method (but that - // doesn't seem to happen for object literals). So sometimes we - // get the text "[object Object]". The shortest way to get that - // string is using "String({})". - // See: http://code.google.com/p/v8/issues/detail?id=2519. - message = JS('String', r"#.replace(String({}), '$receiver$')", message); - - // Since we want to create a new regular expression from an unknown string, - // we must escape all regular expression syntax. - message = quoteStringForRegExp(message); - - // Look for the special pattern \$camelCase\$ (all the $ symbols - // have been escaped already), as we will soon be inserting - // regular expression syntax that we want interpreted by RegExp. - List? match = - JS('JSExtendableArray|Null', r'#.match(/\\\$[a-zA-Z]+\\\$/g)', message); - if (match == null) match = []; - - // Find the positions within the substring matches of the error message - // components. This will help us extract information later, such as the - // method name. - int arguments = JS('int', '#.indexOf(#)', match, r'\$arguments\$'); - int argumentsExpr = JS('int', '#.indexOf(#)', match, r'\$argumentsExpr\$'); - int expr = JS('int', '#.indexOf(#)', match, r'\$expr\$'); - int method = JS('int', '#.indexOf(#)', match, r'\$method\$'); - int receiver = JS('int', '#.indexOf(#)', match, r'\$receiver\$'); - - // Replace the patterns with a regular expression wildcard. - // Note: in a perfect world, one would use "(.*)", but not in - // JavaScript, "." does not match newlines. - String pattern = JS( - 'String', - r"#.replace(new RegExp('\\\\\\$arguments\\\\\\$', 'g'), " - r"'((?:x|[^x])*)')" - r".replace(new RegExp('\\\\\\$argumentsExpr\\\\\\$', 'g'), " - r"'((?:x|[^x])*)')" - r".replace(new RegExp('\\\\\\$expr\\\\\\$', 'g'), '((?:x|[^x])*)')" - r".replace(new RegExp('\\\\\\$method\\\\\\$', 'g'), '((?:x|[^x])*)')" - r".replace(new RegExp('\\\\\\$receiver\\\\\\$', 'g'), " - r"'((?:x|[^x])*)')", - message); - - return new TypeErrorDecoder( - arguments, argumentsExpr, expr, method, receiver, pattern); - } - - /// Provokes a TypeError and returns its message. - /// - /// The error is provoked so all known variable content can be recognized and - /// a pattern can be inferred. - static String provokeCallErrorOn(expression) { - // This function is carefully created to maximize the possibility - // of decoding the TypeError message and turning it into a general - // pattern. - // - // The idea is to inject something known into something unknown. The - // unknown entity is the error message that the browser provides with a - // TypeError. It is a human readable message, possibly localized in a - // language no dart2js engineer understand. We assume that $name$ would - // never naturally occur in a human readable error message, yet it is easy - // to decode. - // - // For example, evaluate this in V8 version 3.13.7.6: - // - // var $expr$ = null; $expr$.$method$() - // - // The VM throws an instance of TypeError whose message property contains - // "Cannot call method '$method$' of null". We can then reasonably assume - // that if the string contains $method$, that's where the method name will - // be in general. Call this automatically reverse engineering the error - // format string in V8. - // - // So the error message from V8 is turned into this regular expression: - // - // "Cannot call method '(.*)' of null" - // - // Similarly, if we evaluate: - // - // var $expr$ = {toString: function() { return '$receiver$'; }}; - // $expr$.$method$() - // - // We get this message: "Object $receiver$ has no method '$method$'" - // - // Which is turned into this regular expression: - // - // "Object (.*) has no method '(.*)'" - // - // Firefox/jsshell is slightly different, it tries to include the source - // code that caused the exception, so we get this message: "$expr$.$method$ - // is not a function" which is turned into this regular expression: - // - // "(.*)\\.(.*) is not a function" - - var function = JS('', r"""function($expr$) { - var $argumentsExpr$ = '$arguments$'; - try { - $expr$.$method$($argumentsExpr$); - } catch (e) { - return e.message; - } -}"""); - return JS('String', '(#)(#)', function, expression); - } - - /// Similar to [provokeCallErrorOn], but provokes an error directly on - /// literal "null" expression. - static String provokeCallErrorOnNull() { - // See [provokeCallErrorOn] for a detailed explanation. - var function = JS('', r"""function() { - var $argumentsExpr$ = '$arguments$'; - try { - null.$method$($argumentsExpr$); - } catch (e) { - return e.message; - } -}"""); - return JS('String', '(#)()', function); - } - - /// Similar to [provokeCallErrorOnNull], but provokes an error directly on - /// (void 0), that is, "undefined". - static String provokeCallErrorOnUndefined() { - // See [provokeCallErrorOn] for a detailed explanation. - var function = JS('', r"""function() { - var $argumentsExpr$ = '$arguments$'; - try { - (void 0).$method$($argumentsExpr$); - } catch (e) { - return e.message; - } -}"""); - return JS('String', '(#)()', function); - } - - /// Similar to [provokeCallErrorOn], but provokes a property access - /// error. - static String provokePropertyErrorOn(expression) { - // See [provokeCallErrorOn] for a detailed explanation. - var function = JS('', r"""function($expr$) { - try { - $expr$.$method$; - } catch (e) { - return e.message; - } -}"""); - return JS('String', '(#)(#)', function, expression); - } - - /// Similar to [provokePropertyErrorOn], but provokes an property access - /// error directly on literal "null" expression. - static String provokePropertyErrorOnNull() { - // See [provokeCallErrorOn] for a detailed explanation. - var function = JS('', r"""function() { - try { - null.$method$; - } catch (e) { - return e.message; - } -}"""); - return JS('String', '(#)()', function); - } - - /// Similar to [provokePropertyErrorOnNull], but provokes an property access - /// error directly on (void 0), that is, "undefined". - static String provokePropertyErrorOnUndefined() { - // See [provokeCallErrorOn] for a detailed explanation. - var function = JS('', r"""function() { - try { - (void 0).$method$; - } catch (e) { - return e.message; - } -}"""); - return JS('String', '(#)()', function); - } -} - -class NullError extends Error implements NoSuchMethodError { - final String _message; - final String? _method; - - NullError(this._message, match) - : _method = match == null ? null : JS('', '#.method', match); - - String toString() { - if (_method == null) return 'NoSuchMethodError: $_message'; - return "NoSuchMethodError: method not found: '$_method' on null"; - } -} - -class JsNoSuchMethodError extends Error implements NoSuchMethodError { - final String _message; - final String? _method; - final String? _receiver; - - JsNoSuchMethodError(this._message, match) - : _method = match == null ? null : JS('String|Null', '#.method', match), - _receiver = - match == null ? null : JS('String|Null', '#.receiver', match); - - String toString() { - if (_method == null) return 'NoSuchMethodError: $_message'; - if (_receiver == null) { - return "NoSuchMethodError: method not found: '$_method' ($_message)"; - } - return "NoSuchMethodError: " - "method not found: '$_method' on '$_receiver' ($_message)"; - } -} - -class UnknownJsTypeError extends Error { - final String _message; - - UnknownJsTypeError(this._message); - - String toString() => _message.isEmpty ? 'Error' : 'Error: $_message'; -} - -class NullThrownFromJavaScriptException implements Exception { - final dynamic _irritant; - NullThrownFromJavaScriptException(this._irritant); - - @override - String toString() { - String description = - JS('bool', '# === null', _irritant) ? 'null' : 'undefined'; - return "Throw of null ('$description' from JavaScript)"; - } -} - -/// A wrapper around an exception, much like the one created by [wrapException] -/// but with a pre-given stack-trace. -class ExceptionAndStackTrace { - dynamic dartException; - StackTrace stackTrace; - - ExceptionAndStackTrace(this.dartException, this.stackTrace); -} - -/// Called from catch blocks in generated code to extract the Dart exception -/// from the thrown value. The thrown value may have been created by -/// [wrapException] or it may be a 'native' JavaScript exception. -/// -/// Some native exceptions are mapped to new Dart instances, others are -/// returned unmodified. -Object unwrapException(Object? ex) { - // Dart converts `null` to `NullThrownError()`. JavaScript can still throw a - // nullish value. - if (ex == null) { - return NullThrownFromJavaScriptException(ex); - } - - if (ex is ExceptionAndStackTrace) { - return saveStackTrace(ex, ex.dartException); - } - - // e.g. a primitive value thrown by JavaScript. - if (JS('bool', 'typeof # !== "object"', ex)) return ex; - - if (JS('bool', r'"dartException" in #', ex)) { - return saveStackTrace(ex, JS('', r'#.dartException', ex)); - } - return _unwrapNonDartException(ex); -} - -/// If error implements Dart [Error], save [ex] in [error.$thrownJsError]. -/// Otherwise, do nothing. Later, the stack trace can then be extracted from -/// [ex]. -Object saveStackTrace(Object ex, Object error) { - if (error is Error) { - var thrownStackTrace = JS('', r'#.$thrownJsError', error); - if (thrownStackTrace == null) { - JS('void', r'#.$thrownJsError = #', error, ex); - } - } - return error; -} - -Object _unwrapNonDartException(Object ex) { - if (!JS('bool', r'"message" in #', ex)) { - return ex; - } - // Grab hold of the exception message. This field is available on - // all supported browsers. - var message = JS('var', r'#.message', ex); - - // Internet Explorer has an error number. This is the most reliable way to - // detect specific errors, so check for this first. - if (JS('bool', '"number" in #', ex) && - JS('bool', 'typeof #.number == "number"', ex)) { - int number = JS('int', '#.number', ex); - - // From http://msdn.microsoft.com/en-us/library/ie/hc53e755(v=vs.94).aspx - // "number" is a 32-bit word. The error code is the low 16 bits, and the - // facility code is the upper 16 bits. - var ieErrorCode = number & 0xffff; - var ieFacilityNumber = (number >> 16) & 0x1fff; - - // http://msdn.microsoft.com/en-us/library/aa264975(v=vs.60).aspx - // http://msdn.microsoft.com/en-us/library/ie/1dk3k160(v=vs.94).aspx - if (ieFacilityNumber == 10) { - switch (ieErrorCode) { - case 438: - return saveStackTrace( - ex, JsNoSuchMethodError('$message (Error $ieErrorCode)', null)); - case 445: - case 5007: - return saveStackTrace( - ex, NullError('$message (Error $ieErrorCode)', null)); - } - } - } - - if (JS('bool', r'# instanceof TypeError', ex)) { - var match; - var nsme = TypeErrorDecoder.noSuchMethodPattern; - var notClosure = TypeErrorDecoder.notClosurePattern; - var nullCall = TypeErrorDecoder.nullCallPattern; - var nullLiteralCall = TypeErrorDecoder.nullLiteralCallPattern; - var undefCall = TypeErrorDecoder.undefinedCallPattern; - var undefLiteralCall = TypeErrorDecoder.undefinedLiteralCallPattern; - var nullProperty = TypeErrorDecoder.nullPropertyPattern; - var nullLiteralProperty = TypeErrorDecoder.nullLiteralPropertyPattern; - var undefProperty = TypeErrorDecoder.undefinedPropertyPattern; - var undefLiteralProperty = TypeErrorDecoder.undefinedLiteralPropertyPattern; - if ((match = nsme.matchTypeError(message)) != null) { - return saveStackTrace(ex, JsNoSuchMethodError(message, match)); - } else if ((match = notClosure.matchTypeError(message)) != null) { - // notClosure may match "({c:null}).c()" or "({c:1}).c()", so we - // cannot tell if this an attempt to invoke call on null or a - // non-function object. - // But we do know the method name is "call". - JS('', '#.method = "call"', match); - return saveStackTrace(ex, JsNoSuchMethodError(message, match)); - } else if ((match = nullCall.matchTypeError(message)) != null || - (match = nullLiteralCall.matchTypeError(message)) != null || - (match = undefCall.matchTypeError(message)) != null || - (match = undefLiteralCall.matchTypeError(message)) != null || - (match = nullProperty.matchTypeError(message)) != null || - (match = nullLiteralCall.matchTypeError(message)) != null || - (match = undefProperty.matchTypeError(message)) != null || - (match = undefLiteralProperty.matchTypeError(message)) != null) { - return saveStackTrace(ex, NullError(message, match)); - } - - // If we cannot determine what kind of error this is, we fall back - // to reporting this as a generic error. It's probably better than - // nothing. - return saveStackTrace( - ex, UnknownJsTypeError(message is String ? message : '')); - } - - if (JS('bool', r'# instanceof RangeError', ex)) { - if (message is String && contains(message, 'call stack')) { - return StackOverflowError(); - } - - // In general, a RangeError is thrown when trying to pass a number as an - // argument to a function that does not allow a range that includes that - // number. Translate to a Dart ArgumentError with the same message. - // TODO(sra): Translate to RangeError. - message = tryStringifyException(ex); - if (message is String) { - message = JS('String', r'#.replace(/^RangeError:\s*/, "")', message); - } - return saveStackTrace(ex, ArgumentError(message)); - } - - // Check for the Firefox specific stack overflow signal. - if (JS( - 'bool', - r'typeof InternalError == "function" && # instanceof InternalError', - ex)) { - if (message is String && message == 'too much recursion') { - return StackOverflowError(); - } - } - - // Just return the exception. We should not wrap it because in case the - // exception comes from the DOM, it is a JavaScript object that has a Dart - // interceptor. - return ex; -} - -String? tryStringifyException(ex) { - // Since this function is called from [unwrapException] which is called from - // code injected into a catch-clause, use JavaScript try-catch to avoid a - // potential loop if stringifying crashes. - return JS( - 'String|Null', - r''' - (function(ex) { - try { - return String(ex); - } catch (e) {} - return null; - })(#) - ''', - ex); -} - -/// Called by generated code to fetch the stack trace from an -/// exception. Should never return null. -StackTrace getTraceFromException(exception) { - if (exception is ExceptionAndStackTrace) { - return exception.stackTrace; - } - if (exception == null) return new _StackTrace(exception); - _StackTrace? trace = JS('_StackTrace|Null', r'#.$cachedTrace', exception); - if (trace != null) return trace; - trace = new _StackTrace(exception); - return JS('_StackTrace', r'#.$cachedTrace = #', exception, trace); -} - -class _StackTrace implements StackTrace { - var _exception; - String? _trace; - _StackTrace(this._exception); - - String toString() { - if (_trace != null) return JS('String', '#', _trace); - - String? trace; - if (JS('bool', '# !== null', _exception) && - JS('bool', 'typeof # === "object"', _exception)) { - trace = JS('String|Null', r'#.stack', _exception); - } - return _trace = (trace == null) ? '' : trace; - } -} - -int objectHashCode(var object) { - if (object == null || JS('bool', "typeof # != 'object'", object)) { - return object.hashCode; - } else { - return Primitives.objectHashCode(object); - } -} - -/// Called by generated code to build a map literal. [keyValuePairs] is -/// a list of key, value, key, value, ..., etc. -fillLiteralMap(keyValuePairs, Map result) { - // TODO(johnniwinther): Use JSArray to optimize this code instead of calling - // [getLength] and [getIndex]. - int index = 0; - int length = getLength(keyValuePairs); - while (index < length) { - var key = getIndex(keyValuePairs, index++); - var value = getIndex(keyValuePairs, index++); - result[key] = value; - } - return result; -} - -/// Called by generated code to build a set literal. -fillLiteralSet(values, Set result) { - // TODO(johnniwinther): Use JSArray to optimize this code instead of calling - // [getLength] and [getIndex]. - int length = getLength(values); - for (int index = 0; index < length; index++) { - result.add(getIndex(values, index)); - } - return result; -} - -invokeClosure(Function closure, int numberOfArguments, var arg1, var arg2, - var arg3, var arg4) { - switch (numberOfArguments) { - case 0: - return closure(); - case 1: - return closure(arg1); - case 2: - return closure(arg1, arg2); - case 3: - return closure(arg1, arg2, arg3); - case 4: - return closure(arg1, arg2, arg3, arg4); - } - throw new Exception('Unsupported number of arguments for wrapped closure'); -} - -/// Called by generated code to convert a Dart closure to a JS -/// closure when the Dart closure is passed to the DOM. -convertDartClosureToJS(closure, int arity) { - if (closure == null) return null; - var function = JS('var', r'#.$identity', closure); - if (JS('bool', r'!!#', function)) return function; - - function = JS( - 'var', - r''' - (function(closure, arity, invoke) { - return function(a1, a2, a3, a4) { - return invoke(closure, arity, a1, a2, a3, a4); - }; - })(#,#,#)''', - closure, - arity, - DART_CLOSURE_TO_JS(invokeClosure)); - - JS('void', r'#.$identity = #', closure, function); - return function; -} - -/// Superclass for Dart closures. -/// -/// All static, tear-off, function declaration and function expression closures -/// extend this class, but classes that implement Function via a `call` method -/// do not. -abstract class Closure implements Function { - // TODO(ahe): These constants must be in sync with - // reflection_data_parser.dart. - static const FUNCTION_INDEX = 0; - static const NAME_INDEX = 1; - static const CALL_NAME_INDEX = 2; - static const REQUIRED_PARAMETER_INDEX = 3; - static const OPTIONAL_PARAMETER_INDEX = 4; - static const DEFAULT_ARGUMENTS_INDEX = 5; - - /// Global counter to prevent reusing function code objects. - /// - /// V8 will share the underlying function code objects when the same string is - /// passed to "new Function". Shared function code objects can lead to - /// sub-optimal performance due to polymorphism, and can be prevented by - /// ensuring the strings are different, for example, by generating a local - /// variable with a name dependent on [functionCounter]. - static int functionCounter = 0; - - Closure(); - - /// Creates a new closure class for use by implicit getters associated with a - /// method. - /// - /// In other words, creates a tear-off closure. - /// - /// Called from [closureFromTearOff] as well as from reflection when tearing - /// of a method via `getField`. - /// - /// This method assumes that [functions] was created by the JavaScript - /// function `addStubs` in `reflection_data_parser.dart`. That is, a list of - /// JavaScript function objects with properties `$stubName` and `$callName`. - /// - /// Further assumes that [reflectionInfo] is the end of the array created by - /// [dart2js.js_emitter.ContainerBuilder.addMemberMethod] starting with - /// required parameter count or, in case of the new emitter, the runtime - /// representation of the function's type. - /// - /// Caution: this function may be called when building constants. - /// TODO(ahe): Don't call this function when building constants. - static fromTearOff( - receiver, - List functions, - int? applyTrampolineIndex, - var reflectionInfo, - bool isStatic, - bool isIntercepted, - String propertyName, - ) { - JS_EFFECT(() { - // The functions are called here to model the calls from JS forms below. - // The types in the JS forms in the arguments are propagated in type - // inference. - var aBoundClosure = JS('BoundClosure', '0'); - var aString = JS('String', '0'); - BoundClosure.receiverOf(aBoundClosure); - BoundClosure.selfOf(aBoundClosure); - BoundClosure.evalRecipeIntercepted(aBoundClosure, aString); - BoundClosure.evalRecipe(aBoundClosure, aString); - getType(JS('int', '0')); - }); - // TODO(ahe): All the place below using \$ should be rewritten to go - // through the namer. - var function = JS('', '#[#]', functions, 0); - String? name = JS('String|Null', '#.\$stubName', function); - String? callName = JS('String|Null', '#[#]', function, - JS_GET_NAME(JsGetName.CALL_NAME_PROPERTY)); - - // This variable holds either an index into the types-table, or a function - // that can compute a function-rti. (The latter is necessary if the type - // is dependent on generic arguments). - var functionType = reflectionInfo; - - // function tmp() {}; - // tmp.prototype = BC.prototype; - // var proto = new tmp; - // for each computed prototype property: - // proto[property] = ...; - // proto._init = BC; - // var dynClosureConstructor = - // new Function('self', 'target', 'receiver', 'name', - // 'this._init(self, target, receiver, name)'); - // proto.constructor = dynClosureConstructor; - // dynClosureConstructor.prototype = proto; - // return dynClosureConstructor; - - // We need to create a new subclass of TearOffClosure, one of StaticClosure - // or BoundClosure. For this, we need to create an object whose prototype - // is the prototype is either StaticClosure.prototype or - // BoundClosure.prototype, respectively in pseudo JavaScript code. The - // simplest way to access the JavaScript construction function of a Dart - // class is to create an instance and access its constructor property. - // Creating an instance ensures that any lazy class initialization has taken - // place. The newly created instance could in theory be used directly as the - // prototype, but it might include additional fields that we don't need. So - // we only use the new instance to access the constructor property and use - // Object.create to create the desired prototype. - // - // TODO(sra): Perhaps cache the prototype to avoid the allocation. - var prototype = isStatic - ? JS('StaticClosure', 'Object.create(#.constructor.prototype)', - new StaticClosure()) - : JS('BoundClosure', 'Object.create(#.constructor.prototype)', - new BoundClosure(null, null, null, '')); - - JS('', '#.\$initialize = #', prototype, JS('', '#.constructor', prototype)); - - // The constructor functions have names to prevent the JavaScript - // implementation from inventing a name that might have special meaning - // (e.g. clashing with minified 'Object' or 'Interceptor'). - var constructor = isStatic - ? JS('', 'function static_tear_off(){this.\$initialize()}') - : isCsp - ? JS('', 'function tear_off(a,b,c,d) {this.\$initialize(a,b,c,d)}') - : JS( - '', - 'new Function("a,b,c,d" + #,' - ' "this.\$initialize(a,b,c,d" + # + ")")', - functionCounter, - functionCounter++); - - // It is necessary to set the constructor property, otherwise it will be - // "Object". - JS('', '#.constructor = #', prototype, constructor); - - JS('', '#.prototype = #', constructor, prototype); - - // Create a closure and "monkey" patch it with call stubs. - var trampoline = function; - if (!isStatic) { - trampoline = forwardCallTo(receiver, function, isIntercepted); - JS('', '#.\$reflectionInfo = #', trampoline, reflectionInfo); - } else { - JS('', '#[#] = #', prototype, STATIC_FUNCTION_NAME_PROPERTY_NAME, - propertyName); - } - - var signatureFunction = - _computeSignatureFunctionNewRti(functionType, isStatic, isIntercepted); - - JS('', '#[#] = #', prototype, JS_GET_NAME(JsGetName.SIGNATURE_NAME), - signatureFunction); - var applyTrampoline = trampoline; - JS('', '#[#] = #', prototype, callName, trampoline); - for (int i = 1; i < functions.length; i++) { - var stub = functions[i]; - var stubCallName = JS('String|Null', '#[#]', stub, - JS_GET_NAME(JsGetName.CALL_NAME_PROPERTY)); - if (stubCallName != null) { - stub = isStatic ? stub : forwardCallTo(receiver, stub, isIntercepted); - JS('', '#[#] = #', prototype, stubCallName, stub); - } - if (i == applyTrampolineIndex) { - applyTrampoline = stub; - JS('', '#.\$reflectionInfo = #', applyTrampoline, reflectionInfo); - } - } - - JS('', '#[#] = #', prototype, JS_GET_NAME(JsGetName.CALL_CATCH_ALL), - applyTrampoline); - String reqArgProperty = JS_GET_NAME(JsGetName.REQUIRED_PARAMETER_PROPERTY); - String defValProperty = JS_GET_NAME(JsGetName.DEFAULT_VALUES_PROPERTY); - JS('', '#.# = #.#', prototype, reqArgProperty, function, reqArgProperty); - JS('', '#.# = #.#', prototype, defValProperty, function, defValProperty); - - return constructor; - } - - static _computeSignatureFunctionLegacy( - Object functionType, bool isStatic, bool isIntercepted) { - if (JS('bool', 'typeof # == "number"', functionType)) { - // We cannot call [getType] here, since the types-metadata might not be - // set yet. This is, because fromTearOff might be called for constants - // when the program isn't completely set up yet. - // - // Note that we cannot just textually inline the call - // `getType(functionType)` since we cannot guarantee that the (then) - // captured variable `functionType` isn't reused. - return JS( - '', - '''(function(getType, t) { - return function(){ return getType(t); }; - })(#, #)''', - RAW_DART_FUNCTION_REF(getType), - functionType); - } - if (JS('bool', 'typeof # == "function"', functionType)) { - if (isStatic) { - return functionType; - } else { - var getReceiver = isIntercepted - ? RAW_DART_FUNCTION_REF(BoundClosure.receiverOf) - : RAW_DART_FUNCTION_REF(BoundClosure.selfOf); - return JS( - '', - 'function(f,r){' - 'return function(){' - 'return f.apply({\$receiver:r(this)},arguments)' - '}' - '}(#,#)', - functionType, - getReceiver); - } - } - throw 'Error in functionType of tearoff'; - } - - static _computeSignatureFunctionNewRti( - Object functionType, bool isStatic, bool isIntercepted) { - if (JS('bool', 'typeof # == "number"', functionType)) { - // Index into types table. - // - // We cannot call [getTypeFromTypesTable] here, since the types-metadata - // might not be set yet. This is, because fromTearOff might be called for - // constants when the program isn't completely set up yet. We also want to - // avoid creating lots of types at startup. - return JS( - '', - '''(function(getType, t) { - return function(){ return getType(t); }; - })(#, #)''', - RAW_DART_FUNCTION_REF(newRti.getTypeFromTypesTable), - functionType); - } - if (JS('bool', 'typeof # == "string"', functionType)) { - // A recipe to evaluate against the instance type. - if (isStatic) { - // TODO(sra): Recipe for static tearoff. - throw 'Cannot compute signature for static tearoff.'; - } - var typeEvalMethod = isIntercepted - ? RAW_DART_FUNCTION_REF(BoundClosure.evalRecipeIntercepted) - : RAW_DART_FUNCTION_REF(BoundClosure.evalRecipe); - return JS( - '', - ' function(recipe, evalOnReceiver) {' - ' return function() {' - ' return evalOnReceiver(this, recipe);' - ' };' - '}(#,#)', - functionType, - typeEvalMethod); - } - throw 'Error in functionType of tearoff'; - } - - static cspForwardCall( - int arity, bool isSuperCall, String? stubName, function) { - var getSelf = RAW_DART_FUNCTION_REF(BoundClosure.selfOf); - // Handle intercepted stub-names with the default slow case. - if (isSuperCall) arity = -1; - switch (arity) { - case 0: - return JS( - '', - 'function(n,S){' - 'return function(){' - 'return S(this)[n]()' - '}' - '}(#,#)', - stubName, - getSelf); - case 1: - return JS( - '', - 'function(n,S){' - 'return function(a){' - 'return S(this)[n](a)' - '}' - '}(#,#)', - stubName, - getSelf); - case 2: - return JS( - '', - 'function(n,S){' - 'return function(a,b){' - 'return S(this)[n](a,b)' - '}' - '}(#,#)', - stubName, - getSelf); - case 3: - return JS( - '', - 'function(n,S){' - 'return function(a,b,c){' - 'return S(this)[n](a,b,c)' - '}' - '}(#,#)', - stubName, - getSelf); - case 4: - return JS( - '', - 'function(n,S){' - 'return function(a,b,c,d){' - 'return S(this)[n](a,b,c,d)' - '}' - '}(#,#)', - stubName, - getSelf); - case 5: - return JS( - '', - 'function(n,S){' - 'return function(a,b,c,d,e){' - 'return S(this)[n](a,b,c,d,e)' - '}' - '}(#,#)', - stubName, - getSelf); - default: - return JS( - '', - 'function(f,s){' - 'return function(){' - 'return f.apply(s(this),arguments)' - '}' - '}(#,#)', - function, - getSelf); - } - } - - static bool get isCsp => JS_GET_FLAG('USE_CONTENT_SECURITY_POLICY'); - - static forwardCallTo(receiver, function, bool isIntercepted) { - if (isIntercepted) return forwardInterceptedCallTo(receiver, function); - String? stubName = JS('String|Null', '#.\$stubName', function); - int arity = JS('int', '#.length', function); - var lookedUpFunction = JS('', '#[#]', receiver, stubName); - // The receiver[stubName] may not be equal to the function if we try to - // forward to a super-method. Especially when we create a bound closure - // of a super-call we need to make sure that we don't forward back to the - // dynamically looked up function. - bool isSuperCall = !identical(function, lookedUpFunction); - - if (isCsp || isSuperCall || arity >= 27) { - return cspForwardCall(arity, isSuperCall, stubName, function); - } - - if (arity == 0) { - // Incorporate functionCounter into a local. - String selfName = 'self${functionCounter++}'; - return JS( - '', - '(new Function(#))()', - 'return function(){' - 'var $selfName = this.${BoundClosure.selfFieldName()};' - 'return $selfName.$stubName();' - '}'); - } - assert(1 <= arity && arity < 27); - String arguments = JS('String', - '"abcdefghijklmnopqrstuvwxyz".split("").splice(0,#).join(",")', arity); - arguments += '${functionCounter++}'; - return JS( - '', - '(new Function(#))()', - 'return function($arguments){' - 'return this.${BoundClosure.selfFieldName()}.$stubName($arguments);' - '}'); - } - - static cspForwardInterceptedCall( - int arity, bool isSuperCall, String? name, function) { - var getSelf = RAW_DART_FUNCTION_REF(BoundClosure.selfOf); - var getReceiver = RAW_DART_FUNCTION_REF(BoundClosure.receiverOf); - // Handle intercepted stub-names with the default slow case. - if (isSuperCall) arity = -1; - switch (arity) { - case 0: - // Intercepted functions always takes at least one argument (the - // receiver). - throw new RuntimeError('Intercepted function with no arguments.'); - case 1: - return JS( - '', - 'function(n,s,r){' - 'return function(){' - 'return s(this)[n](r(this))' - '}' - '}(#,#,#)', - name, - getSelf, - getReceiver); - case 2: - return JS( - '', - 'function(n,s,r){' - 'return function(a){' - 'return s(this)[n](r(this),a)' - '}' - '}(#,#,#)', - name, - getSelf, - getReceiver); - case 3: - return JS( - '', - 'function(n,s,r){' - 'return function(a,b){' - 'return s(this)[n](r(this),a,b)' - '}' - '}(#,#,#)', - name, - getSelf, - getReceiver); - case 4: - return JS( - '', - 'function(n,s,r){' - 'return function(a,b,c){' - 'return s(this)[n](r(this),a,b,c)' - '}' - '}(#,#,#)', - name, - getSelf, - getReceiver); - case 5: - return JS( - '', - 'function(n,s,r){' - 'return function(a,b,c,d){' - 'return s(this)[n](r(this),a,b,c,d)' - '}' - '}(#,#,#)', - name, - getSelf, - getReceiver); - case 6: - return JS( - '', - 'function(n,s,r){' - 'return function(a,b,c,d,e){' - 'return s(this)[n](r(this),a,b,c,d,e)' - '}' - '}(#,#,#)', - name, - getSelf, - getReceiver); - default: - return JS( - '', - 'function(f,s,r,a){' - 'return function(){' - 'a=[r(this)];' - 'Array.prototype.push.apply(a,arguments);' - 'return f.apply(s(this),a)' - '}' - '}(#,#,#)', - function, - getSelf, - getReceiver); - } - } - - static forwardInterceptedCallTo(receiver, function) { - String selfField = BoundClosure.selfFieldName(); - String receiverField = BoundClosure.receiverFieldName(); - String? stubName = JS('String|Null', '#.\$stubName', function); - int arity = JS('int', '#.length', function); - bool isCsp = JS_GET_FLAG('USE_CONTENT_SECURITY_POLICY'); - var lookedUpFunction = JS('', '#[#]', receiver, stubName); - // The receiver[stubName] may not be equal to the function if we try to - // forward to a super-method. Especially when we create a bound closure - // of a super-call we need to make sure that we don't forward back to the - // dynamically looked up function. - bool isSuperCall = !identical(function, lookedUpFunction); - - if (isCsp || isSuperCall || arity >= 28) { - return cspForwardInterceptedCall(arity, isSuperCall, stubName, function); - } - if (arity == 1) { - return JS( - '', - '(new Function(#))()', - 'return function(){' - 'return this.$selfField.$stubName(this.$receiverField);' - '${functionCounter++}' - '}'); - } - assert(1 < arity && arity < 28); - String arguments = JS( - 'String', - '"abcdefghijklmnopqrstuvwxyz".split("").splice(0,#).join(",")', - arity - 1); - return JS( - '', - '(new Function(#))()', - 'return function($arguments){' - 'return this.$selfField.$stubName(this.$receiverField, $arguments);' - '${functionCounter++}' - '}'); - } - - // The backend adds a special getter of the form - // - // Closure get call => this; - // - // to allow tearing off a closure from itself. We do this magically in the - // backend rather than simply adding it here, as we do not want this getter - // to be visible to resolution and the generation of extra stubs. - - String toString() { - String? name; - var constructor = JS('', '#.constructor', this); - name = - constructor == null ? null : JS('String|Null', '#.name', constructor); - if (name == null) name = 'unknown'; - return "Closure '${unminifyOrTag(name)}'"; - } -} - -/// Called from implicit method getter (aka tear-off). -closureFromTearOff(receiver, functions, applyTrampolineIndex, reflectionInfo, - isStatic, isIntercepted, name) { - return Closure.fromTearOff( - receiver, - JS('JSArray', '#', functions), - JS('int|Null', '#', applyTrampolineIndex), - reflectionInfo, - JS('bool', '!!#', isStatic), - JS('bool', '!!#', isIntercepted), - JS('String', '#', name)); -} - -/// Represents an implicit closure of a function. -abstract class TearOffClosure extends Closure {} - -class StaticClosure extends TearOffClosure { - String toString() { - String? name = - JS('String|Null', '#[#]', this, STATIC_FUNCTION_NAME_PROPERTY_NAME); - if (name == null) return 'Closure of unknown static method'; - return "Closure '${unminifyOrTag(name)}'"; - } -} - -/// Represents a 'tear-off' or property extraction closure of an instance -/// method, that is an instance method bound to a specific receiver (instance). -class BoundClosure extends TearOffClosure { - /// The receiver or interceptor. - // TODO(ahe): This could just be the interceptor, we always know if - // we need the interceptor when generating the call method. - final _self; - - /// The method. - final _target; - - /// The receiver. Null if [_self] is not an interceptor. - final _receiver; - - /// The name of the function. Only used by the mirror system. - final String _name; - - BoundClosure(this._self, this._target, this._receiver, this._name); - - bool operator ==(other) { - if (identical(this, other)) return true; - if (other is! BoundClosure) return false; - return JS('bool', '# === #', _self, other._self) && - JS('bool', '# === #', _target, other._target) && - JS('bool', '# === #', _receiver, other._receiver); - } - - int get hashCode { - int receiverHashCode; - if (_receiver == null) { - // A bound closure on a regular Dart object, just use the - // identity hash code. - receiverHashCode = Primitives.objectHashCode(_self); - } else if (JS('String', 'typeof #', _receiver) != 'object') { - // A bound closure on a primitive JavaScript type. We - // use the hashCode method we define for those primitive types. - receiverHashCode = _receiver.hashCode; - } else { - // A bound closure on an intercepted native class, just use the - // identity hash code. - receiverHashCode = Primitives.objectHashCode(_receiver); - } - return receiverHashCode ^ Primitives.objectHashCode(_target); - } - - toString() { - var receiver = _receiver == null ? _self : _receiver; - // TODO(sra): When minified, mark [_name] with a tag, - // e.g. 'minified-property:' so that it can be unminified. - return "Closure '$_name' of " - "${Primitives.objectToHumanReadableString(receiver)}"; - } - - static evalRecipe(BoundClosure closure, String recipe) { - return newRti.evalInInstance(closure._self, recipe); - } - - static evalRecipeIntercepted(BoundClosure closure, String recipe) { - return newRti.evalInInstance(closure._receiver, recipe); - } - - @pragma('dart2js:noInline') - static selfOf(BoundClosure closure) => closure._self; - - static targetOf(BoundClosure closure) => closure._target; - - @pragma('dart2js:noInline') - static receiverOf(BoundClosure closure) => closure._receiver; - - static nameOf(BoundClosure closure) => closure._name; - - static String? selfFieldNameCache; - - static String selfFieldName() { - if (selfFieldNameCache == null) { - selfFieldNameCache = computeFieldNamed('self'); - } - return selfFieldNameCache!; - } - - static String? receiverFieldNameCache; - - static String receiverFieldName() { - if (receiverFieldNameCache == null) { - receiverFieldNameCache = computeFieldNamed('receiver'); - } - return receiverFieldNameCache!; - } - - @pragma('dart2js:noInline') - @pragma('dart2js:noSideEffects') - static String computeFieldNamed(String fieldName) { - var template = new BoundClosure('self', 'target', 'receiver', 'name'); - var names = JSArray.markFixedList( - JS('', 'Object.getOwnPropertyNames(#)', template)); - for (int i = 0; i < names.length; i++) { - var name = names[i]; - if (JS('bool', '#[#] === #', template, name, fieldName)) { - return JS('String', '#', name); - } - } - throw new ArgumentError("Field name $fieldName not found."); - } -} - -bool jsHasOwnProperty(var jsObject, String property) { - return JS('bool', r'#.hasOwnProperty(#)', jsObject, property); -} - -jsPropertyAccess(var jsObject, String property) { - return JS('var', r'#[#]', jsObject, property); -} - -/// Called at the end of unaborted switch cases to get the singleton -/// FallThroughError exception that will be thrown. -getFallThroughError() => new FallThroughErrorImplementation(); - -/// A metadata annotation describing the types instantiated by a native element. -/// -/// The annotation is valid on a native method and a field of a native class. -/// -/// By default, a field of a native class is seen as an instantiation point for -/// all native classes that are a subtype of the field's type, and a native -/// method is seen as an instantiation point fo all native classes that are a -/// subtype of the method's return type, or the argument types of the declared -/// type of the method's callback parameter. -/// -/// An @[Creates] annotation overrides the default set of instantiated types. -/// If one or more @[Creates] annotations are present, the type of the native -/// element is ignored, and the union of @[Creates] annotations is used instead. -/// The names in the strings are resolved and the program will fail to compile -/// with dart2js if they do not name types. -/// -/// The argument to [Creates] is a string. The string is parsed as the names of -/// one or more types, separated by vertical bars `|`. There are some special -/// names: -/// -/// * `=Object`. This means 'exactly Object', which is a plain JavaScript object -/// with properties and none of the subtypes of Object. -/// -/// Example: we may know that a method always returns a specific implementation: -/// -/// @Creates('_NodeList') -/// List getElementsByTagName(String tag) native; -/// -/// Useful trick: A method can be marked as not instantiating any native classes -/// with the annotation `@Creates('Null')`. This is useful for fields on native -/// classes that are used only in Dart code. -/// -/// @Creates('Null') -/// var _cachedFoo; -class Creates { - final String types; - const Creates(this.types); -} - -/// A metadata annotation describing the types returned or yielded by a native -/// element. -/// -/// The annotation is valid on a native method and a field of a native class. -/// -/// By default, a native method or field is seen as returning or yielding all -/// subtypes if the method return type or field type. This annotation allows a -/// more precise set of types to be specified. -/// -/// See [Creates] for the syntax of the argument. -/// -/// Example: IndexedDB keys are numbers, strings and JavaScript Arrays of keys. -/// -/// @Returns('String|num|JSExtendableArray') -/// dynamic key; -/// -/// // Equivalent: -/// @Returns('String') @Returns('num') @Returns('JSExtendableArray') -/// dynamic key; -class Returns { - final String types; - const Returns(this.types); -} - -/// A metadata annotation placed on native methods and fields of native classes -/// to specify the JavaScript name. -/// -/// This example declares a Dart field + getter + setter called `$dom_title` -/// that corresponds to the JavaScript property `title`. -/// -/// class Document native "*Foo" { -/// @JSName('title') -/// String $dom_title; -/// } -class JSName { - final String name; - const JSName(this.name); -} - -/// The following methods are called by the runtime to implement checked mode -/// and casts. We specialize each primitive type (eg int, bool), and use the -/// compiler's convention to do is-checks on regular objects. -bool boolConversionCheck(value) { - // The value from kernel should always be true, false, or null. - if (value == null) assertThrow('boolean expression must not be null'); - return JS('bool', '#', value); -} - -@pragma('dart2js:noInline') -void checkDeferredIsLoaded(String loadId) { - if (!_loadedLibraries.contains(loadId)) { - throw new DeferredNotLoadedError(loadId); - } -} - -/// Special interface recognized by the compiler and implemented by DOM -/// objects that support integer indexing. This interface is not -/// visible to anyone, and is only injected into special libraries. -abstract class JavaScriptIndexingBehavior extends JSMutableIndexable {} - -class FallThroughErrorImplementation extends FallThroughError { - FallThroughErrorImplementation(); - String toString() => 'Switch case fall-through.'; -} - -/// Helper function for implementing asserts. The compiler treats this -/// specially. -/// -/// Returns the negation of the condition. That is: `true` if the assert should -/// fail. -bool assertTest(condition) { - if (true == condition) return false; - if (false == condition) return true; - bool checked = condition as bool; - if (null == condition) { - newRti.throwTypeError('assert condition must not be null'); - } - return !checked; -} - -/// Helper function for implementing asserts with messages. -/// The compiler treats this specially. -void assertThrow(Object message) { - throw _AssertionError(message); -} - -/// Helper function for implementing asserts without messages. -/// The compiler treats this specially. -@pragma('dart2js:noInline') -void assertHelper(condition) { - if (assertTest(condition)) throw AssertionError(); -} - -/// Called by generated code when a method that must be statically -/// resolved cannot be found. -void throwNoSuchMethod(obj, name, arguments, expectedArgumentNames) { - Symbol memberName = new _symbol_dev.Symbol.unvalidated(name); - throw new NoSuchMethodError( - obj, memberName, arguments, new Map()); -} - -/// Called by generated code when a static field's initializer references the -/// field that is currently being initialized. -void throwCyclicInit(String staticName) { - throw new CyclicInitializationError(staticName); -} - -/// Error thrown when a runtime error occurs. -class RuntimeError extends Error { - final message; - RuntimeError(this.message); - String toString() => 'RuntimeError: $message'; -} - -class DeferredNotLoadedError extends Error implements NoSuchMethodError { - String libraryName; - - DeferredNotLoadedError(this.libraryName); - - String toString() { - return 'Deferred library $libraryName was not loaded.'; - } -} - -// TODO(ahe): Remove this class and call noSuchMethod instead. -class UnimplementedNoSuchMethodError extends Error - implements NoSuchMethodError { - final String _message; - - UnimplementedNoSuchMethodError(this._message); - - String toString() => 'Unsupported operation: $_message'; -} - -/// Creates a random number with 64 bits of randomness. -/// -/// This will be truncated to the 53 bits available in a double. -int random64() { - // TODO(lrn): Use a secure random source. - int int32a = JS('int', '(Math.random() * 0x100000000) >>> 0'); - int int32b = JS('int', '(Math.random() * 0x100000000) >>> 0'); - return int32a + int32b * 0x100000000; -} - -String jsonEncodeNative(String string) { - return JS('String', 'JSON.stringify(#)', string); -} - -/// Returns a property name for placing data on JavaScript objects shared -/// between DOM isolates. This happens when multiple programs are loaded in the -/// same JavaScript context (i.e. page). The name is based on [name] but with -/// an additional part that is unique for each isolate. -/// -/// The form of the name is '___dart_$name_$id'. -String getIsolateAffinityTag(String name) { - var isolateTagGetter = JS_EMBEDDED_GLOBAL('', GET_ISOLATE_TAG); - return JS('String', '#(#)', isolateTagGetter, name); -} - -typedef Future LoadLibraryFunctionType(); - -LoadLibraryFunctionType _loadLibraryWrapper(String loadId) { - return () => loadDeferredLibrary(loadId); -} - -final Map?> _loadingLibraries = ?>{}; -final Set _loadedLibraries = new Set(); - -/// Events used to diagnose failures from deferred loading requests. -final List _eventLog = []; - -typedef void DeferredLoadCallback(); - -// Function that will be called every time a new deferred import is loaded. -DeferredLoadCallback? deferredLoadHook; - -Future loadDeferredLibrary(String loadId) { - // For each loadId there is a list of parts to load. The parts are represented - // by an index. There are two arrays, one that maps the index into a Uri and - // another that maps the index to a hash. - var partsMap = JS_EMBEDDED_GLOBAL('', DEFERRED_LIBRARY_PARTS); - List? indexes = JS('JSExtendableArray|Null', '#[#]', partsMap, loadId); - if (indexes == null) return new Future.value(null); - List uris = []; - List hashes = []; - List index2uri = JS_EMBEDDED_GLOBAL('JSArray', DEFERRED_PART_URIS); - List index2hash = JS_EMBEDDED_GLOBAL('JSArray', DEFERRED_PART_HASHES); - for (int i = 0; i < indexes.length; i++) { - int index = JS('int', '#[#]', indexes, i); - uris.add(JS('String', '#[#]', index2uri, index)); - hashes.add(JS('String', '#[#]', index2hash, index)); - } - - int total = hashes.length; - assert(total == uris.length); - List waitingForLoad = new List.filled(total, true); - int nextHunkToInitialize = 0; - var isHunkLoaded = JS_EMBEDDED_GLOBAL('', IS_HUNK_LOADED); - var isHunkInitialized = JS_EMBEDDED_GLOBAL('', IS_HUNK_INITIALIZED); - var initializer = JS_EMBEDDED_GLOBAL('', INITIALIZE_LOADED_HUNK); - - void initializeSomeLoadedHunks() { - for (int i = nextHunkToInitialize; i < total; ++i) { - // A hunk is initialized only if all the preceeding hunks have been - // initialized. - if (waitingForLoad[i]) return; - nextHunkToInitialize++; - - // It is possible for a hash to be repeated. This happens when two - // different parts both end up empty. Checking in the loop rather than - // pre-filtering prevents duplicate hashes leading to duplicated - // initializations. - // TODO(29572): Merge small parts. - // TODO(29635): Remove duplicate parts from tables and output files. - var uri = uris[i]; - var hash = hashes[i]; - if (JS('bool', '#(#)', isHunkInitialized, hash)) { - _eventLog.add(' - already initialized: $uri ($hash)'); - continue; - } - // On strange scenarios, e.g. if js encounters parse errors, we might get - // an "success" callback on the script load but the hunk will be null. - if (JS('bool', '#(#)', isHunkLoaded, hash)) { - _eventLog.add(' - initialize: $uri ($hash)'); - JS('void', '#(#)', initializer, hash); - } else { - _eventLog.add(' - missing hunk: $uri ($hash)'); - throw new DeferredLoadException("Loading ${uris[i]} failed: " - "the code with hash '${hash}' was not loaded.\n" - "event log:\n${_eventLog.join("\n")}\n"); - } - } - } - - Future loadAndInitialize(int i) { - if (JS('bool', '#(#)', isHunkLoaded, hashes[i])) { - waitingForLoad[i] = false; - return new Future.value(); - } - return _loadHunk(uris[i]).then((Null _) { - waitingForLoad[i] = false; - initializeSomeLoadedHunks(); - }); - } - - return Future.wait(new List.generate(total, loadAndInitialize)).then((_) { - initializeSomeLoadedHunks(); - // At this point all hunks have been loaded, so there should be no pending - // initializations to do. - assert(nextHunkToInitialize == total); - bool updated = _loadedLibraries.add(loadId); - if (updated && deferredLoadHook != null) { - deferredLoadHook!(); - } - }); -} - -/// The `nonce` value on the current script used for strict-CSP, if any. -String? _cspNonce = _computeCspNonce(); - -String? _computeCspNonce() { - var currentScript = JS_EMBEDDED_GLOBAL('', CURRENT_SCRIPT); - if (currentScript == null) return null; - String? nonce = JS('String|Null', '#.nonce', currentScript); - return (nonce != null && nonce != '') - ? nonce - : JS('String|Null', '#.getAttribute("nonce")', currentScript); -} - -/// The 'crossOrigin' value on the current script used for CORS, if any. -String? _crossOrigin = _computeCrossOrigin(); - -String? _computeCrossOrigin() { - var currentScript = JS_EMBEDDED_GLOBAL('', CURRENT_SCRIPT); - if (currentScript == null) return null; - return JS('String|Null', '#.crossOrigin', currentScript); -} - -/// Returns true if we are currently in a worker context. -bool _isWorker() { - requiresPreamble(); - return JS('', '!self.window && !!self.postMessage'); -} - -/// The src url for the script tag that loaded this code. -String? thisScript = _computeThisScript(); - -/// The src url for the script tag that loaded this function. -/// -/// Used to create JavaScript workers and load deferred libraries. -String? _computeThisScript() { - var currentScript = JS_EMBEDDED_GLOBAL('', CURRENT_SCRIPT); - if (currentScript != null) { - return JS('String', 'String(#.src)', currentScript); - } - // A worker has no script tag - so get an url from a stack-trace. - if (_isWorker()) return _computeThisScriptFromTrace(); - // An isolate that doesn't support workers, but doesn't have a - // currentScript either. This is most likely a Chrome extension. - return null; -} - -String _computeThisScriptFromTrace() { - var stack = JS('String|Null', 'new Error().stack'); - if (stack == null) { - // According to Internet Explorer documentation, the stack - // property is not set until the exception is thrown. The stack - // property was not provided until IE10. - stack = JS( - 'String|Null', - '(function() {' - 'try { throw new Error() } catch(e) { return e.stack }' - '})()'); - if (stack == null) throw new UnsupportedError('No stack trace'); - } - var pattern, matches; - - // This pattern matches V8, Chrome, and Internet Explorer stack - // traces that look like this: - // Error - // at methodName (URI:LINE:COLUMN) - pattern = JS('', r'new RegExp("^ *at [^(]*\\((.*):[0-9]*:[0-9]*\\)$", "m")'); - - matches = JS('JSExtendableArray|Null', '#.match(#)', stack, pattern); - if (matches != null) return JS('String', '#[1]', matches); - - // This pattern matches Firefox stack traces that look like this: - // methodName@URI:LINE - pattern = JS('', r'new RegExp("^[^@]*@(.*):[0-9]*$", "m")'); - - matches = JS('JSExtendableArray|Null', '#.match(#)', stack, pattern); - if (matches != null) return JS('String', '#[1]', matches); - - throw new UnsupportedError('Cannot extract URI from "$stack"'); -} - -Future _loadHunk(String hunkName) { - var future = _loadingLibraries[hunkName]; - _eventLog.add(' - _loadHunk: $hunkName'); - if (future != null) { - _eventLog.add('reuse: $hunkName'); - return future.then((Null _) => null); - } - - String uri = thisScript!; - - int index = uri.lastIndexOf('/'); - uri = '${uri.substring(0, index + 1)}$hunkName'; - _eventLog.add(' - download: $hunkName from $uri'); - - var deferredLibraryLoader = JS('', 'self.dartDeferredLibraryLoader'); - Completer completer = new Completer(); - - void success() { - _eventLog.add(' - download success: $hunkName'); - completer.complete(null); - } - - void failure(error, String context, StackTrace? stackTrace) { - _eventLog.add(' - download failed: $hunkName (context: $context)'); - _loadingLibraries[hunkName] = null; - stackTrace ??= StackTrace.current; - completer.completeError( - new DeferredLoadException('Loading $uri failed: $error\n' - 'event log:\n${_eventLog.join("\n")}\n'), - stackTrace); - } - - var jsSuccess = convertDartClosureToJS(success, 0); - var jsFailure = convertDartClosureToJS((error) { - failure(unwrapException(error), 'js-failure-wrapper', - getTraceFromException(error)); - }, 1); - - if (JS('bool', 'typeof # === "function"', deferredLibraryLoader)) { - try { - JS('void', '#(#, #, #)', deferredLibraryLoader, uri, jsSuccess, - jsFailure); - } catch (error, stackTrace) { - failure(error, "invoking dartDeferredLibraryLoader hook", stackTrace); - } - } else if (_isWorker()) { - // We are in a web worker. Load the code with an XMLHttpRequest. - int index = uri.lastIndexOf('/'); - uri = '${uri.substring(0, index + 1)}$hunkName'; - var xhr = JS('var', 'new XMLHttpRequest()'); - JS('void', '#.open("GET", #)', xhr, uri); - JS( - 'void', - '#.addEventListener("load", #, false)', - xhr, - convertDartClosureToJS((event) { - int status = JS('int', '#.status', xhr); - if (status != 200) { - failure('Request status: $status', 'worker xhr', null); - } - String code = JS('String', '#.responseText', xhr); - try { - // Create a new function to avoid getting access to current function - // context. - JS('void', '(new Function(#))()', code); - success(); - } catch (error, stackTrace) { - failure(error, 'evaluating the code in worker xhr', stackTrace); - } - }, 1)); - - JS('void', '#.addEventListener("error", #, false)', xhr, (e) { - failure(e, 'xhr error handler', null); - }); - JS('void', '#.addEventListener("abort", #, false)', xhr, (e) { - failure(e, 'xhr abort handler', null); - }); - JS('void', '#.send()', xhr); - } else { - // We are in a dom-context. - // Inject a script tag. - var script = JS('', 'document.createElement("script")'); - JS('', '#.type = "text/javascript"', script); - JS('', '#.src = #', script, uri); - if (_cspNonce != null && _cspNonce != '') { - JS('', '#.nonce = #', script, _cspNonce); - JS('', '#.setAttribute("nonce", #)', script, _cspNonce); - } - if (_crossOrigin != null && _crossOrigin != '') { - JS('', '#.crossOrigin = #', script, _crossOrigin); - } - JS('', '#.addEventListener("load", #, false)', script, jsSuccess); - JS('', '#.addEventListener("error", #, false)', script, jsFailure); - JS('', 'document.body.appendChild(#)', script); - } - _loadingLibraries[hunkName] = completer.future; - return completer.future; -} - -class MainError extends Error implements NoSuchMethodError { - final String _message; - - MainError(this._message); - - String toString() => 'NoSuchMethodError: $_message'; -} - -void missingMain() { - throw new MainError("No top-level function named 'main'."); -} - -void badMain() { - throw new MainError("'main' is not a function."); -} - -void mainHasTooManyParameters() { - throw new MainError("'main' expects too many parameters."); -} - -class _AssertionError extends AssertionError { - _AssertionError(Object message) : super(message); - - String toString() => "Assertion failed: " + Error.safeToString(message); -} - -// [_UnreachableError] is a separate class because we always resolve -// [assertUnreachable] and want to reduce the impact of resolving possibly -// unneeded code. -class _UnreachableError extends AssertionError { - _UnreachableError(); - String toString() => 'Assertion failed: Reached dead code'; -} - -@pragma('dart2js:noInline') -void assertUnreachable() { - throw new _UnreachableError(); -} - -// Hook to register new global object if necessary. -// This is currently a no-op in dart2js. -void registerGlobalObject(object) {} - -// Hook to register new browser classes. -// This is currently a no-op in dart2js. -void applyExtension(name, nativeObject) {} - -// See tests/dart2js_2/platform_environment_variable1_test.dart -const String testPlatformEnvironmentVariableValue = String.fromEnvironment( - 'dart2js.test.platform.environment.variable', - defaultValue: 'not-specified'); - -String testingGetPlatformEnvironmentVariable() { - return testPlatformEnvironmentVariableValue; -} - -// These are used to indicate that a named parameter is required when lazily -// retrieving default values via [JsGetName.DEFAULT_VALUES_PROPERTY]. -class _Required { - const _Required(); -} - -const kRequiredSentinel = const _Required(); -bool isRequired(Object? value) => identical(kRequiredSentinel, value); diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/js_names.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/js_names.dart deleted file mode 100644 index 10efacf5aeb..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/lib/js_names.dart +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright (c) 2013, 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 dart._js_names; - -import 'dart:_js_embedded_names' - show JsGetName, MANGLED_GLOBAL_NAMES, MANGLED_NAMES; - -import 'dart:_foreign_helper' show JS, JS_EMBEDDED_GLOBAL, JS_GET_NAME; - -import 'dart:_js_helper' show JsCache, NoInline; - -import 'dart:_interceptors' show JSArray; - -/// No-op method that is called to inform the compiler that unmangled named -/// must be preserved. -preserveNames() {} - -/// A map from mangled names to "reflective" names, that is, unmangled names -/// with some additional information, such as, number of required arguments. -/// This map is for mangled names used as instance members. -final _LazyMangledNamesMap mangledNames = new _LazyMangledInstanceNamesMap( - JS_EMBEDDED_GLOBAL('=Object', MANGLED_NAMES)); - -/// A map from "reflective" names to mangled names (the reverse of -/// [mangledNames]). -final _LazyReflectiveNamesMap reflectiveNames = new _LazyReflectiveNamesMap( - JS_EMBEDDED_GLOBAL('=Object', MANGLED_NAMES), true); - -/// A map from mangled names to "reflective" names (see [mangledNames]). This -/// map is for globals, that is, static and top-level members. -final _LazyMangledNamesMap mangledGlobalNames = new _LazyMangledNamesMap( - JS_EMBEDDED_GLOBAL('=Object', MANGLED_GLOBAL_NAMES)); - -/// A map from "reflective" names to mangled names (the reverse of -/// [mangledGlobalNames]). -final _LazyReflectiveNamesMap reflectiveGlobalNames = - new _LazyReflectiveNamesMap( - JS_EMBEDDED_GLOBAL('=Object', MANGLED_GLOBAL_NAMES), false); - -/// Implements a mapping from mangled names to their reflective counterparts. -/// The propertiy names of [_jsMangledNames] are the mangled names, and the -/// values are the "reflective" names. -class _LazyMangledNamesMap { - /// [_jsMangledNames] is a JavaScript object literal. - var _jsMangledNames; - - _LazyMangledNamesMap(this._jsMangledNames); - - String? operator [](String key) { - var result = JS('var', '#[#]', _jsMangledNames, key); - // Filter out all non-string values to protect against polution from - // ancillary fields in [_jsMangledNames]. - bool filter = JS('bool', 'typeof # !== "string"', result); - // To ensure that the inferrer sees that result is a String, we explicitly - // give it a better type here. - return filter ? null : JS('String', '#', result); - } -} - -/// Extends [_LazyMangledNamesMap] with additional support for adding mappings -/// from mangled setter names to their reflective counterpart by rewriting a -/// corresponding entry for a getter name, if it exists. -class _LazyMangledInstanceNamesMap extends _LazyMangledNamesMap { - _LazyMangledInstanceNamesMap(_jsMangledNames) : super(_jsMangledNames); - - String? operator [](String key) { - String? result = super[key]; - String setterPrefix = JS_GET_NAME(JsGetName.SETTER_PREFIX); - if (result == null && key.startsWith(setterPrefix)) { - String getterPrefix = JS_GET_NAME(JsGetName.GETTER_PREFIX); - int setterPrefixLength = setterPrefix.length; - - // Generate the setter name from the getter name. - key = '$getterPrefix${key.substring(setterPrefixLength)}'; - result = super[key]; - return (result != null) ? "${result}=" : null; - } - return result; - } -} - -/// Implements the inverse of [_LazyMangledNamesMap]. As it would be too -/// expensive to search the mangled names map for a value that corresponds to -/// the lookup key on each invocation, we compute the full mapping in demand -/// and cache it. The cache is invalidated when the underlying [_jsMangledNames] -/// object changes its length. This condition is sufficient as the name mapping -/// can only grow over time. -/// When [_isInstance] is true, we also apply the inverse of the setter/getter -/// name conversion implemented by [_LazyMangledInstanceNamesMap]. -class _LazyReflectiveNamesMap { - /// [_jsMangledNames] is a JavaScript object literal. - final _jsMangledNames; - final bool _isInstance; - int _cacheLength = 0; - Map? _cache; - - _LazyReflectiveNamesMap(this._jsMangledNames, this._isInstance); - - Map _updateReflectiveNames() { - preserveNames(); - Map result = {}; - List keys = JS('List', 'Object.keys(#)', _jsMangledNames); - for (String key in keys) { - var reflectiveName = JS('var', '#[#]', _jsMangledNames, key); - // Filter out all non-string values to protect against polution from - // ancillary fields in [_jsMangledNames]. - bool filter = JS('bool', 'typeof # !== "string"', reflectiveName); - if (filter) continue; - result[reflectiveName] = JS('String', '#', key); - - String getterPrefix = JS_GET_NAME(JsGetName.GETTER_PREFIX); - if (_isInstance && key.startsWith(getterPrefix)) { - int getterPrefixLength = getterPrefix.length; - String setterPrefix = JS_GET_NAME(JsGetName.SETTER_PREFIX); - result['$reflectiveName='] = - '$setterPrefix${key.substring(getterPrefixLength)}'; - } - } - return result; - } - - int get _jsMangledNamesLength => - JS('int', 'Object.keys(#).length', _jsMangledNames); - - String? operator [](String key) { - if (_cache == null || _jsMangledNamesLength != _cacheLength) { - _cache = _updateReflectiveNames(); - _cacheLength = _jsMangledNamesLength; - } - return _cache![key]; - } -} - -@pragma('dart2js:noInline') -List extractKeys(victim) { - var result = JS('', '# ? Object.keys(#) : []', victim, victim); - return new JSArray.markFixed(result); -} - -/// Returns the (global) unmangled version of [name]. -/// -/// Normally, you should use [mangledGlobalNames] directly, but this method -/// doesn't tell the compiler to preserve names. So this method only returns a -/// non-null value if some other component has made the compiler preserve names. -/// -/// This is used, for example, to return unmangled names from TypeImpl.toString -/// *if* names are being preserved for other reasons (use of dart:mirrors, for -/// example). -String? unmangleGlobalNameIfPreservedAnyways(String name) { - var names = JS_EMBEDDED_GLOBAL('', MANGLED_GLOBAL_NAMES); - return JS('String|Null', '#', JsCache.fetch(names, name)); -} - -String unmangleAllIdentifiersIfPreservedAnyways(String str) { - return JS( - 'String', - r''' - (function(str, names) { - return str.replace( - /[^<,> ]+/g, - function(m) { return names[m] || m; }); - })(#, #)''', - str, - JS_EMBEDDED_GLOBAL('', MANGLED_GLOBAL_NAMES)); -} diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/js_number.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/js_number.dart deleted file mode 100644 index 489da646dea..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/lib/js_number.dart +++ /dev/null @@ -1,707 +0,0 @@ -// Copyright (c) 2012, 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. - -part of _interceptors; - -/// The super interceptor class for [JSInt] and [JSDouble]. The compiler -/// recognizes this class as an interceptor, and changes references to -/// [:this:] to actually use the receiver of the method, which is -/// generated as an extra argument added to each member. -/// -/// Note that none of the methods here delegate to a method defined on JSInt or -/// JSDouble. This is exploited in [tryComputeConstantInterceptor]. -class JSNumber extends Interceptor implements double { - const JSNumber(); - - int compareTo(num b) { - if (b is! num) throw argumentErrorValue(b); - if (this < b) { - return -1; - } else if (this > b) { - return 1; - } else if (this == b) { - if (this == 0) { - bool bIsNegative = b.isNegative; - if (isNegative == bIsNegative) return 0; - if (isNegative) return -1; - return 1; - } - return 0; - } else if (isNaN) { - if (b.isNaN) { - return 0; - } - return 1; - } else { - return -1; - } - } - - bool get isNegative => (this == 0) ? (1 / this) < 0 : this < 0; - - bool get isNaN => JS( - 'returns:bool;effects:none;depends:none;throws:never;gvn:true', - r'isNaN(#)', - this); - - bool get isInfinite { - return JS('bool', r'# == (1/0)', this) || JS('bool', r'# == (-1/0)', this); - } - - bool get isFinite => JS( - 'returns:bool;effects:none;depends:none;throws:never;gvn:true', - r'isFinite(#)', - this); - - JSNumber remainder(num b) { - if (b is! num) throw argumentErrorValue(b); - return JS('num', r'# % #', this, b); - } - - // Use invoke_dynamic_specializer instead of inlining. - @pragma('dart2js:noInline') - JSNumber abs() => JS( - 'returns:num;effects:none;depends:none;throws:never;gvn:true', - r'Math.abs(#)', - this); - - JSNumber get sign => (this > 0 ? 1 : this < 0 ? -1 : this) as JSNumber; - - static const int _MIN_INT32 = -0x80000000; - static const int _MAX_INT32 = 0x7FFFFFFF; - - int toInt() { - if (this >= _MIN_INT32 && this <= _MAX_INT32) { - // 0 and -0.0 handled here. - return JS('int', '# | 0', this); - } - if (JS('bool', r'isFinite(#)', this)) { - return JS('int', r'# + 0', truncateToDouble()); // Converts -0.0 to +0.0. - } - // [this] is either NaN, Infinity or -Infinity. - throw new UnsupportedError(JS('String', '"" + # + ".toInt()"', this)); - } - - int truncate() => toInt(); - - int ceil() { - if (this >= 0) { - if (this <= _MAX_INT32) { - int truncated = JS('int', '# | 0', this); // converts -0.0 to 0. - return this == truncated ? truncated : truncated + 1; - } - } else { - if (this >= _MIN_INT32) { - return JS('int', '# | 0', this); - } - } - var d = JS('num', 'Math.ceil(#)', this); - if (JS('bool', r'isFinite(#)', d)) { - return JS('int', r'#', d); - } - // [this] is either NaN, Infinity or -Infinity. - throw new UnsupportedError(JS('String', '"" + # + ".ceil()"', this)); - } - - int floor() { - if (this >= 0) { - if (this <= _MAX_INT32) { - return JS('int', '# | 0', this); - } - } else { - if (this >= _MIN_INT32) { - int truncated = JS('int', '# | 0', this); - return this == truncated ? truncated : truncated - 1; - } - } - var d = JS('num', 'Math.floor(#)', this); - if (JS('bool', r'isFinite(#)', d)) { - return JS('int', r'#', d); - } - // [this] is either NaN, Infinity or -Infinity. - throw new UnsupportedError(JS('String', '"" + # + ".floor()"', this)); - } - - int round() { - if (this > 0) { - // This path excludes the special cases -0.0, NaN and -Infinity, leaving - // only +Infinity, for which a direct test is faster than [isFinite]. - if (JS('bool', r'# !== (1/0)', this)) { - return JS('int', r'Math.round(#)', this); - } - } else if (JS('bool', '# > (-1/0)', this)) { - // This test excludes NaN and -Infinity, leaving only -0.0. - // - // Subtraction from zero rather than negation forces -0.0 to 0.0 so code - // inside Math.round and code to handle result never sees -0.0, which on - // some JavaScript VMs can be a slow path. - return JS('int', r'0 - Math.round(0 - #)', this); - } - // [this] is either NaN, Infinity or -Infinity. - throw new UnsupportedError(JS('String', '"" + # + ".round()"', this)); - } - - double ceilToDouble() => JS('num', r'Math.ceil(#)', this); - - double floorToDouble() => JS('num', r'Math.floor(#)', this); - - double roundToDouble() { - if (this < 0) { - return JS('num', r'-Math.round(-#)', this); - } else { - return JS('num', r'Math.round(#)', this); - } - } - - double truncateToDouble() => this < 0 ? ceilToDouble() : floorToDouble(); - - num clamp(lowerLimit, upperLimit) { - if (lowerLimit is! num) throw argumentErrorValue(lowerLimit); - if (upperLimit is! num) throw argumentErrorValue(upperLimit); - if (lowerLimit.compareTo(upperLimit) > 0) { - throw argumentErrorValue(lowerLimit); - } - if (this.compareTo(lowerLimit) < 0) return lowerLimit; - if (this.compareTo(upperLimit) > 0) return upperLimit; - return this; - } - - // The return type is intentionally omitted to avoid type checker warnings - // from assigning JSNumber to double. - toDouble() => this; - - String toStringAsFixed(int fractionDigits) { - checkInt(fractionDigits); - if (fractionDigits < 0 || fractionDigits > 20) { - throw new RangeError.range(fractionDigits, 0, 20, 'fractionDigits'); - } - String result = JS('String', r'#.toFixed(#)', this, fractionDigits); - if (this == 0 && isNegative) return '-$result'; - return result; - } - - String toStringAsExponential([int? fractionDigits]) { - String result; - if (fractionDigits != null) { - checkInt(fractionDigits); - if (fractionDigits < 0 || fractionDigits > 20) { - throw new RangeError.range(fractionDigits, 0, 20, 'fractionDigits'); - } - result = JS('String', r'#.toExponential(#)', this, fractionDigits); - } else { - result = JS('String', r'#.toExponential()', this); - } - if (this == 0 && isNegative) return '-$result'; - return result; - } - - String toStringAsPrecision(int precision) { - checkInt(precision); - if (precision < 1 || precision > 21) { - throw new RangeError.range(precision, 1, 21, 'precision'); - } - String result = JS('String', r'#.toPrecision(#)', this, precision); - if (this == 0 && isNegative) return '-$result'; - return result; - } - - String toRadixString(int radix) { - checkInt(radix); - if (radix < 2 || radix > 36) { - throw new RangeError.range(radix, 2, 36, 'radix'); - } - String result = JS('String', r'#.toString(#)', this, radix); - const int rightParenCode = 0x29; - if (result.codeUnitAt(result.length - 1) != rightParenCode) { - return result; - } - return _handleIEtoString(result); - } - - static String _handleIEtoString(String result) { - // Result is probably IE's untraditional format for large numbers, - // e.g., "8.0000000000008(e+15)" for 0x8000000000000800.toString(16). - var match = JS('JSArray|Null', - r'/^([\da-z]+)(?:\.([\da-z]+))?\(e\+(\d+)\)$/.exec(#)', result); - if (match == null) { - // Then we don't know how to handle it at all. - throw new UnsupportedError('Unexpected toString result: $result'); - } - result = JS('String', '#', match[1]); - int exponent = JS('int', '+#', match[3]); - if (match[2] != null) { - result = JS('String', '# + #', result, match[2]); - exponent -= JS('int', '#.length', match[2]); - } - return result + '0' * exponent; - } - - // Note: if you change this, also change the function [S]. - String toString() { - if (this == 0 && JS('bool', '(1 / #) < 0', this)) { - return '-0.0'; - } else { - return JS('String', r'"" + (#)', this); - } - } - - int get hashCode { - int intValue = JS('int', '# | 0', this); - // Fast exit for integers in signed 32-bit range. Masking converts -0.0 to 0 - // and ensures that result fits in JavaScript engine's Smi range. - if (this == intValue) return 0x1FFFFFFF & intValue; - - // We would like to access the exponent and mantissa as integers but there - // are no JavaScript operations that do this, so use log2-floor-pow-divide - // to extract the values. - num absolute = JS('num', 'Math.abs(#)', this); - num lnAbsolute = JS('num', 'Math.log(#)', absolute); - num log2 = lnAbsolute / ln2; - // Floor via '# | 0' converts NaN to zero so the final result is not NaN. - int floorLog2 = JS('int', '# | 0', log2); - num factor = JS('num', 'Math.pow(2, #)', floorLog2); - num scaled = absolute < 1 ? absolute / factor : factor / absolute; - // [scaled] is in the range [0.5, 1]. - - // Multiply and truncate to pick up all the mantissa bits. Multiplying by - // 0x20000000000000 (which has 53 zero bits) converts the mantissa into an - // integer. There are interesting subsets where all the bit variance is in - // the most significant bits of the mantissa (e.g. 0.5, 0.625, 0.75), so we - // need to mix in the most significant bits. We do this by scaling with a - // constant that has many bits set to use the multiplier to mix in bits from - // all over the mantissa into low positions. - num rescaled1 = scaled * 0x20000000000000; - num rescaled2 = scaled * 0x0C95A6C285A6C9; - int d1 = JS('int', '# | 0', rescaled1); - int d2 = JS('int', '# | 0', rescaled2); - // Mix in exponent to distinguish e.g. 1.25 from 2.5. - int d3 = floorLog2; - int h = 0x1FFFFFFF & ((d1 + d2) * (601 * 997) + d3 * (1259)); - return h; - } - - JSNumber operator -() => JS('num', r'-#', this); - - JSNumber operator +(num other) { - if (other is! num) throw argumentErrorValue(other); - return JS('num', '# + #', this, other); - } - - JSNumber operator -(num other) { - if (other is! num) throw argumentErrorValue(other); - return JS('num', '# - #', this, other); - } - - double operator /(num other) { - if (other is! num) throw argumentErrorValue(other); - return JS('num', '# / #', this, other); - } - - JSNumber operator *(num other) { - if (other is! num) throw argumentErrorValue(other); - return JS('num', '# * #', this, other); - } - - JSNumber operator %(num other) { - if (other is! num) throw argumentErrorValue(other); - // Euclidean Modulo. - JSNumber result = JS('JSNumber', r'# % #', this, other); - if (result == 0) return JS('num', '0'); // Make sure we don't return -0.0. - if (result > 0) return result; - if (JS('num', '#', other) < 0) { - return result - JS('JSNumber', '#', other); - } else { - return result + JS('JSNumber', '#', other); - } - } - - bool _isInt32(value) => JS('bool', '(# | 0) === #', value, value); - - int operator ~/(num other) { - if (other is! num) throw argumentErrorValue(other); - if (false) _tdivFast(other); // Ensure resolution. - if (_isInt32(this)) { - if (other >= 1 || other < -1) { - return JS('int', r'(# / #) | 0', this, other); - } - } - return _tdivSlow(other); - } - - int _tdivFast(num other) { - // [other] is known to be a number outside the range [-1, 1). - return _isInt32(this) - ? JS('int', r'(# / #) | 0', this, other) - : _tdivSlow(other); - } - - int _tdivSlow(num other) { - var quotient = JS('num', r'# / #', this, other); - if (quotient >= _MIN_INT32 && quotient <= _MAX_INT32) { - // This path includes -0.0 and +0.0. - return JS('int', '# | 0', quotient); - } - if (quotient > 0) { - // This path excludes the special cases -0.0, NaN and -Infinity, leaving - // only +Infinity, for which a direct test is faster than [isFinite]. - if (JS('bool', r'# !== (1/0)', quotient)) { - return JS('int', r'Math.floor(#)', quotient); - } - } else if (JS('bool', '# > (-1/0)', quotient)) { - // This test excludes NaN and -Infinity. - return JS('int', r'Math.ceil(#)', quotient); - } - - // [quotient] is either NaN, Infinity or -Infinity. - throw new UnsupportedError( - 'Result of truncating division is $quotient: $this ~/ $other'); - } - - // TODO(ngeoffray): Move the bit operations below to [JSInt] and - // make them take an int. Because this will make operations slower, - // we define these methods on number for now but we need to decide - // the grain at which we do the type checks. - - num operator <<(num other) { - if (other is! num) throw argumentErrorValue(other); - if (JS('num', '#', other) < 0) throw argumentErrorValue(other); - return _shlPositive(other); - } - - num _shlPositive(num other) { - // JavaScript only looks at the last 5 bits of the shift-amount. Shifting - // by 33 is hence equivalent to a shift by 1. - return JS('bool', r'# > 31', other) - ? 0 - : JS('JSUInt32', r'(# << #) >>> 0', this, other); - } - - num operator >>(num other) { - if (false) _shrReceiverPositive(other); - if (other is! num) throw argumentErrorValue(other); - if (JS('num', '#', other) < 0) throw argumentErrorValue(other); - return _shrOtherPositive(other); - } - - num _shrOtherPositive(num other) { - return JS('num', '#', this) > 0 - ? _shrBothPositive(other) - // For negative numbers we just clamp the shift-by amount. - // `this` could be negative but not have its 31st bit set. - // The ">>" would then shift in 0s instead of 1s. Therefore - // we cannot simply return 0xFFFFFFFF. - : JS('JSUInt32', r'(# >> #) >>> 0', this, other > 31 ? 31 : other); - } - - num _shrReceiverPositive(num other) { - if (JS('num', '#', other) < 0) throw argumentErrorValue(other); - return _shrBothPositive(other); - } - - num _shrBothPositive(num other) { - return JS('bool', r'# > 31', other) - // JavaScript only looks at the last 5 bits of the shift-amount. In JS - // shifting by 33 is hence equivalent to a shift by 1. Shortcut the - // computation when that happens. - ? 0 - // Given that `this` is positive we must not use '>>'. Otherwise a - // number that has the 31st bit set would be treated as negative and - // shift in ones. - : JS('JSUInt32', r'# >>> #', this, other); - } - - num operator &(num other) { - if (other is! num) throw argumentErrorValue(other); - return JS('JSUInt32', r'(# & #) >>> 0', this, other); - } - - num operator |(num other) { - if (other is! num) throw argumentErrorValue(other); - return JS('JSUInt32', r'(# | #) >>> 0', this, other); - } - - num operator ^(num other) { - if (other is! num) throw argumentErrorValue(other); - return JS('JSUInt32', r'(# ^ #) >>> 0', this, other); - } - - bool operator <(num other) { - if (other is! num) throw argumentErrorValue(other); - return JS('bool', '# < #', this, other); - } - - bool operator >(num other) { - if (other is! num) throw argumentErrorValue(other); - return JS('bool', '# > #', this, other); - } - - bool operator <=(num other) { - if (other is! num) throw argumentErrorValue(other); - return JS('bool', '# <= #', this, other); - } - - bool operator >=(num other) { - if (other is! num) throw argumentErrorValue(other); - return JS('bool', '# >= #', this, other); - } - - Type get runtimeType => num; -} - -/// The interceptor class for [int]s. -/// -/// This class implements double (indirectly through JSNumber) since in -/// JavaScript all numbers are doubles, so while we want to treat `2.0` as an -/// integer for some operations, its interceptor should answer `true` to `is -/// double`. -class JSInt extends JSNumber implements int { - const JSInt(); - - @override - // Use invoke_dynamic_specializer instead of inlining. - @pragma('dart2js:noInline') - JSInt abs() => JS( - 'returns:int;effects:none;depends:none;throws:never;gvn:true', - r'Math.abs(#)', - this); - - @override - JSInt get sign => (this > 0 ? 1 : this < 0 ? -1 : this) as JSInt; - - @override - JSInt operator -() => JS('int', r'-#', this); - - bool get isEven => (this & 1) == 0; - - bool get isOdd => (this & 1) == 1; - - int toUnsigned(int width) { - return this & ((1 << width) - 1); - } - - int toSigned(int width) { - int signMask = 1 << (width - 1); - return (this & (signMask - 1)) - (this & signMask); - } - - int get bitLength { - int nonneg = (this < 0 ? -this - 1 : this) as int; - int wordBits = 32; - while (nonneg >= 0x100000000) { - nonneg = nonneg ~/ 0x100000000; - wordBits += 32; - } - return wordBits - _clz32(nonneg); - } - - static int _clz32(int uint32) { - // TODO(sra): Use `Math.clz32(uint32)` (not available on IE11). - return 32 - _bitCount(_spread(uint32)); - } - - // Returns pow(this, e) % m. - int modPow(int e, int m) { - if (e is! int) { - throw ArgumentError.value(e, 'exponent', 'not an integer'); - } - if (m is! int) { - throw ArgumentError.value(m, 'modulus', 'not an integer'); - } - if (e < 0) throw RangeError.range(e, 0, null, 'exponent'); - if (m <= 0) throw RangeError.range(m, 1, null, 'modulus'); - if (e == 0) return 1; - - const int maxPreciseInteger = 9007199254740991; - - // Reject inputs that are outside the range of integer values that can be - // represented precisely as a Number (double). - if (this < -maxPreciseInteger || this > maxPreciseInteger) { - throw RangeError.range( - this, -maxPreciseInteger, maxPreciseInteger, 'receiver'); - } - if (e > maxPreciseInteger) { - throw RangeError.range(e, 0, maxPreciseInteger, 'exponent'); - } - if (m > maxPreciseInteger) { - throw RangeError.range(e, 1, maxPreciseInteger, 'modulus'); - } - - // This is floor(sqrt(maxPreciseInteger)). - const int maxValueThatCanBeSquaredWithoutTruncation = 94906265; - if (m > maxValueThatCanBeSquaredWithoutTruncation) { - // Use BigInt version to avoid truncation in multiplications below. The - // 'maxPreciseInteger' check on [m] ensures that toInt() does not round. - return BigInt.from(this).modPow(BigInt.from(e), BigInt.from(m)).toInt(); - } - - int b = this; - if (b < 0 || b > m) { - b %= m; - } - int r = 1; - while (e > 0) { - if (e.isOdd) { - r = (r * b) % m; - } - e ~/= 2; - b = (b * b) % m; - } - return r; - } - - // If inv is false, returns gcd(x, y). - // If inv is true and gcd(x, y) = 1, returns d, so that c*x + d*y = 1. - // If inv is true and gcd(x, y) != 1, throws Exception("Not coprime"). - static int _binaryGcd(int x, int y, bool inv) { - int s = 1; - if (!inv) { - while (x.isEven && y.isEven) { - x ~/= 2; - y ~/= 2; - s *= 2; - } - if (y.isOdd) { - var t = x; - x = y; - y = t; - } - } - final bool ac = x.isEven; - int u = x; - int v = y; - int a = 1, b = 0, c = 0, d = 1; - do { - while (u.isEven) { - u ~/= 2; - if (ac) { - if (!a.isEven || !b.isEven) { - a += y; - b -= x; - } - a ~/= 2; - } else if (!b.isEven) { - b -= x; - } - b ~/= 2; - } - while (v.isEven) { - v ~/= 2; - if (ac) { - if (!c.isEven || !d.isEven) { - c += y; - d -= x; - } - c ~/= 2; - } else if (!d.isEven) { - d -= x; - } - d ~/= 2; - } - if (u >= v) { - u -= v; - if (ac) a -= c; - b -= d; - } else { - v -= u; - if (ac) c -= a; - d -= b; - } - } while (u != 0); - if (!inv) return s * v; - if (v != 1) throw new Exception('Not coprime'); - if (d < 0) { - d += x; - if (d < 0) d += x; - } else if (d > x) { - d -= x; - if (d > x) d -= x; - } - return d; - } - - // Returns 1/this % m, with m > 0. - int modInverse(int m) { - if (m is! int) { - throw new ArgumentError.value(m, 'modulus', 'not an integer'); - } - if (m <= 0) throw new RangeError.range(m, 1, null, 'modulus'); - if (m == 1) return 0; - int t = this; - if ((t < 0) || (t >= m)) t %= m; - if (t == 1) return 1; - if ((t == 0) || (t.isEven && m.isEven)) { - throw new Exception('Not coprime'); - } - return _binaryGcd(m, t, true); - } - - // Returns gcd of abs(this) and abs(other). - int gcd(int other) { - if (other is! int) { - throw new ArgumentError.value(other, 'other', 'not an integer'); - } - int x = this.abs(); - int y = other.abs(); - if (x == 0) return y; - if (y == 0) return x; - if ((x == 1) || (y == 1)) return 1; - return _binaryGcd(x, y, false); - } - - // Assumes i is <= 32-bit and unsigned. - static int _bitCount(int i) { - // See "Hacker's Delight", section 5-1, "Counting 1-Bits". - - // The basic strategy is to use "divide and conquer" to - // add pairs (then quads, etc.) of bits together to obtain - // sub-counts. - // - // A straightforward approach would look like: - // - // i = (i & 0x55555555) + ((i >> 1) & 0x55555555); - // i = (i & 0x33333333) + ((i >> 2) & 0x33333333); - // i = (i & 0x0F0F0F0F) + ((i >> 4) & 0x0F0F0F0F); - // i = (i & 0x00FF00FF) + ((i >> 8) & 0x00FF00FF); - // i = (i & 0x0000FFFF) + ((i >> 16) & 0x0000FFFF); - // - // The code below removes unnecessary &'s and uses a - // trick to remove one instruction in the first line. - - i = _shru(i, 0) - (_shru(i, 1) & 0x55555555); - i = (i & 0x33333333) + (_shru(i, 2) & 0x33333333); - i = 0x0F0F0F0F & (i + _shru(i, 4)); - i += _shru(i, 8); - i += _shru(i, 16); - return (i & 0x0000003F); - } - - static int _shru(int value, int shift) => JS('int', '# >>> #', value, shift); - static int _shrs(int value, int shift) => JS('int', '# >> #', value, shift); - static int _ors(int a, int b) => JS('int', '# | #', a, b); - - // Assumes i is <= 32-bit - static int _spread(int i) { - i = _ors(i, _shrs(i, 1)); - i = _ors(i, _shrs(i, 2)); - i = _ors(i, _shrs(i, 4)); - i = _ors(i, _shrs(i, 8)); - i = _shru(_ors(i, _shrs(i, 16)), 0); - return i; - } - - Type get runtimeType => int; - - int operator ~() => JS('JSUInt32', r'(~#) >>> 0', this); -} - -class JSDouble extends JSNumber implements double { - const JSDouble(); - Type get runtimeType => double; -} - -class JSPositiveInt extends JSInt {} - -class JSUInt32 extends JSPositiveInt {} - -class JSUInt31 extends JSUInt32 {} diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/js_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/js_patch.dart deleted file mode 100644 index 1ff2e550b21..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/lib/js_patch.dart +++ /dev/null @@ -1,568 +0,0 @@ -// 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. - -// Patch file for dart:js library. -import 'dart:collection' show HashMap, ListMixin; -import 'dart:typed_data' show TypedData; - -import 'dart:_foreign_helper' show JS, DART_CLOSURE_TO_JS; -import 'dart:_interceptors' show DART_CLOSURE_PROPERTY_NAME; -import 'dart:_js_helper' show patch, Primitives, getIsolateAffinityTag; -import 'dart:_js' show isBrowserObject, convertFromBrowserObject; - -@patch -JsObject get context => _context; - -final JsObject _context = _castToJsObject(_wrapToDart(JS('', 'self'))); - -_convertDartFunction(Function f, {bool captureThis: false}) { - return JS( - 'JavaScriptFunction', - ''' - function(_call, f, captureThis) { - return function() { - return _call(f, captureThis, this, - Array.prototype.slice.apply(arguments)); - } - }(#, #, #) - ''', - DART_CLOSURE_TO_JS(_callDartFunction), - f, - captureThis); -} - -_callDartFunction(callback, bool captureThis, self, List arguments) { - if (captureThis) { - arguments = [self]..addAll(arguments); - } - var dartArgs = List.from(arguments.map(_convertToDart)); - return _convertToJS(Function.apply(callback, dartArgs)); -} - -@patch -class JsObject { - // The wrapped JS object. - final Object _jsObject; - - // This should only be called from _wrapToDart - JsObject._fromJs(this._jsObject) { - assert(_jsObject != null); - } - - @patch - factory JsObject(JsFunction constructor, [List? arguments]) { - var ctor = _convertToJS(constructor); - if (arguments == null) { - return _castToJsObject(_wrapToDart(JS('', 'new #()', ctor))); - } - - if (JS('bool', '# instanceof Array', arguments)) { - int argumentCount = JS('int', '#.length', arguments); - switch (argumentCount) { - case 0: - return _castToJsObject(_wrapToDart(JS('', 'new #()', ctor))); - - case 1: - var arg0 = _convertToJS(JS('', '#[0]', arguments)); - return _castToJsObject(_wrapToDart(JS('', 'new #(#)', ctor, arg0))); - - case 2: - var arg0 = _convertToJS(JS('', '#[0]', arguments)); - var arg1 = _convertToJS(JS('', '#[1]', arguments)); - return _castToJsObject( - _wrapToDart(JS('', 'new #(#, #)', ctor, arg0, arg1))); - - case 3: - var arg0 = _convertToJS(JS('', '#[0]', arguments)); - var arg1 = _convertToJS(JS('', '#[1]', arguments)); - var arg2 = _convertToJS(JS('', '#[2]', arguments)); - return _castToJsObject( - _wrapToDart(JS('', 'new #(#, #, #)', ctor, arg0, arg1, arg2))); - - case 4: - var arg0 = _convertToJS(JS('', '#[0]', arguments)); - var arg1 = _convertToJS(JS('', '#[1]', arguments)); - var arg2 = _convertToJS(JS('', '#[2]', arguments)); - var arg3 = _convertToJS(JS('', '#[3]', arguments)); - return _castToJsObject(_wrapToDart( - JS('', 'new #(#, #, #, #)', ctor, arg0, arg1, arg2, arg3))); - } - } - - // The following code solves the problem of invoking a JavaScript - // constructor with an unknown number arguments. - // First bind the constructor to the argument list using bind.apply(). - // The first argument to bind() is the binding of 'this', so add 'null' to - // the arguments list passed to apply(). - // After that, use the JavaScript 'new' operator which overrides any binding - // of 'this' with the new instance. - var args = [null]..addAll(arguments.map(_convertToJS)); - var factoryFunction = JS('', '#.bind.apply(#, #)', ctor, ctor, args); - // Without this line, calling factoryFunction as a constructor throws - JS('String', 'String(#)', factoryFunction); - // This could return an UnknownJavaScriptObject, or a native - // object for which there is an interceptor - var jsObj = JS('', 'new #()', factoryFunction); - - return _castToJsObject(_wrapToDart(jsObj)); - - // TODO(sra): Investigate: - // - // var jsObj = JS('', 'Object.create(#.prototype)', ctor); - // JS('', '#.apply(#, #)', ctor, jsObj, - // []..addAll(arguments.map(_convertToJS))); - // return _wrapToDart(jsObj); - } - - @patch - factory JsObject.fromBrowserObject(Object object) { - if (object is num || object is String || object is bool || object == null) { - throw ArgumentError("object cannot be a num, string, bool, or null"); - } - return _castToJsObject(_wrapToDart(_convertToJS(object))); - } - - @patch - factory JsObject.jsify(Object object) { - if ((object is! Map) && (object is! Iterable)) { - throw ArgumentError("object must be a Map or Iterable"); - } - return _castToJsObject(_wrapToDart(_convertDataTree(object))); - } - - static _convertDataTree(Object data) { - var _convertedObjects = HashMap.identity(); - - _convert(Object? o) { - if (_convertedObjects.containsKey(o)) { - return _convertedObjects[o]; - } - if (o is Map) { - final convertedMap = JS('=Object', '{}'); - _convertedObjects[o] = convertedMap; - for (var key in o.keys) { - JS('=Object', '#[#] = #', convertedMap, key, _convert(o[key])); - } - return convertedMap; - } else if (o is Iterable) { - var convertedList = []; - _convertedObjects[o] = convertedList; - convertedList.addAll(o.map(_convert)); - return convertedList; - } else { - return _convertToJS(o); - } - } - - return _convert(data); - } - - @patch - dynamic operator [](Object property) { - if (property is! String && property is! num) { - throw ArgumentError("property is not a String or num"); - } - return _convertToDart(JS('', '#[#]', _jsObject, property)); - } - - @patch - void operator []=(Object property, Object? value) { - if (property is! String && property is! num) { - throw ArgumentError("property is not a String or num"); - } - JS('', '#[#] = #', _jsObject, property, _convertToJS(value)); - } - - @patch - bool operator ==(Object other) => - other is JsObject && JS('bool', '# === #', _jsObject, other._jsObject); - - @patch - bool hasProperty(Object property) { - if (property is! String && property is! num) { - throw ArgumentError("property is not a String or num"); - } - return JS('bool', '# in #', property, _jsObject); - } - - @patch - void deleteProperty(Object property) { - if (property is! String && property is! num) { - throw ArgumentError("property is not a String or num"); - } - JS('bool', 'delete #[#]', _jsObject, property); - } - - @patch - bool instanceof(JsFunction type) { - return JS('bool', '# instanceof #', _jsObject, _convertToJS(type)); - } - - @patch - String toString() { - try { - return JS('String', 'String(#)', _jsObject); - } catch (e) { - return super.toString(); - } - } - - @patch - dynamic callMethod(Object method, [List? args]) { - if (method is! String && method is! num) { - throw ArgumentError("method is not a String or num"); - } - return _convertToDart(JS('', '#[#].apply(#, #)', _jsObject, method, - _jsObject, args == null ? null : List.from(args.map(_convertToJS)))); - } -} - -@patch -class JsFunction extends JsObject { - @patch - factory JsFunction.withThis(Function f) { - var jsFunc = _convertDartFunction(f, captureThis: true); - return JsFunction._fromJs(jsFunc); - } - - JsFunction._fromJs(Object jsObject) : super._fromJs(jsObject); - - @patch - dynamic apply(List args, {thisArg}) => _convertToDart(JS( - '', - '#.apply(#, #)', - _jsObject, - _convertToJS(thisArg), - args == null ? null : List.from(args.map(_convertToJS)))); -} - -@patch -class JsArray extends JsObject with ListMixin { - @patch - factory JsArray() => JsArray._fromJs([]); - - @patch - factory JsArray.from(Iterable other) => - JsArray._fromJs([]..addAll(other.map(_convertToJS))); - - JsArray._fromJs(Object jsObject) : super._fromJs(jsObject); - - _checkIndex(int index) { - if (index is int && (index < 0 || index >= length)) { - throw RangeError.range(index, 0, length); - } - } - - _checkInsertIndex(int index) { - if (index is int && (index < 0 || index >= length + 1)) { - throw RangeError.range(index, 0, length); - } - } - - static _checkRange(int start, int end, int length) { - if (start < 0 || start > length) { - throw RangeError.range(start, 0, length); - } - if (end < start || end > length) { - throw RangeError.range(end, start, length); - } - } - - // Methods required by ListMixin - - @patch - E operator [](Object index) { - if (index is int) { - _checkIndex(index); - } - return super[index]; - } - - @patch - void operator []=(Object index, Object? value) { - if (index is int) { - _checkIndex(index); - } - super[index] = value; - } - - @patch - int get length { - // Check the length honours the List contract. - var len = JS('', '#.length', _jsObject); - // JavaScript arrays have lengths which are unsigned 32-bit integers. - if (JS('bool', 'typeof # === "number" && (# >>> 0) === #', len, len, len)) { - return JS('int', '#', len); - } - throw StateError('Bad JsArray length'); - } - - @patch - void set length(int length) { - super['length'] = length; - } - - // Methods overridden for better performance - - @patch - void add(E value) { - callMethod('push', [value]); - } - - @patch - void addAll(Iterable iterable) { - var list = (JS('bool', '# instanceof Array', iterable)) - ? JS('JSArray', '#', iterable) - : List.from(iterable); - callMethod('push', list); - } - - @patch - void insert(int index, E element) { - _checkInsertIndex(index); - callMethod('splice', [index, 0, element]); - } - - @patch - E removeAt(int index) { - _checkIndex(index); - return callMethod('splice', [index, 1])[0]; - } - - @patch - E removeLast() { - if (length == 0) throw RangeError(-1); - return callMethod('pop'); - } - - @patch - void removeRange(int start, int end) { - _checkRange(start, end, length); - callMethod('splice', [start, end - start]); - } - - @patch - void setRange(int start, int end, Iterable iterable, [int skipCount = 0]) { - _checkRange(start, end, this.length); - int length = end - start; - if (length == 0) return; - if (skipCount < 0) throw ArgumentError(skipCount); - var args = [start, length] - ..addAll(iterable.skip(skipCount).take(length)); - callMethod('splice', args); - } - - @patch - void sort([int compare(E a, E b)?]) { - // Note: arr.sort(null) is a type error in FF - callMethod('sort', compare == null ? [] : [compare]); - } -} - -// property added to a Dart object referencing its JS-side DartObject proxy -final String _DART_OBJECT_PROPERTY_NAME = - getIsolateAffinityTag(r'_$dart_dartObject'); - -// property added to a JS object referencing its Dart-side JsObject proxy -const _JS_OBJECT_PROPERTY_NAME = r'_$dart_jsObject'; -const _JS_FUNCTION_PROPERTY_NAME = r'$dart_jsFunction'; -const _JS_FUNCTION_PROPERTY_NAME_CAPTURE_THIS = r'_$dart_jsFunctionCaptureThis'; - -@pragma('dart2js:tryInline') -JsObject _castToJsObject(o) => JS('', '#', o); - -bool _defineProperty(o, String name, value) { - try { - if (_isExtensible(o) && - // TODO(ahe): Calling _hasOwnProperty to work around - // https://code.google.com/p/dart/issues/detail?id=21331. - !_hasOwnProperty(o, name)) { - JS('void', 'Object.defineProperty(#, #, { value: #})', o, name, value); - return true; - } - } catch (e) { - // object is native and lies about being extensible - // see https://bugzilla.mozilla.org/show_bug.cgi?id=775185 - // Or, isExtensible throws for this object. - } - return false; -} - -bool _hasOwnProperty(o, String name) { - return JS('bool', 'Object.prototype.hasOwnProperty.call(#, #)', o, name); -} - -bool _isExtensible(o) => JS('bool', 'Object.isExtensible(#)', o); - -Object? _getOwnProperty(o, String name) { - if (_hasOwnProperty(o, name)) { - return JS('', '#[#]', o, name); - } - return null; -} - -bool _isLocalObject(o) => JS('bool', '# instanceof Object', o); - -// The shared constructor function for proxies to Dart objects in JavaScript. -final _dartProxyCtor = JS('', 'function DartObject(o) { this.o = o; }'); - -Object? _convertToJS(Object? o) { - // Note: we don't write `if (o == null) return null;` to make sure dart2js - // doesn't convert `return null;` into `return;` (which would make `null` be - // `undefined` in Javascprit). See dartbug.com/20305 for details. - if (o == null || o is String || o is num || o is bool) { - return o; - } - if (o is JsObject) { - return o._jsObject; - } - if (isBrowserObject(o)) { - return o; - } - if (o is TypedData) { - return o; - } - if (o is DateTime) { - return Primitives.lazyAsJsDate(o); - } - if (o is Function) { - return _getJsProxy(o, _JS_FUNCTION_PROPERTY_NAME, (o) { - var jsFunction = _convertDartFunction(o); - // set a property on the JS closure referencing the Dart closure - _defineProperty(jsFunction, DART_CLOSURE_PROPERTY_NAME, o); - return jsFunction; - }); - } - var ctor = _dartProxyCtor; - return _getJsProxy( - o, _JS_OBJECT_PROPERTY_NAME, (o) => JS('', 'new #(#)', ctor, o)); -} - -Object? _getJsProxy(o, String propertyName, createProxy(o)) { - var jsProxy = _getOwnProperty(o, propertyName); - if (jsProxy == null) { - jsProxy = createProxy(o); - _defineProperty(o, propertyName, jsProxy); - } - return jsProxy; -} - -// converts a Dart object to a reference to a native JS object -// which might be a DartObject JS->Dart proxy -Object? _convertToDart(o) { - if (JS('bool', '# == null', o) || - JS('bool', 'typeof # == "string"', o) || - JS('bool', 'typeof # == "number"', o) || - JS('bool', 'typeof # == "boolean"', o)) { - return o; - } else if (_isLocalObject(o) && isBrowserObject(o)) { - return convertFromBrowserObject(o); - } else if (_isLocalObject(o) && o is TypedData) { - return JS('TypedData', '#', o); - } else if (JS('bool', '# instanceof Date', o)) { - var ms = JS('num', '#.getTime()', o); - return DateTime.fromMillisecondsSinceEpoch(ms); - } else if (JS('bool', '#.constructor === #', o, _dartProxyCtor)) { - return JS('', '#.o', o); - } else { - return _wrapToDart(o); - } -} - -Object _wrapToDart(o) { - if (JS('bool', 'typeof # == "function"', o)) { - return _getDartProxy( - o, DART_CLOSURE_PROPERTY_NAME, (o) => JsFunction._fromJs(o)); - } - if (JS('bool', '# instanceof Array', o)) { - return _getDartProxy( - o, _DART_OBJECT_PROPERTY_NAME, (o) => JsArray._fromJs(o)); - } - return _getDartProxy( - o, _DART_OBJECT_PROPERTY_NAME, (o) => JsObject._fromJs(o)); -} - -Object _getDartProxy(o, String propertyName, JsObject createProxy(o)) { - var dartProxy = _getOwnProperty(o, propertyName); - // Temporary fix for dartbug.com/15193 - // In some cases it's possible to see a JavaScript object that - // came from a different context and was previously proxied to - // Dart in that context. The JS object will have a cached proxy - // but it won't be a valid Dart object in this context. - // For now we throw away the cached proxy, but we should be able - // to cache proxies from multiple JS contexts and Dart isolates. - if (dartProxy == null || !_isLocalObject(o)) { - dartProxy = createProxy(o); - _defineProperty(o, propertyName, dartProxy); - } - return dartProxy; -} - -_convertDartFunctionFast(Function f) { - var existing = JS('', '#.#', f, _JS_FUNCTION_PROPERTY_NAME); - if (existing != null) return existing; - var ret = JS( - 'JavaScriptFunction', - ''' - function(_call, f) { - return function() { - return _call(f, Array.prototype.slice.apply(arguments)); - } - }(#, #) - ''', - DART_CLOSURE_TO_JS(_callDartFunctionFast), - f); - JS('', '#.# = #', ret, DART_CLOSURE_PROPERTY_NAME, f); - JS('', '#.# = #', f, _JS_FUNCTION_PROPERTY_NAME, ret); - return ret; -} - -_convertDartFunctionFastCaptureThis(Function f) { - var existing = JS('', '#.#', f, _JS_FUNCTION_PROPERTY_NAME_CAPTURE_THIS); - if (existing != null) return existing; - var ret = JS( - 'JavaScriptFunction', - ''' - function(_call, f) { - return function() { - return _call(f, this,Array.prototype.slice.apply(arguments)); - } - }(#, #) - ''', - DART_CLOSURE_TO_JS(_callDartFunctionFastCaptureThis), - f); - JS('', '#.# = #', ret, DART_CLOSURE_PROPERTY_NAME, f); - JS('', '#.# = #', f, _JS_FUNCTION_PROPERTY_NAME_CAPTURE_THIS, ret); - return ret; -} - -_callDartFunctionFast(callback, List arguments) { - return Function.apply(callback, arguments); -} - -_callDartFunctionFastCaptureThis(callback, self, List arguments) { - return Function.apply(callback, [self]..addAll(arguments)); -} - -@patch -F allowInterop(F f) { - if (JS('bool', 'typeof(#) == "function"', f)) { - // Already supports interop, just use the existing function. - return f; - } else { - return _convertDartFunctionFast(f); - } -} - -@patch -Function allowInteropCaptureThis(Function f) { - if (JS('bool', 'typeof(#) == "function"', f)) { - // Behavior when the function is already a JS function is unspecified. - throw ArgumentError( - "Function is already a JS function so cannot capture this."); - return f; - } else { - return _convertDartFunctionFastCaptureThis(f); - } -} diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/js_primitives.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/js_primitives.dart deleted file mode 100644 index 97577a0ca05..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/lib/js_primitives.dart +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) 2013, 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. - -/// dart2js "primitives", that is, features that cannot be implemented without -/// access to JavaScript features. -library dart2js._js_primitives; - -import 'dart:_foreign_helper' show JS; - -/// This is the low-level method that is used to implement [print]. It is -/// possible to override this function from JavaScript by defining a function in -/// JavaScript called "dartPrint". -/// -/// Notice that it is also possible to intercept calls to [print] from within a -/// Dart program using zones. This means that there is no guarantee that a call -/// to print ends in this method. -void printString(String string) { - if (JS('bool', r'typeof dartPrint == "function"')) { - // Support overriding print from JavaScript. - JS('void', r'dartPrint(#)', string); - return; - } - - // Inside browser or nodejs. - if (JS('bool', r'typeof console == "object"') && - JS('bool', r'typeof console.log != "undefined"')) { - JS('void', r'console.log(#)', string); - return; - } - - // Don't throw inside IE, the console is only defined if dev tools is open. - if (JS('bool', r'typeof window == "object"')) { - return; - } - - // Running in d8, the V8 developer shell, or in Firefox' js-shell. - if (JS('bool', r'typeof print == "function"')) { - JS('void', r'print(#)', string); - return; - } - - // This is somewhat nasty, but we don't want to drag in a bunch of - // dependencies to handle a situation that cannot happen. So we - // avoid using Dart [:throw:] and Dart [toString]. - JS('void', 'throw "Unable to print message: " + String(#)', string); -} diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/js_rti.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/js_rti.dart deleted file mode 100644 index 9b850c94a03..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/lib/js_rti.dart +++ /dev/null @@ -1,554 +0,0 @@ -// Copyright (c) 2013, 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. - -/// This part contains helpers for supporting runtime type information. -/// -/// The helper use a mixture of Dart and JavaScript objects. To indicate which -/// is used where we adopt the scheme of using explicit type annotation for Dart -/// objects and 'var' or omitted return type for JavaScript objects. -/// -/// Since bool, int, and String values are represented by the same JavaScript -/// primitives, type annotations are used for these types in all cases. -/// -/// Several methods use a common JavaScript encoding of runtime type -/// information. This encoding is referred to as the type representation which -/// is one of these: -/// 1) a JavaScript constructor for a class C: the represented type is the raw -/// type C. -/// 2) a JavaScript array: the first entry is of type 1 and contains the -/// subtyping flags and the substitution of the type and the rest of the -/// array are the type arguments. -/// 3) `null`: the dynamic type. -/// 4) a JavaScript object representing the function type. For instance, it has -/// the form {ret: rti, args: [rti], opt: [rti], named: {name: rti}} for a -/// function with a return type, regular, optional and named arguments. -/// Generic function types have a 'bounds' property. -/// -/// To check subtype relations between generic classes we use a JavaScript -/// expression that describes the necessary substitution for type arguments. -/// Such a substitution expression can be: -/// 1) `null`, if no substituted check is necessary, because the -/// type variables are the same or there are no type variables in the class -/// that is checked for. -/// 2) A list expression describing the type arguments to be used in the -/// subtype check, if the type arguments to be used in the check do not -/// depend on the type arguments of the object. -/// 3) A function mapping the type variables of the object to be checked to a -/// list expression. The function may also return null, which is equivalent -/// to an array containing only null values. - -part of _js_helper; - -/// Represents a type variable. -/// -/// This class holds the information needed when reflecting on generic classes -/// and their members. -class TypeVariable { - final Type owner; - final String name; - final int bound; - - const TypeVariable(this.owner, this.name, this.bound); -} - -/// Sets the runtime type information on [target]. [rti] is a type -/// representation of type 4 or 5, that is, either a JavaScript array or `null`. -/// -/// Called from generated code. -/// -/// This is used only for marking JavaScript Arrays (JSArray) with the element -/// type. -// Don't inline. Let the JS engine inline this. The call expression is much -// more compact that the inlined expansion. -@pragma('dart2js:noInline') -Object setRuntimeTypeInfo(Object target, var rti) { - assert(rti != null); - var rtiProperty = JS_EMBEDDED_GLOBAL('', ARRAY_RTI_PROPERTY); - JS('var', r'#[#] = #', target, rtiProperty, rti); - return target; -} - -/// Returns the runtime type information of [target]. The returned value is a -/// list of type representations for the type arguments. -/// -/// Called from generated code. -getRuntimeTypeInfo(Object target) { - if (target == null) return null; - String rtiName = JS_GET_NAME(JsGetName.RTI_NAME); - return JS('var', r'#[#]', target, rtiName); -} - -/// Returns the type arguments of [object] as an instance of [substitutionName]. -getRuntimeTypeArguments(interceptor, object, substitutionName) { - var substitution = getField(interceptor, - '${JS_GET_NAME(JsGetName.OPERATOR_AS_PREFIX)}$substitutionName'); - return substitute(substitution, getRuntimeTypeInfo(object)); -} - -/// Retrieves the class name from type information stored on the constructor -/// of [object]. -String getClassName(var object) { - return rawRtiToJsConstructorName(getRawRuntimeType(getInterceptor(object))); -} - -Type getRuntimeType(var object) { - return newRti.getRuntimeType(object); -} - -/// Applies the [substitution] on the [arguments]. -/// -/// See the comment in the beginning of this file for a description of the -/// possible values for [substitution]. -substitute(var substitution, var arguments) { - if (substitution == null) return arguments; - assert(isJsFunction(substitution)); - assert(arguments == null || isJsArray(arguments)); - substitution = invoke(substitution, arguments); - if (substitution == null) return null; - if (isJsArray(substitution)) { - // Substitutions are generated too late to mark Array as used, so use a - // tautological JS 'cast' to mark Array as used. This is needed only in - // some tiny tests where the substition is the only thing that creates an - // Array. - return JS('JSArray', '#', substitution); - } - if (isJsFunction(substitution)) { - // TODO(johnniwinther): Check if this is still needed. - return invoke(substitution, arguments); - } - return arguments; -} - -bool checkArguments( - var substitution, var arguments, var sEnv, var checks, var tEnv) { - return areSubtypes(substitute(substitution, arguments), sEnv, checks, tEnv); -} - -/// Checks whether the types of [s] are all subtypes of the types of [t]. -/// -/// [s] and [t] are either `null` or JavaScript arrays of type representations, -/// A `null` argument is interpreted as the arguments of a raw type, that is a -/// list of `dynamic`. If [s] and [t] are JavaScript arrays they must be of the -/// same length. -/// -/// See the comment in the beginning of this file for a description of type -/// representations. - -bool areSubtypes(var s, var sEnv, var t, var tEnv) { - // `null` means a raw type. - if (t == null) return true; - if (s == null) { - int len = getLength(t); - for (int i = 0; i < len; i++) { - if (!_isSubtype(null, null, getIndex(t, i), tEnv)) { - return false; - } - } - return true; - } - - assert(isJsArray(s)); - assert(isJsArray(t)); - assert(getLength(s) == getLength(t)); - - int len = getLength(s); - for (int i = 0; i < len; i++) { - if (!_isSubtype(getIndex(s, i), sEnv, getIndex(t, i), tEnv)) { - return false; - } - } - return true; -} - -/// Computes the signature by applying the type arguments of [context] as an -/// instance of [contextName] to the signature function [signature]. -computeSignature(var signature, var context, var contextName) { - var interceptor = getInterceptor(context); - var typeArguments = - getRuntimeTypeArguments(interceptor, context, contextName); - return invokeOn(signature, context, typeArguments); -} - -/// Returns `true` if the runtime type representation [type] is a top type. -/// That is, either `dynamic`, `void` or `Object`. -@pragma('dart2js:tryInline') -bool isTopType(var type) { - return isDartDynamicTypeRti(type) || - isDartVoidTypeRti(type) || - isDartObjectTypeRti(type) || - isDartJsInteropTypeArgumentRti(type); -} - -/// Returns the type argument of the `FutureOr` runtime type representation -/// [type]. -/// -/// For instance `num` of `FutureOr`. -@pragma('dart2js:tryInline') -Object getFutureOrArgument(var type) { - assert(isDartFutureOrType(type)); - var typeArgumentTag = JS_GET_NAME(JsGetName.FUTURE_OR_TYPE_ARGUMENT_TAG); - return hasField(type, typeArgumentTag) - ? getField(type, typeArgumentTag) - : null; -} - -/// Checks whether the type represented by the type representation [s] is a -/// subtype of the type represented by the type representation [t]. -/// -/// See the comment in the beginning of this file for a description of type -/// representations. -/// -/// The arguments [s] and [t] must be types, usually represented by the -/// constructor of the class, or an array (for generic class types). -bool isSubtype(var s, var t) { - return _isSubtype(s, null, t, null); -} - -bool _isSubtype(var s, var sEnv, var t, var tEnv) { - return false; -} - -/// Top-level function subtype check when [t] is known to be a function type -/// rti. -bool isFunctionSubtype(var s, var t) { - return _isFunctionSubtype(s, null, t, null); -} - -bool _isFunctionSubtype(var s, var sEnv, var t, var tEnv) { - assert(isDartFunctionType(t)); - if (!isDartFunctionType(s)) return false; - var genericBoundsTag = - JS_GET_NAME(JsGetName.FUNCTION_TYPE_GENERIC_BOUNDS_TAG); - var voidReturnTag = JS_GET_NAME(JsGetName.FUNCTION_TYPE_VOID_RETURN_TAG); - var returnTypeTag = JS_GET_NAME(JsGetName.FUNCTION_TYPE_RETURN_TYPE_TAG); - - // Generic function types must agree on number of type parameters and bounds. - if (hasField(s, genericBoundsTag)) { - if (hasNoField(t, genericBoundsTag)) return false; - var sBounds = getField(s, genericBoundsTag); - var tBounds = getField(t, genericBoundsTag); - int sGenericParameters = getLength(sBounds); - int tGenericParameters = getLength(tBounds); - if (sGenericParameters != tGenericParameters) return false; - // TODO(sra): Compare bounds, which should be 'equal' trees due to the de - // Bruijn numbering of type parameters. - sEnv = sEnv == null ? sBounds : concat(sBounds, sEnv); - tEnv = tEnv == null ? tBounds : concat(tBounds, tEnv); - } else if (hasField(t, genericBoundsTag)) { - return false; - } - - var sReturnType = getField(s, returnTypeTag); - var tReturnType = getField(t, returnTypeTag); - if (!_isSubtype(sReturnType, sEnv, tReturnType, tEnv)) return false; - - var requiredParametersTag = - JS_GET_NAME(JsGetName.FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG); - var sParameterTypes = getField(s, requiredParametersTag); - var tParameterTypes = getField(t, requiredParametersTag); - - var optionalParametersTag = - JS_GET_NAME(JsGetName.FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG); - var sOptionalParameterTypes = getField(s, optionalParametersTag); - var tOptionalParameterTypes = getField(t, optionalParametersTag); - - int sParametersLen = sParameterTypes != null ? getLength(sParameterTypes) : 0; - int tParametersLen = tParameterTypes != null ? getLength(tParameterTypes) : 0; - - int sOptionalParametersLen = - sOptionalParameterTypes != null ? getLength(sOptionalParameterTypes) : 0; - int tOptionalParametersLen = - tOptionalParameterTypes != null ? getLength(tOptionalParameterTypes) : 0; - - if (sParametersLen > tParametersLen) { - // Too many required parameters in [s]. - return false; - } - if (sParametersLen + sOptionalParametersLen < - tParametersLen + tOptionalParametersLen) { - // Too few required and optional parameters in [s]. - return false; - } - - int pos = 0; - // Check all required parameters of [s]. - for (; pos < sParametersLen; pos++) { - if (!_isSubtype(getIndex(tParameterTypes, pos), tEnv, - getIndex(sParameterTypes, pos), sEnv)) { - return false; - } - } - int sPos = 0; - int tPos = pos; - // Check the remaining parameters of [t] with the first optional parameters - // of [s]. - for (; tPos < tParametersLen; sPos++, tPos++) { - if (!_isSubtype(getIndex(tParameterTypes, tPos), tEnv, - getIndex(sOptionalParameterTypes, sPos), sEnv)) { - return false; - } - } - tPos = 0; - // Check the optional parameters of [t] with the remaining optional - // parameters of [s]: - for (; tPos < tOptionalParametersLen; sPos++, tPos++) { - if (!_isSubtype(getIndex(tOptionalParameterTypes, tPos), tEnv, - getIndex(sOptionalParameterTypes, sPos), sEnv)) { - return false; - } - } - - var namedParametersTag = - JS_GET_NAME(JsGetName.FUNCTION_TYPE_NAMED_PARAMETERS_TAG); - var sNamedParameters = getField(s, namedParametersTag); - var tNamedParameters = getField(t, namedParametersTag); - if (tNamedParameters == null) return true; - if (sNamedParameters == null) return false; - return namedParametersSubtypeCheck( - sNamedParameters, sEnv, tNamedParameters, tEnv); -} - -bool namedParametersSubtypeCheck(var s, var sEnv, var t, var tEnv) { - assert(isJsObject(s)); - assert(isJsObject(t)); - - // Each named parameter in [t] must exist in [s] and be a subtype of the type - // in [s]. - List names = JS('JSFixedArray', 'Object.getOwnPropertyNames(#)', t); - for (int i = 0; i < names.length; i++) { - var name = names[i]; - if (JS('bool', '!Object.hasOwnProperty.call(#, #)', s, name)) { - return false; - } - var tType = JS('', '#[#]', t, name); - var sType = JS('', '#[#]', s, name); - if (!_isSubtype(tType, tEnv, sType, sEnv)) return false; - } - return true; -} - -/// Returns whether [type] is the representation of a generic function type -/// parameter. Generic function type parameters are represented de Bruijn -/// indexes. -/// -/// This test is only valid if [type] is known _not_ to be the void rti, whose -/// runtime representation is -1. -bool isGenericFunctionTypeParameter(var type) { - assert(!isDartVoidTypeRti(type)); - return type is num; // Actually int, but 'is num' is faster. -} - -/// Returns [genericFunctionRti] with type parameters bound to [parameters]. -/// -/// [genericFunctionRti] must be an rti representation with a number of generic -/// type parameters matching the number of types in [parameters]. -/// -/// Called from generated code. -@pragma('dart2js:noInline') -instantiatedGenericFunctionType(genericFunctionRti, parameters) { - if (genericFunctionRti == null) return null; - - assert(isDartFunctionType(genericFunctionRti)); - - var genericBoundsTag = - JS_GET_NAME(JsGetName.FUNCTION_TYPE_GENERIC_BOUNDS_TAG); - - assert(hasField(genericFunctionRti, genericBoundsTag)); - var bounds = getField(genericFunctionRti, genericBoundsTag); - - // Generic function types must agree on number of type parameters and bounds. - int boundLength = getLength(bounds); - int parametersLength = getLength(parameters); - assert(boundLength == parametersLength); - - var result = JS('', '{#:1}', JS_GET_NAME(JsGetName.FUNCTION_TYPE_TAG)); - return finishBindInstantiatedFunctionType( - genericFunctionRti, result, parameters, 0); -} - -bindInstantiatedFunctionType(rti, parameters, int depth) { - var result = JS('', '{#:1}', JS_GET_NAME(JsGetName.FUNCTION_TYPE_TAG)); - - var genericBoundsTag = - JS_GET_NAME(JsGetName.FUNCTION_TYPE_GENERIC_BOUNDS_TAG); - if (hasField(rti, genericBoundsTag)) { - var bounds = getField(rti, genericBoundsTag); - depth += getLength(bounds); - setField(result, genericBoundsTag, - bindInstantiatedTypes(bounds, parameters, depth)); - } - - return finishBindInstantiatedFunctionType(rti, result, parameters, depth); -} - -/// Common code for function types that copies all non-bounds parts of the -/// function [rti] into [result]. -finishBindInstantiatedFunctionType(rti, result, parameters, int depth) { - var voidReturnTag = JS_GET_NAME(JsGetName.FUNCTION_TYPE_VOID_RETURN_TAG); - var returnTypeTag = JS_GET_NAME(JsGetName.FUNCTION_TYPE_RETURN_TYPE_TAG); - - if (hasField(rti, voidReturnTag)) { - setField(result, voidReturnTag, getField(rti, voidReturnTag)); - } else if (hasField(rti, returnTypeTag)) { - setField(result, returnTypeTag, - bindInstantiatedType(getField(rti, returnTypeTag), parameters, depth)); - } - - var requiredParametersTag = - JS_GET_NAME(JsGetName.FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG); - if (hasField(rti, requiredParametersTag)) { - setField( - result, - requiredParametersTag, - bindInstantiatedTypes( - getField(rti, requiredParametersTag), parameters, depth)); - } - - String optionalParametersTag = - JS_GET_NAME(JsGetName.FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG); - if (hasField(rti, optionalParametersTag)) { - setField( - result, - optionalParametersTag, - bindInstantiatedTypes( - getField(rti, optionalParametersTag), parameters, depth)); - } - - String namedParametersTag = - JS_GET_NAME(JsGetName.FUNCTION_TYPE_NAMED_PARAMETERS_TAG); - if (hasField(rti, namedParametersTag)) { - var namedParameters = getField(rti, namedParametersTag); - var boundNamed = JS('', '{}'); - var names = JS('JSFixedArray', 'Object.keys(#)', namedParameters); - for (var name in names) { - setField( - boundNamed, - name, - bindInstantiatedType( - getField(namedParameters, name), parameters, depth)); - } - setField(result, namedParametersTag, boundNamed); - } - - return result; -} - -/// Copies [rti], substituting generic type parameters from [parameters]. -/// -/// Generic type parameters are de Bruijn indexes counting up through the -/// generic function type parameters scopes to index into [parameters]. -/// -/// [depth] is the number of subsequent generic function parameters that are in -/// scope. This is subtracted off the de Bruijn index for the type parameter to -/// arrive at an potential index into [parameters]. -bindInstantiatedType(rti, parameters, int depth) { - if (isDartDynamicTypeRti(rti)) return rti; // dynamic. - if (isDartVoidTypeRti(rti)) return rti; // void. - // Functions are constructors denoting the class of the constructor. - if (isJsFunction(rti)) return rti; - - // de Bruijn type indexes. - if (isGenericFunctionTypeParameter(rti)) { - if (rti < depth) return rti; - return JS('', '#[#]', parameters, rti - depth); - } - // Other things encoded as numbers. - if (rti is num) return rti; - - if (isJsArray(rti)) { - // An array is a parameterized class type, e.g. the list of three - // constructor functions [Map, String, int] represents `Map`. - // Since the 'head' of the term and the arguments are encoded in the same - // scheme, it is sufficient to walk all the types. - return bindInstantiatedTypes(rti, parameters, depth); - } - if (isDartFunctionType(rti)) { - return bindInstantiatedFunctionType(rti, parameters, depth); - } - - // Can't include the bad [rti] since it is not a Dart value. - throw new ArgumentError('Unknown RTI format in bindInstantiatedType.'); -} - -/// Returns a copy of array [rti] with each type bound. -bindInstantiatedTypes(rti, parameters, int depth) { - List array = JS('JSFixedArray', '#.slice()', rti); - for (int i = 0; i < array.length; i++) { - array[i] = bindInstantiatedType(array[i], parameters, depth); - } - return array; -} - -/// Calls the JavaScript [function] with the [arguments] with the global scope -/// as the `this` context. -invoke(var function, var arguments) => invokeOn(function, null, arguments); - -/// Calls the JavaScript [function] with the [arguments] with [receiver] as the -/// `this` context. -Object invokeOn(function, receiver, arguments) { - assert(isJsFunction(function)); - assert(arguments == null || isJsArray(arguments)); - return JS('var', r'#.apply(#, #)', function, receiver, arguments); -} - -/// Calls the property [name] on the JavaScript [object]. -call(var object, String name) => JS('var', r'#[#]()', object, name); - -/// Returns the property [name] of the JavaScript object [object]. -getField(var object, String name) => JS('var', r'#[#]', object, name); - -/// Returns the property [index] of the JavaScript array [array]. -getIndex(var array, int index) { - assert(isJsArray(array)); - return JS('var', r'#[#]', array, index); -} - -setField(var object, String name, var value) { - JS('', '#[#] = #', object, name, value); -} - -setIndex(var array, int index, var value) { - JS('', '#[#] = #', array, index, value); -} - -/// Returns the length of the JavaScript array [array]. -int getLength(var array) { - assert(isJsArray(array)); - return JS('int', r'#.length', array); -} - -/// Returns whether [value] is a JavaScript array. -bool isJsArray(var value) { - return value is JSArray; -} - -hasField(var object, var name) => JS('bool', r'# in #', name, object); - -hasNoField(var object, var name) => !hasField(object, name); - -/// Returns `true` if [o] is a JavaScript function. -bool isJsFunction(var o) => JS('bool', r'typeof # == "function"', o); - -/// Returns `true` if [o] is a JavaScript object. -bool isJsObject(var o) => JS('bool', r"typeof # == 'object'", o); - -/// Returns `true` if the JavaScript values [s] and [t] are identical. We use -/// this helper instead of [identical] because `identical` needs to merge -/// `null` and `undefined` (which we can avoid). -bool isIdentical(var s, var t) => JS('bool', '# === #', s, t); - -/// Returns `true` if the JavaScript values [s] and [t] are not identical. We -/// use this helper instead of [identical] because `identical` needs to merge -/// `null` and `undefined` (which we can avoid). -bool isNotIdentical(var s, var t) => JS('bool', '# !== #', s, t); - -/// 'Top' bounds are uninteresting: null/undefined and Object. -bool isInterestingBound(rti) => - rti != null && - isNotIdentical( - rti, - JS_BUILTIN( - 'depends:none;effects:none;', JsBuiltin.dartObjectConstructor)); - -concat(Object a1, Object a2) => JS('JSArray', '#.concat(#)', a1, a2); diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/js_string.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/js_string.dart deleted file mode 100644 index 8ba4c371a17..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/lib/js_string.dart +++ /dev/null @@ -1,470 +0,0 @@ -// Copyright (c) 2012, 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. - -part of _interceptors; - -/// The interceptor class for [String]. The compiler recognizes this -/// class as an interceptor, and changes references to [:this:] to -/// actually use the receiver of the method, which is generated as an extra -/// argument added to each member. -class JSString extends Interceptor implements String, JSIndexable { - const JSString(); - - @pragma('dart2js:noInline') - int codeUnitAt(int index) { - if (index is! int) throw diagnoseIndexError(this, index); - if (index < 0) throw diagnoseIndexError(this, index); - return _codeUnitAt(index); - } - - int _codeUnitAt(int index) { - if (index >= length) throw diagnoseIndexError(this, index); - return JS('JSUInt31', r'#.charCodeAt(#)', this, index); - } - - Iterable allMatches(String string, [int start = 0]) { - checkString(string); - checkInt(start); - if (0 > start || start > string.length) { - throw new RangeError.range(start, 0, string.length); - } - return allMatchesInStringUnchecked(this, string, start); - } - - Match? matchAsPrefix(String string, [int start = 0]) { - if (start < 0 || start > string.length) { - throw new RangeError.range(start, 0, string.length); - } - if (start + this.length > string.length) return null; - // TODO(lrn): See if this can be optimized. - for (int i = 0; i < this.length; i++) { - if (string.codeUnitAt(start + i) != this.codeUnitAt(i)) { - return null; - } - } - return new StringMatch(start, string, this); - } - - String operator +(String other) { - if (other is! String) throw new ArgumentError.value(other); - return JS('String', r'# + #', this, other); - } - - bool endsWith(String other) { - checkString(other); - int otherLength = other.length; - if (otherLength > length) return false; - return other == substring(length - otherLength); - } - - String replaceAll(Pattern from, String to) { - return stringReplaceAllUnchecked(this, from, checkString(to)); - } - - String replaceAllMapped(Pattern from, String Function(Match) convert) { - return this.splitMapJoin(from, onMatch: convert); - } - - String splitMapJoin(Pattern from, - {String Function(Match)? onMatch, String Function(String)? onNonMatch}) { - return stringReplaceAllFuncUnchecked(this, from, onMatch, onNonMatch); - } - - String replaceFirst(Pattern from, String to, [int startIndex = 0]) { - checkString(to); - checkInt(startIndex); - RangeError.checkValueInInterval(startIndex, 0, this.length, "startIndex"); - return stringReplaceFirstUnchecked(this, from, to, startIndex); - } - - String replaceFirstMapped(Pattern from, String replace(Match match), - [int startIndex = 0]) { - checkNull(replace); - checkInt(startIndex); - RangeError.checkValueInInterval(startIndex, 0, this.length, "startIndex"); - return stringReplaceFirstMappedUnchecked(this, from, replace, startIndex); - } - - List split(Pattern pattern) { - checkNull(pattern); - if (pattern is String) { - return stringSplitUnchecked(this, pattern); - } else if (pattern is JSSyntaxRegExp && regExpCaptureCount(pattern) == 0) { - var re = regExpGetNative(pattern); - return stringSplitUnchecked(this, re); - } else { - return _defaultSplit(pattern); - } - } - - String replaceRange(int start, int? end, String replacement) { - checkString(replacement); - checkInt(start); - var e = RangeError.checkValidRange(start, end, this.length); - checkInt(e); - return stringReplaceRangeUnchecked(this, start, e, replacement); - } - - List _defaultSplit(Pattern pattern) { - List result = []; - // End of most recent match. That is, start of next part to add to result. - int start = 0; - // Length of most recent match. - // Set >0, so no match on the empty string causes the result to be [""]. - int length = 1; - for (var match in pattern.allMatches(this)) { - int matchStart = match.start; - int matchEnd = match.end; - length = matchEnd - matchStart; - if (length == 0 && start == matchStart) { - // An empty match right after another match is ignored. - // This includes an empty match at the start of the string. - continue; - } - int end = matchStart; - result.add(this.substring(start, end)); - start = matchEnd; - } - if (start < this.length || length > 0) { - // An empty match at the end of the string does not cause a "" at the end. - // A non-empty match ending at the end of the string does add a "". - result.add(this.substring(start)); - } - return result; - } - - bool startsWith(Pattern pattern, [int index = 0]) { - checkInt(index); - if (index < 0 || index > this.length) { - throw new RangeError.range(index, 0, this.length); - } - if (pattern is String) { - String other = pattern; - int otherLength = other.length; - int endIndex = index + otherLength; - if (endIndex > length) return false; - return other == JS('String', r'#.substring(#, #)', this, index, endIndex); - } - return pattern.matchAsPrefix(this, index) != null; - } - - String substring(int startIndex, [int? endIndex]) { - checkInt(startIndex); - if (endIndex == null) endIndex = length; - checkInt(endIndex); - if (startIndex < 0) throw new RangeError.value(startIndex); - if (startIndex > endIndex) throw new RangeError.value(startIndex); - if (endIndex > length) throw new RangeError.value(endIndex); - return JS('String', r'#.substring(#, #)', this, startIndex, endIndex); - } - - String toLowerCase() { - return JS('returns:String;effects:none;depends:none;throws:null(1)', - r'#.toLowerCase()', this); - } - - String toUpperCase() { - return JS('returns:String;effects:none;depends:none;throws:null(1)', - r'#.toUpperCase()', this); - } - - // Characters with Whitespace property (Unicode 6.3). - // 0009..000D ; White_Space # Cc .. - // 0020 ; White_Space # Zs SPACE - // 0085 ; White_Space # Cc - // 00A0 ; White_Space # Zs NO-BREAK SPACE - // 1680 ; White_Space # Zs OGHAM SPACE MARK - // 2000..200A ; White_Space # Zs EN QUAD..HAIR SPACE - // 2028 ; White_Space # Zl LINE SEPARATOR - // 2029 ; White_Space # Zp PARAGRAPH SEPARATOR - // 202F ; White_Space # Zs NARROW NO-BREAK SPACE - // 205F ; White_Space # Zs MEDIUM MATHEMATICAL SPACE - // 3000 ; White_Space # Zs IDEOGRAPHIC SPACE - // - // BOM: 0xFEFF - static bool _isWhitespace(int codeUnit) { - // Most codeUnits should be less than 256. Special case with a smaller - // switch. - if (codeUnit < 256) { - switch (codeUnit) { - case 0x09: - case 0x0A: - case 0x0B: - case 0x0C: - case 0x0D: - case 0x20: - case 0x85: - case 0xA0: - return true; - default: - return false; - } - } - switch (codeUnit) { - case 0x1680: - case 0x2000: - case 0x2001: - case 0x2002: - case 0x2003: - case 0x2004: - case 0x2005: - case 0x2006: - case 0x2007: - case 0x2008: - case 0x2009: - case 0x200A: - case 0x2028: - case 0x2029: - case 0x202F: - case 0x205F: - case 0x3000: - case 0xFEFF: - return true; - default: - return false; - } - } - - /// Finds the index of the first non-whitespace character, or the - /// end of the string. Start looking at position [index]. - static int _skipLeadingWhitespace(String string, int index) { - const int SPACE = 0x20; - const int CARRIAGE_RETURN = 0x0D; - while (index < string.length) { - int codeUnit = string.codeUnitAt(index); - if (codeUnit != SPACE && - codeUnit != CARRIAGE_RETURN && - !_isWhitespace(codeUnit)) { - break; - } - index++; - } - return index; - } - - /// Finds the index after the last non-whitespace character, or 0. - /// Start looking at position [index - 1]. - static int _skipTrailingWhitespace(String string, int index) { - const int SPACE = 0x20; - const int CARRIAGE_RETURN = 0x0D; - while (index > 0) { - int codeUnit = string.codeUnitAt(index - 1); - if (codeUnit != SPACE && - codeUnit != CARRIAGE_RETURN && - !_isWhitespace(codeUnit)) { - break; - } - index--; - } - return index; - } - - // Dart2js can't use JavaScript trim directly, - // because JavaScript does not trim - // the NEXT LINE (NEL) character (0x85). - String trim() { - const int NEL = 0x85; - - // Start by doing JS trim. Then check if it leaves a NEL at - // either end of the string. - String result = JS('String', '#.trim()', this); - if (result.length == 0) return result; - int firstCode = result.codeUnitAt(0); - int startIndex = 0; - if (firstCode == NEL) { - startIndex = _skipLeadingWhitespace(result, 1); - if (startIndex == result.length) return ""; - } - - int endIndex = result.length; - // We know that there is at least one character that is non-whitespace. - // Therefore we don't need to verify that endIndex > startIndex. - int lastCode = result.codeUnitAt(endIndex - 1); - if (lastCode == NEL) { - endIndex = _skipTrailingWhitespace(result, endIndex - 1); - } - if (startIndex == 0 && endIndex == result.length) return result; - return JS('String', r'#.substring(#, #)', result, startIndex, endIndex); - } - - // Dart2js can't use JavaScript trimLeft directly, - // because it is not in ES5, so not every browser implements it, - // and because those that do will not trim the NEXT LINE character (0x85). - String trimLeft() { - const int NEL = 0x85; - - // Start by doing JS trim. Then check if it leaves a NEL at - // the beginning of the string. - String result; - int startIndex = 0; - if (JS('bool', 'typeof #.trimLeft != "undefined"', this)) { - result = JS('String', '#.trimLeft()', this); - if (result.length == 0) return result; - int firstCode = result.codeUnitAt(0); - if (firstCode == NEL) { - startIndex = _skipLeadingWhitespace(result, 1); - } - } else { - result = this; - startIndex = _skipLeadingWhitespace(this, 0); - } - if (startIndex == 0) return result; - if (startIndex == result.length) return ""; - return JS('String', r'#.substring(#)', result, startIndex); - } - - // Dart2js can't use JavaScript trimRight directly, - // because it is not in ES5 and because JavaScript does not trim - // the NEXT LINE character (0x85). - String trimRight() { - const int NEL = 0x85; - - // Start by doing JS trim. Then check if it leaves a NEL or BOM at - // the end of the string. - String result; - int endIndex; - // trimRight is implemented by Firefox and Chrome/Blink, - // so use it if it is there. - if (JS('bool', 'typeof #.trimRight != "undefined"', this)) { - result = JS('String', '#.trimRight()', this); - endIndex = result.length; - if (endIndex == 0) return result; - int lastCode = result.codeUnitAt(endIndex - 1); - if (lastCode == NEL) { - endIndex = _skipTrailingWhitespace(result, endIndex - 1); - } - } else { - result = this; - endIndex = _skipTrailingWhitespace(this, this.length); - } - - if (endIndex == result.length) return result; - if (endIndex == 0) return ""; - return JS('String', r'#.substring(#, #)', result, 0, endIndex); - } - - String operator *(int times) { - if (0 >= times) return ''; // Unnecessary but hoists argument type check. - if (times == 1 || this.length == 0) return this; - if (times != JS('JSUInt32', '# >>> 0', times)) { - // times >= 2^32. We can't create a string that big. - throw const OutOfMemoryError(); - } - var result = ''; - String s = this; - while (true) { - if (times & 1 == 1) result = s + result; - times = JS('JSUInt31', '# >>> 1', times); - if (times == 0) break; - s += s; - } - return result; - } - - String padLeft(int width, [String padding = ' ']) { - int delta = width - this.length; - if (delta <= 0) return this; - return padding * delta + this; - } - - String padRight(int width, [String padding = ' ']) { - int delta = width - this.length; - if (delta <= 0) return this; - return this + padding * delta; - } - - List get codeUnits => new CodeUnits(this); - - Runes get runes => new Runes(this); - - int indexOf(Pattern pattern, [int start = 0]) { - checkNull(pattern); - if (start is! int) throw argumentErrorValue(start); - if (start < 0 || start > this.length) { - throw new RangeError.range(start, 0, this.length); - } - if (pattern is String) { - return stringIndexOfStringUnchecked(this, pattern, start); - } - if (pattern is JSSyntaxRegExp) { - JSSyntaxRegExp re = pattern; - Match? match = firstMatchAfter(re, this, start); - return (match == null) ? -1 : match.start; - } - for (int i = start; i <= this.length; i++) { - if (pattern.matchAsPrefix(this, i) != null) return i; - } - return -1; - } - - int lastIndexOf(Pattern pattern, [int? start]) { - checkNull(pattern); - if (start == null) { - start = length; - } else if (start is! int) { - throw argumentErrorValue(start); - } else if (start < 0 || start > this.length) { - throw new RangeError.range(start, 0, this.length); - } - if (pattern is String) { - String other = pattern; - if (start + other.length > this.length) { - start = this.length - other.length; - } - return stringLastIndexOfUnchecked(this, other, start); - } - for (int i = start; i >= 0; i--) { - if (pattern.matchAsPrefix(this, i) != null) return i; - } - return -1; - } - - bool contains(Pattern other, [int startIndex = 0]) { - checkNull(other); - if (startIndex < 0 || startIndex > this.length) { - throw new RangeError.range(startIndex, 0, this.length); - } - return stringContainsUnchecked(this, other, startIndex); - } - - bool get isEmpty => length == 0; - - bool get isNotEmpty => !isEmpty; - - int compareTo(String other) { - if (other is! String) throw argumentErrorValue(other); - return this == other ? 0 : JS('bool', r'# < #', this, other) ? -1 : 1; - } - - // Note: if you change this, also change the function [S]. - String toString() => this; - - /// This is the [Jenkins hash function][1] but using masking to keep - /// values in SMI range. - /// - /// [1]: http://en.wikipedia.org/wiki/Jenkins_hash_function - int get hashCode { - // TODO(ahe): This method shouldn't have to use JS. Update when our - // optimizations are smarter. - int hash = 0; - for (int i = 0; i < length; i++) { - hash = 0x1fffffff & (hash + JS('int', r'#.charCodeAt(#)', this, i)); - hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10)); - hash = JS('int', '# ^ (# >> 6)', hash, hash); - } - hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3)); - hash = JS('int', '# ^ (# >> 11)', hash, hash); - return 0x1fffffff & (hash + ((0x00003fff & hash) << 15)); - } - - Type get runtimeType => String; - - int get length => JS('int', r'#.length', this); - - String operator [](int index) { - if (index is! int) throw diagnoseIndexError(this, index); - if (index >= length || index < 0) throw diagnoseIndexError(this, index); - return JS('String', '#[#]', this, index); - } -} diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/linked_hash_map.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/linked_hash_map.dart deleted file mode 100644 index 70882d8a17d..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/lib/linked_hash_map.dart +++ /dev/null @@ -1,441 +0,0 @@ -// Copyright (c) 2014, 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. - -// Efficient JavaScript based implementation of a linked hash map used as a -// backing map for constant maps and the [LinkedHashMap] patch - -part of _js_helper; - -const _USE_ES6_MAPS = const bool.fromEnvironment("dart2js.use.es6.maps"); - -class JsLinkedHashMap extends MapBase - implements LinkedHashMap, InternalMap { - int _length = 0; - - // The hash map contents are divided into three parts: one part for - // string keys, one for numeric keys, and one for the rest. String - // and numeric keys map directly to their linked cells, but the rest - // of the entries are stored in bucket lists of the form: - // - // [cell-0, cell-1, ...] - // - // where all keys in the same bucket share the same hash code. - var _strings; - var _nums; - var _rest; - - // The keys and values are stored in cells that are linked together - // to form a double linked list. - LinkedHashMapCell? _first; - LinkedHashMapCell? _last; - - // We track the number of modifications done to the key set of the - // hash map to be able to throw when the map is modified while being - // iterated over. - int _modifications = 0; - - static bool get _supportsEs6Maps { - return JS('returns:bool;depends:none;effects:none;throws:never;gvn:true', - 'typeof Map != "undefined"'); - } - - JsLinkedHashMap(); - - /// If ES6 Maps are available returns a linked hash-map backed by an ES6 Map. - @pragma('dart2js:tryInline') - factory JsLinkedHashMap.es6() { - return (_USE_ES6_MAPS && JsLinkedHashMap._supportsEs6Maps) - ? new Es6LinkedHashMap() - : new JsLinkedHashMap(); - } - - int get length => _length; - bool get isEmpty => _length == 0; - bool get isNotEmpty => !isEmpty; - - Iterable get keys { - return new LinkedHashMapKeyIterable(this); - } - - Iterable get values { - return new MappedIterable(keys, (each) => this[each] as V); - } - - bool containsKey(Object? key) { - if (_isStringKey(key)) { - var strings = _strings; - if (strings == null) return false; - return _containsTableEntry(strings, key); - } else if (_isNumericKey(key)) { - var nums = _nums; - if (nums == null) return false; - return _containsTableEntry(nums, key); - } else { - return internalContainsKey(key); - } - } - - bool internalContainsKey(Object? key) { - var rest = _rest; - if (rest == null) return false; - var bucket = _getBucket(rest, key); - return internalFindBucketIndex(bucket, key) >= 0; - } - - bool containsValue(Object? value) { - return keys.any((each) => this[each] == value); - } - - void addAll(Map other) { - other.forEach((K key, V value) { - this[key] = value; - }); - } - - V? operator [](Object? key) { - if (_isStringKey(key)) { - var strings = _strings; - if (strings == null) return null; - LinkedHashMapCell? cell = _getTableCell(strings, key); - return JS('', '#', cell == null ? null : cell.hashMapCellValue); - } else if (_isNumericKey(key)) { - var nums = _nums; - if (nums == null) return null; - LinkedHashMapCell? cell = _getTableCell(nums, key); - return JS('', '#', cell == null ? null : cell.hashMapCellValue); - } else { - return internalGet(key); - } - } - - V? internalGet(Object? key) { - var rest = _rest; - if (rest == null) return null; - var bucket = _getBucket(rest, key); - int index = internalFindBucketIndex(bucket, key); - if (index < 0) return null; - LinkedHashMapCell cell = JS('var', '#[#]', bucket, index); - return JS('', '#', cell.hashMapCellValue); - } - - void operator []=(K key, V value) { - if (_isStringKey(key)) { - var strings = _strings; - if (strings == null) _strings = strings = _newHashTable(); - _addHashTableEntry(strings, key, value); - } else if (_isNumericKey(key)) { - var nums = _nums; - if (nums == null) _nums = nums = _newHashTable(); - _addHashTableEntry(nums, key, value); - } else { - internalSet(key, value); - } - } - - void internalSet(K key, V value) { - var rest = _rest; - if (rest == null) _rest = rest = _newHashTable(); - var hash = internalComputeHashCode(key); - var bucket = _getTableBucket(rest, hash); - if (bucket == null) { - LinkedHashMapCell cell = _newLinkedCell(key, value); - _setTableEntry(rest, hash, JS('var', '[#]', cell)); - } else { - int index = internalFindBucketIndex(bucket, key); - if (index >= 0) { - LinkedHashMapCell cell = JS('var', '#[#]', bucket, index); - cell.hashMapCellValue = value; - } else { - LinkedHashMapCell cell = _newLinkedCell(key, value); - JS('void', '#.push(#)', bucket, cell); - } - } - } - - V putIfAbsent(K key, V ifAbsent()) { - if (containsKey(key)) return this[key] as V; - V value = ifAbsent(); - this[key] = value; - return value; - } - - V? remove(Object? key) { - if (_isStringKey(key)) { - return _removeHashTableEntry(_strings, key); - } else if (_isNumericKey(key)) { - return _removeHashTableEntry(_nums, key); - } else { - return internalRemove(key); - } - } - - V? internalRemove(Object? key) { - var rest = _rest; - if (rest == null) return null; - var hash = internalComputeHashCode(key); - var bucket = _getTableBucket(rest, hash); - int index = internalFindBucketIndex(bucket, key); - if (index < 0) return null; - // Use splice to remove the [cell] element at the index and - // unlink the cell before returning its value. - LinkedHashMapCell cell = JS('var', '#.splice(#, 1)[0]', bucket, index); - _unlinkCell(cell); - // Remove empty bucket list to avoid memory leak. - if (JS('int', '#.length', bucket) == 0) { - _deleteTableEntry(rest, hash); - } - return JS('', '#', cell.hashMapCellValue); - } - - void clear() { - if (_length > 0) { - _strings = _nums = _rest = _first = _last = null; - _length = 0; - _modified(); - } - } - - void forEach(void action(K key, V value)) { - LinkedHashMapCell? cell = _first; - int modifications = _modifications; - while (cell != null) { - K key = JS('', '#', cell.hashMapCellKey); - V value = JS('', '#', cell.hashMapCellValue); - action(key, value); - if (modifications != _modifications) { - throw new ConcurrentModificationError(this); - } - cell = cell._next; - } - } - - void _addHashTableEntry(var table, K key, V value) { - LinkedHashMapCell? cell = _getTableCell(table, key); - if (cell == null) { - _setTableEntry(table, key, _newLinkedCell(key, value)); - } else { - cell.hashMapCellValue = value; - } - } - - V? _removeHashTableEntry(var table, Object? key) { - if (table == null) return null; - LinkedHashMapCell? cell = _getTableCell(table, key); - if (cell == null) return null; - _unlinkCell(cell); - _deleteTableEntry(table, key); - return JS('', '#', cell.hashMapCellValue); - } - - void _modified() { - // Value cycles after 2^30 modifications so that modification counts are - // always unboxed (Smi) values. Modification detection will be missed if you - // make exactly some multiple of 2^30 modifications between advances of an - // iterator. - _modifications = (_modifications + 1) & 0x3ffffff; - } - - // Create a new cell and link it in as the last one in the list. - LinkedHashMapCell _newLinkedCell(K key, V value) { - LinkedHashMapCell cell = new LinkedHashMapCell(key, value); - if (_first == null) { - _first = _last = cell; - } else { - LinkedHashMapCell last = _last!; - cell._previous = last; - _last = last._next = cell; - } - _length++; - _modified(); - return cell; - } - - // Unlink the given cell from the linked list of cells. - void _unlinkCell(LinkedHashMapCell cell) { - LinkedHashMapCell? previous = cell._previous; - LinkedHashMapCell? next = cell._next; - if (previous == null) { - assert(cell == _first); - _first = next; - } else { - previous._next = next; - } - if (next == null) { - assert(cell == _last); - _last = previous; - } else { - next._previous = previous; - } - _length--; - _modified(); - } - - static bool _isStringKey(var key) { - return key is String; - } - - static bool _isNumericKey(var key) { - // Only treat unsigned 30-bit integers as numeric keys. This way, - // we avoid converting them to strings when we use them as keys in - // the JavaScript hash table object. - return key is num && JS('bool', '(# & 0x3ffffff) === #', key, key); - } - - int internalComputeHashCode(var key) { - // We force the hash codes to be unsigned 30-bit integers to avoid - // issues with problematic keys like '__proto__'. Another option - // would be to throw an exception if the hash code isn't a number. - return JS('int', '# & 0x3ffffff', key.hashCode); - } - - List? _getBucket(var table, var key) { - var hash = internalComputeHashCode(key); - return _getTableBucket(table, hash); - } - - int internalFindBucketIndex(var bucket, var key) { - if (bucket == null) return -1; - int length = JS('int', '#.length', bucket); - for (int i = 0; i < length; i++) { - LinkedHashMapCell cell = JS('var', '#[#]', bucket, i); - if (cell.hashMapCellKey == key) return i; - } - return -1; - } - - String toString() => MapBase.mapToString(this); - - LinkedHashMapCell? _getTableCell(var table, var key) { - return JS('var', '#[#]', table, key); - } - - List? _getTableBucket(var table, var key) { - return JS('var', '#[#]', table, key); - } - - void _setTableEntry(var table, var key, var value) { - assert(value != null); - JS('void', '#[#] = #', table, key, value); - } - - void _deleteTableEntry(var table, var key) { - JS('void', 'delete #[#]', table, key); - } - - bool _containsTableEntry(var table, var key) { - LinkedHashMapCell? cell = _getTableCell(table, key); - return cell != null; - } - - _newHashTable() { - // Create a new JavaScript object to be used as a hash table. Use - // Object.create to avoid the properties on Object.prototype - // showing up as entries. - var table = JS('var', 'Object.create(null)'); - // Attempt to force the hash table into 'dictionary' mode by - // adding a property to it and deleting it again. - var temporaryKey = ''; - _setTableEntry(table, temporaryKey, table); - _deleteTableEntry(table, temporaryKey); - return table; - } -} - -class Es6LinkedHashMap extends JsLinkedHashMap { - @override - LinkedHashMapCell? _getTableCell(var table, var key) { - return JS('var', '#.get(#)', table, key); - } - - @override - List? _getTableBucket(var table, var key) { - return JS('var', '#.get(#)', table, key); - } - - @override - void _setTableEntry(var table, var key, var value) { - JS('void', '#.set(#, #)', table, key, value); - } - - @override - void _deleteTableEntry(var table, var key) { - JS('void', '#.delete(#)', table, key); - } - - @override - bool _containsTableEntry(var table, var key) { - return JS('bool', '#.has(#)', table, key); - } - - @override - _newHashTable() { - return JS('var', 'new Map()'); - } -} - -class LinkedHashMapCell { - final dynamic hashMapCellKey; - dynamic hashMapCellValue; - - LinkedHashMapCell? _next; - LinkedHashMapCell? _previous; - - LinkedHashMapCell(this.hashMapCellKey, this.hashMapCellValue); -} - -class LinkedHashMapKeyIterable extends EfficientLengthIterable { - final dynamic _map; - LinkedHashMapKeyIterable(this._map); - - int get length => _map._length; - bool get isEmpty => _map._length == 0; - - Iterator get iterator { - return new LinkedHashMapKeyIterator(_map, _map._modifications); - } - - bool contains(Object? element) { - return _map.containsKey(element); - } - - void forEach(void f(E element)) { - LinkedHashMapCell? cell = _map._first; - int modifications = _map._modifications; - while (cell != null) { - f(JS('', '#', cell.hashMapCellKey)); - if (modifications != _map._modifications) { - throw new ConcurrentModificationError(_map); - } - cell = cell._next; - } - } -} - -class LinkedHashMapKeyIterator implements Iterator { - final dynamic _map; - final int _modifications; - LinkedHashMapCell? _cell; - E? _current; - - LinkedHashMapKeyIterator(this._map, this._modifications) { - _cell = _map._first; - } - - E get current => _current as E; - - bool moveNext() { - if (_modifications != _map._modifications) { - throw new ConcurrentModificationError(_map); - } - var cell = _cell; - if (cell == null) { - _current = null; - return false; - } else { - _current = JS('', '#', cell.hashMapCellKey); - _cell = cell._next; - return true; - } - } -} diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/math_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/math_patch.dart deleted file mode 100644 index 585f4c5aec4..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/lib/math_patch.dart +++ /dev/null @@ -1,329 +0,0 @@ -// Copyright (c) 2012, 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. - -// Patch file for dart:math library. -import 'dart:_foreign_helper' show JS; -import 'dart:_js_helper' show patch, checkNum; -import 'dart:typed_data' show ByteData; - -@patch -T min(T a, T b) => JS( - 'returns:num;depends:none;effects:none;gvn:true', - r'Math.min(#, #)', - checkNum(a), - checkNum(b)); - -@patch -T max(T a, T b) => JS( - 'returns:num;depends:none;effects:none;gvn:true', - r'Math.max(#, #)', - checkNum(a), - checkNum(b)); - -@patch -double sqrt(num x) => JS('num', r'Math.sqrt(#)', checkNum(x)); - -@patch -double sin(num radians) => JS('num', r'Math.sin(#)', checkNum(radians)); - -@patch -double cos(num radians) => JS('num', r'Math.cos(#)', checkNum(radians)); - -@patch -double tan(num radians) => JS('num', r'Math.tan(#)', checkNum(radians)); - -@patch -double acos(num x) => JS('num', r'Math.acos(#)', checkNum(x)); - -@patch -double asin(num x) => JS('num', r'Math.asin(#)', checkNum(x)); - -@patch -double atan(num x) => JS('num', r'Math.atan(#)', checkNum(x)); - -@patch -double atan2(num a, num b) => - JS('num', r'Math.atan2(#, #)', checkNum(a), checkNum(b)); - -@patch -double exp(num x) => JS('num', r'Math.exp(#)', checkNum(x)); - -@patch -double log(num x) => JS('num', r'Math.log(#)', checkNum(x)); - -@patch -num pow(num x, num exponent) { - checkNum(x); - checkNum(exponent); - return JS('num', r'Math.pow(#, #)', x, exponent); -} - -const int _POW2_32 = 0x100000000; - -@patch -class Random { - static Random? _secureRandom; - - @patch - factory Random([int? seed]) => - (seed == null) ? const _JSRandom() : new _Random(seed); - - @patch - factory Random.secure() => _secureRandom ??= _JSSecureRandom(); -} - -class _JSRandom implements Random { - // The Dart2JS implementation of Random doesn't use a seed. - const _JSRandom(); - - int nextInt(int max) { - if (max <= 0 || max > _POW2_32) { - throw new RangeError('max must be in range 0 < max ≤ 2^32, was $max'); - } - return JS('int', '(Math.random() * #) >>> 0', max); - } - - /// Generates a positive random floating point value uniformly distributed on - /// the range from 0.0, inclusive, to 1.0, exclusive. - double nextDouble() => JS('double', 'Math.random()'); - - /// Generates a random boolean value. - bool nextBool() => JS('bool', 'Math.random() < 0.5'); -} - -class _Random implements Random { - // Constants used by the algorithm or masking. - static const double _POW2_53_D = 1.0 * (0x20000000000000); - static const double _POW2_27_D = 1.0 * (1 << 27); - static const int _MASK32 = 0xFFFFFFFF; - - // State comprised of two unsigned 32 bit integers. - int _lo = 0; - int _hi = 0; - - // Implements: - // uint64_t hash = 0; - // do { - // hash = hash * 1037 ^ mix64((uint64_t)seed); - // seed >>= 64; - // } while (seed != 0 && seed != -1); // Limits for pos/neg seed. - // if (hash == 0) { - // hash = 0x5A17; - // } - // _lo = hash & _MASK_32; - // _hi = hash >> 32; - // and then does four _nextState calls to shuffle bits around. - _Random(int seed) { - int empty_seed = 0; - if (seed < 0) { - empty_seed = -1; - } - do { - int low = seed & _MASK32; - seed = (seed - low) ~/ _POW2_32; - int high = seed & _MASK32; - seed = (seed - high) ~/ _POW2_32; - - // Thomas Wang's 64-bit mix function. - // http://www.concentric.net/~Ttwang/tech/inthash.htm - // via. http://web.archive.org/web/20071223173210/http://www.concentric.net/~Ttwang/tech/inthash.htm - - // key = ~key + (key << 21); - int tmplow = low << 21; - int tmphigh = (high << 21) | (low >> 11); - tmplow = (~low & _MASK32) + tmplow; - low = tmplow & _MASK32; - high = (~high + tmphigh + ((tmplow - low) ~/ 0x100000000)) & _MASK32; - // key = key ^ (key >> 24). - tmphigh = high >> 24; - tmplow = (low >> 24) | (high << 8); - low ^= tmplow; - high ^= tmphigh; - // key = key * 265 - tmplow = low * 265; - low = tmplow & _MASK32; - high = (high * 265 + (tmplow - low) ~/ 0x100000000) & _MASK32; - // key = key ^ (key >> 14); - tmphigh = high >> 14; - tmplow = (low >> 14) | (high << 18); - low ^= tmplow; - high ^= tmphigh; - // key = key * 21 - tmplow = low * 21; - low = tmplow & _MASK32; - high = (high * 21 + (tmplow - low) ~/ 0x100000000) & _MASK32; - // key = key ^ (key >> 28). - tmphigh = high >> 28; - tmplow = (low >> 28) | (high << 4); - low ^= tmplow; - high ^= tmphigh; - // key = key + (key << 31); - tmplow = low << 31; - tmphigh = (high << 31) | (low >> 1); - tmplow += low; - low = tmplow & _MASK32; - high = (high + tmphigh + (tmplow - low) ~/ 0x100000000) & _MASK32; - // Mix end. - - // seed = seed * 1037 ^ key; - tmplow = _lo * 1037; - _lo = tmplow & _MASK32; - _hi = (_hi * 1037 + (tmplow - _lo) ~/ 0x100000000) & _MASK32; - _lo ^= low; - _hi ^= high; - } while (seed != empty_seed); - - if (_hi == 0 && _lo == 0) { - _lo = 0x5A17; - } - _nextState(); - _nextState(); - _nextState(); - _nextState(); - } - - // The algorithm used here is Multiply with Carry (MWC) with a Base b = 2^32. - // http://en.wikipedia.org/wiki/Multiply-with-carry - // The constant A (0xFFFFDA61) is selected from "Numerical Recipes 3rd - // Edition" p.348 B1. - - // Implements: - // var state = (A * _lo + _hi) & _MASK_64; - // _lo = state & _MASK_32; - // _hi = state >> 32; - void _nextState() { - // Simulate (0xFFFFDA61 * lo + hi) without overflowing 53 bits. - int tmpHi = 0xFFFF0000 * _lo; // At most 48 bits of significant result. - int tmpHiLo = tmpHi & _MASK32; // Get the lower 32 bits. - int tmpHiHi = tmpHi - tmpHiLo; // And just the upper 32 bits. - int tmpLo = 0xDA61 * _lo; - int tmpLoLo = tmpLo & _MASK32; - int tmpLoHi = tmpLo - tmpLoLo; - - int newLo = tmpLoLo + tmpHiLo + _hi; - _lo = newLo & _MASK32; - int newLoHi = newLo - _lo; - _hi = ((tmpLoHi + tmpHiHi + newLoHi) ~/ _POW2_32) & _MASK32; - assert(_lo < _POW2_32); - assert(_hi < _POW2_32); - } - - int nextInt(int max) { - if (max <= 0 || max > _POW2_32) { - throw new RangeError('max must be in range 0 < max ≤ 2^32, was $max'); - } - if ((max & (max - 1)) == 0) { - // Fast case for powers of two. - _nextState(); - return _lo & (max - 1); - } - - int rnd32; - int result; - do { - _nextState(); - rnd32 = _lo; - result = rnd32.remainder(max) as int; // % max; - } while ((rnd32 - result + max) >= _POW2_32); - return result; - } - - double nextDouble() { - _nextState(); - int bits26 = _lo & ((1 << 26) - 1); - _nextState(); - int bits27 = _lo & ((1 << 27) - 1); - return (bits26 * _POW2_27_D + bits27) / _POW2_53_D; - } - - bool nextBool() { - _nextState(); - return (_lo & 1) == 0; - } -} - -class _JSSecureRandom implements Random { - // Reused buffer with room enough for a double. - final _buffer = new ByteData(8); - - _JSSecureRandom() { - var crypto = JS('', 'self.crypto'); - if (crypto != null) { - var getRandomValues = JS('', '#.getRandomValues', crypto); - if (getRandomValues != null) { - return; - } - } - throw new UnsupportedError( - 'No source of cryptographically secure random numbers available.'); - } - - /// Fill _buffer from [start] to `start + length` with random bytes. - void _getRandomBytes(int start, int length) { - JS('void', 'crypto.getRandomValues(#)', - _buffer.buffer.asUint8List(start, length)); - } - - bool nextBool() { - _getRandomBytes(0, 1); - return _buffer.getUint8(0).isOdd; - } - - double nextDouble() { - _getRandomBytes(1, 7); - // Set top bits 12 of double to 0x3FF which is the exponent for numbers - // between 1.0 and 2.0. - _buffer.setUint8(0, 0x3F); - int highByte = _buffer.getUint8(1); - _buffer.setUint8(1, highByte | 0xF0); - - // Buffer now contains double in the range [1.0-2.0) - // with 52 bits of entropy (not 53). - // To get 53 bits, we extract the 53rd bit from higthByte before - // overwriting it, and add that as a least significant bit. - // The getFloat64 method is big-endian as default. - double result = _buffer.getFloat64(0) - 1.0; - if (highByte & 0x10 != 0) { - result += 1.1102230246251565e-16; // pow(2,-53). - } - return result; - } - - int nextInt(int max) { - if (max <= 0 || max > _POW2_32) { - throw new RangeError('max must be in range 0 < max ≤ 2^32, was $max'); - } - int byteCount = 1; - if (max > 0xFF) { - byteCount++; - if (max > 0xFFFF) { - byteCount++; - if (max > 0xFFFFFF) { - byteCount++; - } - } - } - _buffer.setUint32(0, 0); - int start = 4 - byteCount; - int randomLimit = pow(256, byteCount) as int; - while (true) { - _getRandomBytes(start, byteCount); - // The getUint32 method is big-endian as default. - int random = _buffer.getUint32(0); - if (max & (max - 1) == 0) { - // Max is power of 2. - return random & (max - 1); - } - int result = random.remainder(max) as int; - // Ensure results have equal probability by rejecting values in the - // last range of k*max .. 256**byteCount. - // TODO: Consider picking a higher byte count if the last range is a - // significant portion of the entire range - a 50% chance of having - // to use two more bytes is no worse than always using one more. - if (random - result + max < randomLimit) { - return result; - } - } - } -} diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/mirrors_patch_cfe.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/mirrors_patch_cfe.dart deleted file mode 100644 index cd961a023a9..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/lib/mirrors_patch_cfe.dart +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) 2012, 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. - -// Patch library for dart:mirrors. - -import 'dart:_js_helper' show patch; -import 'dart:mirrors'; - -const String _message = 'dart:mirrors is no longer supported for web apps'; - -@patch -MirrorSystem currentMirrorSystem() => throw new UnsupportedError(_message); - -@patch -InstanceMirror reflect(dynamic reflectee) => - throw new UnsupportedError(_message); - -@patch -ClassMirror reflectClass(Type key) => throw new UnsupportedError(_message); - -@patch -TypeMirror reflectType(Type key, [List typeArguments]) => - throw new UnsupportedError(_message); - -@patch -abstract class MirrorSystem { - Map get libraries; - IsolateMirror get isolate; - TypeMirror get dynamicType; - TypeMirror get voidType; - TypeMirror get neverType; - - @patch - LibraryMirror findLibrary(Symbol libraryName) => - throw new UnsupportedError(_message); - - @patch - static String getName(Symbol symbol) => throw new UnsupportedError(_message); - - @patch - static Symbol getSymbol(String name, [LibraryMirror library]) => - throw new UnsupportedError(_message); -} diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/native_helper.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/native_helper.dart deleted file mode 100644 index f5f40b7c2ae..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/lib/native_helper.dart +++ /dev/null @@ -1,593 +0,0 @@ -// Copyright (c) 2012, 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. - -part of _js_helper; - -// TODO(ngeoffray): stop using this method once our optimizers can -// change str1.contains(str2) into str1.indexOf(str2) != -1. -bool contains(String userAgent, String name) { - return JS('int', '#.indexOf(#)', userAgent, name) != -1; -} - -int arrayLength(List array) { - return JS('int', '#.length', array); -} - -arrayGet(List array, int index) { - return JS('var', '#[#]', array, index); -} - -void arraySet(List array, int index, var value) { - JS('var', '#[#] = #', array, index, value); -} - -propertyGet(var object, String property) { - return JS('var', '#[#]', object, property); -} - -bool callHasOwnProperty(var function, var object, String property) { - return JS('bool', '#.call(#, #)', function, object, property); -} - -void propertySet(var object, String property, var value) { - JS('var', '#[#] = #', object, property, value); -} - -getPropertyFromPrototype(var object, String name) { - return JS('var', 'Object.getPrototypeOf(#)[#]', object, name); -} - -/// Returns a String tag identifying the type of the native object, or `null`. -/// The tag is not the name of the type, but usually the name of the JavaScript -/// constructor function. Initialized by [initHooks]. -Function? getTagFunction; - -/// If a lookup via [getTagFunction] on an object [object] that has [tag] fails, -/// this function is called to provide an alternate tag. This allows us to fail -/// gracefully if we can make a good guess, for example, when browsers add novel -/// kinds of HTMLElement that we have never heard of. Initialized by -/// [initHooks]. -Function? alternateTagFunction; - -/// Returns the prototype for the JavaScript constructor named by an input tag. -/// Returns `null` if there is no such constructor, or if pre-patching of the -/// constructor is to be avoided. Initialized by [initHooks]. -Function? prototypeForTagFunction; - -String toStringForNativeObject(var obj) { - // TODO(sra): Is this code dead? - // [getTagFunction] might be uninitialized, but in usual usage, toString has - // been called via an interceptor and initialized it. - String name = getTagFunction == null - ? '' - : JS('String', '#', getTagFunction!(obj)); - return 'Instance of $name'; -} - -int hashCodeForNativeObject(object) => Primitives.objectHashCode(object); - -/// Sets a JavaScript property on an object. -void defineProperty(var obj, String property, var value) { - JS( - 'void', - 'Object.defineProperty(#, #, ' - '{value: #, enumerable: false, writable: true, configurable: true})', - obj, - property, - value); -} - -// Is [obj] an instance of a Dart-defined class? -bool isDartObject(obj) { - // Some of the extra parens here are necessary. - return JS( - 'bool', - '((#) instanceof (#))', - obj, - JS_BUILTIN( - 'depends:none;effects:none;', JsBuiltin.dartObjectConstructor)); -} - -/// A JavaScript object mapping tags to the constructors of interceptors. -/// This is a JavaScript object with no prototype. -/// -/// Example: 'HTMLImageElement' maps to the ImageElement class constructor. -get interceptorsByTag => JS_EMBEDDED_GLOBAL('=Object', INTERCEPTORS_BY_TAG); - -/// A JavaScript object mapping tags to `true` or `false`. -/// -/// Example: 'HTMLImageElement' maps to `true` since, as there are no subclasses -/// of ImageElement, it is a leaf class in the native class hierarchy. -get leafTags => JS_EMBEDDED_GLOBAL('=Object', LEAF_TAGS); - -String findDispatchTagForInterceptorClass(interceptorClassConstructor) { - return JS( - '', r'#.#', interceptorClassConstructor, NATIVE_SUPERCLASS_TAG_NAME); -} - -/// Cache of dispatch records for instances. This is a JavaScript object used -/// as a map. Keys are instance tags, e.g. "!SomeThing". The cache permits the -/// sharing of one dispatch record between multiple instances. -var dispatchRecordsForInstanceTags; - -/// Cache of interceptors indexed by uncacheable tags, e.g. "~SomeThing". -/// This is a JavaScript object used as a map. -var interceptorsForUncacheableTags; - -lookupInterceptor(String tag) { - return propertyGet(interceptorsByTag, tag); -} - -// Dispatch tag marks are optional prefixes for a dispatch tag that direct how -// the interceptor for the tag may be cached. - -/// No caching permitted. -const UNCACHED_MARK = '~'; - -/// Dispatch record must be cached per instance -const INSTANCE_CACHED_MARK = '!'; - -/// Dispatch record is cached on immediate prototype. -const LEAF_MARK = '-'; - -/// Dispatch record is cached on immediate prototype with a prototype -/// verification to prevent the interceptor being associated with a subclass -/// before a dispatch record is cached on the subclass. -const INTERIOR_MARK = '+'; - -/// A 'discriminator' function is to be used. TBD. -const DISCRIMINATED_MARK = '*'; - -/// Returns the interceptor for a native object, or returns `null` if not found. -/// -/// A dispatch record is cached according to the specification of the dispatch -/// tag for [obj]. -@pragma('dart2js:noInline') -lookupAndCacheInterceptor(obj) { - assert(!isDartObject(obj)); - String tag = getTagFunction!(obj); - - // Fast path for instance (and uncached) tags because the lookup is repeated - // for each instance (or getInterceptor call). - var record = propertyGet(dispatchRecordsForInstanceTags, tag); - if (record != null) return patchInstance(obj, record); - var interceptor = propertyGet(interceptorsForUncacheableTags, tag); - if (interceptor != null) return interceptor; - - // This lookup works for derived dispatch tags because we add them all in - // [initNativeDispatch]. - var interceptorClass = lookupInterceptor(tag); - if (interceptorClass == null) { - String? altTag = alternateTagFunction!(obj, tag); - if (altTag != null) { - tag = altTag; - // Fast path for instance and uncached tags again. - record = propertyGet(dispatchRecordsForInstanceTags, tag); - if (record != null) return patchInstance(obj, record); - interceptor = propertyGet(interceptorsForUncacheableTags, tag); - if (interceptor != null) return interceptor; - - interceptorClass = lookupInterceptor(tag); - } - } - - if (interceptorClass == null) { - // This object is not known to Dart. There could be several reasons for - // that, including (but not limited to): - // - // * A bug in native code (hopefully this is caught during development). - // * An unknown DOM object encountered. - // * JavaScript code running in an unexpected context. For example, on - // node.js. - return null; - } - - interceptor = JS('', '#.prototype', interceptorClass); - - var mark = JS('String|Null', '#[0]', tag); - - if (mark == INSTANCE_CACHED_MARK) { - record = makeLeafDispatchRecord(interceptor); - propertySet(dispatchRecordsForInstanceTags, tag, record); - return patchInstance(obj, record); - } - - if (mark == UNCACHED_MARK) { - propertySet(interceptorsForUncacheableTags, tag, interceptor); - return interceptor; - } - - if (mark == LEAF_MARK) { - return patchProto(obj, makeLeafDispatchRecord(interceptor)); - } - - if (mark == INTERIOR_MARK) { - return patchInteriorProto(obj, interceptor); - } - - if (mark == DISCRIMINATED_MARK) { - // TODO(sra): Use discriminator of tag. - throw new UnimplementedError(tag); - } - - // [tag] was not explicitly an interior or leaf tag, so - var isLeaf = JS('bool', '(#[#]) === true', leafTags, tag); - if (isLeaf) { - return patchProto(obj, makeLeafDispatchRecord(interceptor)); - } else { - return patchInteriorProto(obj, interceptor); - } -} - -patchInstance(obj, record) { - setDispatchProperty(obj, record); - return dispatchRecordInterceptor(record); -} - -patchProto(obj, record) { - setDispatchProperty(JS('', 'Object.getPrototypeOf(#)', obj), record); - return dispatchRecordInterceptor(record); -} - -patchInteriorProto(obj, interceptor) { - var proto = JS('', 'Object.getPrototypeOf(#)', obj); - var record = makeDispatchRecord(interceptor, proto, null, null); - setDispatchProperty(proto, record); - return interceptor; -} - -makeLeafDispatchRecord(interceptor) { - var fieldName = JS_GET_NAME(JsGetName.IS_INDEXABLE_FIELD_NAME); - bool indexability = JS('bool', r'!!#[#]', interceptor, fieldName); - return makeDispatchRecord(interceptor, false, null, indexability); -} - -makeDefaultDispatchRecord(tag, interceptorClass, proto) { - var interceptor = JS('', '#.prototype', interceptorClass); - var isLeaf = JS('bool', '(#[#]) === true', leafTags, tag); - if (isLeaf) { - return makeLeafDispatchRecord(interceptor); - } else { - return makeDispatchRecord(interceptor, proto, null, null); - } -} - -/// [proto] should have no shadowing prototypes that are not also assigned a -/// dispatch rescord. -setNativeSubclassDispatchRecord(proto, interceptor) { - setDispatchProperty(proto, makeLeafDispatchRecord(interceptor)); -} - -String constructorNameFallback(object) { - return JS('String', '#(#)', _constructorNameFallback, object); -} - -var initNativeDispatchFlag; // null or true - -@pragma('dart2js:noInline') -void initNativeDispatch() { - if (true == initNativeDispatchFlag) return; - initNativeDispatchFlag = true; - initNativeDispatchContinue(); -} - -@pragma('dart2js:noInline') -void initNativeDispatchContinue() { - dispatchRecordsForInstanceTags = JS('', 'Object.create(null)'); - interceptorsForUncacheableTags = JS('', 'Object.create(null)'); - - initHooks(); - - // Try to pro-actively patch prototypes of DOM objects. For each of our known - // tags `TAG`, if `window.TAG` is a (constructor) function, set the dispatch - // property if the function's prototype to a dispatch record. - var map = interceptorsByTag; - var tags = JS('JSMutableArray', 'Object.getOwnPropertyNames(#)', map); - - if (JS('bool', 'typeof window != "undefined"')) { - var context = JS('=Object', 'window'); - var fun = JS('=Object', 'function () {}'); - for (int i = 0; i < tags.length; i++) { - var tag = tags[i]; - var proto = prototypeForTagFunction!(tag); - if (proto != null) { - var interceptorClass = JS('', '#[#]', map, tag); - var record = makeDefaultDispatchRecord(tag, interceptorClass, proto); - if (record != null) { - setDispatchProperty(proto, record); - // Ensure the modified prototype is still fast by assigning it to - // the prototype property of a function object. - JS('', '#.prototype = #', fun, proto); - } - } - } - } - - // [interceptorsByTag] maps 'plain' dispatch tags. Add all the derived - // dispatch tags to simplify lookup of derived tags. - for (int i = 0; i < tags.length; i++) { - var tag = JS('String', '#[#]', tags, i); - if (JS('bool', '/^[A-Za-z_]/.test(#)', tag)) { - var interceptorClass = propertyGet(map, tag); - propertySet(map, INSTANCE_CACHED_MARK + tag, interceptorClass); - propertySet(map, UNCACHED_MARK + tag, interceptorClass); - propertySet(map, LEAF_MARK + tag, interceptorClass); - propertySet(map, INTERIOR_MARK + tag, interceptorClass); - propertySet(map, DISCRIMINATED_MARK + tag, interceptorClass); - } - } -} - -/// Initializes [getTagFunction] and [alternateTagFunction]. -/// -/// These functions are 'hook functions', collectively 'hooks'. They -/// initialized by applying a series of hooks transformers. Built-in hooks -/// transformers deal with various known browser behaviours. -/// -/// Each hook tranformer takes a 'hooks' input which is a JavaScript object -/// containing the hook functions, and returns the same or a new object with -/// replacements. The replacements can wrap the originals to provide alternate -/// or modified behaviour. -/// -/// { getTag: function(obj) {...}, -/// getUnknownTag: function(obj, tag) {...}, -/// prototypeForTag: function(tag) {...}, -/// discriminator: function(tag) {...}, -/// } -/// -/// * getTag(obj) returns the dispatch tag, or `null`. -/// * getUnknownTag(obj, tag) returns a tag when [getTag] fails. -/// * prototypeForTag(tag) returns the prototype of the constructor for tag, -/// or `null` if not available or prepatching is undesirable. -/// * discriminator(tag) returns a function TBD. -/// -/// The web site can adapt a dart2js application by loading code ahead of the -/// dart2js application that defines hook transformers to be after the built in -/// ones. Code defining a transformer HT should use the following pattern to -/// ensure multiple transformers can be composed: -/// -/// (dartNativeDispatchHooksTransformer = -/// window.dartNativeDispatchHooksTransformer || []).push(HT); -/// -/// -/// TODO: Implement and describe dispatch tags and their caching methods. -void initHooks() { - // The initial simple hooks: - var hooks = JS('', '#()', _baseHooks); - - // Customize for browsers where `object.constructor.name` fails: - var _fallbackConstructorHooksTransformer = JS('', '#(#)', - _fallbackConstructorHooksTransformerGenerator, _constructorNameFallback); - hooks = applyHooksTransformer(_fallbackConstructorHooksTransformer, hooks); - - // Customize for browsers: - hooks = applyHooksTransformer(_firefoxHooksTransformer, hooks); - hooks = applyHooksTransformer(_ieHooksTransformer, hooks); - hooks = applyHooksTransformer(_operaHooksTransformer, hooks); - hooks = applyHooksTransformer(_safariHooksTransformer, hooks); - - hooks = applyHooksTransformer(_fixDocumentHooksTransformer, hooks); - - // TODO(sra): Update ShadowDOM polyfil to use - // [dartNativeDispatchHooksTransformer] and remove this hook. - hooks = applyHooksTransformer( - _dartExperimentalFixupGetTagHooksTransformer, hooks); - - // Apply global hooks. - // - // If defined, dartNativeDispatchHookdTransformer should be a single function - // of a JavaScript Array of functions. - - if (JS('bool', 'typeof dartNativeDispatchHooksTransformer != "undefined"')) { - var transformers = JS('', 'dartNativeDispatchHooksTransformer'); - if (JS('bool', 'typeof # == "function"', transformers)) { - transformers = [transformers]; - } - if (JS('bool', '#.constructor == Array', transformers)) { - for (int i = 0; i < JS('int', '#.length', transformers); i++) { - var transformer = JS('', '#[#]', transformers, i); - if (JS('bool', 'typeof # == "function"', transformer)) { - hooks = applyHooksTransformer(transformer, hooks); - } - } - } - } - - var getTag = JS('', '#.getTag', hooks); - var getUnknownTag = JS('', '#.getUnknownTag', hooks); - var prototypeForTag = JS('', '#.prototypeForTag', hooks); - - getTagFunction = (o) => JS('String|Null', '#(#)', getTag, o); - alternateTagFunction = - (o, String tag) => JS('String|Null', '#(#, #)', getUnknownTag, o, tag); - prototypeForTagFunction = - (String tag) => JS('', '#(#)', prototypeForTag, tag); -} - -applyHooksTransformer(transformer, hooks) { - var newHooks = JS('=Object|Null', '#(#)', transformer, hooks); - return JS('', '# || #', newHooks, hooks); -} - -// JavaScript code fragments. -// -// This is a temporary place for the JavaScript code. -// -// TODO(sra): These code fragments are not minified. They could be generated by -// the code emitter, or JS_CONST could be improved to parse entire functions and -// take care of the minification. - -const _baseHooks = const JS_CONST(r''' -function() { - var toStringFunction = Object.prototype.toString; - function getTag(o) { - var s = toStringFunction.call(o); - return s.substring(8, s.length - 1); - } - function getUnknownTag(object, tag) { - // This code really belongs in [getUnknownTagGenericBrowser] but having it - // here allows [getUnknownTag] to be tested on d8. - if (/^HTML[A-Z].*Element$/.test(tag)) { - // Check that it is not a simple JavaScript object. - var name = toStringFunction.call(object); - if (name == "[object Object]") return null; - return "HTMLElement"; - } - } - function getUnknownTagGenericBrowser(object, tag) { - if (self.HTMLElement && object instanceof HTMLElement) return "HTMLElement"; - return getUnknownTag(object, tag); - } - function prototypeForTag(tag) { - if (typeof window == "undefined") return null; - if (typeof window[tag] == "undefined") return null; - var constructor = window[tag]; - if (typeof constructor != "function") return null; - return constructor.prototype; - } - function discriminator(tag) { return null; } - - var isBrowser = typeof navigator == "object"; - - return { - getTag: getTag, - getUnknownTag: isBrowser ? getUnknownTagGenericBrowser : getUnknownTag, - prototypeForTag: prototypeForTag, - discriminator: discriminator }; -}'''); - -/// Returns the name of the constructor function for browsers where -/// `object.constructor.name` is not reliable. -/// -/// This function is split out of -/// [_fallbackConstructorHooksTransformerGenerator] as it is called from both -/// the dispatch hooks and via [constructorNameFallback] from objectToString. -const _constructorNameFallback = const JS_CONST(r''' -function getTagFallback(o) { - var s = Object.prototype.toString.call(o); - return s.substring(8, s.length - 1); -}'''); - -const _fallbackConstructorHooksTransformerGenerator = const JS_CONST(r''' -function(getTagFallback) { - return function(hooks) { - // If we are not in a browser, assume we are in d8. - // TODO(sra): Recognize jsshell. - if (typeof navigator != "object") return hooks; - - var ua = navigator.userAgent; - // TODO(antonm): remove a reference to DumpRenderTree. - if (ua.indexOf("DumpRenderTree") >= 0) return hooks; - if (ua.indexOf("Chrome") >= 0) { - // Confirm constructor name is usable for dispatch. - function confirm(p) { - return typeof window == "object" && window[p] && window[p].name == p; - } - if (confirm("Window") && confirm("HTMLElement")) return hooks; - } - - hooks.getTag = getTagFallback; - }; -}'''); - -const _ieHooksTransformer = const JS_CONST(r''' -function(hooks) { - var userAgent = typeof navigator == "object" ? navigator.userAgent : ""; - if (userAgent.indexOf("Trident/") == -1) return hooks; - - var getTag = hooks.getTag; - - var quickMap = { - "BeforeUnloadEvent": "Event", - "DataTransfer": "Clipboard", - "HTMLDDElement": "HTMLElement", - "HTMLDTElement": "HTMLElement", - "HTMLPhraseElement": "HTMLElement", - "Position": "Geoposition" - }; - - function getTagIE(o) { - var tag = getTag(o); - var newTag = quickMap[tag]; - if (newTag) return newTag; - // Patches for types which report themselves as Objects. - if (tag == "Object") { - if (window.DataView && (o instanceof window.DataView)) return "DataView"; - } - return tag; - } - - function prototypeForTagIE(tag) { - var constructor = window[tag]; - if (constructor == null) return null; - return constructor.prototype; - } - - hooks.getTag = getTagIE; - hooks.prototypeForTag = prototypeForTagIE; -}'''); - -const _fixDocumentHooksTransformer = const JS_CONST(r''' -function(hooks) { - var getTag = hooks.getTag; - var prototypeForTag = hooks.prototypeForTag; - function getTagFixed(o) { - var tag = getTag(o); - if (tag == "Document") { - // Some browsers and the polymer polyfill call both HTML and XML documents - // "Document", so we check for the xmlVersion property, which is the empty - // string on HTML documents. Since both dart:html classes Document and - // HtmlDocument share the same type, we must patch the instances and not - // the prototype. - if (!!o.xmlVersion) return "!Document"; - return "!HTMLDocument"; - } - return tag; - } - - function prototypeForTagFixed(tag) { - if (tag == "Document") return null; // Do not pre-patch Document. - return prototypeForTag(tag); - } - - hooks.getTag = getTagFixed; - hooks.prototypeForTag = prototypeForTagFixed; -}'''); - -const _firefoxHooksTransformer = const JS_CONST(r''' -function(hooks) { - var userAgent = typeof navigator == "object" ? navigator.userAgent : ""; - if (userAgent.indexOf("Firefox") == -1) return hooks; - - var getTag = hooks.getTag; - - var quickMap = { - "BeforeUnloadEvent": "Event", - "DataTransfer": "Clipboard", - "GeoGeolocation": "Geolocation", - "Location": "!Location", // Fixes issue 18151 - "WorkerMessageEvent": "MessageEvent", - "XMLDocument": "!Document"}; - - function getTagFirefox(o) { - var tag = getTag(o); - return quickMap[tag] || tag; - } - - hooks.getTag = getTagFirefox; -}'''); - -const _operaHooksTransformer = const JS_CONST(r''' -function(hooks) { return hooks; } -'''); - -const _safariHooksTransformer = const JS_CONST(r''' -function(hooks) { return hooks; } -'''); - -const _dartExperimentalFixupGetTagHooksTransformer = const JS_CONST(r''' -function(hooks) { - if (typeof dartExperimentalFixupGetTag != "function") return hooks; - hooks.getTag = dartExperimentalFixupGetTag(hooks.getTag); -}'''); diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/native_typed_data.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/native_typed_data.dart deleted file mode 100644 index 39d527b1483..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/lib/native_typed_data.dart +++ /dev/null @@ -1,1816 +0,0 @@ -// Copyright (c) 2013, 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. - -/// Specialized integers and floating point numbers, -/// with SIMD support and efficient lists. -library dart.typed_data.implementation; - -import 'dart:collection' show ListMixin; -import 'dart:_internal' show FixedLengthListMixin hide Symbol; -import 'dart:_interceptors' show JSIndexable, JSUInt32, JSUInt31; -import 'dart:_js_helper' - show - Creates, - JavaScriptIndexingBehavior, - JSName, - Native, - Returns, - diagnoseIndexError, - diagnoseRangeError; -import 'dart:_foreign_helper' show JS; -import 'dart:math' as Math; - -import 'dart:typed_data'; - -@Native('ArrayBuffer') -class NativeByteBuffer implements ByteBuffer { - @JSName('byteLength') - int get lengthInBytes native; - - Type get runtimeType => ByteBuffer; - - Uint8List asUint8List([int offsetInBytes = 0, int? length]) { - return NativeUint8List.view(this, offsetInBytes, length); - } - - Int8List asInt8List([int offsetInBytes = 0, int? length]) { - return NativeInt8List.view(this, offsetInBytes, length); - } - - Uint8ClampedList asUint8ClampedList([int offsetInBytes = 0, int? length]) { - return NativeUint8ClampedList.view(this, offsetInBytes, length); - } - - Uint16List asUint16List([int offsetInBytes = 0, int? length]) { - return NativeUint16List.view(this, offsetInBytes, length); - } - - Int16List asInt16List([int offsetInBytes = 0, int? length]) { - return NativeInt16List.view(this, offsetInBytes, length); - } - - Uint32List asUint32List([int offsetInBytes = 0, int? length]) { - return NativeUint32List.view(this, offsetInBytes, length); - } - - Int32List asInt32List([int offsetInBytes = 0, int? length]) { - return NativeInt32List.view(this, offsetInBytes, length); - } - - Uint64List asUint64List([int offsetInBytes = 0, int? length]) { - throw UnsupportedError('Uint64List not supported by dart2js.'); - } - - Int64List asInt64List([int offsetInBytes = 0, int? length]) { - throw UnsupportedError('Int64List not supported by dart2js.'); - } - - Int32x4List asInt32x4List([int offsetInBytes = 0, int? length]) { - var storage = - this.asInt32List(offsetInBytes, length != null ? length * 4 : null); - return NativeInt32x4List._externalStorage(storage); - } - - Float32List asFloat32List([int offsetInBytes = 0, int? length]) { - return NativeFloat32List.view(this, offsetInBytes, length); - } - - Float64List asFloat64List([int offsetInBytes = 0, int? length]) { - return NativeFloat64List.view(this, offsetInBytes, length); - } - - Float32x4List asFloat32x4List([int offsetInBytes = 0, int? length]) { - var storage = - this.asFloat32List(offsetInBytes, length != null ? length * 4 : null); - return NativeFloat32x4List._externalStorage(storage); - } - - Float64x2List asFloat64x2List([int offsetInBytes = 0, int? length]) { - var storage = - this.asFloat64List(offsetInBytes, length != null ? length * 2 : null); - return NativeFloat64x2List._externalStorage(storage); - } - - ByteData asByteData([int offsetInBytes = 0, int? length]) { - return NativeByteData.view(this, offsetInBytes, length); - } -} - -/// A fixed-length list of Float32x4 numbers that is viewable as a -/// [TypedData]. For long lists, this implementation will be considerably more -/// space- and time-efficient than the default [List] implementation. -class NativeFloat32x4List extends Object - with ListMixin, FixedLengthListMixin - implements Float32x4List { - final Float32List _storage; - - /// Creates a [Float32x4List] of the specified length (in elements), - /// all of whose elements are initially zero. - NativeFloat32x4List(int length) : _storage = NativeFloat32List(length * 4); - - NativeFloat32x4List._externalStorage(this._storage); - - NativeFloat32x4List._slowFromList(List list) - : _storage = NativeFloat32List(list.length * 4) { - for (int i = 0; i < list.length; i++) { - var e = list[i]; - _storage[(i * 4) + 0] = e.x; - _storage[(i * 4) + 1] = e.y; - _storage[(i * 4) + 2] = e.z; - _storage[(i * 4) + 3] = e.w; - } - } - - Type get runtimeType => Float32x4List; - - /// Creates a [Float32x4List] with the same size as the [elements] list - /// and copies over the elements. - factory NativeFloat32x4List.fromList(List list) { - if (list is NativeFloat32x4List) { - return NativeFloat32x4List._externalStorage( - NativeFloat32List.fromList(list._storage)); - } else { - return NativeFloat32x4List._slowFromList(list); - } - } - - ByteBuffer get buffer => _storage.buffer; - - int get lengthInBytes => _storage.lengthInBytes; - - int get offsetInBytes => _storage.offsetInBytes; - - int get elementSizeInBytes => Float32x4List.bytesPerElement; - - int get length => _storage.length ~/ 4; - - Float32x4 operator [](int index) { - _checkValidIndex(index, this, this.length); - double _x = _storage[(index * 4) + 0]; - double _y = _storage[(index * 4) + 1]; - double _z = _storage[(index * 4) + 2]; - double _w = _storage[(index * 4) + 3]; - return NativeFloat32x4._truncated(_x, _y, _z, _w); - } - - void operator []=(int index, Float32x4 value) { - _checkValidIndex(index, this, this.length); - _storage[(index * 4) + 0] = value.x; - _storage[(index * 4) + 1] = value.y; - _storage[(index * 4) + 2] = value.z; - _storage[(index * 4) + 3] = value.w; - } - - Float32x4List sublist(int start, [int? end]) { - var stop = _checkValidRange(start, end, this.length); - return NativeFloat32x4List._externalStorage( - _storage.sublist(start * 4, stop * 4)); - } -} - -/// A fixed-length list of Int32x4 numbers that is viewable as a -/// [TypedData]. For long lists, this implementation will be considerably more -/// space- and time-efficient than the default [List] implementation. -class NativeInt32x4List extends Object - with ListMixin, FixedLengthListMixin - implements Int32x4List { - final Int32List _storage; - - /// Creates a [Int32x4List] of the specified length (in elements), - /// all of whose elements are initially zero. - NativeInt32x4List(int length) : _storage = NativeInt32List(length * 4); - - NativeInt32x4List._externalStorage(Int32List storage) : _storage = storage; - - NativeInt32x4List._slowFromList(List list) - : _storage = NativeInt32List(list.length * 4) { - for (int i = 0; i < list.length; i++) { - var e = list[i]; - _storage[(i * 4) + 0] = e.x; - _storage[(i * 4) + 1] = e.y; - _storage[(i * 4) + 2] = e.z; - _storage[(i * 4) + 3] = e.w; - } - } - - Type get runtimeType => Int32x4List; - - /// Creates a [Int32x4List] with the same size as the [elements] list - /// and copies over the elements. - factory NativeInt32x4List.fromList(List list) { - if (list is NativeInt32x4List) { - return NativeInt32x4List._externalStorage( - NativeInt32List.fromList(list._storage)); - } else { - return NativeInt32x4List._slowFromList(list); - } - } - - ByteBuffer get buffer => _storage.buffer; - - int get lengthInBytes => _storage.lengthInBytes; - - int get offsetInBytes => _storage.offsetInBytes; - - int get elementSizeInBytes => Int32x4List.bytesPerElement; - - int get length => _storage.length ~/ 4; - - Int32x4 operator [](int index) { - _checkValidIndex(index, this, this.length); - int _x = _storage[(index * 4) + 0]; - int _y = _storage[(index * 4) + 1]; - int _z = _storage[(index * 4) + 2]; - int _w = _storage[(index * 4) + 3]; - return NativeInt32x4._truncated(_x, _y, _z, _w); - } - - void operator []=(int index, Int32x4 value) { - _checkValidIndex(index, this, this.length); - _storage[(index * 4) + 0] = value.x; - _storage[(index * 4) + 1] = value.y; - _storage[(index * 4) + 2] = value.z; - _storage[(index * 4) + 3] = value.w; - } - - Int32x4List sublist(int start, [int? end]) { - var stop = _checkValidRange(start, end, this.length); - return NativeInt32x4List._externalStorage( - _storage.sublist(start * 4, stop * 4)); - } -} - -/// A fixed-length list of Float64x2 numbers that is viewable as a -/// [TypedData]. For long lists, this implementation will be considerably more -/// space- and time-efficient than the default [List] implementation. -class NativeFloat64x2List extends Object - with ListMixin, FixedLengthListMixin - implements Float64x2List { - final Float64List _storage; - - /// Creates a [Float64x2List] of the specified length (in elements), - /// all of whose elements are initially zero. - NativeFloat64x2List(int length) : _storage = NativeFloat64List(length * 2); - - NativeFloat64x2List._externalStorage(this._storage); - - NativeFloat64x2List._slowFromList(List list) - : _storage = NativeFloat64List(list.length * 2) { - for (int i = 0; i < list.length; i++) { - var e = list[i]; - _storage[(i * 2) + 0] = e.x; - _storage[(i * 2) + 1] = e.y; - } - } - - /// Creates a [Float64x2List] with the same size as the [elements] list - /// and copies over the elements. - factory NativeFloat64x2List.fromList(List list) { - if (list is NativeFloat64x2List) { - return NativeFloat64x2List._externalStorage( - NativeFloat64List.fromList(list._storage)); - } else { - return NativeFloat64x2List._slowFromList(list); - } - } - - Type get runtimeType => Float64x2List; - - ByteBuffer get buffer => _storage.buffer; - - int get lengthInBytes => _storage.lengthInBytes; - - int get offsetInBytes => _storage.offsetInBytes; - - int get elementSizeInBytes => Float64x2List.bytesPerElement; - - int get length => _storage.length ~/ 2; - - Float64x2 operator [](int index) { - _checkValidIndex(index, this, this.length); - double _x = _storage[(index * 2) + 0]; - double _y = _storage[(index * 2) + 1]; - return Float64x2(_x, _y); - } - - void operator []=(int index, Float64x2 value) { - _checkValidIndex(index, this, this.length); - _storage[(index * 2) + 0] = value.x; - _storage[(index * 2) + 1] = value.y; - } - - Float64x2List sublist(int start, [int? end]) { - var stop = _checkValidRange(start, end, this.length); - return NativeFloat64x2List._externalStorage( - _storage.sublist(start * 2, stop * 2)); - } -} - -@Native('ArrayBufferView') -class NativeTypedData implements TypedData { - /// Returns the byte buffer associated with this object. - @Creates('NativeByteBuffer') - @Returns('NativeByteBuffer') - ByteBuffer get buffer native; - - /// Returns the length of this view, in bytes. - @JSName('byteLength') - int get lengthInBytes native; - - /// Returns the offset in bytes into the underlying byte buffer of this view. - @JSName('byteOffset') - int get offsetInBytes native; - - /// Returns the number of bytes in the representation of each element in this - /// list. - @JSName('BYTES_PER_ELEMENT') - int get elementSizeInBytes native; - - void _invalidPosition(int position, int length, String name) { - if (position is! int) { - throw ArgumentError.value(position, name, 'Invalid list position'); - } else { - throw RangeError.range(position, 0, length, name); - } - } - - void _checkPosition(int position, int length, String name) { - if (JS('bool', '(# >>> 0) !== #', position, position) || - JS('int', '#', position) > length) { - // 'int' guaranteed by above test. - _invalidPosition(position, length, name); - } - } -} - -// Validates the unnamed constructor length argument. Checking is necessary -// because passing unvalidated values to the native constructors can cause -// conversions or create views. -int _checkLength(length) { - if (length is! int) throw ArgumentError('Invalid length $length'); - return length; -} - -// Validates `.view` constructor arguments. Checking is necessary because -// passing unvalidated values to the native constructors can cause conversions -// (e.g. String arguments) or create typed data objects that are not actually -// views of the input. -void _checkViewArguments(buffer, offsetInBytes, length) { - if (buffer is! NativeByteBuffer) { - throw ArgumentError('Invalid view buffer'); - } - if (offsetInBytes is! int) { - throw ArgumentError('Invalid view offsetInBytes $offsetInBytes'); - } - if (length is! int?) { - throw ArgumentError('Invalid view length $length'); - } -} - -// Ensures that [list] is a JavaScript Array or a typed array. If necessary, -// returns a copy of the list. -List _ensureNativeList(List list) { - if (list is JSIndexable) return list; - List result = List.filled(list.length, null); - for (int i = 0; i < list.length; i++) { - result[i] = list[i]; - } - return result; -} - -@Native('DataView') -class NativeByteData extends NativeTypedData implements ByteData { - /// Creates a [ByteData] of the specified length (in elements), all of - /// whose elements are initially zero. - factory NativeByteData(int length) => _create1(_checkLength(length)); - - /// Creates an [ByteData] _view_ of the specified region in the specified - /// byte buffer. Changes in the [ByteData] will be visible in the byte - /// buffer and vice versa. If the [offsetInBytes] index of the region is not - /// specified, it defaults to zero (the first byte in the byte buffer). - /// If the length is not specified, it defaults to null, which indicates - /// that the view extends to the end of the byte buffer. - /// - /// Throws [RangeError] if [offsetInBytes] or [length] are negative, or - /// if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than - /// the length of [buffer]. - factory NativeByteData.view( - ByteBuffer buffer, int offsetInBytes, int? length) { - _checkViewArguments(buffer, offsetInBytes, length); - return length == null - ? _create2(buffer, offsetInBytes) - : _create3(buffer, offsetInBytes, length); - } - - Type get runtimeType => ByteData; - - int get elementSizeInBytes => 1; - - /// Returns the floating point number represented by the four bytes at - /// the specified [byteOffset] in this object, in IEEE 754 - /// single-precision binary floating-point format (binary32). - /// - /// Throws [RangeError] if [byteOffset] is negative, or - /// `byteOffset + 4` is greater than the length of this object. - double getFloat32(int byteOffset, [Endian endian = Endian.big]) => - _getFloat32(byteOffset, Endian.little == endian); - - @JSName('getFloat32') - @Returns('double') - double _getFloat32(int byteOffset, [bool? littleEndian]) native; - - /// Returns the floating point number represented by the eight bytes at - /// the specified [byteOffset] in this object, in IEEE 754 - /// double-precision binary floating-point format (binary64). - /// - /// Throws [RangeError] if [byteOffset] is negative, or - /// `byteOffset + 8` is greater than the length of this object. - double getFloat64(int byteOffset, [Endian endian = Endian.big]) => - _getFloat64(byteOffset, Endian.little == endian); - - @JSName('getFloat64') - @Returns('double') - double _getFloat64(int byteOffset, [bool? littleEndian]) native; - - /// Returns the (possibly negative) integer represented by the two bytes at - /// the specified [byteOffset] in this object, in two's complement binary - /// form. - /// The return value will be between 215 and 215 - 1, - /// inclusive. - /// - /// Throws [RangeError] if [byteOffset] is negative, or - /// `byteOffset + 2` is greater than the length of this object. - int getInt16(int byteOffset, [Endian endian = Endian.big]) => - _getInt16(byteOffset, Endian.little == endian); - - @JSName('getInt16') - @Returns('int') - int _getInt16(int byteOffset, [bool? littleEndian]) native; - - /// Returns the (possibly negative) integer represented by the four bytes at - /// the specified [byteOffset] in this object, in two's complement binary - /// form. - /// The return value will be between 231 and 231 - 1, - /// inclusive. - /// - /// Throws [RangeError] if [byteOffset] is negative, or - /// `byteOffset + 4` is greater than the length of this object. - int getInt32(int byteOffset, [Endian endian = Endian.big]) => - _getInt32(byteOffset, Endian.little == endian); - - @JSName('getInt32') - @Returns('int') - int _getInt32(int byteOffset, [bool? littleEndian]) native; - - /// Returns the (possibly negative) integer represented by the eight bytes at - /// the specified [byteOffset] in this object, in two's complement binary - /// form. - /// The return value will be between 263 and 263 - 1, - /// inclusive. - /// - /// Throws [RangeError] if [byteOffset] is negative, or - /// `byteOffset + 8` is greater than the length of this object. - int getInt64(int byteOffset, [Endian endian = Endian.big]) { - throw UnsupportedError('Int64 accessor not supported by dart2js.'); - } - - /// Returns the (possibly negative) integer represented by the byte at the - /// specified [byteOffset] in this object, in two's complement binary - /// representation. The return value will be between -128 and 127, inclusive. - /// - /// Throws [RangeError] if [byteOffset] is negative, or - /// greater than or equal to the length of this object. - int getInt8(int byteOffset) native; - - /// Returns the positive integer represented by the two bytes starting - /// at the specified [byteOffset] in this object, in unsigned binary - /// form. - /// The return value will be between 0 and 216 - 1, inclusive. - /// - /// Throws [RangeError] if [byteOffset] is negative, or - /// `byteOffset + 2` is greater than the length of this object. - int getUint16(int byteOffset, [Endian endian = Endian.big]) => - _getUint16(byteOffset, Endian.little == endian); - - @JSName('getUint16') - @Returns('JSUInt31') - int _getUint16(int byteOffset, [bool? littleEndian]) native; - - /// Returns the positive integer represented by the four bytes starting - /// at the specified [byteOffset] in this object, in unsigned binary - /// form. - /// The return value will be between 0 and 232 - 1, inclusive. - /// - /// Throws [RangeError] if [byteOffset] is negative, or - /// `byteOffset + 4` is greater than the length of this object. - int getUint32(int byteOffset, [Endian endian = Endian.big]) => - _getUint32(byteOffset, Endian.little == endian); - - @JSName('getUint32') - @Returns('JSUInt32') - int _getUint32(int byteOffset, [bool? littleEndian]) native; - - /// Returns the positive integer represented by the eight bytes starting - /// at the specified [byteOffset] in this object, in unsigned binary - /// form. - /// The return value will be between 0 and 264 - 1, inclusive. - /// - /// Throws [RangeError] if [byteOffset] is negative, or - /// `byteOffset + 8` is greater than the length of this object. - int getUint64(int byteOffset, [Endian endian = Endian.big]) { - throw UnsupportedError('Uint64 accessor not supported by dart2js.'); - } - - /// Returns the positive integer represented by the byte at the specified - /// [byteOffset] in this object, in unsigned binary form. The - /// return value will be between 0 and 255, inclusive. - /// - /// Throws [RangeError] if [byteOffset] is negative, or - /// greater than or equal to the length of this object. - int getUint8(int byteOffset) native; - - /// Sets the four bytes starting at the specified [byteOffset] in this - /// object to the IEEE 754 single-precision binary floating-point - /// (binary32) representation of the specified [value]. - /// - /// **Note that this method can lose precision.** The input [value] is - /// a 64-bit floating point value, which will be converted to 32-bit - /// floating point value by IEEE 754 rounding rules before it is stored. - /// If [value] cannot be represented exactly as a binary32, it will be - /// converted to the nearest binary32 value. If two binary32 values are - /// equally close, the one whose least significant bit is zero will be used. - /// Note that finite (but large) values can be converted to infinity, and - /// small non-zero values can be converted to zero. - /// - /// Throws [RangeError] if [byteOffset] is negative, or - /// `byteOffset + 4` is greater than the length of this object. - void setFloat32(int byteOffset, num value, [Endian endian = Endian.big]) => - _setFloat32(byteOffset, value, Endian.little == endian); - - @JSName('setFloat32') - void _setFloat32(int byteOffset, num value, [bool? littleEndian]) native; - - /// Sets the eight bytes starting at the specified [byteOffset] in this - /// object to the IEEE 754 double-precision binary floating-point - /// (binary64) representation of the specified [value]. - /// - /// Throws [RangeError] if [byteOffset] is negative, or - /// `byteOffset + 8` is greater than the length of this object. - void setFloat64(int byteOffset, num value, [Endian endian = Endian.big]) => - _setFloat64(byteOffset, value, Endian.little == endian); - - @JSName('setFloat64') - void _setFloat64(int byteOffset, num value, [bool? littleEndian]) native; - - /// Sets the two bytes starting at the specified [byteOffset] in this - /// object to the two's complement binary representation of the specified - /// [value], which must fit in two bytes. In other words, [value] must lie - /// between 215 and 215 - 1, inclusive. - /// - /// Throws [RangeError] if [byteOffset] is negative, or - /// `byteOffset + 2` is greater than the length of this object. - void setInt16(int byteOffset, int value, [Endian endian = Endian.big]) => - _setInt16(byteOffset, value, Endian.little == endian); - - @JSName('setInt16') - void _setInt16(int byteOffset, int value, [bool? littleEndian]) native; - - /// Sets the four bytes starting at the specified [byteOffset] in this - /// object to the two's complement binary representation of the specified - /// [value], which must fit in four bytes. In other words, [value] must lie - /// between 231 and 231 - 1, inclusive. - /// - /// Throws [RangeError] if [byteOffset] is negative, or - /// `byteOffset + 4` is greater than the length of this object. - void setInt32(int byteOffset, int value, [Endian endian = Endian.big]) => - _setInt32(byteOffset, value, Endian.little == endian); - - @JSName('setInt32') - void _setInt32(int byteOffset, int value, [bool? littleEndian]) native; - - /// Sets the eight bytes starting at the specified [byteOffset] in this - /// object to the two's complement binary representation of the specified - /// [value], which must fit in eight bytes. In other words, [value] must lie - /// between 263 and 263 - 1, inclusive. - /// - /// Throws [RangeError] if [byteOffset] is negative, or - /// `byteOffset + 8` is greater than the length of this object. - void setInt64(int byteOffset, int value, [Endian endian = Endian.big]) { - throw UnsupportedError('Int64 accessor not supported by dart2js.'); - } - - /// Sets the byte at the specified [byteOffset] in this object to the - /// two's complement binary representation of the specified [value], which - /// must fit in a single byte. In other words, [value] must be between - /// -128 and 127, inclusive. - /// - /// Throws [RangeError] if [byteOffset] is negative, or - /// greater than or equal to the length of this object. - void setInt8(int byteOffset, int value) native; - - /// Sets the two bytes starting at the specified [byteOffset] in this object - /// to the unsigned binary representation of the specified [value], - /// which must fit in two bytes. in other words, [value] must be between - /// 0 and 216 - 1, inclusive. - /// - /// Throws [RangeError] if [byteOffset] is negative, or - /// `byteOffset + 2` is greater than the length of this object. - void setUint16(int byteOffset, int value, [Endian endian = Endian.big]) => - _setUint16(byteOffset, value, Endian.little == endian); - - @JSName('setUint16') - void _setUint16(int byteOffset, int value, [bool? littleEndian]) native; - - /// Sets the four bytes starting at the specified [byteOffset] in this object - /// to the unsigned binary representation of the specified [value], - /// which must fit in four bytes. in other words, [value] must be between - /// 0 and 232 - 1, inclusive. - /// - /// Throws [RangeError] if [byteOffset] is negative, or - /// `byteOffset + 4` is greater than the length of this object. - void setUint32(int byteOffset, int value, [Endian endian = Endian.big]) => - _setUint32(byteOffset, value, Endian.little == endian); - - @JSName('setUint32') - void _setUint32(int byteOffset, int value, [bool? littleEndian]) native; - - /// Sets the eight bytes starting at the specified [byteOffset] in this object - /// to the unsigned binary representation of the specified [value], - /// which must fit in eight bytes. in other words, [value] must be between - /// 0 and 264 - 1, inclusive. - /// - /// Throws [RangeError] if [byteOffset] is negative, or - /// `byteOffset + 8` is greater than the length of this object. - void setUint64(int byteOffset, int value, [Endian endian = Endian.big]) { - throw UnsupportedError('Uint64 accessor not supported by dart2js.'); - } - - /// Sets the byte at the specified [byteOffset] in this object to the - /// unsigned binary representation of the specified [value], which must fit - /// in a single byte. in other words, [value] must be between 0 and 255, - /// inclusive. - /// - /// Throws [RangeError] if [byteOffset] is negative, - /// or greater than or equal to the length of this object. - void setUint8(int byteOffset, int value) native; - - static NativeByteData _create1(arg) => - JS('NativeByteData', 'new DataView(new ArrayBuffer(#))', arg); - - static NativeByteData _create2(arg1, arg2) => - JS('NativeByteData', 'new DataView(#, #)', arg1, arg2); - - static NativeByteData _create3(arg1, arg2, arg3) => - JS('NativeByteData', 'new DataView(#, #, #)', arg1, arg2, arg3); -} - -abstract class NativeTypedArray extends NativeTypedData - implements JavaScriptIndexingBehavior { - int get length => JS('JSUInt32', '#.length', this); - - void _setRangeFast( - int start, int end, NativeTypedArray source, int skipCount) { - int targetLength = this.length; - _checkPosition(start, targetLength, 'start'); - _checkPosition(end, targetLength, 'end'); - if (start > end) throw RangeError.range(start, 0, end); - int count = end - start; - - if (skipCount < 0) throw ArgumentError(skipCount); - - int sourceLength = source.length; - if (sourceLength - skipCount < count) { - throw StateError('Not enough elements'); - } - - if (skipCount != 0 || sourceLength != count) { - // Create a view of the exact subrange that is copied from the source. - source = JS('', '#.subarray(#, #)', source, skipCount, skipCount + count); - } - JS('void', '#.set(#, #)', this, source, start); - } -} - -abstract class NativeTypedArrayOfDouble extends NativeTypedArray - with ListMixin, FixedLengthListMixin { - double operator [](int index) { - _checkValidIndex(index, this, this.length); - return JS('num', '#[#]', this, index); - } - - void operator []=(int index, double value) { - _checkValidIndex(index, this, this.length); - JS('void', '#[#] = #', this, index, value); - } - - void setRange(int start, int end, Iterable iterable, - [int skipCount = 0]) { - if (iterable is NativeTypedArrayOfDouble) { - _setRangeFast(start, end, iterable, skipCount); - return; - } - super.setRange(start, end, iterable, skipCount); - } -} - -abstract class NativeTypedArrayOfInt extends NativeTypedArray - with ListMixin, FixedLengthListMixin - implements List { - // operator[]() is not here since different versions have different return - // types - - void operator []=(int index, int value) { - _checkValidIndex(index, this, this.length); - JS('void', '#[#] = #', this, index, value); - } - - void setRange(int start, int end, Iterable iterable, - [int skipCount = 0]) { - if (iterable is NativeTypedArrayOfInt) { - _setRangeFast(start, end, iterable, skipCount); - return; - } - super.setRange(start, end, iterable, skipCount); - } -} - -@Native('Float32Array') -class NativeFloat32List extends NativeTypedArrayOfDouble - implements Float32List { - factory NativeFloat32List(int length) => _create1(_checkLength(length)); - - factory NativeFloat32List.fromList(List elements) => - _create1(_ensureNativeList(elements)); - - factory NativeFloat32List.view( - ByteBuffer buffer, int offsetInBytes, int? length) { - _checkViewArguments(buffer, offsetInBytes, length); - return length == null - ? _create2(buffer, offsetInBytes) - : _create3(buffer, offsetInBytes, length); - } - - Type get runtimeType => Float32List; - - Float32List sublist(int start, [int? end]) { - var stop = _checkValidRange(start, end, this.length); - var source = JS('NativeFloat32List', '#.subarray(#, #)', this, start, stop); - return _create1(source); - } - - static NativeFloat32List _create1(arg) => - JS('NativeFloat32List', 'new Float32Array(#)', arg); - - static NativeFloat32List _create2(arg1, arg2) => - JS('NativeFloat32List', 'new Float32Array(#, #)', arg1, arg2); - - static NativeFloat32List _create3(arg1, arg2, arg3) => - JS('NativeFloat32List', 'new Float32Array(#, #, #)', arg1, arg2, arg3); -} - -@Native('Float64Array') -class NativeFloat64List extends NativeTypedArrayOfDouble - implements Float64List { - factory NativeFloat64List(int length) => _create1(_checkLength(length)); - - factory NativeFloat64List.fromList(List elements) => - _create1(_ensureNativeList(elements)); - - factory NativeFloat64List.view( - ByteBuffer buffer, int offsetInBytes, int? length) { - _checkViewArguments(buffer, offsetInBytes, length); - return length == null - ? _create2(buffer, offsetInBytes) - : _create3(buffer, offsetInBytes, length); - } - - Type get runtimeType => Float64List; - - Float64List sublist(int start, [int? end]) { - var stop = _checkValidRange(start, end, this.length); - var source = JS('NativeFloat64List', '#.subarray(#, #)', this, start, stop); - return _create1(source); - } - - static NativeFloat64List _create1(arg) => - JS('NativeFloat64List', 'new Float64Array(#)', arg); - - static NativeFloat64List _create2(arg1, arg2) => - JS('NativeFloat64List', 'new Float64Array(#, #)', arg1, arg2); - - static NativeFloat64List _create3(arg1, arg2, arg3) => - JS('NativeFloat64List', 'new Float64Array(#, #, #)', arg1, arg2, arg3); -} - -@Native('Int16Array') -class NativeInt16List extends NativeTypedArrayOfInt implements Int16List { - factory NativeInt16List(int length) => _create1(_checkLength(length)); - - factory NativeInt16List.fromList(List elements) => - _create1(_ensureNativeList(elements)); - - factory NativeInt16List.view( - NativeByteBuffer buffer, int offsetInBytes, int? length) { - _checkViewArguments(buffer, offsetInBytes, length); - return length == null - ? _create2(buffer, offsetInBytes) - : _create3(buffer, offsetInBytes, length); - } - - Type get runtimeType => Int16List; - - int operator [](int index) { - _checkValidIndex(index, this, this.length); - return JS('int', '#[#]', this, index); - } - - Int16List sublist(int start, [int? end]) { - var stop = _checkValidRange(start, end, this.length); - var source = JS('NativeInt16List', '#.subarray(#, #)', this, start, stop); - return _create1(source); - } - - static NativeInt16List _create1(arg) => - JS('NativeInt16List', 'new Int16Array(#)', arg); - - static NativeInt16List _create2(arg1, arg2) => - JS('NativeInt16List', 'new Int16Array(#, #)', arg1, arg2); - - static NativeInt16List _create3(arg1, arg2, arg3) => - JS('NativeInt16List', 'new Int16Array(#, #, #)', arg1, arg2, arg3); -} - -@Native('Int32Array') -class NativeInt32List extends NativeTypedArrayOfInt implements Int32List { - factory NativeInt32List(int length) => _create1(_checkLength(length)); - - factory NativeInt32List.fromList(List elements) => - _create1(_ensureNativeList(elements)); - - factory NativeInt32List.view( - ByteBuffer buffer, int offsetInBytes, int? length) { - _checkViewArguments(buffer, offsetInBytes, length); - return length == null - ? _create2(buffer, offsetInBytes) - : _create3(buffer, offsetInBytes, length); - } - - Type get runtimeType => Int32List; - - int operator [](int index) { - _checkValidIndex(index, this, this.length); - return JS('int', '#[#]', this, index); - } - - Int32List sublist(int start, [int? end]) { - var stop = _checkValidRange(start, end, this.length); - var source = JS('NativeInt32List', '#.subarray(#, #)', this, start, stop); - return _create1(source); - } - - static NativeInt32List _create1(arg) => - JS('NativeInt32List', 'new Int32Array(#)', arg); - - static NativeInt32List _create2(arg1, arg2) => - JS('NativeInt32List', 'new Int32Array(#, #)', arg1, arg2); - - static NativeInt32List _create3(arg1, arg2, arg3) => - JS('NativeInt32List', 'new Int32Array(#, #, #)', arg1, arg2, arg3); -} - -@Native('Int8Array') -class NativeInt8List extends NativeTypedArrayOfInt implements Int8List { - factory NativeInt8List(int length) => _create1(_checkLength(length)); - - factory NativeInt8List.fromList(List elements) => - _create1(_ensureNativeList(elements)); - - factory NativeInt8List.view( - ByteBuffer buffer, int offsetInBytes, int? length) { - _checkViewArguments(buffer, offsetInBytes, length); - return length == null - ? _create2(buffer, offsetInBytes) - : _create3(buffer, offsetInBytes, length); - } - - Type get runtimeType => Int8List; - - int operator [](int index) { - _checkValidIndex(index, this, this.length); - return JS('int', '#[#]', this, index); - } - - Int8List sublist(int start, [int? end]) { - var stop = _checkValidRange(start, end, this.length); - var source = JS('NativeInt8List', '#.subarray(#, #)', this, start, stop); - return _create1(source); - } - - static NativeInt8List _create1(arg) => - JS('NativeInt8List', 'new Int8Array(#)', arg); - - static NativeInt8List _create2(arg1, arg2) => - JS('NativeInt8List', 'new Int8Array(#, #)', arg1, arg2); - - static NativeInt8List _create3(arg1, arg2, arg3) => - JS('NativeInt8List', 'new Int8Array(#, #, #)', arg1, arg2, arg3); -} - -@Native('Uint16Array') -class NativeUint16List extends NativeTypedArrayOfInt implements Uint16List { - factory NativeUint16List(int length) => _create1(_checkLength(length)); - - factory NativeUint16List.fromList(List list) => - _create1(_ensureNativeList(list)); - - factory NativeUint16List.view( - ByteBuffer buffer, int offsetInBytes, int? length) { - _checkViewArguments(buffer, offsetInBytes, length); - return length == null - ? _create2(buffer, offsetInBytes) - : _create3(buffer, offsetInBytes, length); - } - - Type get runtimeType => Uint16List; - - int operator [](int index) { - _checkValidIndex(index, this, this.length); - return JS('JSUInt31', '#[#]', this, index); - } - - Uint16List sublist(int start, [int? end]) { - var stop = _checkValidRange(start, end, this.length); - var source = JS('NativeUint16List', '#.subarray(#, #)', this, start, stop); - return _create1(source); - } - - static NativeUint16List _create1(arg) => - JS('NativeUint16List', 'new Uint16Array(#)', arg); - - static NativeUint16List _create2(arg1, arg2) => - JS('NativeUint16List', 'new Uint16Array(#, #)', arg1, arg2); - - static NativeUint16List _create3(arg1, arg2, arg3) => - JS('NativeUint16List', 'new Uint16Array(#, #, #)', arg1, arg2, arg3); -} - -@Native('Uint32Array') -class NativeUint32List extends NativeTypedArrayOfInt implements Uint32List { - factory NativeUint32List(int length) => _create1(_checkLength(length)); - - factory NativeUint32List.fromList(List elements) => - _create1(_ensureNativeList(elements)); - - factory NativeUint32List.view( - ByteBuffer buffer, int offsetInBytes, int? length) { - _checkViewArguments(buffer, offsetInBytes, length); - return length == null - ? _create2(buffer, offsetInBytes) - : _create3(buffer, offsetInBytes, length); - } - - Type get runtimeType => Uint32List; - - int operator [](int index) { - _checkValidIndex(index, this, this.length); - return JS('JSUInt32', '#[#]', this, index); - } - - Uint32List sublist(int start, [int? end]) { - var stop = _checkValidRange(start, end, this.length); - var source = JS('NativeUint32List', '#.subarray(#, #)', this, start, stop); - return _create1(source); - } - - static NativeUint32List _create1(arg) => - JS('NativeUint32List', 'new Uint32Array(#)', arg); - - static NativeUint32List _create2(arg1, arg2) => - JS('NativeUint32List', 'new Uint32Array(#, #)', arg1, arg2); - - static NativeUint32List _create3(arg1, arg2, arg3) => - JS('NativeUint32List', 'new Uint32Array(#, #, #)', arg1, arg2, arg3); -} - -@Native('Uint8ClampedArray,CanvasPixelArray') -class NativeUint8ClampedList extends NativeTypedArrayOfInt - implements Uint8ClampedList { - factory NativeUint8ClampedList(int length) => _create1(_checkLength(length)); - - factory NativeUint8ClampedList.fromList(List elements) => - _create1(_ensureNativeList(elements)); - - factory NativeUint8ClampedList.view( - ByteBuffer buffer, int offsetInBytes, int? length) { - _checkViewArguments(buffer, offsetInBytes, length); - return length == null - ? _create2(buffer, offsetInBytes) - : _create3(buffer, offsetInBytes, length); - } - - Type get runtimeType => Uint8ClampedList; - - int get length => JS('JSUInt32', '#.length', this); - - int operator [](int index) { - _checkValidIndex(index, this, this.length); - return JS('JSUInt31', '#[#]', this, index); - } - - Uint8ClampedList sublist(int start, [int? end]) { - var stop = _checkValidRange(start, end, this.length); - var source = - JS('NativeUint8ClampedList', '#.subarray(#, #)', this, start, stop); - return _create1(source); - } - - static NativeUint8ClampedList _create1(arg) => - JS('NativeUint8ClampedList', 'new Uint8ClampedArray(#)', arg); - - static NativeUint8ClampedList _create2(arg1, arg2) => - JS('NativeUint8ClampedList', 'new Uint8ClampedArray(#, #)', arg1, arg2); - - static NativeUint8ClampedList _create3(arg1, arg2, arg3) => JS( - 'NativeUint8ClampedList', - 'new Uint8ClampedArray(#, #, #)', - arg1, - arg2, - arg3); -} - -// On some browsers Uint8ClampedArray is a subtype of Uint8Array. Marking -// Uint8List as !nonleaf ensures that the native dispatch correctly handles -// the potential for Uint8ClampedArray to 'accidentally' pick up the -// dispatch record for Uint8List. -@Native('Uint8Array,!nonleaf') -class NativeUint8List extends NativeTypedArrayOfInt implements Uint8List { - factory NativeUint8List(int length) => _create1(_checkLength(length)); - - factory NativeUint8List.fromList(List elements) => - _create1(_ensureNativeList(elements)); - - factory NativeUint8List.view( - ByteBuffer buffer, int offsetInBytes, int? length) { - _checkViewArguments(buffer, offsetInBytes, length); - return length == null - ? _create2(buffer, offsetInBytes) - : _create3(buffer, offsetInBytes, length); - } - - Type get runtimeType => Uint8List; - - int get length => JS('JSUInt32', '#.length', this); - - int operator [](int index) { - _checkValidIndex(index, this, this.length); - return JS('JSUInt31', '#[#]', this, index); - } - - Uint8List sublist(int start, [int? end]) { - var stop = _checkValidRange(start, end, this.length); - var source = JS('NativeUint8List', '#.subarray(#, #)', this, start, stop); - return _create1(source); - } - - static NativeUint8List _create1(arg) => - JS('NativeUint8List', 'new Uint8Array(#)', arg); - - static NativeUint8List _create2(arg1, arg2) => - JS('NativeUint8List', 'new Uint8Array(#, #)', arg1, arg2); - - static NativeUint8List _create3(arg1, arg2, arg3) => - JS('NativeUint8List', 'new Uint8Array(#, #, #)', arg1, arg2, arg3); -} - -/// Implementation of Dart Float32x4 immutable value type and operations. -/// Float32x4 stores 4 32-bit floating point values in "lanes". -/// The lanes are "x", "y", "z", and "w" respectively. -class NativeFloat32x4 implements Float32x4 { - final double x; - final double y; - final double z; - final double w; - - static final NativeFloat32List _list = NativeFloat32List(4); - static final Uint32List _uint32view = _list.buffer.asUint32List(); - - static _truncate(x) { - _list[0] = x; - return _list[0]; - } - - NativeFloat32x4(double x, double y, double z, double w) - : this.x = _truncate(x), - this.y = _truncate(y), - this.z = _truncate(z), - this.w = _truncate(w) { - // We would prefer to check for `double` but in dart2js we can't see the - // difference anyway. - if (x is! num) throw ArgumentError(x); - if (y is! num) throw ArgumentError(y); - if (z is! num) throw ArgumentError(z); - if (w is! num) throw ArgumentError(w); - } - - NativeFloat32x4.splat(double v) : this(v, v, v, v); - NativeFloat32x4.zero() : this._truncated(0.0, 0.0, 0.0, 0.0); - - /// Returns a bit-wise copy of [i] as a Float32x4. - factory NativeFloat32x4.fromInt32x4Bits(Int32x4 i) { - _uint32view[0] = i.x; - _uint32view[1] = i.y; - _uint32view[2] = i.z; - _uint32view[3] = i.w; - return NativeFloat32x4._truncated(_list[0], _list[1], _list[2], _list[3]); - } - - NativeFloat32x4.fromFloat64x2(Float64x2 v) - : this._truncated(_truncate(v.x), _truncate(v.y), 0.0, 0.0); - - /// Creates a new NativeFloat32x4. - /// - /// Does not verify if the given arguments are non-null. - NativeFloat32x4._doubles(double x, double y, double z, double w) - : this.x = _truncate(x), - this.y = _truncate(y), - this.z = _truncate(z), - this.w = _truncate(w); - - /// Creates a new NativeFloat32x4. - /// - /// The constructor does not truncate the arguments. They must already be in - /// the correct range. It does not verify the type of the given arguments, - /// either. - NativeFloat32x4._truncated(this.x, this.y, this.z, this.w); - - String toString() { - return '[$x, $y, $z, $w]'; - } - - /// Addition operator. - Float32x4 operator +(Float32x4 other) { - double _x = x + other.x; - double _y = y + other.y; - double _z = z + other.z; - double _w = w + other.w; - return NativeFloat32x4._doubles(_x, _y, _z, _w); - } - - /// Negate operator. - Float32x4 operator -() { - return NativeFloat32x4._truncated(-x, -y, -z, -w); - } - - /// Subtraction operator. - Float32x4 operator -(Float32x4 other) { - double _x = x - other.x; - double _y = y - other.y; - double _z = z - other.z; - double _w = w - other.w; - return NativeFloat32x4._doubles(_x, _y, _z, _w); - } - - /// Multiplication operator. - Float32x4 operator *(Float32x4 other) { - double _x = x * other.x; - double _y = y * other.y; - double _z = z * other.z; - double _w = w * other.w; - return NativeFloat32x4._doubles(_x, _y, _z, _w); - } - - /// Division operator. - Float32x4 operator /(Float32x4 other) { - double _x = x / other.x; - double _y = y / other.y; - double _z = z / other.z; - double _w = w / other.w; - return NativeFloat32x4._doubles(_x, _y, _z, _w); - } - - /// Relational less than. - Int32x4 lessThan(Float32x4 other) { - bool _cx = x < other.x; - bool _cy = y < other.y; - bool _cz = z < other.z; - bool _cw = w < other.w; - return NativeInt32x4._truncated( - _cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0); - } - - /// Relational less than or equal. - Int32x4 lessThanOrEqual(Float32x4 other) { - bool _cx = x <= other.x; - bool _cy = y <= other.y; - bool _cz = z <= other.z; - bool _cw = w <= other.w; - return NativeInt32x4._truncated( - _cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0); - } - - /// Relational greater than. - Int32x4 greaterThan(Float32x4 other) { - bool _cx = x > other.x; - bool _cy = y > other.y; - bool _cz = z > other.z; - bool _cw = w > other.w; - return NativeInt32x4._truncated( - _cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0); - } - - /// Relational greater than or equal. - Int32x4 greaterThanOrEqual(Float32x4 other) { - bool _cx = x >= other.x; - bool _cy = y >= other.y; - bool _cz = z >= other.z; - bool _cw = w >= other.w; - return NativeInt32x4._truncated( - _cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0); - } - - /// Relational equal. - Int32x4 equal(Float32x4 other) { - bool _cx = x == other.x; - bool _cy = y == other.y; - bool _cz = z == other.z; - bool _cw = w == other.w; - return NativeInt32x4._truncated( - _cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0); - } - - /// Relational not-equal. - Int32x4 notEqual(Float32x4 other) { - bool _cx = x != other.x; - bool _cy = y != other.y; - bool _cz = z != other.z; - bool _cw = w != other.w; - return NativeInt32x4._truncated( - _cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0); - } - - /// Returns a copy of [this] each lane being scaled by [s]. - Float32x4 scale(double s) { - double _x = s * x; - double _y = s * y; - double _z = s * z; - double _w = s * w; - return NativeFloat32x4._doubles(_x, _y, _z, _w); - } - - /// Returns the absolute value of this [Float32x4]. - Float32x4 abs() { - double _x = x.abs(); - double _y = y.abs(); - double _z = z.abs(); - double _w = w.abs(); - return NativeFloat32x4._truncated(_x, _y, _z, _w); - } - - /// Clamps [this] to be in the range [lowerLimit]-[upperLimit]. - Float32x4 clamp(Float32x4 lowerLimit, Float32x4 upperLimit) { - double _lx = lowerLimit.x; - double _ly = lowerLimit.y; - double _lz = lowerLimit.z; - double _lw = lowerLimit.w; - double _ux = upperLimit.x; - double _uy = upperLimit.y; - double _uz = upperLimit.z; - double _uw = upperLimit.w; - double _x = x; - double _y = y; - double _z = z; - double _w = w; - // MAX(MIN(self, upper), lower). - _x = _x > _ux ? _ux : _x; - _y = _y > _uy ? _uy : _y; - _z = _z > _uz ? _uz : _z; - _w = _w > _uw ? _uw : _w; - _x = _x < _lx ? _lx : _x; - _y = _y < _ly ? _ly : _y; - _z = _z < _lz ? _lz : _z; - _w = _w < _lw ? _lw : _w; - return NativeFloat32x4._truncated(_x, _y, _z, _w); - } - - /// Extract the sign bit from each lane return them in the first 4 bits. - int get signMask { - var view = _uint32view; - var mx, my, mz, mw; - _list[0] = x; - _list[1] = y; - _list[2] = z; - _list[3] = w; - // This is correct because dart2js uses the unsigned right shift. - mx = (view[0] & 0x80000000) >> 31; - my = (view[1] & 0x80000000) >> 30; - mz = (view[2] & 0x80000000) >> 29; - mw = (view[3] & 0x80000000) >> 28; - return mx | my | mz | mw; - } - - /// Shuffle the lane values. [mask] must be one of the 256 shuffle constants. - Float32x4 shuffle(int mask) { - if ((mask < 0) || (mask > 255)) { - throw RangeError.range(mask, 0, 255, 'mask'); - } - _list[0] = x; - _list[1] = y; - _list[2] = z; - _list[3] = w; - - double _x = _list[mask & 0x3]; - double _y = _list[(mask >> 2) & 0x3]; - double _z = _list[(mask >> 4) & 0x3]; - double _w = _list[(mask >> 6) & 0x3]; - return NativeFloat32x4._truncated(_x, _y, _z, _w); - } - - /// Shuffle the lane values in [this] and [other]. The returned - /// Float32x4 will have XY lanes from [this] and ZW lanes from [other]. - /// Uses the same [mask] as [shuffle]. - Float32x4 shuffleMix(Float32x4 other, int mask) { - if ((mask < 0) || (mask > 255)) { - throw RangeError.range(mask, 0, 255, 'mask'); - } - _list[0] = x; - _list[1] = y; - _list[2] = z; - _list[3] = w; - double _x = _list[mask & 0x3]; - double _y = _list[(mask >> 2) & 0x3]; - - _list[0] = other.x; - _list[1] = other.y; - _list[2] = other.z; - _list[3] = other.w; - double _z = _list[(mask >> 4) & 0x3]; - double _w = _list[(mask >> 6) & 0x3]; - return NativeFloat32x4._truncated(_x, _y, _z, _w); - } - - /// Copy [this] and replace the [x] lane. - Float32x4 withX(double newX) { - return NativeFloat32x4._truncated(_truncate(newX), y, z, w); - } - - /// Copy [this] and replace the [y] lane. - Float32x4 withY(double newY) { - return NativeFloat32x4._truncated(x, _truncate(newY), z, w); - } - - /// Copy [this] and replace the [z] lane. - Float32x4 withZ(double newZ) { - return NativeFloat32x4._truncated(x, y, _truncate(newZ), w); - } - - /// Copy [this] and replace the [w] lane. - Float32x4 withW(double newW) { - return NativeFloat32x4._truncated(x, y, z, _truncate(newW)); - } - - /// Returns the lane-wise minimum value in [this] or [other]. - Float32x4 min(Float32x4 other) { - double _x = x < other.x ? x : other.x; - double _y = y < other.y ? y : other.y; - double _z = z < other.z ? z : other.z; - double _w = w < other.w ? w : other.w; - return NativeFloat32x4._truncated(_x, _y, _z, _w); - } - - /// Returns the lane-wise maximum value in [this] or [other]. - Float32x4 max(Float32x4 other) { - double _x = x > other.x ? x : other.x; - double _y = y > other.y ? y : other.y; - double _z = z > other.z ? z : other.z; - double _w = w > other.w ? w : other.w; - return NativeFloat32x4._truncated(_x, _y, _z, _w); - } - - /// Returns the square root of [this]. - Float32x4 sqrt() { - double _x = Math.sqrt(x); - double _y = Math.sqrt(y); - double _z = Math.sqrt(z); - double _w = Math.sqrt(w); - return NativeFloat32x4._doubles(_x, _y, _z, _w); - } - - /// Returns the reciprocal of [this]. - Float32x4 reciprocal() { - double _x = 1.0 / x; - double _y = 1.0 / y; - double _z = 1.0 / z; - double _w = 1.0 / w; - return NativeFloat32x4._doubles(_x, _y, _z, _w); - } - - /// Returns the square root of the reciprocal of [this]. - Float32x4 reciprocalSqrt() { - double _x = Math.sqrt(1.0 / x); - double _y = Math.sqrt(1.0 / y); - double _z = Math.sqrt(1.0 / z); - double _w = Math.sqrt(1.0 / w); - return NativeFloat32x4._doubles(_x, _y, _z, _w); - } -} - -/// Interface of Dart Int32x4 and operations. -/// Int32x4 stores 4 32-bit bit-masks in "lanes". -/// The lanes are "x", "y", "z", and "w" respectively. -class NativeInt32x4 implements Int32x4 { - final int x; - final int y; - final int z; - final int w; - - static final _list = NativeInt32List(4); - - static _truncate(x) { - _list[0] = x; - return _list[0]; - } - - NativeInt32x4(int x, int y, int z, int w) - : this.x = _truncate(x), - this.y = _truncate(y), - this.z = _truncate(z), - this.w = _truncate(w) { - if (x != this.x && x is! int) throw ArgumentError(x); - if (y != this.y && y is! int) throw ArgumentError(y); - if (z != this.z && z is! int) throw ArgumentError(z); - if (w != this.w && w is! int) throw ArgumentError(w); - } - - NativeInt32x4.bool(bool x, bool y, bool z, bool w) - : this.x = x ? -1 : 0, - this.y = y ? -1 : 0, - this.z = z ? -1 : 0, - this.w = w ? -1 : 0; - - /// Returns a bit-wise copy of [f] as a Int32x4. - factory NativeInt32x4.fromFloat32x4Bits(Float32x4 f) { - NativeFloat32List floatList = NativeFloat32x4._list; - floatList[0] = f.x; - floatList[1] = f.y; - floatList[2] = f.z; - floatList[3] = f.w; - var view = floatList.buffer.asInt32List(); - return NativeInt32x4._truncated(view[0], view[1], view[2], view[3]); - } - - NativeInt32x4._truncated(this.x, this.y, this.z, this.w); - - String toString() => '[$x, $y, $z, $w]'; - - /// The bit-wise or operator. - Int32x4 operator |(Int32x4 other) { - // Dart2js uses unsigned results for bit-operations. - // We use "JS" to fall back to the signed versions. - return NativeInt32x4._truncated( - JS('int', '# | #', x, other.x), - JS('int', '# | #', y, other.y), - JS('int', '# | #', z, other.z), - JS('int', '# | #', w, other.w)); - } - - /// The bit-wise and operator. - Int32x4 operator &(Int32x4 other) { - // Dart2js uses unsigned results for bit-operations. - // We use "JS" to fall back to the signed versions. - return NativeInt32x4._truncated( - JS('int', '# & #', x, other.x), - JS('int', '# & #', y, other.y), - JS('int', '# & #', z, other.z), - JS('int', '# & #', w, other.w)); - } - - /// The bit-wise xor operator. - Int32x4 operator ^(Int32x4 other) { - // Dart2js uses unsigned results for bit-operations. - // We use "JS" to fall back to the signed versions. - return NativeInt32x4._truncated( - JS('int', '# ^ #', x, other.x), - JS('int', '# ^ #', y, other.y), - JS('int', '# ^ #', z, other.z), - JS('int', '# ^ #', w, other.w)); - } - - Int32x4 operator +(Int32x4 other) { - // Avoid going through the typed array by "| 0" the result. - return NativeInt32x4._truncated( - JS('int', '(# + #) | 0', x, other.x), - JS('int', '(# + #) | 0', y, other.y), - JS('int', '(# + #) | 0', z, other.z), - JS('int', '(# + #) | 0', w, other.w)); - } - - Int32x4 operator -(Int32x4 other) { - // Avoid going through the typed array by "| 0" the result. - return NativeInt32x4._truncated( - JS('int', '(# - #) | 0', x, other.x), - JS('int', '(# - #) | 0', y, other.y), - JS('int', '(# - #) | 0', z, other.z), - JS('int', '(# - #) | 0', w, other.w)); - } - - Int32x4 operator -() { - // Avoid going through the typed array by "| 0" the result. - return NativeInt32x4._truncated( - JS('int', '(-#) | 0', x), - JS('int', '(-#) | 0', y), - JS('int', '(-#) | 0', z), - JS('int', '(-#) | 0', w)); - } - - /// Extract the top bit from each lane return them in the first 4 bits. - int get signMask { - int mx = (x & 0x80000000) >> 31; - int my = (y & 0x80000000) >> 31; - int mz = (z & 0x80000000) >> 31; - int mw = (w & 0x80000000) >> 31; - return mx | my << 1 | mz << 2 | mw << 3; - } - - /// Shuffle the lane values. [mask] must be one of the 256 shuffle constants. - Int32x4 shuffle(int mask) { - if ((mask < 0) || (mask > 255)) { - throw RangeError.range(mask, 0, 255, 'mask'); - } - _list[0] = x; - _list[1] = y; - _list[2] = z; - _list[3] = w; - int _x = _list[mask & 0x3]; - int _y = _list[(mask >> 2) & 0x3]; - int _z = _list[(mask >> 4) & 0x3]; - int _w = _list[(mask >> 6) & 0x3]; - return NativeInt32x4._truncated(_x, _y, _z, _w); - } - - /// Shuffle the lane values in [this] and [other]. The returned - /// Int32x4 will have XY lanes from [this] and ZW lanes from [other]. - /// Uses the same [mask] as [shuffle]. - Int32x4 shuffleMix(Int32x4 other, int mask) { - if ((mask < 0) || (mask > 255)) { - throw RangeError.range(mask, 0, 255, 'mask'); - } - _list[0] = x; - _list[1] = y; - _list[2] = z; - _list[3] = w; - int _x = _list[mask & 0x3]; - int _y = _list[(mask >> 2) & 0x3]; - - _list[0] = other.x; - _list[1] = other.y; - _list[2] = other.z; - _list[3] = other.w; - int _z = _list[(mask >> 4) & 0x3]; - int _w = _list[(mask >> 6) & 0x3]; - return NativeInt32x4._truncated(_x, _y, _z, _w); - } - - /// Returns a new [Int32x4] copied from [this] with a new x value. - Int32x4 withX(int x) { - int _x = _truncate(x); - return NativeInt32x4._truncated(_x, y, z, w); - } - - /// Returns a new [Int32x4] copied from [this] with a new y value. - Int32x4 withY(int y) { - int _y = _truncate(y); - return NativeInt32x4._truncated(x, _y, z, w); - } - - /// Returns a new [Int32x4] copied from [this] with a new z value. - Int32x4 withZ(int z) { - int _z = _truncate(z); - return NativeInt32x4._truncated(x, y, _z, w); - } - - /// Returns a new [Int32x4] copied from [this] with a new w value. - Int32x4 withW(int w) { - int _w = _truncate(w); - return NativeInt32x4._truncated(x, y, z, _w); - } - - /// Extracted x value. Returns `false` for 0, `true` for any other value. - bool get flagX => x != 0; - - /// Extracted y value. Returns `false` for 0, `true` for any other value. - bool get flagY => y != 0; - - /// Extracted z value. Returns `false` for 0, `true` for any other value. - bool get flagZ => z != 0; - - /// Extracted w value. Returns `false` for 0, `true` for any other value. - bool get flagW => w != 0; - - /// Returns a new [Int32x4] copied from [this] with a new x value. - Int32x4 withFlagX(bool flagX) { - int _x = flagX ? -1 : 0; - return NativeInt32x4._truncated(_x, y, z, w); - } - - /// Returns a new [Int32x4] copied from [this] with a new y value. - Int32x4 withFlagY(bool flagY) { - int _y = flagY ? -1 : 0; - return NativeInt32x4._truncated(x, _y, z, w); - } - - /// Returns a new [Int32x4] copied from [this] with a new z value. - Int32x4 withFlagZ(bool flagZ) { - int _z = flagZ ? -1 : 0; - return NativeInt32x4._truncated(x, y, _z, w); - } - - /// Returns a new [Int32x4] copied from [this] with a new w value. - Int32x4 withFlagW(bool flagW) { - int _w = flagW ? -1 : 0; - return NativeInt32x4._truncated(x, y, z, _w); - } - - /// Merge [trueValue] and [falseValue] based on [this]' bit mask: - /// Select bit from [trueValue] when bit in [this] is on. - /// Select bit from [falseValue] when bit in [this] is off. - Float32x4 select(Float32x4 trueValue, Float32x4 falseValue) { - var floatList = NativeFloat32x4._list; - var intView = NativeFloat32x4._uint32view; - - floatList[0] = trueValue.x; - floatList[1] = trueValue.y; - floatList[2] = trueValue.z; - floatList[3] = trueValue.w; - int stx = intView[0]; - int sty = intView[1]; - int stz = intView[2]; - int stw = intView[3]; - - floatList[0] = falseValue.x; - floatList[1] = falseValue.y; - floatList[2] = falseValue.z; - floatList[3] = falseValue.w; - int sfx = intView[0]; - int sfy = intView[1]; - int sfz = intView[2]; - int sfw = intView[3]; - int _x = (x & stx) | (~x & sfx); - int _y = (y & sty) | (~y & sfy); - int _z = (z & stz) | (~z & sfz); - int _w = (w & stw) | (~w & sfw); - intView[0] = _x; - intView[1] = _y; - intView[2] = _z; - intView[3] = _w; - return NativeFloat32x4._truncated( - floatList[0], floatList[1], floatList[2], floatList[3]); - } -} - -class NativeFloat64x2 implements Float64x2 { - final double x; - final double y; - - static NativeFloat64List _list = NativeFloat64List(2); - static Uint32List _uint32View = _list.buffer.asUint32List(); - - NativeFloat64x2(this.x, this.y) { - if (x is! num) throw ArgumentError(x); - if (y is! num) throw ArgumentError(y); - } - - NativeFloat64x2.splat(double v) : this(v, v); - - NativeFloat64x2.zero() : this.splat(0.0); - - NativeFloat64x2.fromFloat32x4(Float32x4 v) : this(v.x, v.y); - - /// Arguments [x] and [y] must be doubles. - NativeFloat64x2._doubles(this.x, this.y); - - String toString() => '[$x, $y]'; - - /// Addition operator. - Float64x2 operator +(Float64x2 other) { - return NativeFloat64x2._doubles(x + other.x, y + other.y); - } - - /// Negate operator. - Float64x2 operator -() { - return NativeFloat64x2._doubles(-x, -y); - } - - /// Subtraction operator. - Float64x2 operator -(Float64x2 other) { - return NativeFloat64x2._doubles(x - other.x, y - other.y); - } - - /// Multiplication operator. - Float64x2 operator *(Float64x2 other) { - return NativeFloat64x2._doubles(x * other.x, y * other.y); - } - - /// Division operator. - Float64x2 operator /(Float64x2 other) { - return NativeFloat64x2._doubles(x / other.x, y / other.y); - } - - /// Returns a copy of [this] each lane being scaled by [s]. - Float64x2 scale(double s) { - return NativeFloat64x2._doubles(x * s, y * s); - } - - /// Returns the absolute value of this [Float64x2]. - Float64x2 abs() { - return NativeFloat64x2._doubles(x.abs(), y.abs()); - } - - /// Clamps [this] to be in the range [lowerLimit]-[upperLimit]. - Float64x2 clamp(Float64x2 lowerLimit, Float64x2 upperLimit) { - double _lx = lowerLimit.x; - double _ly = lowerLimit.y; - double _ux = upperLimit.x; - double _uy = upperLimit.y; - double _x = x; - double _y = y; - // MAX(MIN(self, upper), lower). - _x = _x > _ux ? _ux : _x; - _y = _y > _uy ? _uy : _y; - _x = _x < _lx ? _lx : _x; - _y = _y < _ly ? _ly : _y; - return NativeFloat64x2._doubles(_x, _y); - } - - /// Extract the sign bits from each lane return them in the first 2 bits. - int get signMask { - var view = _uint32View; - _list[0] = x; - _list[1] = y; - var mx = (view[1] & 0x80000000) >> 31; - var my = (view[3] & 0x80000000) >> 31; - return mx | my << 1; - } - - /// Returns a new [Float64x2] copied from [this] with a new x value. - Float64x2 withX(double x) { - if (x is! num) throw ArgumentError(x); - return NativeFloat64x2._doubles(x, y); - } - - /// Returns a new [Float64x2] copied from [this] with a new y value. - Float64x2 withY(double y) { - if (y is! num) throw ArgumentError(y); - return NativeFloat64x2._doubles(x, y); - } - - /// Returns the lane-wise minimum value in [this] or [other]. - Float64x2 min(Float64x2 other) { - return NativeFloat64x2._doubles( - x < other.x ? x : other.x, y < other.y ? y : other.y); - } - - /// Returns the lane-wise maximum value in [this] or [other]. - Float64x2 max(Float64x2 other) { - return NativeFloat64x2._doubles( - x > other.x ? x : other.x, y > other.y ? y : other.y); - } - - /// Returns the lane-wise square root of [this]. - Float64x2 sqrt() { - return NativeFloat64x2._doubles(Math.sqrt(x), Math.sqrt(y)); - } -} - -/// Checks that the value is a Uint32. If not, it's not valid as an array -/// index or offset. Also ensures that the value is non-negative. -bool _isInvalidArrayIndex(int index) { - return (JS('bool', '(# >>> 0 !== #)', index, index)); -} - -/// Checks that [index] is a valid index into [list] which has length [length]. -/// -/// That is, [index] is an integer in the range `0..length - 1`. -void _checkValidIndex(int index, List list, int length) { - if (_isInvalidArrayIndex(index) || JS('int', '#', index) >= length) { - throw diagnoseIndexError(list, index); - } -} - -/// Checks that [start] and [end] form a range of a list of length [length]. -/// -/// That is: `start` and `end` are integers with `0 <= start <= end <= length`. -/// If `end` is `null` in which case it is considered to be `length` -/// -/// Returns the actual value of `end`, which is `length` if `end` is `null`, and -/// the original value of `end` otherwise. -int _checkValidRange(int start, int? end, int length) { - if (_isInvalidArrayIndex(start) || // Ensures start is non-negative int. - ((end == null) - ? start > length - : (_isInvalidArrayIndex(end) || start > end || end > length))) { - throw diagnoseRangeError(start, end, length); - } - if (end == null) return length; - return end; -} diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/preambles/README b/sdk_nnbd/lib/_internal/js_runtime/lib/preambles/README deleted file mode 100644 index 446501233c5..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/lib/preambles/README +++ /dev/null @@ -1,17 +0,0 @@ -The files in this directory polyfill some of the functionality that browsers -provide. When running command-line JS evaluators it is frequently necessary to -execute the preambles before executing the output of dart2js. - -=Usage= -- d8: - d8 /lib/_internal/js_runtime/lib/preambles/d8.js .js - -- jsshell: - jsshell -f /lib/_internal/js_runtime/lib/preambles/d8.js -f .js - -- node.js: - The d8 preamble file works for most programs. - - Unfortunately we are not aware of any easy way to provide multiple input files - to node. It seems to be necessary to concatenate the d8 preamble and the - dart2js output. diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/preambles/d8.js b/sdk_nnbd/lib/_internal/js_runtime/lib/preambles/d8.js deleted file mode 100644 index 0174d95ee1b..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/lib/preambles/d8.js +++ /dev/null @@ -1,348 +0,0 @@ -// 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. - -// Javascript preamble, that lets the output of dart2js run on V8's d8 shell. - -// Node wraps files and provides them with a different `this`. The global -// `this` can be accessed through `global`. - -var self = this; -if (typeof global != "undefined") self = global; // Node.js. - -(function(self) { - // Using strict mode to avoid accidentally defining global variables. - "use strict"; // Should be first statement of this function. - - // Location (Uri.base) - var baseUri = 'org-dartlang-d8-preamble:///mock/uri/base/'; - if (typeof process != "undefined" && - typeof process.cwd == "function") { - // Node.js. - baseUri = 'file://' + process.cwd() + '/'; - } - self.location = { href: baseUri }; - - // Event loop. - - // Task queue as cyclic list queue. - var taskQueue = new Array(8); // Length is power of 2. - var head = 0; - var tail = 0; - var mask = taskQueue.length - 1; - function addTask(elem) { - taskQueue[head] = elem; - head = (head + 1) & mask; - if (head == tail) _growTaskQueue(); - } - function removeTask() { - if (head == tail) return; - var result = taskQueue[tail]; - taskQueue[tail] = undefined; - tail = (tail + 1) & mask; - return result; - } - function _growTaskQueue() { - // head == tail. - var length = taskQueue.length; - var split = head; - taskQueue.length = length * 2; - if (split * 2 < length) { // split < length / 2 - for (var i = 0; i < split; i++) { - taskQueue[length + i] = taskQueue[i]; - taskQueue[i] = undefined; - } - head += length; - } else { - for (var i = split; i < length; i++) { - taskQueue[length + i] = taskQueue[i]; - taskQueue[i] = undefined; - } - tail += length; - } - mask = taskQueue.length - 1; - } - - // Mapping from timer id to timer function. - // The timer id is written on the function as .$timerId. - // That field is cleared when the timer is cancelled, but it is not returned - // from the queue until its time comes. - var timerIds = {}; - var timerIdCounter = 1; // Counter used to assign ids. - - // Zero-timer queue as simple array queue using push/shift. - var zeroTimerQueue = []; - - function addTimer(f, ms) { - var id = timerIdCounter++; - f.$timerId = id; - timerIds[id] = f; - if (ms == 0 && !isNextTimerDue()) { - zeroTimerQueue.push(f); - } else { - addDelayedTimer(f, ms); - } - return id; - } - - function nextZeroTimer() { - while (zeroTimerQueue.length > 0) { - var action = zeroTimerQueue.shift(); - if (action.$timerId !== undefined) return action; - } - } - - function nextEvent() { - var action = removeTask(); - if (action) { - return action; - } - do { - action = nextZeroTimer(); - if (action) break; - var nextList = nextDelayedTimerQueue(); - if (!nextList) { - return; - } - var newTime = nextList.shift(); - advanceTimeTo(newTime); - zeroTimerQueue = nextList; - } while (true) - var id = action.$timerId; - clearTimerId(action, id); - return action; - } - - // Mocking time. - var timeOffset = 0; - var now = function() { - // Install the mock Date object only once. - // Following calls to "now" will just use the new (mocked) Date.now - // method directly. - installMockDate(); - now = Date.now; - return Date.now(); - }; - var originalDate = Date; - var originalNow = originalDate.now; - function advanceTimeTo(time) { - var now = originalNow(); - if (timeOffset < time - now) { - timeOffset = time - now; - } - } - function installMockDate() { - var NewDate = function Date(Y, M, D, h, m, s, ms) { - if (this instanceof Date) { - // Assume a construct call. - switch (arguments.length) { - case 0: return new originalDate(originalNow() + timeOffset); - case 1: return new originalDate(Y); - case 2: return new originalDate(Y, M); - case 3: return new originalDate(Y, M, D); - case 4: return new originalDate(Y, M, D, h); - case 5: return new originalDate(Y, M, D, h, m); - case 6: return new originalDate(Y, M, D, h, m, s); - default: return new originalDate(Y, M, D, h, m, s, ms); - } - } - return new originalDate(originalNow() + timeOffset).toString(); - }; - NewDate.UTC = originalDate.UTC; - NewDate.parse = originalDate.parse; - NewDate.now = function now() { return originalNow() + timeOffset; }; - NewDate.prototype = originalDate.prototype; - originalDate.prototype.constructor = NewDate; - Date = NewDate; - } - - // Heap priority queue with key index. - // Each entry is list of [timeout, callback1 ... callbackn]. - var timerHeap = []; - var timerIndex = {}; - function addDelayedTimer(f, ms) { - var timeout = now() + ms; - var timerList = timerIndex[timeout]; - if (timerList == null) { - timerList = [timeout, f]; - timerIndex[timeout] = timerList; - var index = timerHeap.length; - timerHeap.length += 1; - bubbleUp(index, timeout, timerList); - } else { - timerList.push(f); - } - } - - function isNextTimerDue() { - if (timerHeap.length == 0) return false; - var head = timerHeap[0]; - return head[0] < originalNow() + timeOffset; - } - - function nextDelayedTimerQueue() { - if (timerHeap.length == 0) return null; - var result = timerHeap[0]; - var last = timerHeap.pop(); - if (timerHeap.length > 0) { - bubbleDown(0, last[0], last); - } - return result; - } - - function bubbleUp(index, key, value) { - while (index != 0) { - var parentIndex = (index - 1) >> 1; - var parent = timerHeap[parentIndex]; - var parentKey = parent[0]; - if (key > parentKey) break; - timerHeap[index] = parent; - index = parentIndex; - } - timerHeap[index] = value; - } - - function bubbleDown(index, key, value) { - while (true) { - var leftChildIndex = index * 2 + 1; - if (leftChildIndex >= timerHeap.length) break; - var minChildIndex = leftChildIndex; - var minChild = timerHeap[leftChildIndex]; - var minChildKey = minChild[0]; - var rightChildIndex = leftChildIndex + 1; - if (rightChildIndex < timerHeap.length) { - var rightChild = timerHeap[rightChildIndex]; - var rightKey = rightChild[0]; - if (rightKey < minChildKey) { - minChildIndex = rightChildIndex; - minChild = rightChild; - minChildKey = rightKey; - } - } - if (minChildKey > key) break; - timerHeap[index] = minChild; - index = minChildIndex; - } - timerHeap[index] = value; - } - - function addInterval(f, ms) { - var id = timerIdCounter++; - function repeat() { - // Reactivate with the same id. - repeat.$timerId = id; - timerIds[id] = repeat; - addDelayedTimer(repeat, ms); - f(); - } - repeat.$timerId = id; - timerIds[id] = repeat; - addDelayedTimer(repeat, ms); - return id; - } - - function cancelTimer(id) { - var f = timerIds[id]; - if (f == null) return; - clearTimerId(f, id); - } - - function clearTimerId(f, id) { - f.$timerId = undefined; - delete timerIds[id]; - } - - function eventLoop(action) { - while (action) { - try { - action(); - } catch (e) { - if (typeof onerror == "function") { - onerror(e, null, -1); - } else { - throw e; - } - } - action = nextEvent(); - } - } - - // Global properties. "self" refers to the global object, so adding a - // property to "self" defines a global variable. - self.self = self; - self.dartMainRunner = function(main, args) { - // Initialize. - var action = function() { main(args); } - eventLoop(action); - }; - self.setTimeout = addTimer; - self.clearTimeout = cancelTimer; - self.setInterval = addInterval; - self.clearInterval = cancelTimer; - self.scheduleImmediate = addTask; - - function computeCurrentScript() { - try { - throw new Error(); - } catch(e) { - var stack = e.stack; - // The V8 stack looks like: - // at computeCurrentScript (preambles/d8.js:286:13) - // at Object.currentScript (preambles/d8.js:308:31) - // at init.currentScript (/tmp/foo.js:308:19) - // at /tmp/foo.js:320:7 - // at /tmp/foo.js:331:4 - // Sometimes the 'init.currentScript' line is in the format without the - // function name, so match with or without parentheses. - - // vvvvvvvvvvvv Optional prefix up to '('. - var re = /^ *at (?:[^(]*\()?(.*):[0-9]*:[0-9]*\)?$/mg - // Optional ')' at end ^^^ - - var lastMatch = null; - do { - var match = re.exec(stack); - if (match != null) lastMatch = match; - } while (match != null); - return lastMatch[1]; - } - } - - // Adding a 'document' is dangerous since it invalidates the 'typeof document' - // test to see if we are running in the browser. It means that the runtime - // needs to do more precise checks. - // Note that we can't run "currentScript" right away, since that would give - // us the location of the preamble file. Instead we wait for the first access - // which should happen just before invoking main. At this point we are in - // the main file and setting the currentScript property is correct. - var cachedCurrentScript = null; - self.document = { get currentScript() { - if (cachedCurrentScript == null) { - cachedCurrentScript = {src: computeCurrentScript()}; - } - return cachedCurrentScript; - } - }; - - // Support for deferred loading. - self.dartDeferredLibraryLoader = function(uri, successCallback, errorCallback) { - try { - load(uri); - successCallback(); - } catch (error) { - errorCallback(error); - } - }; - - // Mock cryptographically secure random by using plain random. - self.crypto = {getRandomValues: function(array) { - for (var i = 0; i < array.length; i++) { - array[i] = Math.random() * 256; - } - }}; - - // D8 Workers are not sufficiently compatible with browser Workers - // so pretend they don't exist. - // TODO(30217): Try to use D8's worker. - delete self.Worker; -})(self); diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/preambles/jsshell.js b/sdk_nnbd/lib/_internal/js_runtime/lib/preambles/jsshell.js deleted file mode 100644 index a6b41c40b2f..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/lib/preambles/jsshell.js +++ /dev/null @@ -1,340 +0,0 @@ -// 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. - -// Javascript preamble, that lets the output of dart2js run on JSShell. - -(function(self) { - // Using strict mode to avoid accidentally defining global variables. - "use strict"; // Should be first statement of this function. - - // Location (Uri.base) - - var workingDirectory = os.getenv("PWD"); - - // Global properties. "self" refers to the global object, so adding a - // property to "self" defines a global variable. - self.self = self; - - self.location = { href: "file://" + workingDirectory + "/" }; - - // Event loop. - - // Task queue as cyclic list queue. - var taskQueue = new Array(8); // Length is power of 2. - var head = 0; - var tail = 0; - var mask = taskQueue.length - 1; - function addTask(elem) { - taskQueue[head] = elem; - head = (head + 1) & mask; - if (head == tail) _growTaskQueue(); - } - function removeTask() { - if (head == tail) return; - var result = taskQueue[tail]; - taskQueue[tail] = undefined; - tail = (tail + 1) & mask; - return result; - } - function _growTaskQueue() { - // head == tail. - var length = taskQueue.length; - var split = head; - taskQueue.length = length * 2; - if (split * 2 < length) { // split < length / 2 - for (var i = 0; i < split; i++) { - taskQueue[length + i] = taskQueue[i]; - taskQueue[i] = undefined; - } - head += length; - } else { - for (var i = split; i < length; i++) { - taskQueue[length + i] = taskQueue[i]; - taskQueue[i] = undefined; - } - tail += length; - } - mask = taskQueue.length - 1; - } - - // Mapping from timer id to timer function. - // The timer id is written on the function as .$timerId. - // That field is cleared when the timer is cancelled, but it is not returned - // from the queue until its time comes. - var timerIds = {}; - var timerIdCounter = 1; // Counter used to assign ids. - - // Zero-timer queue as simple array queue using push/shift. - var zeroTimerQueue = []; - - function addTimer(f, ms) { - var id = timerIdCounter++; - f.$timerId = id; - timerIds[id] = f; - if (ms == 0 && !isNextTimerDue()) { - zeroTimerQueue.push(f); - } else { - addDelayedTimer(f, ms); - } - return id; - } - - function nextZeroTimer() { - while (zeroTimerQueue.length > 0) { - var action = zeroTimerQueue.shift(); - if (action.$timerId !== undefined) return action; - } - } - - function nextEvent() { - var action = removeTask(); - if (action) { - return action; - } - do { - action = nextZeroTimer(); - if (action) break; - var nextList = nextDelayedTimerQueue(); - if (!nextList) { - return; - } - var newTime = nextList.shift(); - advanceTimeTo(newTime); - zeroTimerQueue = nextList; - } while (true) - var id = action.$timerId; - clearTimerId(action, id); - return action; - } - - // Mocking time. - var timeOffset = 0; - var now = function() { - // Install the mock Date object only once. - // Following calls to "now" will just use the new (mocked) Date.now - // method directly. - installMockDate(); - now = Date.now; - return Date.now(); - }; - var originalDate = Date; - var originalNow = originalDate.now; - function advanceTimeTo(time) { - var now = originalNow(); - if (timeOffset < time - now) { - timeOffset = time - now; - } - } - function installMockDate() { - var NewDate = function Date(Y, M, D, h, m, s, ms) { - if (this instanceof Date) { - // Assume a construct call. - switch (arguments.length) { - case 0: return new originalDate(originalNow() + timeOffset); - case 1: return new originalDate(Y); - case 2: return new originalDate(Y, M); - case 3: return new originalDate(Y, M, D); - case 4: return new originalDate(Y, M, D, h); - case 5: return new originalDate(Y, M, D, h, m); - case 6: return new originalDate(Y, M, D, h, m, s); - default: return new originalDate(Y, M, D, h, m, s, ms); - } - } - return new originalDate(originalNow() + timeOffset).toString(); - }; - NewDate.UTC = originalDate.UTC; - NewDate.parse = originalDate.parse; - NewDate.now = function now() { return originalNow() + timeOffset; }; - NewDate.prototype = originalDate.prototype; - originalDate.prototype.constructor = NewDate; - Date = NewDate; - } - - // Heap priority queue with key index. - // Each entry is list of [timeout, callback1 ... callbackn]. - var timerHeap = []; - var timerIndex = {}; - function addDelayedTimer(f, ms) { - var timeout = now() + ms; - var timerList = timerIndex[timeout]; - if (timerList == null) { - timerList = [timeout, f]; - timerIndex[timeout] = timerList; - var index = timerHeap.length; - timerHeap.length += 1; - bubbleUp(index, timeout, timerList); - } else { - timerList.push(f); - } - } - - function isNextTimerDue() { - if (timerHeap.length == 0) return false; - var head = timerHeap[0]; - return head[0] < originalNow() + timeOffset; - } - - function nextDelayedTimerQueue() { - if (timerHeap.length == 0) return null; - var result = timerHeap[0]; - var last = timerHeap.pop(); - if (timerHeap.length > 0) { - bubbleDown(0, last[0], last); - } - return result; - } - - function bubbleUp(index, key, value) { - while (index != 0) { - var parentIndex = (index - 1) >> 1; - var parent = timerHeap[parentIndex]; - var parentKey = parent[0]; - if (key > parentKey) break; - timerHeap[index] = parent; - index = parentIndex; - } - timerHeap[index] = value; - } - - function bubbleDown(index, key, value) { - while (true) { - var leftChildIndex = index * 2 + 1; - if (leftChildIndex >= timerHeap.length) break; - var minChildIndex = leftChildIndex; - var minChild = timerHeap[leftChildIndex]; - var minChildKey = minChild[0]; - var rightChildIndex = leftChildIndex + 1; - if (rightChildIndex < timerHeap.length) { - var rightChild = timerHeap[rightChildIndex]; - var rightKey = rightChild[0]; - if (rightKey < minChildKey) { - minChildIndex = rightChildIndex; - minChild = rightChild; - minChildKey = rightKey; - } - } - if (minChildKey > key) break; - timerHeap[index] = minChild; - index = minChildIndex; - } - timerHeap[index] = value; - } - - function addInterval(f, ms) { - var id = timerIdCounter++; - function repeat() { - // Reactivate with the same id. - repeat.$timerId = id; - timerIds[id] = repeat; - addDelayedTimer(repeat, ms); - f(); - } - repeat.$timerId = id; - timerIds[id] = repeat; - addDelayedTimer(repeat, ms); - return id; - } - - function cancelTimer(id) { - var f = timerIds[id]; - if (f == null) return; - clearTimerId(f, id); - } - - function clearTimerId(f, id) { - f.$timerId = undefined; - delete timerIds[id]; - } - - function eventLoop(action) { - while (action) { - try { - action(); - } catch (e) { - if (typeof onerror == "function") { - onerror(e, null, -1); - } else { - throw e; - } - } - action = nextEvent(); - } - } - - self.dartMainRunner = function(main, args) { - // Initialize. - var action = function() { main(args); } - eventLoop(action); - }; - self.setTimeout = addTimer; - self.clearTimeout = cancelTimer; - self.setInterval = addInterval; - self.clearInterval = cancelTimer; - self.scheduleImmediate = addTask; - - function computeCurrentScript() { - try { - throw new Error(); - } catch(e) { - var stack = e.stack; - print(stack); - // The jsshell stack looks like: - // computeCurrentScript@...preambles/jsshell.js:23:13 - // self.document.currentScript@...preambles/jsshell.js:53:37 - // @/tmp/foo.js:308:1 - // @/tmp/foo.js:303:1 - // @/tmp/foo.js:5:1 - var re = new RegExp("^.*@(.*):[0-9]*:[0-9]*$", "mg"); - var lastMatch = null; - do { - var match = re.exec(stack); - if (match != null) lastMatch = match; - } while (match != null); - return lastMatch[1]; - } - } - - // Adding a 'document' is dangerous since it invalidates the 'typeof document' - // test to see if we are running in the browser. It means that the runtime - // needs to do more precise checks. - // Note that we can't run "currentScript" right away, since that would give - // us the location of the preamble file. Instead we wait for the first access - // which should happen just before invoking main. At this point we are in - // the main file and setting the currentScript property is correct. - // Note that we cannot use `thisFileName()`, since that would give us the - // preamble and not the script file. - var cachedCurrentScript = null; - self.document = { get currentScript() { - if (cachedCurrentScript == null) { - cachedCurrentScript = {src: computeCurrentScript()}; - } - return cachedCurrentScript; - } - }; - - // Support for deferred loading. - self.dartDeferredLibraryLoader = function(uri, successCallback, errorCallback) { - try { - load(uri); - successCallback(); - } catch (error) { - errorCallback(error); - } - }; - - // Mock cryptographically secure random by using plain random. - self.crypto = {getRandomValues: function(array) { - for (var i = 0; i < array.length; i++) { - array[i] = Math.random() * 256; - } - }}; -})(this) - -var getKeys = function(obj){ - var keys = []; - for(var key in obj){ - keys.push(key); - } - return keys; -} diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/regexp_helper.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/regexp_helper.dart deleted file mode 100644 index 8eaad602f0c..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/lib/regexp_helper.dart +++ /dev/null @@ -1,295 +0,0 @@ -// Copyright (c) 2012, 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. - -part of _js_helper; - -// Helper method used by internal libraries. -regExpGetNative(JSSyntaxRegExp regexp) => regexp._nativeRegExp; - -/// Returns a native version of the RegExp with the global flag set. -/// -/// The RegExp's `lastIndex` property is zero when it is returned. -/// -/// The returned regexp is shared, and its `lastIndex` property may be -/// modified by other uses, so the returned regexp must be used immediately -/// when it's returned, with no user-provided code run in between. -regExpGetGlobalNative(JSSyntaxRegExp regexp) { - var nativeRegexp = regexp._nativeGlobalVersion; - JS('void', '#.lastIndex = 0', nativeRegexp); - return nativeRegexp; -} - -/// Computes the number of captures in a regexp. -/// -/// This currently involves creating a new RegExp object with a different -/// source and running it against the empty string (the last part is usually -/// fast). -/// -/// The JSSyntaxRegExp could cache the result, and set the cache any time -/// it finds a match. -int regExpCaptureCount(JSSyntaxRegExp regexp) { - var nativeAnchoredRegExp = regexp._nativeAnchoredVersion; - var match = JS('JSExtendableArray', '#.exec("")', nativeAnchoredRegExp); - // The native-anchored regexp always have one capture more than the original, - // and always matches the empty string. - return match.length - 2; -} - -class JSSyntaxRegExp implements RegExp { - final String pattern; - final _nativeRegExp; - var _nativeGlobalRegExp; - var _nativeAnchoredRegExp; - - String toString() => - 'RegExp/$pattern/' + JS('String', '#.flags', _nativeRegExp); - - JSSyntaxRegExp(String source, - {bool multiLine: false, - bool caseSensitive: true, - bool unicode: false, - bool dotAll: false}) - : this.pattern = source, - this._nativeRegExp = makeNative( - source, multiLine, caseSensitive, unicode, dotAll, false); - - get _nativeGlobalVersion { - if (_nativeGlobalRegExp != null) return _nativeGlobalRegExp; - return _nativeGlobalRegExp = makeNative( - pattern, _isMultiLine, _isCaseSensitive, _isUnicode, _isDotAll, true); - } - - get _nativeAnchoredVersion { - if (_nativeAnchoredRegExp != null) return _nativeAnchoredRegExp; - // An "anchored version" of a regexp is created by adding "|()" to the - // source. This means that the regexp always matches at the first position - // that it tries, and you can see if the original regexp matched, or it - // was the added zero-width match that matched, by looking at the last - // capture. If it is a String, the match participated, otherwise it didn't. - return _nativeAnchoredRegExp = makeNative('$pattern|()', _isMultiLine, - _isCaseSensitive, _isUnicode, _isDotAll, true); - } - - bool get _isMultiLine => JS('bool', '#.multiline', _nativeRegExp); - bool get _isCaseSensitive => JS('bool', '!#.ignoreCase', _nativeRegExp); - bool get _isUnicode => JS('bool', '#.unicode', _nativeRegExp); - bool get _isDotAll => JS('bool', '#.dotAll', _nativeRegExp); - - static makeNative(String source, bool multiLine, bool caseSensitive, - bool unicode, bool dotAll, bool global) { - checkString(source); - String m = multiLine == true ? 'm' : ''; - String i = caseSensitive == true ? '' : 'i'; - String u = unicode ? 'u' : ''; - String s = dotAll ? 's' : ''; - String g = global ? 'g' : ''; - // We're using the JavaScript's try catch instead of the Dart one to avoid - // dragging in Dart runtime support just because of using RegExp. - var regexp = JS( - '', - r''' - (function(source, modifiers) { - try { - return new RegExp(source, modifiers); - } catch (e) { - return e; - } - })(#, # + # + # + # + #)''', - source, - m, - i, - u, - s, - g); - if (JS('bool', '# instanceof RegExp', regexp)) return regexp; - // The returned value is the JavaScript exception. Turn it into a - // Dart exception. - String errorMessage = JS('String', r'String(#)', regexp); - throw new FormatException('Illegal RegExp pattern ($errorMessage)', source); - } - - RegExpMatch? firstMatch(String string) { - JSArray? m = JS('JSExtendableArray|Null', r'#.exec(#)', _nativeRegExp, - checkString(string)); - if (m == null) return null; - return new _MatchImplementation(this, m); - } - - bool hasMatch(String string) { - return JS('bool', r'#.test(#)', _nativeRegExp, checkString(string)); - } - - String? stringMatch(String string) { - var match = firstMatch(string); - if (match != null) return match.group(0); - return null; - } - - Iterable allMatches(String string, [int start = 0]) { - checkString(string); - checkInt(start); - if (start < 0 || start > string.length) { - throw new RangeError.range(start, 0, string.length); - } - return new _AllMatchesIterable(this, string, start); - } - - RegExpMatch? _execGlobal(String string, int start) { - Object regexp = _nativeGlobalVersion; - JS('void', '#.lastIndex = #', regexp, start); - JSArray? match = JS('JSExtendableArray|Null', '#.exec(#)', regexp, string); - if (match == null) return null; - return new _MatchImplementation(this, match); - } - - RegExpMatch? _execAnchored(String string, int start) { - Object regexp = _nativeAnchoredVersion; - JS('void', '#.lastIndex = #', regexp, start); - JSArray? match = JS('JSExtendableArray|Null', '#.exec(#)', regexp, string); - if (match == null) return null; - // If the last capture group participated, the original regexp did not - // match at the start position. - if (match.removeLast() != null) return null; - return new _MatchImplementation(this, match); - } - - RegExpMatch? matchAsPrefix(String string, [int start = 0]) { - if (start < 0 || start > string.length) { - throw new RangeError.range(start, 0, string.length); - } - return _execAnchored(string, start); - } - - bool get isMultiLine => _isMultiLine; - bool get isCaseSensitive => _isCaseSensitive; - bool get isUnicode => _isUnicode; - bool get isDotAll => _isDotAll; -} - -class _MatchImplementation implements RegExpMatch { - final Pattern pattern; - // Contains a JS RegExp match object. - // It is an Array of String values with extra 'index' and 'input' properties. - // If there were named capture groups, there will also be an extra 'groups' - // property containing an object with capture group names as keys and - // matched strings as values. - // We didn't force it to be JSArray, so it is JSArray, but - // containing String or `undefined` values. - final JSArray _match; - - _MatchImplementation(this.pattern, this._match) { - assert(JS('var', '#.input', _match) is String); - assert(JS('var', '#.index', _match) is int); - } - - String get input => JS('String', '#.input', _match); - - int get start => - JS('returns:int;depends:none;effects:none;gvn:true', '#.index', _match); - - int get end => (start + - JS('returns:int;depends:none;effects:none;gvn:true', '#[0].length', - _match)) as int; - - // The JS below changes the static type to avoid an implicit cast. - // TODO(sra): Find a nicer way to do this, e.g. unsafeCast. - String? group(int index) => JS('String|Null', '#', _match[index]); - - String? operator [](int index) => group(index); - - int get groupCount => _match.length - 1; - - List groups(List groups) { - List out = []; - for (int i in groups) { - out.add(group(i)); - } - return out; - } - - String namedGroup(String name) { - var groups = JS('Object|Null', '#.groups', _match); - if (groups != null) { - var result = JS('String|Null', '#[#]', groups, name); - if (result != null || JS('bool', '# in #', name, groups)) { - return result; - } - } - throw ArgumentError.value(name, "name", "Not a capture group name"); - } - - Iterable get groupNames { - var groups = JS('Object|Null', '#.groups', _match); - if (groups != null) { - var keys = new JSArray.markGrowable( - JS('returns:JSExtendableArray;new:true', 'Object.keys(#)', groups)); - return SubListIterable(keys, 0, null); - } - return Iterable.empty(); - } -} - -class _AllMatchesIterable extends IterableBase { - final JSSyntaxRegExp _re; - final String _string; - final int _start; - - _AllMatchesIterable(this._re, this._string, this._start); - - Iterator get iterator => - new _AllMatchesIterator(_re, _string, _start); -} - -class _AllMatchesIterator implements Iterator { - final JSSyntaxRegExp _regExp; - String? _string; - int _nextIndex; - RegExpMatch? _current; - - _AllMatchesIterator(this._regExp, this._string, this._nextIndex); - - RegExpMatch get current => _current!; - - static bool _isLeadSurrogate(int c) { - return c >= 0xd800 && c <= 0xdbff; - } - - static bool _isTrailSurrogate(int c) { - return c >= 0xdc00 && c <= 0xdfff; - } - - bool moveNext() { - var string = _string; - if (string == null) return false; - if (_nextIndex <= string.length) { - RegExpMatch? match = _regExp._execGlobal(string, _nextIndex); - if (match != null) { - _current = match; - int nextIndex = match.end; - if (match.start == nextIndex) { - // Zero-width match. Advance by one more, unless the regexp - // is in unicode mode and it would put us within a surrogate - // pair. In that case, advance past the code point as a whole. - if (_regExp.isUnicode && - _nextIndex + 1 < string.length && - _isLeadSurrogate(string.codeUnitAt(_nextIndex)) && - _isTrailSurrogate(string.codeUnitAt(_nextIndex + 1))) { - nextIndex++; - } - nextIndex++; - } - _nextIndex = nextIndex; - return true; - } - } - _current = null; - _string = null; // Marks iteration as ended. - return false; - } -} - -/// Find the first match of [regExp] in [string] at or after [start]. -RegExpMatch? firstMatchAfter(JSSyntaxRegExp regExp, String string, int start) { - return regExp._execGlobal(string, start); -} diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart deleted file mode 100644 index 39ec922797a..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart +++ /dev/null @@ -1,3167 +0,0 @@ -// Copyright (c) 2019, 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. - -/// This library contains support for runtime type information. -library rti; - -import 'dart:_foreign_helper' - show - getInterceptor, - getJSArrayInteropRti, - JS, - JS_BUILTIN, - JS_EMBEDDED_GLOBAL, - JS_GET_FLAG, - JS_GET_NAME, - JS_STRING_CONCAT, - RAW_DART_FUNCTION_REF, - TYPE_REF, - LEGACY_TYPE_REF; - -import 'dart:_interceptors' - show JavaScriptFunction, JSArray, JSNull, JSUnmodifiableArray; - -import 'dart:_js_names' show unmangleGlobalNameIfPreservedAnyways; - -import 'dart:_js_embedded_names' - show - JsBuiltin, - JsGetName, - RtiUniverseFieldNames, - ARRAY_RTI_PROPERTY, - CONSTRUCTOR_RTI_CACHE_PROPERTY_NAME, - RTI_UNIVERSE, - TYPES; - -import 'dart:_recipe_syntax'; - -// The top type `Object?` is used throughout this library even when values are -// not nullable or have narrower types in order to avoid incurring type checks -// before the type checking infrastructure has been set up. -// We could use `dynamic`, but this would allow inadvertent implicit downcasts. -// TODO(fishythefish, dart-lang/language#115): Replace `Object?` with a typedef -// when possible. - -/// An Rti object represents both a type (e.g `Map`) and a type -/// environment (`Map` binds `Map.K=int` and `Map.V=String`). -/// -/// There is a single [Rti] class to help reduce polymorphism in the JavaScript -/// runtime. The class has a default constructor and no final fields so it can -/// be created before much of the runtime exists. -/// -/// The fields are declared in an order that gets shorter minified names for the -/// more commonly used fields. (TODO: we should exploit the fact that an Rti -/// instance never appears in a dynamic context, so does not need field names to -/// be distinct from dynamic selectors). -/// -class Rti { - /// JavaScript method for 'as' check. The method is called from generated code, - /// e.g. `o as T` generates something like `rtiForT._as(o)`. - @pragma('dart2js:noElision') - Object? _as; - - /// JavaScript method for 'is' test. The method is called from generated - /// code, e.g. `o is T` generates something like `rtiForT._is(o)`. - @pragma('dart2js:noElision') - Object? _is; - - static void _setAsCheckFunction(Rti rti, Object? fn) { - rti._as = fn; - } - - static void _setIsTestFunction(Rti rti, Object? fn) { - rti._is = fn; - } - - @pragma('dart2js:tryInline') - static bool _asCheck(Rti rti, Object? object) { - return JS( - 'bool', '#.#(#)', rti, JS_GET_NAME(JsGetName.RTI_FIELD_AS), object); - } - - @pragma('dart2js:tryInline') - static bool _isCheck(Rti rti, Object? object) { - return JS( - 'bool', '#.#(#)', rti, JS_GET_NAME(JsGetName.RTI_FIELD_IS), object); - } - - /// Method called from generated code to evaluate a type environment recipe in - /// `this` type environment. - Rti _eval(Object? recipe) { - // TODO(sra): Clone the fast-path of _Universe.evalInEnvironment to here. - return _rtiEval(this, _Utils.asString(recipe)); - } - - /// Method called from generated code to extend `this` type environment (an - /// interface or binding Rti) with function type arguments (a singleton - /// argument or tuple of arguments). - Rti _bind(Object? typeOrTuple) => _rtiBind(this, _Utils.asRti(typeOrTuple)); - - /// Method called from generated code to extend `this` type (as a singleton - /// type environment) with function type arguments (a singleton argument or - /// tuple of arguments). - Rti _bind1(Object? typeOrTuple) => _rtiBind1(this, _Utils.asRti(typeOrTuple)); - - // Precomputed derived types. These fields are used to hold derived types that - // are computed eagerly. - // TODO(sra): Implement precomputed type optimizations. - - /// If kind == kindInterface, holds the first type argument (if any). - /// If kind == kindFutureOr, holds Future where T is the base type. - /// - This case is lazily initialized during subtype checks. - /// If kind == kindStar, holds T? where T is the base type. - /// - This case is lazily initialized during subtype checks. - @pragma('dart2js:noElision') - Object? _precomputed1; - - static Object? _getPrecomputed1(Rti rti) => rti._precomputed1; - - static void _setPrecomputed1(Rti rti, Object? precomputed) { - rti._precomputed1 = precomputed; - } - - static Rti _getQuestionFromStar(Object? universe, Rti rti) { - assert(_getKind(rti) == kindStar); - Rti? question = _Utils.asRtiOrNull(_getPrecomputed1(rti)); - if (question == null) { - question = - _Universe._lookupQuestionRti(universe, _getStarArgument(rti), true); - Rti._setPrecomputed1(rti, question); - } - return question; - } - - static Rti _getFutureFromFutureOr(Object? universe, Rti rti) { - assert(_getKind(rti) == kindFutureOr); - Rti? future = _Utils.asRtiOrNull(_getPrecomputed1(rti)); - if (future == null) { - future = _Universe._lookupFutureRti(universe, _getFutureOrArgument(rti)); - Rti._setPrecomputed1(rti, future); - } - return future; - } - - Object? _precomputed2; - Object? _precomputed3; - Object? _precomputed4; - - // Data value used by some tests. - @pragma('dart2js:noElision') - Object? _specializedTestResource; - - static Object? _getSpecializedTestResource(Rti rti) { - return rti._specializedTestResource; - } - - static void _setSpecializedTestResource(Rti rti, Object? value) { - rti._specializedTestResource = value; - } - - // The Type object corresponding to this Rti. - Object? _cachedRuntimeType; - static _Type? _getCachedRuntimeType(Rti rti) => - JS('_Type|Null', '#', rti._cachedRuntimeType); - static void _setCachedRuntimeType(Rti rti, _Type type) { - rti._cachedRuntimeType = type; - } - - /// The kind of Rti `this` is, one of the kindXXX constants below. - /// - /// We don't use an enum since we need to create Rti objects very early. - /// - /// The zero initializer ensures dart2js type analysis considers [_kind] is - /// non-nullable. - Object? /*int*/ _kind = 0; - - static int _getKind(Rti rti) => _Utils.asInt(rti._kind); - static void _setKind(Rti rti, int kind) { - rti._kind = kind; - } - - // Terminal terms. - static const int kindNever = 1; - static const int kindDynamic = 2; - static const int kindVoid = 3; // TODO(sra): Use `dynamic` instead? - static const int kindAny = 4; // Dart1-style 'dynamic' for JS-interop. - static const int kindErased = 5; - // Unary terms. - static const int kindStar = 6; - static const int kindQuestion = 7; - static const int kindFutureOr = 8; - // More complex terms. - static const int kindInterface = 9; - // A vector of type parameters from enclosing functions and closures. - static const int kindBinding = 10; - static const int kindFunction = 11; - static const int kindGenericFunction = 12; - static const int kindGenericFunctionParameter = 13; - - static bool _isUnionOfFunctionType(Rti rti) { - int kind = Rti._getKind(rti); - if (kind == kindStar || kind == kindQuestion || kind == kindFutureOr) { - return _isUnionOfFunctionType(_Utils.asRti(_getPrimary(rti))); - } - return kind == kindFunction || kind == kindGenericFunction; - } - - /// Primary data associated with type. - /// - /// - Minified name of interface for interface types. - /// - Underlying type for unary terms. - /// - Class part of a type environment inside a generic class, or `null` for - /// type tuple. - /// - Return type of a function type. - /// - Underlying function type for a generic function. - /// - de Bruijn index for a generic function parameter. - Object? _primary; - - static Object? _getPrimary(Rti rti) => rti._primary; - static void _setPrimary(Rti rti, Object? value) { - rti._primary = value; - } - - /// Additional data associated with type. - /// - /// - The type arguments of an interface type. - /// - The type arguments from enclosing functions and closures for a - /// kindBinding. - /// - The [_FunctionParameters] of a function type. - /// - The type parameter bounds of a generic function. - Object? _rest; - - static Object? _getRest(Rti rti) => rti._rest; - static void _setRest(Rti rti, Object? value) { - rti._rest = value; - } - - static String _getInterfaceName(Rti rti) { - assert(_getKind(rti) == kindInterface); - return _Utils.asString(_getPrimary(rti)); - } - - static JSArray _getInterfaceTypeArguments(Rti rti) { - // The array is a plain JavaScript Array, otherwise we would need the type - // `JSArray` to exist before we could create the type `JSArray`. - assert(_getKind(rti) == kindInterface); - return JS('JSUnmodifiableArray', '#', _getRest(rti)); - } - - static Rti _getBindingBase(Rti rti) { - assert(_getKind(rti) == kindBinding); - return _Utils.asRti(_getPrimary(rti)); - } - - static JSArray _getBindingArguments(Rti rti) { - assert(_getKind(rti) == kindBinding); - return JS('JSUnmodifiableArray', '#', _getRest(rti)); - } - - static Rti _getStarArgument(Rti rti) { - assert(_getKind(rti) == kindStar); - return _Utils.asRti(_getPrimary(rti)); - } - - static Rti _getQuestionArgument(Rti rti) { - assert(_getKind(rti) == kindQuestion); - return _Utils.asRti(_getPrimary(rti)); - } - - static Rti _getFutureOrArgument(Rti rti) { - assert(_getKind(rti) == kindFutureOr); - return _Utils.asRti(_getPrimary(rti)); - } - - static Rti _getReturnType(Rti rti) { - assert(_getKind(rti) == kindFunction); - return _Utils.asRti(_getPrimary(rti)); - } - - static _FunctionParameters _getFunctionParameters(Rti rti) { - assert(_getKind(rti) == kindFunction); - return JS('_FunctionParameters', '#', _getRest(rti)); - } - - static Rti _getGenericFunctionBase(Rti rti) { - assert(_getKind(rti) == kindGenericFunction); - return _Utils.asRti(_getPrimary(rti)); - } - - static JSArray _getGenericFunctionBounds(Rti rti) { - assert(_getKind(rti) == kindGenericFunction); - return JS('JSUnmodifiableArray', '#', _getRest(rti)); - } - - static int _getGenericFunctionParameterIndex(Rti rti) { - assert(_getKind(rti) == kindGenericFunctionParameter); - return _Utils.asInt(_getPrimary(rti)); - } - - /// On [Rti]s that are type environments*, derived types are cached on the - /// environment to ensure fast canonicalization. Ground-term types (i.e. not - /// dependent on class or function type parameters) are cached in the - /// universe. This field starts as `null` and the cache is created on demand. - /// - /// *Any Rti can be a type environment, since we use the type for a function - /// type environment. The ambiguity between 'generic class is the environment' - /// and 'generic class is a singleton type argument' is resolved by using - /// different indexing in the recipe. - Object? _evalCache; - - static Object? _getEvalCache(Rti rti) => rti._evalCache; - static void _setEvalCache(Rti rti, Object? value) { - rti._evalCache = value; - } - - /// On [Rti]s that are type environments*, extended environments are cached on - /// the base environment to ensure fast canonicalization. - /// - /// This field starts as `null` and the cache is created on demand. - /// - /// *This is valid only on kindInterface and kindBinding Rtis. The ambiguity - /// between 'generic class is the base environment' and 'generic class is a - /// singleton type argument' is resolved [TBD] (either (1) a bind1 cache, or - /// (2)using `env._eval("@<0>")._bind(args)` in place of `env._bind1(args)`). - /// - /// On [Rti]s that are generic function types, results of instantiation are - /// cached on the generic function type to ensure fast repeated - /// instantiations. - Object? _bindCache; - - static Object? _getBindCache(Rti rti) => rti._bindCache; - static void _setBindCache(Rti rti, Object? value) { - rti._bindCache = value; - } - - static Rti allocate() { - return new Rti(); - } - - Object? _canonicalRecipe; - - static String _getCanonicalRecipe(Rti rti) { - var s = rti._canonicalRecipe; - assert(_Utils.isString(s), 'Missing canonical recipe'); - return _Utils.asString(s); - } - - static void _setCanonicalRecipe(Rti rti, String s) { - rti._canonicalRecipe = s; - } -} - -class _FunctionParameters { - static _FunctionParameters allocate() => _FunctionParameters(); - - Object? _requiredPositional; - static JSArray _getRequiredPositional(_FunctionParameters parameters) => - JS('JSUnmodifiableArray', '#', parameters._requiredPositional); - static void _setRequiredPositional( - _FunctionParameters parameters, Object? requiredPositional) { - parameters._requiredPositional = requiredPositional; - } - - Object? _optionalPositional; - static JSArray _getOptionalPositional(_FunctionParameters parameters) => - JS('JSUnmodifiableArray', '#', parameters._optionalPositional); - static void _setOptionalPositional( - _FunctionParameters parameters, Object? optionalPositional) { - parameters._optionalPositional = optionalPositional; - } - - /// These are a sequence of name/bool/type triplets that correspond to named - /// parameters. - /// - /// void foo({int bar, required double baz}) - /// - /// would be encoded as ["bar", false, int, "baz", true, double], where each - /// triplet consists of the name [String], a bool indicating whether or not - /// the parameter is required, and the [Rti]. - /// - /// Invariant: These groups are sorted by name in lexicographically ascending order. - Object? _named; - static JSArray _getNamed(_FunctionParameters parameters) => - JS('JSUnmodifiableArray', '#', parameters._named); - static void _setNamed(_FunctionParameters parameters, Object? named) { - parameters._named = named; - } -} - -Object? _theUniverse() => JS_EMBEDDED_GLOBAL('', RTI_UNIVERSE); - -Rti _rtiEval(Rti environment, String recipe) { - return _Universe.evalInEnvironment(_theUniverse(), environment, recipe); -} - -Rti _rtiBind1(Rti environment, Rti types) { - return _Universe.bind1(_theUniverse(), environment, types); -} - -Rti _rtiBind(Rti environment, Rti types) { - return _Universe.bind(_theUniverse(), environment, types); -} - -/// Evaluate a ground-term type. -/// Called from generated code. -Rti findType(String recipe) { - // Since [findType] should only be called on recipes computed during - // compilation, we can assume that the recipe is already normalized (since all - // [DartType]s are normalized. This allows us to avoid an unfortunate cycle: - // - // If we attempt to normalize here, then during the course of normalization, - // we may attempt to access a [TYPE_REF]. This uses the `type$` object, and - // the values of this object are calls to [findType]. Thus, if we're currently - // in one of these calls, then `type$` will appear to be undefined. - return _Universe.eval(_theUniverse(), recipe, false); -} - -/// Evaluate a type recipe in the environment of an instance. -Rti evalInInstance(Object? instance, String recipe) { - return _rtiEval(instanceType(instance), recipe); -} - -/// Returns [genericFunctionRti] with type parameters bound to those specified -/// by [instantiationRti]. -/// -/// [genericFunctionRti] must be an rti representation with a number of generic -/// type parameters matching the number of types provided by [instantiationRti]. -/// -/// Called from generated code. -@pragma('dart2js:noInline') -Rti? instantiatedGenericFunctionType( - Rti? genericFunctionRti, Rti instantiationRti) { - // If --lax-runtime-type-to-string is enabled and we never check the function - // type, then the function won't have a signature, so its RTI will be null. In - // this case, there is nothing to instantiate, so we return `null` and the - // instantiation appears to be an interface type instead. - if (genericFunctionRti == null) return null; - var bounds = Rti._getGenericFunctionBounds(genericFunctionRti); - var typeArguments = Rti._getInterfaceTypeArguments(instantiationRti); - assert(_Utils.arrayLength(bounds) == _Utils.arrayLength(typeArguments)); - - var cache = Rti._getBindCache(genericFunctionRti); - if (cache == null) { - cache = JS('', 'new Map()'); - Rti._setBindCache(genericFunctionRti, cache); - } - String key = Rti._getCanonicalRecipe(instantiationRti); - var probe = _Utils.mapGet(cache, key); - if (probe != null) return _Utils.asRti(probe); - Rti rti = _substitute(_theUniverse(), - Rti._getGenericFunctionBase(genericFunctionRti), typeArguments, 0); - _Utils.mapSet(cache, key, rti); - return rti; -} - -/// Substitutes [typeArguments] for generic function parameters in [rti]. -/// -/// Generic function parameters are de Bruijn indices counting up through the -/// parameters' scopes to index into [typeArguments]. -/// -/// [depth] is the number of subsequent generic function parameters that are in -/// scope. This is subtracted off the de Bruijn index for the type parameter to -/// arrive at an potential index into [typeArguments]. -/// -/// In order to do a partial substitution - that is, substituting only some -/// type parameters rather than all of them - we encode the unsubstituted -/// positions of the argument list as `undefined` or `null`. -Rti _substitute(Object? universe, Rti rti, Object? typeArguments, int depth) { - int kind = Rti._getKind(rti); - switch (kind) { - case Rti.kindErased: - case Rti.kindNever: - case Rti.kindDynamic: - case Rti.kindVoid: - case Rti.kindAny: - return rti; - case Rti.kindStar: - Rti baseType = _Utils.asRti(Rti._getPrimary(rti)); - Rti substitutedBaseType = - _substitute(universe, baseType, typeArguments, depth); - if (_Utils.isIdentical(substitutedBaseType, baseType)) return rti; - return _Universe._lookupStarRti(universe, substitutedBaseType, true); - case Rti.kindQuestion: - Rti baseType = _Utils.asRti(Rti._getPrimary(rti)); - Rti substitutedBaseType = - _substitute(universe, baseType, typeArguments, depth); - if (_Utils.isIdentical(substitutedBaseType, baseType)) return rti; - return _Universe._lookupQuestionRti(universe, substitutedBaseType, true); - case Rti.kindFutureOr: - Rti baseType = _Utils.asRti(Rti._getPrimary(rti)); - Rti substitutedBaseType = - _substitute(universe, baseType, typeArguments, depth); - if (_Utils.isIdentical(substitutedBaseType, baseType)) return rti; - return _Universe._lookupFutureOrRti(universe, substitutedBaseType, true); - case Rti.kindInterface: - var interfaceTypeArguments = Rti._getInterfaceTypeArguments(rti); - var substitutedInterfaceTypeArguments = _substituteArray( - universe, interfaceTypeArguments, typeArguments, depth); - if (_Utils.isIdentical( - substitutedInterfaceTypeArguments, interfaceTypeArguments)) - return rti; - return _Universe._lookupInterfaceRti(universe, Rti._getInterfaceName(rti), - substitutedInterfaceTypeArguments); - case Rti.kindBinding: - Rti base = Rti._getBindingBase(rti); - Rti substitutedBase = _substitute(universe, base, typeArguments, depth); - var arguments = Rti._getBindingArguments(rti); - var substitutedArguments = - _substituteArray(universe, arguments, typeArguments, depth); - if (_Utils.isIdentical(substitutedBase, base) && - _Utils.isIdentical(substitutedArguments, arguments)) return rti; - return _Universe._lookupBindingRti( - universe, substitutedBase, substitutedArguments); - case Rti.kindFunction: - Rti returnType = Rti._getReturnType(rti); - Rti substitutedReturnType = - _substitute(universe, returnType, typeArguments, depth); - _FunctionParameters functionParameters = Rti._getFunctionParameters(rti); - _FunctionParameters substitutedFunctionParameters = - _substituteFunctionParameters( - universe, functionParameters, typeArguments, depth); - if (_Utils.isIdentical(substitutedReturnType, returnType) && - _Utils.isIdentical(substitutedFunctionParameters, functionParameters)) - return rti; - return _Universe._lookupFunctionRti( - universe, substitutedReturnType, substitutedFunctionParameters); - case Rti.kindGenericFunction: - var bounds = Rti._getGenericFunctionBounds(rti); - depth += _Utils.arrayLength(bounds); - var substitutedBounds = - _substituteArray(universe, bounds, typeArguments, depth); - Rti base = Rti._getGenericFunctionBase(rti); - Rti substitutedBase = _substitute(universe, base, typeArguments, depth); - if (_Utils.isIdentical(substitutedBounds, bounds) && - _Utils.isIdentical(substitutedBase, base)) return rti; - return _Universe._lookupGenericFunctionRti( - universe, substitutedBase, substitutedBounds, true); - case Rti.kindGenericFunctionParameter: - int index = Rti._getGenericFunctionParameterIndex(rti); - // Indices below the current depth are out of scope for substitution and - // can be returned unchanged. - if (index < depth) return rti; - var argument = _Utils.arrayAt(typeArguments, index - depth); - // In order to do a partial substitution - that is, substituting only some - // type parameters rather than all of them - we encode the unsubstituted - // positions of the argument list as `undefined` (which will compare equal - // to `null`). - if (argument == null) return rti; - return _Utils.asRti(argument); - default: - throw AssertionError('Attempted to substitute unexpected RTI kind $kind'); - } -} - -Object? _substituteArray( - Object? universe, Object? rtiArray, Object? typeArguments, int depth) { - bool changed = false; - int length = _Utils.arrayLength(rtiArray); - Object? result = JS('', '[]'); - for (int i = 0; i < length; i++) { - Rti rti = _Utils.asRti(_Utils.arrayAt(rtiArray, i)); - Rti substitutedRti = _substitute(universe, rti, typeArguments, depth); - if (_Utils.isNotIdentical(substitutedRti, rti)) { - changed = true; - } - _Utils.arrayPush(result, substitutedRti); - } - return changed ? result : rtiArray; -} - -Object? _substituteNamed( - Object? universe, Object? namedArray, Object? typeArguments, int depth) { - bool changed = false; - int length = _Utils.arrayLength(namedArray); - assert(_Utils.isMultipleOf(length, 3)); - Object? result = JS('', '[]'); - for (int i = 0; i < length; i += 3) { - String name = _Utils.asString(_Utils.arrayAt(namedArray, i)); - bool isRequired = _Utils.asBool(_Utils.arrayAt(namedArray, i + 1)); - Rti rti = _Utils.asRti(_Utils.arrayAt(namedArray, i + 2)); - Rti substitutedRti = _substitute(universe, rti, typeArguments, depth); - if (_Utils.isNotIdentical(substitutedRti, rti)) { - changed = true; - } - _Utils.arrayPush(result, name); - _Utils.arrayPush(result, isRequired); - _Utils.arrayPush(result, substitutedRti); - } - return changed ? result : namedArray; -} - -_FunctionParameters _substituteFunctionParameters(Object? universe, - _FunctionParameters functionParameters, Object? typeArguments, int depth) { - var requiredPositional = - _FunctionParameters._getRequiredPositional(functionParameters); - var substitutedRequiredPositional = - _substituteArray(universe, requiredPositional, typeArguments, depth); - var optionalPositional = - _FunctionParameters._getOptionalPositional(functionParameters); - var substitutedOptionalPositional = - _substituteArray(universe, optionalPositional, typeArguments, depth); - var named = _FunctionParameters._getNamed(functionParameters); - var substitutedNamed = - _substituteNamed(universe, named, typeArguments, depth); - if (_Utils.isIdentical(substitutedRequiredPositional, requiredPositional) && - _Utils.isIdentical(substitutedOptionalPositional, optionalPositional) && - _Utils.isIdentical(substitutedNamed, named)) return functionParameters; - _FunctionParameters result = _FunctionParameters.allocate(); - _FunctionParameters._setRequiredPositional( - result, substitutedRequiredPositional); - _FunctionParameters._setOptionalPositional( - result, substitutedOptionalPositional); - _FunctionParameters._setNamed(result, substitutedNamed); - return result; -} - -bool _isDartObject(Object? object) => _Utils.instanceOf(object, - JS_BUILTIN('depends:none;effects:none;', JsBuiltin.dartObjectConstructor)); - -bool _isClosure(Object? object) => _Utils.instanceOf(object, - JS_BUILTIN('depends:none;effects:none;', JsBuiltin.dartClosureConstructor)); - -/// Returns the structural function [Rti] of [closure], or `null`. -/// [closure] must be a subclass of [Closure]. -/// Called from generated code. -Rti? closureFunctionType(Object? closure) { - var signatureName = JS_GET_NAME(JsGetName.SIGNATURE_NAME); - var signature = JS('', '#[#]', closure, signatureName); - if (signature != null) { - if (JS('bool', 'typeof # == "number"', signature)) { - return getTypeFromTypesTable(_Utils.asInt(signature)); - } - return _Utils.asRti(JS('', '#[#]()', closure, signatureName)); - } - return null; -} - -/// Returns the Rti type of [object]. Closures have both an interface type -/// (Closures implement `Function`) and a structural function type. Uses -/// [testRti] to choose the appropriate type. -/// -/// Called from generated code. -Rti instanceOrFunctionType(Object? object, Rti testRti) { - if (Rti._isUnionOfFunctionType(testRti)) { - if (_isClosure(object)) { - // If [testRti] is e.g. `FutureOr` (where `Action` is some - // function type), we don't need to worry about the `Future` - // branch because closures can't be `Future`s. - Rti? rti = closureFunctionType(object); - if (rti != null) return rti; - } - } - return instanceType(object); -} - -/// Returns the Rti type of [object]. -/// This is the general entry for obtaining the interface type of any value. -/// Called from generated code. -Rti instanceType(Object? object) { - // TODO(sra): Add interceptor-based specializations of this method. Inject a - // _getRti method into (Dart)Object, JSArray, and Interceptor. Then calls to - // this method can be generated as `getInterceptor(o)._getRti(o)`, allowing - // interceptor optimizations to select the specialization. If the only use of - // `getInterceptor` is for calling `_getRti`, then `instanceType` can be - // called, similar to a one-shot interceptor call. This would improve type - // lookup in ListMixin code as the interceptor is JavaScript 'this'. - - if (_isDartObject(object)) { - return _instanceType(object); - } - - if (_Utils.isArray(object)) { - return _arrayInstanceType(object); - } - - var interceptor = getInterceptor(object); - return _instanceTypeFromConstructor(interceptor); -} - -/// Returns the Rti type of JavaScript Array [object]. -/// Called from generated code. -Rti _arrayInstanceType(Object? object) { - // A JavaScript Array can come from three places: - // 1. This Dart program. - // 2. Another Dart program loaded in the JavaScript environment. - // 3. From outside of a Dart program. - // - // In case 3 we default to a fixed type for all external Arrays. To protect - // against an Array passed between two Dart programs loaded into the same - // JavaScript isolate (communicating e.g. via JS-interop), we check that the - // stored value is 'our' Rti type. - // - // TODO(40175): Investigate if it is more efficient to have each Dart program - // use a unique JavaScript property so that both case 2 and case 3 look like a - // missing value. In ES6 we could use a globally named JavaScript Symbol. For - // IE11 we would have to synthesise a String property-name with almost zero - // chance of conflict. - - var rti = JS('', r'#[#]', object, JS_EMBEDDED_GLOBAL('', ARRAY_RTI_PROPERTY)); - var defaultRti = getJSArrayInteropRti(); - - // Case 3. - if (rti == null) return _Utils.asRti(defaultRti); - - // Case 2 and perhaps case 3. Check constructor of extracted type against a - // known instance of Rti - this is an easy way to get the constructor. - if (JS('bool', '#.constructor !== #.constructor', rti, defaultRti)) { - return _Utils.asRti(defaultRti); - } - - // Case 1. - return _Utils.asRti(rti); -} - -/// Returns the Rti type of user-defined class [object]. -/// [object] must not be an intercepted class or a closure. -/// Called from generated code. -Rti _instanceType(Object? object) { - var rti = JS('', r'#[#]', object, JS_GET_NAME(JsGetName.RTI_NAME)); - return rti != null ? _Utils.asRti(rti) : _instanceTypeFromConstructor(object); -} - -String instanceTypeName(Object? object) { - Rti rti = instanceType(object); - return _rtiToString(rti, null); -} - -Rti _instanceTypeFromConstructor(Object? instance) { - var constructor = JS('', '#.constructor', instance); - var probe = JS('', r'#[#]', constructor, CONSTRUCTOR_RTI_CACHE_PROPERTY_NAME); - if (probe != null) return _Utils.asRti(probe); - return _instanceTypeFromConstructorMiss(instance, constructor); -} - -@pragma('dart2js:noInline') -Rti _instanceTypeFromConstructorMiss(Object? instance, Object? constructor) { - // Subclasses of Closure are synthetic classes. The synthetic classes all - // extend a 'normal' class (Closure, BoundClosure, StaticClosure), so make - // them appear to be the superclass. Instantiations have a `$ti` field so - // don't reach here. - // - // TODO(39214): This will need fixing if we ever use instances of - // StaticClosure for static tear-offs. - // - // TODO(sra): Can this test be avoided, e.g. by putting $ti on the - // prototype of Closure/BoundClosure/StaticClosure classes? - var effectiveConstructor = _isClosure(instance) - ? JS('', '#.__proto__.__proto__.constructor', instance) - : constructor; - Rti rti = _Universe.findErasedType( - _theUniverse(), JS('String', '#.name', effectiveConstructor)); - JS('', r'#[#] = #', constructor, CONSTRUCTOR_RTI_CACHE_PROPERTY_NAME, rti); - return rti; -} - -/// Returns the structural function type of [object], or `null` if the object is -/// not a closure. -Rti? _instanceFunctionType(Object? object) => - _isClosure(object) ? closureFunctionType(object) : null; - -/// Returns Rti from types table. The types table is initialized with recipe -/// strings. -Rti getTypeFromTypesTable(int index) { - var table = JS_EMBEDDED_GLOBAL('', TYPES); - var type = _Utils.arrayAt(table, index); - if (_Utils.isString(type)) { - Rti rti = findType(_Utils.asString(type)); - _Utils.arraySetAt(table, index, rti); - return rti; - } - return _Utils.asRti(type); -} - -Type getRuntimeType(Object? object) { - Rti rti = _instanceFunctionType(object) ?? instanceType(object); - return createRuntimeType(rti); -} - -/// Called from generated code. -Type createRuntimeType(Rti rti) { - _Type? type = Rti._getCachedRuntimeType(rti); - if (type != null) return type; - if (JS_GET_FLAG('PRINT_LEGACY_STARS')) { - return _Type(rti); - } else { - String recipe = Rti._getCanonicalRecipe(rti); - String starErasedRecipe = JS('String', '#.replace(/\\*/g, "")', recipe); - if (starErasedRecipe == recipe) { - return _Type(rti); - } - Rti starErasedRti = _Universe.eval(_theUniverse(), starErasedRecipe, true); - type = Rti._getCachedRuntimeType(starErasedRti) ?? _Type(starErasedRti); - Rti._setCachedRuntimeType(rti, type); - return type; - } -} - -/// Called from generated code in the constant pool. -Type typeLiteral(String recipe) { - return createRuntimeType(findType(recipe)); -} - -/// Implementation of [Type] based on Rti. -class _Type implements Type { - final Rti _rti; - - _Type(this._rti) : assert(Rti._getCachedRuntimeType(_rti) == null) { - Rti._setCachedRuntimeType(_rti, this); - } - - @override - String toString() => _rtiToString(_rti, null); -} - -/// Called from generated code. -/// -/// The first time the default `_is` method is called, it replaces itself with a -/// specialized version. -// TODO(sra): Emit code to force-replace the `_is` method, generated dependent -// on the types used in the program. e.g. -// -// findType("bool")._is = H._isBool; -// -// This could be omitted if (1) the `bool` rti is not used directly for a test -// (e.g. we lower a check to a direct helper), and (2) `bool` does not flow to a -// tested type parameter. The trick will be to ensure that `H._isBool` is -// generated. -bool _installSpecializedIsTest(Object? object) { - // This static method is installed on an Rti object as a JavaScript instance - // method. The Rti object is 'this'. - Rti testRti = _Utils.asRti(JS('', 'this')); - - if (isObjectType(testRti)) { - return _finishIsFn(testRti, object, RAW_DART_FUNCTION_REF(_isObject)); - } - if (isTopType(testRti)) { - return _finishIsFn(testRti, object, RAW_DART_FUNCTION_REF(_isTop)); - } - - // `o is T*` generally behaves like `o is T`. - // The exeptions are `Object*` (handled above) and `Never*` - // - // `null is Never` --> `false` - // `null is Never*` --> `true` - Rti unstarred = Rti._getKind(testRti) == Rti.kindStar - ? Rti._getStarArgument(testRti) - : testRti; - - var isFn = _simpleSpecializedIsTest(unstarred); - if (isFn != null) { - return _finishIsFn(testRti, object, isFn); - } - - if (Rti._getKind(unstarred) == Rti.kindInterface) { - String name = Rti._getInterfaceName(unstarred); - var arguments = Rti._getInterfaceTypeArguments(unstarred); - // This recognizes interface types instantiated with Top, which includes the - // common case of interfaces that have no type parameters. - // TODO(sra): Can we easily recognize other interface types instantiated to - // bounds? - if (JS('bool', '#.every(#)', arguments, RAW_DART_FUNCTION_REF(isTopType))) { - String propertyName = - '${JS_GET_NAME(JsGetName.OPERATOR_IS_PREFIX)}${name}'; - Rti._setSpecializedTestResource(testRti, propertyName); - return _finishIsFn( - testRti, object, RAW_DART_FUNCTION_REF(_isTestViaProperty)); - } - // fall through to general implementation. - } else if (Rti._getKind(testRti) == Rti.kindQuestion) { - return _finishIsFn(testRti, object, - RAW_DART_FUNCTION_REF(_generalNullableIsTestImplementation)); - } - return _finishIsFn( - testRti, object, RAW_DART_FUNCTION_REF(_generalIsTestImplementation)); -} - -@pragma('dart2js:noInline') // Slightly smaller code. -bool _finishIsFn(Rti testRti, Object? object, Object? isFn) { - Rti._setIsTestFunction(testRti, isFn); - return Rti._isCheck(testRti, object); -} - -Object? _simpleSpecializedIsTest(Rti testRti) { - // Note: We must not match `Never` below. - var isFn = null; - if (_Utils.isIdentical(testRti, TYPE_REF())) { - isFn = RAW_DART_FUNCTION_REF(_isInt); - } else if (_Utils.isIdentical(testRti, TYPE_REF()) || - _Utils.isIdentical(testRti, TYPE_REF())) { - isFn = RAW_DART_FUNCTION_REF(_isNum); - } else if (_Utils.isIdentical(testRti, TYPE_REF())) { - isFn = RAW_DART_FUNCTION_REF(_isString); - } else if (_Utils.isIdentical(testRti, TYPE_REF())) { - isFn = RAW_DART_FUNCTION_REF(_isBool); - } - return isFn; -} - -/// Called from generated code. -/// -/// The first time this default `_as` method is called, it replaces itself with -/// a specialized version. -bool _installSpecializedAsCheck(Object? object) { - // This static method is installed on an Rti object as a JavaScript instance - // method. The Rti object is 'this'. - Rti testRti = _Utils.asRti(JS('', 'this')); - - var asFn = RAW_DART_FUNCTION_REF(_generalAsCheckImplementation); - if (isTopType(testRti)) { - asFn = RAW_DART_FUNCTION_REF(_asTop); - } else if (isObjectType(testRti)) { - asFn = RAW_DART_FUNCTION_REF(_asObject); - } else { - if (JS_GET_FLAG('LEGACY') || isNullable(testRti)) { - asFn = RAW_DART_FUNCTION_REF(_generalNullableAsCheckImplementation); - } - } - - Rti._setAsCheckFunction(testRti, asFn); - return Rti._asCheck(testRti, object); -} - -bool _nullIs(Rti testRti) { - int kind = Rti._getKind(testRti); - return isTopType(testRti) || - _Utils.isIdentical(testRti, LEGACY_TYPE_REF()) || - kind == Rti.kindQuestion || - isNullType(testRti); -} - -/// Called from generated code. -bool _generalIsTestImplementation(Object? object) { - // This static method is installed on an Rti object as a JavaScript instance - // method. The Rti object is 'this'. - Rti testRti = _Utils.asRti(JS('', 'this')); - if (object == null) return _nullIs(testRti); - Rti objectRti = instanceOrFunctionType(object, testRti); - return isSubtype(_theUniverse(), objectRti, testRti); -} - -/// Specialized test for `x is T1` where `T1` has the form `T2?`. Test is -/// compositional, calling `T2._is(object)`, so if `T2` has a specialized -/// version, the composed test will be fast (but not quite as fast as a -/// single-step specialization). -/// -/// Called from generated code. -bool _generalNullableIsTestImplementation(Object? object) { - if (object == null) return true; - // This static method is installed on an Rti object as a JavaScript instance - // method. The Rti object is 'this'. - Rti testRti = _Utils.asRti(JS('', 'this')); - Rti baseRti = Rti._getQuestionArgument(testRti); - return Rti._isCheck(baseRti, object); -} - -/// Called from generated code. -bool _isTestViaProperty(Object? object) { - // This static method is installed on an Rti object as a JavaScript instance - // method. The Rti object is 'this'. - Rti testRti = _Utils.asRti(JS('', 'this')); - if (object == null) return _nullIs(testRti); - var tag = Rti._getSpecializedTestResource(testRti); - - // This test is redundant with getInterceptor below, but getInterceptor does - // the tests in the wrong order for most tags, so it is usually faster to have - // this check. - if (_isDartObject(object)) { - return JS('bool', '!!#[#]', object, tag); - } - - var interceptor = getInterceptor(object); - return JS('bool', '!!#[#]', interceptor, tag); -} - -/// General unspecialized 'as' check that works for any type. -/// Called from generated code. -Object? _generalAsCheckImplementation(Object? object) { - // This static method is installed on an Rti object as a JavaScript instance - // method. The Rti object is 'this'. - Rti testRti = _Utils.asRti(JS('', 'this')); - if (object == null) { - if (JS_GET_FLAG('LEGACY') || isNullable(testRti)) return object; - } else if (Rti._isCheck(testRti, object)) return object; - _failedAsCheck(object, testRti); -} - -/// General 'as' check for types that accept `null`. -/// Called from generated code. -Object? _generalNullableAsCheckImplementation(Object? object) { - // This static method is installed on an Rti object as a JavaScript instance - // method. The Rti object is 'this'. - Rti testRti = _Utils.asRti(JS('', 'this')); - if (object == null) { - return object; - } else if (Rti._isCheck(testRti, object)) return object; - _failedAsCheck(object, testRti); -} - -void _failedAsCheck(Object? object, Rti testRti) { - Rti objectRti = instanceOrFunctionType(object, testRti); - String message = - _Error.compose(object, objectRti, _rtiToString(testRti, null)); - throw _TypeError.fromMessage(message); -} - -/// Called from generated code. -Rti checkTypeBound(Rti type, Rti bound, String variable, String methodName) { - if (isSubtype(_theUniverse(), type, bound)) return type; - String message = "The type argument '${_rtiToString(type, null)}' is not" - " a subtype of the type variable bound '${_rtiToString(bound, null)}'" - " of type variable '$variable' in '$methodName'."; - throw _TypeError.fromMessage(message); -} - -/// Called from generated code. -throwTypeError(String message) { - throw _TypeError.fromMessage(message); -} - -/// Base class to _TypeError. -class _Error extends Error { - final String _message; - _Error(this._message); - - static String compose( - Object? object, Rti? objectRti, String checkedTypeDescription) { - String objectDescription = Error.safeToString(object); - objectRti ??= instanceType(object); - String objectTypeDescription = _rtiToString(objectRti, null); - return "${objectDescription}:" - " type '${objectTypeDescription}'" - " is not a subtype of type '${checkedTypeDescription}'"; - } - - @override - String toString() => _message; -} - -class _TypeError extends _Error implements TypeError, CastError { - _TypeError.fromMessage(String message) : super('TypeError: $message'); - - factory _TypeError.forType(object, String type) { - return _TypeError.fromMessage(_Error.compose(object, null, type)); - } - - @override - String get message => _message; -} - -// Specializations. -// -// Specializations can be placed on Rti objects as the _as and _is -// 'methods'. They can also be called directly called from generated code. - -/// Specialization for 'is Object'. -/// Called from generated code via Rti `_is` method. -bool _isObject(Object? object) { - return !JS_GET_FLAG('NNBD') || object != null; -} - -/// Specialization for 'as Object'. -/// Called from generated code via Rti `_as` method. -Object? _asObject(Object? object) { - if (JS_GET_FLAG('LEGACY') || object != null) return object; - throw _TypeError.forType(object, 'Object'); -} - -/// Specialization for 'is dynamic' and other top types. -/// Called from generated code via Rti `_is` method. -bool _isTop(Object? object) { - return true; -} - -/// Specialization for 'as dynamic' and other top types. -/// Called from generated code via Rti `_as` methods. -Object? _asTop(Object? object) { - return object; -} - -/// Specialization for 'is bool'. -/// Called from generated code. -bool _isBool(Object? object) { - return true == object || false == object; -} - -// TODO(fishythefish): Change `dynamic` to `Object?` below once promotion works. - -/// Specialization for 'as bool'. -/// Called from generated code. -bool _asBool(Object? object) { - if (true == object) return true; - if (false == object) return false; - throw _TypeError.forType(object, 'bool'); -} - -/// Specialization for 'as bool*'. -/// Called from generated code. -bool? _asBoolS(dynamic object) { - if (true == object) return true; - if (false == object) return false; - if (object == null) return object; - throw _TypeError.forType(object, 'bool'); -} - -/// Specialization for 'as bool?'. -/// Called from generated code. -bool? _asBoolQ(dynamic object) { - if (true == object) return true; - if (false == object) return false; - if (object == null) return object; - throw _TypeError.forType(object, 'bool?'); -} - -/// Specialization for 'as double'. -/// Called from generated code. -double _asDouble(Object? object) { - if (_isNum(object)) return _Utils.asDouble(object); - throw _TypeError.forType(object, 'double'); -} - -/// Specialization for 'as double*'. -/// Called from generated code. -double? _asDoubleS(dynamic object) { - if (_isNum(object)) return _Utils.asDouble(object); - if (object == null) return object; - throw _TypeError.forType(object, 'double'); -} - -/// Specialization for 'as double?'. -/// Called from generated code. -double? _asDoubleQ(dynamic object) { - if (_isNum(object)) return _Utils.asDouble(object); - if (object == null) return object; - throw _TypeError.forType(object, 'double?'); -} - -/// Specialization for 'is int'. -/// Called from generated code. -bool _isInt(Object? object) { - return JS('bool', 'typeof # == "number"', object) && - JS('bool', 'Math.floor(#) === #', object, object); -} - -/// Specialization for 'as int'. -/// Called from generated code. -int _asInt(Object? object) { - if (_isInt(object)) return _Utils.asInt(object); - throw _TypeError.forType(object, 'int'); -} - -/// Specialization for 'as int*'. -/// Called from generated code. -int? _asIntS(dynamic object) { - if (_isInt(object)) return _Utils.asInt(object); - if (object == null) return object; - throw _TypeError.forType(object, 'int'); -} - -/// Specialization for 'as int?'. -/// Called from generated code. -int? _asIntQ(dynamic object) { - if (_isInt(object)) return _Utils.asInt(object); - if (object == null) return object; - throw _TypeError.forType(object, 'int?'); -} - -/// Specialization for 'is num' and 'is double'. -/// Called from generated code. -bool _isNum(Object? object) { - return JS('bool', 'typeof # == "number"', object); -} - -/// Specialization for 'as num'. -/// Called from generated code. -num _asNum(Object? object) { - if (_isNum(object)) return _Utils.asNum(object); - throw _TypeError.forType(object, 'num'); -} - -/// Specialization for 'as num*'. -/// Called from generated code. -num? _asNumS(dynamic object) { - if (_isNum(object)) return _Utils.asNum(object); - if (object == null) return object; - throw _TypeError.forType(object, 'num'); -} - -/// Specialization for 'as num?'. -/// Called from generated code. -num? _asNumQ(dynamic object) { - if (_isNum(object)) return _Utils.asNum(object); - if (object == null) return object; - throw _TypeError.forType(object, 'num?'); -} - -/// Specialization for 'is String'. -/// Called from generated code. -bool _isString(Object? object) { - return JS('bool', 'typeof # == "string"', object); -} - -/// Specialization for 'as String'. -/// Called from generated code. -String _asString(Object? object) { - if (_isString(object)) return _Utils.asString(object); - throw _TypeError.forType(object, 'String'); -} - -/// Specialization for 'as String*'. -/// Called from generated code. -String? _asStringS(dynamic object) { - if (_isString(object)) return _Utils.asString(object); - if (object == null) return object; - throw _TypeError.forType(object, 'String'); -} - -/// Specialization for 'as String?'. -/// Called from generated code. -String? _asStringQ(dynamic object) { - if (_isString(object)) return _Utils.asString(object); - if (object == null) return object; - throw _TypeError.forType(object, 'String?'); -} - -String _rtiArrayToString(Object? array, List? genericContext) { - String s = '', sep = ''; - for (int i = 0; i < _Utils.arrayLength(array); i++) { - s += sep + - _rtiToString(_Utils.asRti(_Utils.arrayAt(array, i)), genericContext); - sep = ', '; - } - return s; -} - -String _functionRtiToString(Rti functionType, List? genericContext, - {Object? bounds = null}) { - String typeParametersText = ''; - int? outerContextLength; - - if (bounds != null) { - int boundsLength = _Utils.arrayLength(bounds); - if (genericContext == null) { - genericContext = []; - } else { - outerContextLength = genericContext.length; - } - int offset = genericContext.length; - for (int i = boundsLength; i > 0; i--) { - genericContext.add('T${offset + i}'); - } - - String typeSep = ''; - typeParametersText = '<'; - for (int i = 0; i < boundsLength; i++) { - typeParametersText += typeSep; - typeParametersText += genericContext[genericContext.length - 1 - i]; - Rti boundRti = _Utils.asRti(_Utils.arrayAt(bounds, i)); - if (!isTopType(boundRti)) { - typeParametersText += - ' extends ' + _rtiToString(boundRti, genericContext); - } - typeSep = ', '; - } - typeParametersText += '>'; - } - - Rti returnType = Rti._getReturnType(functionType); - _FunctionParameters parameters = Rti._getFunctionParameters(functionType); - var requiredPositional = - _FunctionParameters._getRequiredPositional(parameters); - int requiredPositionalLength = _Utils.arrayLength(requiredPositional); - var optionalPositional = - _FunctionParameters._getOptionalPositional(parameters); - int optionalPositionalLength = _Utils.arrayLength(optionalPositional); - var named = _FunctionParameters._getNamed(parameters); - int namedLength = _Utils.arrayLength(named); - assert(optionalPositionalLength == 0 || namedLength == 0); - - String returnTypeText = _rtiToString(returnType, genericContext); - - String argumentsText = ''; - String sep = ''; - for (int i = 0; i < requiredPositionalLength; i++) { - argumentsText += sep + - _rtiToString(_Utils.asRti(_Utils.arrayAt(requiredPositional, i)), - genericContext); - sep = ', '; - } - - if (optionalPositionalLength > 0) { - argumentsText += sep + '['; - sep = ''; - for (int i = 0; i < optionalPositionalLength; i++) { - argumentsText += sep + - _rtiToString(_Utils.asRti(_Utils.arrayAt(optionalPositional, i)), - genericContext); - sep = ', '; - } - argumentsText += ']'; - } - - if (namedLength > 0) { - argumentsText += sep + '{'; - sep = ''; - for (int i = 0; i < namedLength; i += 3) { - argumentsText += sep; - if (_Utils.asBool(_Utils.arrayAt(named, i + 1))) { - argumentsText += 'required '; - } - argumentsText += _rtiToString( - _Utils.asRti(_Utils.arrayAt(named, i + 2)), genericContext) + - ' ' + - _Utils.asString(_Utils.arrayAt(named, i)); - sep = ', '; - } - argumentsText += '}'; - } - - if (outerContextLength != null) { - // Pop all of the generic type parameters. - JS('', '#.length = #', genericContext!, outerContextLength); - } - - // TODO(fishythefish): Below is the same format as the VM. Change to: - // - // return '${returnTypeText} Function${typeParametersText}(${argumentsText})'; - // - return '${typeParametersText}(${argumentsText}) => ${returnTypeText}'; -} - -String _rtiToString(Rti rti, List? genericContext) { - int kind = Rti._getKind(rti); - - if (kind == Rti.kindErased) return 'erased'; - if (kind == Rti.kindDynamic) return 'dynamic'; - if (kind == Rti.kindVoid) return 'void'; - if (kind == Rti.kindNever) return 'Never'; - if (kind == Rti.kindAny) return 'any'; - - if (kind == Rti.kindStar) { - Rti starArgument = Rti._getStarArgument(rti); - String s = _rtiToString(starArgument, genericContext); - if (JS_GET_FLAG('PRINT_LEGACY_STARS')) { - int argumentKind = Rti._getKind(starArgument); - if (argumentKind == Rti.kindFunction || - argumentKind == Rti.kindGenericFunction) { - s = '(' + s + ')'; - } - return s + '*'; - } else { - return s; - } - } - - if (kind == Rti.kindQuestion) { - Rti questionArgument = Rti._getQuestionArgument(rti); - String s = _rtiToString(questionArgument, genericContext); - int argumentKind = Rti._getKind(questionArgument); - if (argumentKind == Rti.kindFunction || - argumentKind == Rti.kindGenericFunction) { - s = '(' + s + ')'; - } - return s + '?'; - } - - if (kind == Rti.kindFutureOr) { - Rti futureOrArgument = Rti._getFutureOrArgument(rti); - return 'FutureOr<${_rtiToString(futureOrArgument, genericContext)}>'; - } - - if (kind == Rti.kindInterface) { - String name = Rti._getInterfaceName(rti); - name = _unminifyOrTag(name); - var arguments = Rti._getInterfaceTypeArguments(rti); - if (arguments.length != 0) { - name += '<' + _rtiArrayToString(arguments, genericContext) + '>'; - } - return name; - } - - if (kind == Rti.kindFunction) { - return _functionRtiToString(rti, genericContext); - } - - if (kind == Rti.kindGenericFunction) { - Rti baseFunctionType = Rti._getGenericFunctionBase(rti); - var bounds = Rti._getGenericFunctionBounds(rti); - return _functionRtiToString(baseFunctionType, genericContext, - bounds: bounds); - } - - if (kind == Rti.kindGenericFunctionParameter) { - var context = genericContext!; - int index = Rti._getGenericFunctionParameterIndex(rti); - return context[context.length - 1 - index]; - } - - return '?'; -} - -String _unminifyOrTag(String rawClassName) { - String? preserved = unmangleGlobalNameIfPreservedAnyways(rawClassName); - if (preserved != null) return preserved; - return JS_GET_FLAG('MINIFIED') ? 'minified:$rawClassName' : rawClassName; -} - -String _rtiArrayToDebugString(Object? array) { - String s = '[', sep = ''; - for (int i = 0; i < _Utils.arrayLength(array); i++) { - s += sep + _rtiToDebugString(_Utils.asRti(_Utils.arrayAt(array, i))); - sep = ', '; - } - return s + ']'; -} - -String functionParametersToString(_FunctionParameters parameters) { - String s = '(', sep = ''; - var requiredPositional = - _FunctionParameters._getRequiredPositional(parameters); - int requiredPositionalLength = _Utils.arrayLength(requiredPositional); - var optionalPositional = - _FunctionParameters._getOptionalPositional(parameters); - int optionalPositionalLength = _Utils.arrayLength(optionalPositional); - var named = _FunctionParameters._getNamed(parameters); - int namedLength = _Utils.arrayLength(named); - assert(optionalPositionalLength == 0 || namedLength == 0); - - for (int i = 0; i < requiredPositionalLength; i++) { - s += sep + - _rtiToDebugString(_Utils.asRti(_Utils.arrayAt(requiredPositional, i))); - sep = ', '; - } - - if (optionalPositionalLength > 0) { - s += sep + '['; - sep = ''; - for (int i = 0; i < optionalPositionalLength; i++) { - s += sep + - _rtiToDebugString( - _Utils.asRti(_Utils.arrayAt(optionalPositional, i))); - sep = ', '; - } - s += ']'; - } - - if (namedLength > 0) { - s += sep + '{'; - sep = ''; - for (int i = 0; i < namedLength; i += 3) { - s += sep; - if (_Utils.asBool(_Utils.arrayAt(named, i + 1))) { - s += 'required '; - } - s += _rtiToDebugString(_Utils.asRti(_Utils.arrayAt(named, i + 2))) + - ' ' + - _Utils.asString(_Utils.arrayAt(named, i)); - sep = ', '; - } - s += '}'; - } - - return s + ')'; -} - -String _rtiToDebugString(Rti rti) { - int kind = Rti._getKind(rti); - - if (kind == Rti.kindErased) return 'erased'; - if (kind == Rti.kindDynamic) return 'dynamic'; - if (kind == Rti.kindVoid) return 'void'; - if (kind == Rti.kindNever) return 'Never'; - if (kind == Rti.kindAny) return 'any'; - - if (kind == Rti.kindStar) { - Rti starArgument = Rti._getStarArgument(rti); - return 'star(${_rtiToDebugString(starArgument)})'; - } - - if (kind == Rti.kindQuestion) { - Rti questionArgument = Rti._getQuestionArgument(rti); - return 'question(${_rtiToDebugString(questionArgument)})'; - } - - if (kind == Rti.kindFutureOr) { - Rti futureOrArgument = Rti._getFutureOrArgument(rti); - return 'FutureOr(${_rtiToDebugString(futureOrArgument)})'; - } - - if (kind == Rti.kindInterface) { - String name = Rti._getInterfaceName(rti); - var arguments = Rti._getInterfaceTypeArguments(rti); - if (_Utils.arrayLength(arguments) == 0) { - return 'interface("$name")'; - } else { - return 'interface("$name", ${_rtiArrayToDebugString(arguments)})'; - } - } - - if (kind == Rti.kindBinding) { - Rti base = Rti._getBindingBase(rti); - var arguments = Rti._getBindingArguments(rti); - return 'binding(${_rtiToDebugString(base)}, ${_rtiArrayToDebugString(arguments)})'; - } - - if (kind == Rti.kindFunction) { - Rti returnType = Rti._getReturnType(rti); - _FunctionParameters parameters = Rti._getFunctionParameters(rti); - return 'function(${_rtiToDebugString(returnType)}, ${functionParametersToString(parameters)})'; - } - - if (kind == Rti.kindGenericFunction) { - Rti baseFunctionType = Rti._getGenericFunctionBase(rti); - var bounds = Rti._getGenericFunctionBounds(rti); - return 'genericFunction(${_rtiToDebugString(baseFunctionType)}, ${_rtiArrayToDebugString(bounds)})'; - } - - if (kind == Rti.kindGenericFunctionParameter) { - int index = Rti._getGenericFunctionParameterIndex(rti); - return 'genericFunctionParameter($index)'; - } - - return 'other(kind=$kind)'; -} - -/// Class of static methods for the universe of Rti objects. -/// -/// The universe is the manager object for the Rti instances. -/// -/// The universe itself is allocated at startup before any types or Dart objects -/// can be created, so it does not have a Dart type. -class _Universe { - _Universe._() { - throw UnimplementedError('_Universe is static methods only'); - } - - @pragma('dart2js:noInline') - static Object create() { - // This needs to be kept in sync with `FragmentEmitter.createRtiUniverse` in - // `fragment_emitter.dart`. - return JS( - '', - '{' - '#: new Map(),' - '#: {},' - '#: {},' - '#: {},' - '#: [],' // shared empty array. - '}', - RtiUniverseFieldNames.evalCache, - RtiUniverseFieldNames.typeRules, - RtiUniverseFieldNames.erasedTypes, - RtiUniverseFieldNames.typeParameterVariances, - RtiUniverseFieldNames.sharedEmptyArray); - } - - // Field accessors. - - static Object evalCache(Object? universe) => - JS('', '#.#', universe, RtiUniverseFieldNames.evalCache); - - static Object typeRules(Object? universe) => - JS('', '#.#', universe, RtiUniverseFieldNames.typeRules); - - static Object erasedTypes(Object? universe) => - JS('', '#.#', universe, RtiUniverseFieldNames.erasedTypes); - - static Object typeParameterVariances(Object? universe) => - JS('', '#.#', universe, RtiUniverseFieldNames.typeParameterVariances); - - static Object? _findRule(Object? universe, String targetType) => - JS('', '#.#', typeRules(universe), targetType); - - static Object? findRule(Object? universe, String targetType) { - var rule = _findRule(universe, targetType); - while (_Utils.isString(rule)) { - rule = _findRule(universe, _Utils.asString(rule)); - } - return rule; - } - - static Rti findErasedType(Object? universe, String cls) { - var metadata = erasedTypes(universe); - var probe = JS('', '#.#', metadata, cls); - if (probe == null) { - return eval(universe, cls, false); - } else if (_Utils.isNum(probe)) { - int length = _Utils.asInt(probe); - Rti erased = _lookupErasedRti(universe); - Object? arguments = JS('', '[]'); - for (int i = 0; i < length; i++) { - _Utils.arrayPush(arguments, erased); - } - Rti interface = _lookupInterfaceRti(universe, cls, arguments); - JS('', '#.# = #', metadata, cls, interface); - return interface; - } else { - return _Utils.asRti(probe); - } - } - - static Object? findTypeParameterVariances(Object? universe, String cls) => - JS('', '#.#', typeParameterVariances(universe), cls); - - static void addRules(Object? universe, Object? rules) => - _Utils.objectAssign(typeRules(universe), rules); - - static void addErasedTypes(Object? universe, Object? types) => - _Utils.objectAssign(erasedTypes(universe), types); - - static void addTypeParameterVariances(Object? universe, Object? variances) => - _Utils.objectAssign(typeParameterVariances(universe), variances); - - static JSArray sharedEmptyArray(Object? universe) => - JS('JSArray', '#.#', universe, RtiUniverseFieldNames.sharedEmptyArray); - - /// Evaluates [recipe] in the global environment. - static Rti eval(Object? universe, String recipe, bool normalize) { - var cache = evalCache(universe); - var probe = _Utils.mapGet(cache, recipe); - if (probe != null) return _Utils.asRti(probe); - Rti rti = _parseRecipe(universe, null, recipe, normalize); - _Utils.mapSet(cache, recipe, rti); - return rti; - } - - static Rti evalInEnvironment( - Object? universe, Rti environment, String recipe) { - var cache = Rti._getEvalCache(environment); - if (cache == null) { - cache = JS('', 'new Map()'); - Rti._setEvalCache(environment, cache); - } - var probe = _Utils.mapGet(cache, recipe); - if (probe != null) return _Utils.asRti(probe); - Rti rti = _parseRecipe(universe, environment, recipe, true); - _Utils.mapSet(cache, recipe, rti); - return rti; - } - - static Rti bind(Object? universe, Rti environment, Rti argumentsRti) { - var cache = Rti._getBindCache(environment); - if (cache == null) { - cache = JS('', 'new Map()'); - Rti._setBindCache(environment, cache); - } - String argumentsRecipe = Rti._getCanonicalRecipe(argumentsRti); - var probe = _Utils.mapGet(cache, argumentsRecipe); - if (probe != null) return _Utils.asRti(probe); - var argumentsArray; - if (Rti._getKind(argumentsRti) == Rti.kindBinding) { - argumentsArray = Rti._getBindingArguments(argumentsRti); - } else { - argumentsArray = JS('', '[#]', argumentsRti); - } - Rti rti = _lookupBindingRti(universe, environment, argumentsArray); - _Utils.mapSet(cache, argumentsRecipe, rti); - return rti; - } - - static Rti bind1(Object? universe, Rti environment, Rti argumentsRti) { - throw UnimplementedError('_Universe.bind1'); - } - - static Rti evalTypeVariable(Object? universe, Rti environment, String name) { - int kind = Rti._getKind(environment); - if (kind == Rti.kindBinding) { - environment = Rti._getBindingBase(environment); - } - - String interfaceName = Rti._getInterfaceName(environment); - var rule = _Universe.findRule(universe, interfaceName); - assert(rule != null); - String? recipe = TypeRule.lookupTypeVariable(rule, name); - if (recipe == null) { - throw 'No "$name" in "${Rti._getCanonicalRecipe(environment)}"'; - } - return _Universe.evalInEnvironment(universe, environment, recipe); - } - - static Rti _parseRecipe( - Object? universe, Object? environment, String recipe, bool normalize) { - var parser = _Parser.create(universe, environment, recipe, normalize); - Rti rti = _Parser.parse(parser); - return rti; - } - - static Rti _installTypeTests(Object? universe, Rti rti) { - // Set up methods to perform type tests. The general as-check methods use - // the is-test method. The is-test method on first use overwrites itself, - // and possibly the as-check methods, with a specialized version. - var asFn = RAW_DART_FUNCTION_REF(_installSpecializedAsCheck); - var isFn = RAW_DART_FUNCTION_REF(_installSpecializedIsTest); - Rti._setAsCheckFunction(rti, asFn); - Rti._setIsTestFunction(rti, isFn); - return rti; - } - - static Rti _installRti(Object? universe, String key, Rti rti) { - _Utils.mapSet(evalCache(universe), key, rti); - return rti; - } - - // These helpers are used for creating canonical recipes. The key feature of - // the generated code is that it makes no reference to the constant pool, - // which does not exist when the type$ pool is created. - // - // The strange association is so that usage like - // - // s = _recipeJoin3(s, a, b); - // - // associates as `s+=(a+b)` rather than `s=s+a+b`. As recipe fragments are - // small, this tends to create smaller cons-string trees. - - static String _recipeJoin(String s1, String s2) => JS_STRING_CONCAT(s1, s2); - static String _recipeJoin3(String s1, String s2, String s3) => - JS_STRING_CONCAT(s1, JS_STRING_CONCAT(s2, s3)); - static String _recipeJoin4(String s1, String s2, String s3, String s4) => - JS_STRING_CONCAT(s1, JS_STRING_CONCAT(JS_STRING_CONCAT(s2, s3), s4)); - static String _recipeJoin5( - String s1, String s2, String s3, String s4, String s5) => - JS_STRING_CONCAT(s1, - JS_STRING_CONCAT(JS_STRING_CONCAT(JS_STRING_CONCAT(s2, s3), s4), s5)); - - // For each kind of Rti there are three methods: - // - // * `lookupXXX` which takes the component parts and returns an existing Rti - // object if it exists. - // * `canonicalRecipeOfXXX` that returns the compositional canonical recipe - // for the proposed type. - // * `createXXX` to create the type if it does not exist. - // - // The create method performs normalization before allocating a new Rti. Cache - // keys are not normalized, so if multiple recipes normalize to the same type, - // then their corresponding cache entries will point to the same value. This - // prevents us from having to normalize on every lookup instead of every - // allocation. - - static String _canonicalRecipeOfErased() => Recipe.pushErasedString; - static String _canonicalRecipeOfDynamic() => Recipe.pushDynamicString; - static String _canonicalRecipeOfVoid() => Recipe.pushVoidString; - static String _canonicalRecipeOfNever() => - _recipeJoin(Recipe.pushNeverExtensionString, Recipe.extensionOpString); - static String _canonicalRecipeOfAny() => - _recipeJoin(Recipe.pushAnyExtensionString, Recipe.extensionOpString); - - static String _canonicalRecipeOfStar(Rti baseType) => - _recipeJoin(Rti._getCanonicalRecipe(baseType), Recipe.wrapStarString); - static String _canonicalRecipeOfQuestion(Rti baseType) => - _recipeJoin(Rti._getCanonicalRecipe(baseType), Recipe.wrapQuestionString); - static String _canonicalRecipeOfFutureOr(Rti baseType) => - _recipeJoin(Rti._getCanonicalRecipe(baseType), Recipe.wrapFutureOrString); - - static String _canonicalRecipeOfGenericFunctionParameter(int index) => - _recipeJoin('$index', Recipe.genericFunctionTypeParameterIndexString); - - static Rti _lookupErasedRti(Object? universe) { - return _lookupTerminalRti( - universe, Rti.kindErased, _canonicalRecipeOfErased()); - } - - static Rti _lookupDynamicRti(Object? universe) { - return _lookupTerminalRti( - universe, Rti.kindDynamic, _canonicalRecipeOfDynamic()); - } - - static Rti _lookupVoidRti(Object? universe) { - return _lookupTerminalRti(universe, Rti.kindVoid, _canonicalRecipeOfVoid()); - } - - static Rti _lookupNeverRti(Object? universe) { - return _lookupTerminalRti( - universe, Rti.kindNever, _canonicalRecipeOfNever()); - } - - static Rti _lookupAnyRti(Object? universe) { - return _lookupTerminalRti(universe, Rti.kindAny, _canonicalRecipeOfAny()); - } - - static Rti _lookupTerminalRti(Object? universe, int kind, String key) { - var cache = evalCache(universe); - var probe = _Utils.mapGet(cache, key); - if (probe != null) return _Utils.asRti(probe); - return _installRti(universe, key, _createTerminalRti(universe, kind, key)); - } - - static Rti _createTerminalRti(Object? universe, int kind, String key) { - Rti rti = Rti.allocate(); - Rti._setKind(rti, kind); - Rti._setCanonicalRecipe(rti, key); - return _installTypeTests(universe, rti); - } - - static Rti _lookupStarRti(Object? universe, Rti baseType, bool normalize) { - String key = _canonicalRecipeOfStar(baseType); - var cache = evalCache(universe); - var probe = _Utils.mapGet(cache, key); - if (probe != null) return _Utils.asRti(probe); - return _installRti( - universe, key, _createStarRti(universe, baseType, key, normalize)); - } - - static Rti _createStarRti( - Object? universe, Rti baseType, String key, bool normalize) { - if (normalize) { - int baseKind = Rti._getKind(baseType); - if (isStrongTopType(baseType) || - isNullType(baseType) || - baseKind == Rti.kindQuestion || - baseKind == Rti.kindStar) { - return baseType; - } - } - Rti rti = Rti.allocate(); - Rti._setKind(rti, Rti.kindStar); - Rti._setPrimary(rti, baseType); - Rti._setCanonicalRecipe(rti, key); - return _installTypeTests(universe, rti); - } - - static Rti _lookupQuestionRti( - Object? universe, Rti baseType, bool normalize) { - String key = _canonicalRecipeOfQuestion(baseType); - var cache = evalCache(universe); - var probe = _Utils.mapGet(cache, key); - if (probe != null) return _Utils.asRti(probe); - return _installRti( - universe, key, _createQuestionRti(universe, baseType, key, normalize)); - } - - static Rti _createQuestionRti( - Object? universe, Rti baseType, String key, bool normalize) { - if (normalize) { - int baseKind = Rti._getKind(baseType); - if (isStrongTopType(baseType) || - isNullType(baseType) || - baseKind == Rti.kindQuestion || - baseKind == Rti.kindFutureOr && - isNullable(Rti._getFutureOrArgument(baseType))) { - return baseType; - } else if (baseKind == Rti.kindNever || - _Utils.isIdentical(baseType, LEGACY_TYPE_REF())) { - return TYPE_REF(); - } else if (baseKind == Rti.kindStar) { - Rti starArgument = Rti._getStarArgument(baseType); - int starArgumentKind = Rti._getKind(starArgument); - if (starArgumentKind == Rti.kindFutureOr && - isNullable(Rti._getFutureOrArgument(starArgument))) { - return starArgument; - } else { - return Rti._getQuestionFromStar(universe, baseType); - } - } - } - Rti rti = Rti.allocate(); - Rti._setKind(rti, Rti.kindQuestion); - Rti._setPrimary(rti, baseType); - Rti._setCanonicalRecipe(rti, key); - return _installTypeTests(universe, rti); - } - - static Rti _lookupFutureOrRti( - Object? universe, Rti baseType, bool normalize) { - String key = _canonicalRecipeOfFutureOr(baseType); - var cache = evalCache(universe); - var probe = _Utils.mapGet(cache, key); - if (probe != null) return _Utils.asRti(probe); - return _installRti( - universe, key, _createFutureOrRti(universe, baseType, key, normalize)); - } - - static Rti _createFutureOrRti( - Object? universe, Rti baseType, String key, bool normalize) { - if (normalize) { - int baseKind = Rti._getKind(baseType); - if (isTopType(baseType) || isObjectType(baseType)) { - return baseType; - } else if (baseKind == Rti.kindNever) { - return _lookupFutureRti(universe, baseType); - } else if (isNullType(baseType)) { - return JS_GET_FLAG('NNBD') - ? TYPE_REF?>() - : TYPE_REF>(); - } - } - Rti rti = Rti.allocate(); - Rti._setKind(rti, Rti.kindFutureOr); - Rti._setPrimary(rti, baseType); - Rti._setCanonicalRecipe(rti, key); - return _installTypeTests(universe, rti); - } - - static Rti _lookupGenericFunctionParameterRti(Object? universe, int index) { - String key = _canonicalRecipeOfGenericFunctionParameter(index); - var cache = evalCache(universe); - var probe = _Utils.mapGet(cache, key); - if (probe != null) return _Utils.asRti(probe); - return _installRti(universe, key, - _createGenericFunctionParameterRti(universe, index, key)); - } - - static Rti _createGenericFunctionParameterRti( - Object? universe, int index, String key) { - Rti rti = Rti.allocate(); - Rti._setKind(rti, Rti.kindGenericFunctionParameter); - Rti._setPrimary(rti, index); - Rti._setCanonicalRecipe(rti, key); - return _installTypeTests(universe, rti); - } - - static String _canonicalRecipeJoin(Object? arguments) { - String s = '', sep = ''; - int length = _Utils.arrayLength(arguments); - for (int i = 0; i < length; i++) { - Rti argument = _Utils.asRti(_Utils.arrayAt(arguments, i)); - String subrecipe = Rti._getCanonicalRecipe(argument); - s = _recipeJoin3(s, sep, subrecipe); - sep = Recipe.separatorString; - } - return s; - } - - static String _canonicalRecipeJoinNamed(Object? arguments) { - String s = '', sep = ''; - int length = _Utils.arrayLength(arguments); - assert(_Utils.isMultipleOf(length, 3)); - for (int i = 0; i < length; i += 3) { - String name = _Utils.asString(_Utils.arrayAt(arguments, i)); - bool isRequired = _Utils.asBool(_Utils.arrayAt(arguments, i + 1)); - String nameSep = isRequired - ? Recipe.requiredNameSeparatorString - : Recipe.nameSeparatorString; - Rti type = _Utils.asRti(_Utils.arrayAt(arguments, i + 2)); - String subrecipe = Rti._getCanonicalRecipe(type); - s = _recipeJoin5(s, sep, name, nameSep, subrecipe); - sep = Recipe.separatorString; - } - return s; - } - - static String _canonicalRecipeOfInterface(String name, Object? arguments) { - assert(_Utils.isString(name)); - String s = _Utils.asString(name); - int length = _Utils.arrayLength(arguments); - if (length != 0) { - s = _recipeJoin4(s, Recipe.startTypeArgumentsString, - _canonicalRecipeJoin(arguments), Recipe.endTypeArgumentsString); - } - return s; - } - - static Rti _lookupInterfaceRti( - Object? universe, String name, Object? arguments) { - String key = _canonicalRecipeOfInterface(name, arguments); - var cache = evalCache(universe); - var probe = _Utils.mapGet(cache, key); - if (probe != null) return _Utils.asRti(probe); - return _installRti( - universe, key, _createInterfaceRti(universe, name, arguments, key)); - } - - static Rti _createInterfaceRti( - Object? universe, String name, Object? typeArguments, String key) { - Rti rti = Rti.allocate(); - Rti._setKind(rti, Rti.kindInterface); - Rti._setPrimary(rti, name); - Rti._setRest(rti, typeArguments); - int length = _Utils.arrayLength(typeArguments); - if (length > 0) { - Rti._setPrecomputed1(rti, _Utils.arrayAt(typeArguments, 0)); - } - Rti._setCanonicalRecipe(rti, key); - return _installTypeTests(universe, rti); - } - - static Rti _lookupFutureRti(Object? universe, Rti base) => - _lookupInterfaceRti(universe, - JS_GET_NAME(JsGetName.FUTURE_CLASS_TYPE_NAME), JS('', '[#]', base)); - - static String _canonicalRecipeOfBinding(Rti base, Object? arguments) { - return _recipeJoin5( - Rti._getCanonicalRecipe(base), - // TODO(sra): Omit when base encoding is Rti without ToType: - Recipe.toTypeString, - Recipe.startTypeArgumentsString, - _canonicalRecipeJoin(arguments), - Recipe.endTypeArgumentsString); - } - - /// [arguments] becomes owned by the created Rti. - static Rti _lookupBindingRti(Object? universe, Rti base, Object? arguments) { - Rti newBase = base; - var newArguments = arguments; - if (Rti._getKind(base) == Rti.kindBinding) { - newBase = Rti._getBindingBase(base); - newArguments = - _Utils.arrayConcat(Rti._getBindingArguments(base), arguments); - } - String key = _canonicalRecipeOfBinding(newBase, newArguments); - var cache = evalCache(universe); - var probe = _Utils.mapGet(cache, key); - if (probe != null) return _Utils.asRti(probe); - return _installRti( - universe, key, _createBindingRti(universe, newBase, newArguments, key)); - } - - static Rti _createBindingRti( - Object? universe, Rti base, Object? arguments, String key) { - Rti rti = Rti.allocate(); - Rti._setKind(rti, Rti.kindBinding); - Rti._setPrimary(rti, base); - Rti._setRest(rti, arguments); - Rti._setCanonicalRecipe(rti, key); - return _installTypeTests(universe, rti); - } - - static String _canonicalRecipeOfFunction( - Rti returnType, _FunctionParameters parameters) => - _recipeJoin(Rti._getCanonicalRecipe(returnType), - _canonicalRecipeOfFunctionParameters(parameters)); - - static String _canonicalRecipeOfFunctionParameters( - _FunctionParameters parameters) { - var requiredPositional = - _FunctionParameters._getRequiredPositional(parameters); - int requiredPositionalLength = _Utils.arrayLength(requiredPositional); - var optionalPositional = - _FunctionParameters._getOptionalPositional(parameters); - int optionalPositionalLength = _Utils.arrayLength(optionalPositional); - var named = _FunctionParameters._getNamed(parameters); - int namedLength = _Utils.arrayLength(named); - assert(optionalPositionalLength == 0 || namedLength == 0); - - String recipe = _recipeJoin(Recipe.startFunctionArgumentsString, - _canonicalRecipeJoin(requiredPositional)); - - if (optionalPositionalLength > 0) { - String sep = requiredPositionalLength > 0 ? Recipe.separatorString : ''; - recipe = _recipeJoin5( - recipe, - sep, - Recipe.startOptionalGroupString, - _canonicalRecipeJoin(optionalPositional), - Recipe.endOptionalGroupString); - } - - if (namedLength > 0) { - String sep = requiredPositionalLength > 0 ? Recipe.separatorString : ''; - recipe = _recipeJoin5(recipe, sep, Recipe.startNamedGroupString, - _canonicalRecipeJoinNamed(named), Recipe.endNamedGroupString); - } - - return _recipeJoin(recipe, Recipe.endFunctionArgumentsString); - } - - static Rti _lookupFunctionRti( - Object? universe, Rti returnType, _FunctionParameters parameters) { - String key = _canonicalRecipeOfFunction(returnType, parameters); - var cache = evalCache(universe); - var probe = _Utils.mapGet(cache, key); - if (probe != null) return _Utils.asRti(probe); - return _installRti(universe, key, - _createFunctionRti(universe, returnType, parameters, key)); - } - - static Rti _createFunctionRti(Object? universe, Rti returnType, - _FunctionParameters parameters, String key) { - Rti rti = Rti.allocate(); - Rti._setKind(rti, Rti.kindFunction); - Rti._setPrimary(rti, returnType); - Rti._setRest(rti, parameters); - Rti._setCanonicalRecipe(rti, key); - return _installTypeTests(universe, rti); - } - - static String _canonicalRecipeOfGenericFunction( - Rti baseFunctionType, Object? bounds) => - _recipeJoin4( - Rti._getCanonicalRecipe(baseFunctionType), - Recipe.startTypeArgumentsString, - _canonicalRecipeJoin(bounds), - Recipe.endTypeArgumentsString); - - static Rti _lookupGenericFunctionRti( - Object? universe, Rti baseFunctionType, Object? bounds, bool normalize) { - String key = _canonicalRecipeOfGenericFunction(baseFunctionType, bounds); - var cache = evalCache(universe); - var probe = _Utils.mapGet(cache, key); - if (probe != null) return _Utils.asRti(probe); - return _installRti( - universe, - key, - _createGenericFunctionRti( - universe, baseFunctionType, bounds, key, normalize)); - } - - static Rti _createGenericFunctionRti(Object? universe, Rti baseFunctionType, - Object? bounds, String key, bool normalize) { - if (normalize) { - int length = _Utils.arrayLength(bounds); - int count = 0; - Object? typeArguments = JS('', 'new Array(#)', length); - for (int i = 0; i < length; i++) { - Rti bound = _Utils.asRti(_Utils.arrayAt(bounds, i)); - if (Rti._getKind(bound) == Rti.kindNever) { - _Utils.arraySetAt(typeArguments, i, bound); - count++; - } - } - if (count > 0) { - var substitutedBase = - _substitute(universe, baseFunctionType, typeArguments, 0); - var substitutedBounds = - _substituteArray(universe, bounds, typeArguments, 0); - return _lookupGenericFunctionRti( - universe, - substitutedBase, - substitutedBounds, - _Utils.isNotIdentical(bounds, substitutedBounds)); - } - } - Rti rti = Rti.allocate(); - Rti._setKind(rti, Rti.kindGenericFunction); - Rti._setPrimary(rti, baseFunctionType); - Rti._setRest(rti, bounds); - Rti._setCanonicalRecipe(rti, key); - return _installTypeTests(universe, rti); - } -} - -/// Class of static methods implementing recipe parser. -/// -/// The recipe is a sequence of operations on a stack machine. The operations -/// are described below using the format -/// -/// operation: stack elements before --- stack elements after -/// -/// integer: --- integer-value -/// -/// identifier: --- string-value -/// -/// identifier-with-one-period: --- type-variable-value -/// -/// Period may be in any position, including first and last e.g. `.x`. -/// -/// ',': --- -/// -/// Ignored. Used to separate elements. -/// -/// ';': item --- ToType(item) -/// -/// Used to separate elements. -/// -/// '#': --- erasedType -/// -/// '@': --- dynamicType -/// -/// '~': --- voidType -/// -/// '?': type --- type? -/// -/// '&': 0 --- NeverType -/// '&': 1 --- anyType -/// -/// Escape op-code with small integer values for encoding rare operations. -/// -/// '<': --- position -/// -/// Saves (pushes) position register, sets position register to end of stack. -/// -/// '>': name saved-position type ... type --- name -/// '>': type saved-position type ... type --- binding(type, type, ..., type) -/// -/// When first element is a String: Creates interface type from string 'name' -/// and the types pushed since the position register was last set. The types -/// are converted with a ToType operation. Restores position register to -/// previous saved value. -/// -/// When first element is an Rti: Creates binding Rti wrapping the first -/// element. Binding Rtis are flattened: if the first element is a binding -/// Rti, the new binding Rti has the concatentation of the first element -/// bindings and new type. -/// -/// -/// The ToType operation coerces an item to an Rti. This saves encoding looking -/// up simple interface names and indexed variables. -/// -/// ToType(string): Creates an interface Rti for the non-generic class. -/// ToType(integer): Indexes into the environment. -/// ToType(Rti): Same Rti -/// -/// -/// Notes on enviroments and indexing. -/// -/// To avoid creating a binding Rti for a single function type parameter, the -/// type is passed without creating a 1-tuple object. This means that the -/// interface Rti for, say, `Map` serves as two environments with -/// different shapes. It is a class environment (K=num, V=dynamic) and a simple -/// 1-tuple environment. This is supported by index '0' refering to the whole -/// type, and '1 and '2' refering to K and V positionally: -/// -/// interface("Map", [num,dynamic]) -/// 0 1 2 -/// -/// Thus the type expression `List` encodes as `List<1>` and in this -/// environment evaluates to `List`. `List>` could be encoded as -/// either `List<0>` or `List>` (and in this environment evaluates to -/// `List>`). -/// -/// When `Map` is combined with a binding `` (e.g. inside -/// the instance method `Map.cast()`), '0' refers to the base object -/// of the binding, and then the numbering counts the bindings followed by the -/// class parameters. -/// -/// binding(interface("Map", [num,dynamic]), [int, bool]) -/// 0 3 4 1 2 -/// -/// Any environment can be reconstructed via a recipe. The above enviroment for -/// method `cast` can be constructed as the ground term -/// `Map`, or (somewhat pointlessly) reconstructed via -/// `0<1,2>` or `Map<3,4><1,2>`. The ability to construct an environment -/// directly rather than via `bind` calls is used in folding sequences of `eval` -/// and `bind` calls. -/// -/// While a single type parameter is passed as the type, multiple type -/// parameters are passed as a tuple. Tuples are encoded as a binding with an -/// ignored base. `dynamic` can be used as the base, giving an encoding like -/// `@`. -/// -/// Bindings flatten, so `@` is the same as `@`. -/// -/// The base of a binding does not have to have type parameters. Consider -/// `CodeUnits`, which mixes in `ListMixin`. The environment inside of -/// `ListMixin.fold` (from the call `x.codeUnits.fold(...)`) would be -/// -/// binding(interface("CodeUnits", []), [bool]) -/// -/// This can be encoded as `CodeUnits;` (note the `;` to force ToType to -/// avoid creating an interface type Rti with a single class type -/// argument). Metadata about the supertypes is used to resolve the recipe -/// `ListMixin.E` to `int`. - -class _Parser { - _Parser._() { - throw UnimplementedError('_Parser is static methods only'); - } - - /// Creates a parser object for parsing a recipe against an environment in a - /// universe. - /// - /// Marked as no-inline so the object literal is not cloned by inlining. - @pragma('dart2js:noInline') - static Object create( - Object? universe, Object? environment, String recipe, bool normalize) { - return JS( - '', - '{' - 'u:#,' // universe - 'e:#,' // environment - 'r:#,' // recipe - 's:[],' // stack - 'p:0,' // position of sequence start - 'n:#,' // whether to normalize - '}', - universe, - environment, - recipe, - normalize); - } - - // Field accessors for the parser. - static Object universe(Object? parser) => JS('', '#.u', parser); - static Rti environment(Object? parser) => JS('Rti', '#.e', parser); - static String recipe(Object? parser) => JS('String', '#.r', parser); - static Object stack(Object? parser) => JS('', '#.s', parser); - static int position(Object? parser) => JS('int', '#.p', parser); - static void setPosition(Object? parser, int p) { - JS('', '#.p = #', parser, p); - } - - static bool normalize(Object? parser) => JS('bool', '#.n', parser); - - static int charCodeAt(String s, int i) => JS('int', '#.charCodeAt(#)', s, i); - static void push(Object? stack, Object? value) { - JS('', '#.push(#)', stack, value); - } - - static Object? pop(Object? stack) => JS('', '#.pop()', stack); - - static Rti parse(Object? parser) { - String source = _Parser.recipe(parser); - var stack = _Parser.stack(parser); - int i = 0; - while (i < source.length) { - int ch = charCodeAt(source, i); - if (Recipe.isDigit(ch)) { - i = handleDigit(i + 1, ch, source, stack); - } else if (Recipe.isIdentifierStart(ch)) { - i = handleIdentifier(parser, i, source, stack, false); - } else if (ch == Recipe.period) { - i = handleIdentifier(parser, i, source, stack, true); - } else { - i++; - switch (ch) { - case Recipe.separator: - break; - - case Recipe.nameSeparator: - push(stack, false); - break; - - case Recipe.requiredNameSeparator: - push(stack, true); - break; - - case Recipe.toType: - push(stack, - toType(universe(parser), environment(parser), pop(stack))); - break; - - case Recipe.genericFunctionTypeParameterIndex: - push(stack, - toGenericFunctionParameter(universe(parser), pop(stack))); - break; - - case Recipe.pushErased: - push(stack, _Universe._lookupErasedRti(universe(parser))); - break; - - case Recipe.pushDynamic: - push(stack, _Universe._lookupDynamicRti(universe(parser))); - break; - - case Recipe.pushVoid: - push(stack, _Universe._lookupVoidRti(universe(parser))); - break; - - case Recipe.startTypeArguments: - pushStackFrame(parser, stack); - break; - - case Recipe.endTypeArguments: - handleTypeArguments(parser, stack); - break; - - case Recipe.extensionOp: - handleExtendedOperations(parser, stack); - break; - - case Recipe.wrapStar: - var u = universe(parser); - push( - stack, - _Universe._lookupStarRti( - u, - toType(u, environment(parser), pop(stack)), - normalize(parser))); - break; - - case Recipe.wrapQuestion: - var u = universe(parser); - push( - stack, - _Universe._lookupQuestionRti( - u, - toType(u, environment(parser), pop(stack)), - normalize(parser))); - break; - - case Recipe.wrapFutureOr: - var u = universe(parser); - push( - stack, - _Universe._lookupFutureOrRti( - u, - toType(u, environment(parser), pop(stack)), - normalize(parser))); - break; - - case Recipe.startFunctionArguments: - pushStackFrame(parser, stack); - break; - - case Recipe.endFunctionArguments: - handleFunctionArguments(parser, stack); - break; - - case Recipe.startOptionalGroup: - pushStackFrame(parser, stack); - break; - - case Recipe.endOptionalGroup: - handleOptionalGroup(parser, stack); - break; - - case Recipe.startNamedGroup: - pushStackFrame(parser, stack); - break; - - case Recipe.endNamedGroup: - handleNamedGroup(parser, stack); - break; - - default: - JS('', 'throw "Bad character " + #', ch); - } - } - } - var item = pop(stack); - return toType(universe(parser), environment(parser), item); - } - - static void pushStackFrame(Object? parser, Object? stack) { - push(stack, position(parser)); - setPosition(parser, _Utils.arrayLength(stack)); - } - - static int handleDigit(int i, int digit, String source, Object? stack) { - int value = Recipe.digitValue(digit); - for (; i < source.length; i++) { - int ch = charCodeAt(source, i); - if (!Recipe.isDigit(ch)) break; - value = value * 10 + Recipe.digitValue(ch); - } - push(stack, value); - return i; - } - - static int handleIdentifier( - Object? parser, int start, String source, Object? stack, bool hasPeriod) { - int i = start + 1; - for (; i < source.length; i++) { - int ch = charCodeAt(source, i); - if (ch == Recipe.period) { - if (hasPeriod) break; - hasPeriod = true; - } else if (Recipe.isIdentifierStart(ch) || Recipe.isDigit(ch)) { - // Accept. - } else { - break; - } - } - String string = _Utils.substring(source, start, i); - if (hasPeriod) { - push( - stack, - _Universe.evalTypeVariable( - universe(parser), environment(parser), string)); - } else { - push(stack, string); - } - return i; - } - - static void handleTypeArguments(Object? parser, Object? stack) { - var universe = _Parser.universe(parser); - var arguments = collectArray(parser, stack); - var head = pop(stack); - if (_Utils.isString(head)) { - String name = _Utils.asString(head); - push(stack, _Universe._lookupInterfaceRti(universe, name, arguments)); - } else { - Rti base = toType(universe, environment(parser), head); - switch (Rti._getKind(base)) { - case Rti.kindFunction: - push( - stack, - _Universe._lookupGenericFunctionRti( - universe, base, arguments, normalize(parser))); - break; - - default: - push(stack, _Universe._lookupBindingRti(universe, base, arguments)); - break; - } - } - } - - static const int optionalPositionalSentinel = -1; - static const int namedSentinel = -2; - - static void handleFunctionArguments(Object? parser, Object? stack) { - var universe = _Parser.universe(parser); - _FunctionParameters parameters = _FunctionParameters.allocate(); - Object? optionalPositional = _Universe.sharedEmptyArray(universe); - Object? named = _Universe.sharedEmptyArray(universe); - - var head = pop(stack); - if (_Utils.isNum(head)) { - int sentinel = _Utils.asInt(head); - switch (sentinel) { - case optionalPositionalSentinel: - optionalPositional = pop(stack); - break; - - case namedSentinel: - named = pop(stack); - break; - - default: - push(stack, head); - break; - } - } else { - push(stack, head); - } - - _FunctionParameters._setRequiredPositional( - parameters, collectArray(parser, stack)); - _FunctionParameters._setOptionalPositional(parameters, optionalPositional); - _FunctionParameters._setNamed(parameters, named); - Rti returnType = toType(universe, environment(parser), pop(stack)); - push(stack, _Universe._lookupFunctionRti(universe, returnType, parameters)); - } - - static void handleOptionalGroup(Object? parser, Object? stack) { - var parameters = collectArray(parser, stack); - push(stack, parameters); - push(stack, optionalPositionalSentinel); - } - - static void handleNamedGroup(Object? parser, Object? stack) { - var parameters = collectNamed(parser, stack); - push(stack, parameters); - push(stack, namedSentinel); - } - - static void handleExtendedOperations(Object? parser, Object? stack) { - var top = pop(stack); - if (0 == top) { - push(stack, _Universe._lookupNeverRti(universe(parser))); - return; - } - if (1 == top) { - push(stack, _Universe._lookupAnyRti(universe(parser))); - return; - } - throw AssertionError('Unexpected extended operation $top'); - } - - static JSArray collectArray(Object? parser, Object? stack) { - var array = _Utils.arraySplice(stack, position(parser)); - toTypes(_Parser.universe(parser), environment(parser), array); - setPosition(parser, _Utils.asInt(pop(stack))); - return array; - } - - static JSArray collectNamed(Object? parser, Object? stack) { - var array = _Utils.arraySplice(stack, position(parser)); - toTypesNamed(_Parser.universe(parser), environment(parser), array); - setPosition(parser, _Utils.asInt(pop(stack))); - return array; - } - - /// Coerce a stack item into an Rti object. Strings are converted to interface - /// types, integers are looked up in the type environment. - static Rti toType(Object? universe, Rti environment, Object? item) { - if (_Utils.isString(item)) { - String name = _Utils.asString(item); - return _Universe._lookupInterfaceRti( - universe, name, _Universe.sharedEmptyArray(universe)); - } else if (_Utils.isNum(item)) { - return _Parser.indexToType(universe, environment, _Utils.asInt(item)); - } else { - return _Utils.asRti(item); - } - } - - static void toTypes(Object? universe, Rti environment, Object? items) { - int length = _Utils.arrayLength(items); - for (int i = 0; i < length; i++) { - var item = _Utils.arrayAt(items, i); - Rti type = toType(universe, environment, item); - _Utils.arraySetAt(items, i, type); - } - } - - static void toTypesNamed(Object? universe, Rti environment, Object? items) { - int length = _Utils.arrayLength(items); - assert(_Utils.isMultipleOf(length, 3)); - for (int i = 2; i < length; i += 3) { - var item = _Utils.arrayAt(items, i); - Rti type = toType(universe, environment, item); - _Utils.arraySetAt(items, i, type); - } - } - - static Rti indexToType(Object? universe, Rti environment, int index) { - int kind = Rti._getKind(environment); - if (kind == Rti.kindBinding) { - if (index == 0) return Rti._getBindingBase(environment); - var typeArguments = Rti._getBindingArguments(environment); - int len = _Utils.arrayLength(typeArguments); - if (index <= len) { - return _Utils.asRti(_Utils.arrayAt(typeArguments, index - 1)); - } - // Is index into interface Rti in base. - index -= len; - environment = Rti._getBindingBase(environment); - kind = Rti._getKind(environment); - } else { - if (index == 0) return environment; - } - if (kind != Rti.kindInterface) { - throw AssertionError('Indexed base must be an interface type'); - } - var typeArguments = Rti._getInterfaceTypeArguments(environment); - int len = _Utils.arrayLength(typeArguments); - if (index <= len) { - return _Utils.asRti(_Utils.arrayAt(typeArguments, index - 1)); - } - throw AssertionError('Bad index $index for $environment'); - } - - static Rti toGenericFunctionParameter(Object? universe, Object? item) { - assert(_Utils.isNum(item)); - return _Universe._lookupGenericFunctionParameterRti( - universe, _Utils.asInt(item)); - } -} - -/// Represents the set of supertypes and type variable bindings for a given -/// target type. The target type itself is not stored on the [TypeRule]. -class TypeRule { - TypeRule._() { - throw UnimplementedError("TypeRule is static methods only."); - } - - static String? lookupTypeVariable(Object? rule, String typeVariable) => - JS('', '#.#', rule, typeVariable); - - static JSArray? lookupSupertype(Object? rule, String supertype) => - JS('', '#.#', rule, supertype); -} - -// This needs to be kept in sync with `Variance` in `entities.dart`. -class Variance { - // TODO(fishythefish): Try bitmask representation. - static const int legacyCovariant = 0; - static const int covariant = 1; - static const int contravariant = 2; - static const int invariant = 3; -} - -// -------- Subtype tests ------------------------------------------------------ - -// Future entry point from compiled code. -bool isSubtype(Object? universe, Rti s, Rti t) { - return _isSubtype(universe, s, null, t, null); -} - -/// Based on -/// https://github.com/dart-lang/language/blob/master/resources/type-system/subtyping.md#rules -/// and https://github.com/dart-lang/language/pull/388. -/// In particular, the bulk of the structure is derived from the former -/// resource, with a few adaptations taken from the latter. -/// - We freely skip subcases which would have already been handled by a -/// previous case. -/// - Some rules are reordered in conjunction with the previous point to reduce -/// the amount of casework. -/// - Left Type Variable Bound in particular is split into two pieces: an -/// optimistic check performed early in the algorithm to reduce the number of -/// backtracking cases when a union appears on the right, and a pessimistic -/// check performed at the usual place in order to completely eliminate the -/// case. -/// - Function type rules are applied before interface type rules. -/// -/// [s] is considered a legacy subtype of [t] if [s] would be a subtype of [t] -/// in a modification of the NNBD rules in which `?` on types were ignored, `*` -/// were added to each time, and `required` parameters were treated as -/// optional. In effect, `Never` is equivalent to `Null`, `Null` is restored to -/// the bottom of the type hierarchy, `Object` is treated as nullable, and -/// `required` is ignored on named parameters. This should provide the same -/// subtyping results as pre-NNBD Dart. -bool _isSubtype(Object? universe, Rti s, Object? sEnv, Rti t, Object? tEnv) { - bool isLegacy = JS_GET_FLAG('LEGACY'); - - // Reflexivity: - if (_Utils.isIdentical(s, t)) return true; - - // Right Top: - if (isTopType(t)) return true; - - int sKind = Rti._getKind(s); - if (sKind == Rti.kindAny) return true; - - // Left Top: - if (isStrongTopType(s)) return false; - - // Left Bottom: - if (isBottomType(s)) return true; - - // Left Type Variable Bound 1: - bool leftTypeVariable = sKind == Rti.kindGenericFunctionParameter; - if (leftTypeVariable) { - int index = Rti._getGenericFunctionParameterIndex(s); - Rti bound = _Utils.asRti(_Utils.arrayAt(sEnv, index)); - if (_isSubtype(universe, bound, sEnv, t, tEnv)) return true; - } - - int tKind = Rti._getKind(t); - - // Left Null: - // Note: Interchanging the Left Null and Right Object rules allows us to - // reduce casework. - if (!isLegacy && isNullType(s)) { - if (tKind == Rti.kindFutureOr) { - return _isSubtype(universe, s, sEnv, Rti._getFutureOrArgument(t), tEnv); - } - return isNullType(t) || tKind == Rti.kindQuestion || tKind == Rti.kindStar; - } - - // Right Object: - if (!isLegacy && isObjectType(t)) { - if (sKind == Rti.kindFutureOr) { - return _isSubtype(universe, Rti._getFutureOrArgument(s), sEnv, t, tEnv); - } - if (sKind == Rti.kindStar) { - return _isSubtype(universe, Rti._getStarArgument(s), sEnv, t, tEnv); - } - return sKind != Rti.kindQuestion; - } - - // Left Legacy: - if (sKind == Rti.kindStar) { - return _isSubtype(universe, Rti._getStarArgument(s), sEnv, t, tEnv); - } - - // Right Legacy: - if (tKind == Rti.kindStar) { - return _isSubtype( - universe, - s, - sEnv, - isLegacy - ? Rti._getStarArgument(t) - : Rti._getQuestionFromStar(universe, t), - tEnv); - } - - // Left FutureOr: - if (sKind == Rti.kindFutureOr) { - if (!_isSubtype(universe, Rti._getFutureOrArgument(s), sEnv, t, tEnv)) { - return false; - } - return _isSubtype( - universe, Rti._getFutureFromFutureOr(universe, s), sEnv, t, tEnv); - } - - // Left Nullable: - if (sKind == Rti.kindQuestion) { - return (isLegacy || - _isSubtype(universe, TYPE_REF(), sEnv, t, tEnv)) && - _isSubtype(universe, Rti._getQuestionArgument(s), sEnv, t, tEnv); - } - - // Type Variable Reflexivity 1 is subsumed by Reflexivity and therefore - // elided. - // Type Variable Reflexivity 2 does not apply at runtime. - // Right Promoted Variable does not apply at runtime. - - // Right FutureOr: - if (tKind == Rti.kindFutureOr) { - if (_isSubtype(universe, s, sEnv, Rti._getFutureOrArgument(t), tEnv)) { - return true; - } - return _isSubtype( - universe, s, sEnv, Rti._getFutureFromFutureOr(universe, t), tEnv); - } - - // Right Nullable: - if (tKind == Rti.kindQuestion) { - return (!isLegacy && - _isSubtype(universe, s, sEnv, TYPE_REF(), tEnv)) || - _isSubtype(universe, s, sEnv, Rti._getQuestionArgument(t), tEnv); - } - - // Left Promoted Variable does not apply at runtime. - - // Left Type Variable Bound 2: - if (leftTypeVariable) return false; - - // Function Type/Function: - if ((sKind == Rti.kindFunction || sKind == Rti.kindGenericFunction) && - isFunctionType(t)) { - return true; - } - - // Positional Function Types + Named Function Types: - // TODO(fishythefish): Disallow JavaScriptFunction as a subtype of function - // types using features inaccessible from JavaScript. - if (tKind == Rti.kindGenericFunction) { - if (isJsFunctionType(s)) return true; - if (sKind != Rti.kindGenericFunction) return false; - - var sBounds = Rti._getGenericFunctionBounds(s); - var tBounds = Rti._getGenericFunctionBounds(t); - int sLength = _Utils.arrayLength(sBounds); - int tLength = _Utils.arrayLength(tBounds); - if (sLength != tLength) return false; - - sEnv = sEnv == null ? sBounds : _Utils.arrayConcat(sBounds, sEnv); - tEnv = tEnv == null ? tBounds : _Utils.arrayConcat(tBounds, tEnv); - - for (int i = 0; i < sLength; i++) { - var sBound = _Utils.asRti(_Utils.arrayAt(sBounds, i)); - var tBound = _Utils.asRti(_Utils.arrayAt(tBounds, i)); - if (!_isSubtype(universe, sBound, sEnv, tBound, tEnv) || - !_isSubtype(universe, tBound, tEnv, sBound, sEnv)) { - return false; - } - } - - return _isFunctionSubtype(universe, Rti._getGenericFunctionBase(s), sEnv, - Rti._getGenericFunctionBase(t), tEnv); - } - if (tKind == Rti.kindFunction) { - if (isJsFunctionType(s)) return true; - if (sKind != Rti.kindFunction) return false; - return _isFunctionSubtype(universe, s, sEnv, t, tEnv); - } - - // Interface Compositionality + Super-Interface: - if (sKind == Rti.kindInterface) { - if (tKind != Rti.kindInterface) return false; - return _isInterfaceSubtype(universe, s, sEnv, t, tEnv); - } - - return false; -} - -bool _isFunctionSubtype( - Object? universe, Rti s, Object? sEnv, Rti t, Object? tEnv) { - assert(Rti._getKind(s) == Rti.kindFunction); - assert(Rti._getKind(t) == Rti.kindFunction); - - Rti sReturnType = Rti._getReturnType(s); - Rti tReturnType = Rti._getReturnType(t); - if (!_isSubtype(universe, sReturnType, sEnv, tReturnType, tEnv)) { - return false; - } - - _FunctionParameters sParameters = Rti._getFunctionParameters(s); - _FunctionParameters tParameters = Rti._getFunctionParameters(t); - - var sRequiredPositional = - _FunctionParameters._getRequiredPositional(sParameters); - var tRequiredPositional = - _FunctionParameters._getRequiredPositional(tParameters); - int sRequiredPositionalLength = _Utils.arrayLength(sRequiredPositional); - int tRequiredPositionalLength = _Utils.arrayLength(tRequiredPositional); - if (sRequiredPositionalLength > tRequiredPositionalLength) return false; - int requiredPositionalDelta = - tRequiredPositionalLength - sRequiredPositionalLength; - - var sOptionalPositional = - _FunctionParameters._getOptionalPositional(sParameters); - var tOptionalPositional = - _FunctionParameters._getOptionalPositional(tParameters); - int sOptionalPositionalLength = _Utils.arrayLength(sOptionalPositional); - int tOptionalPositionalLength = _Utils.arrayLength(tOptionalPositional); - if (sRequiredPositionalLength + sOptionalPositionalLength < - tRequiredPositionalLength + tOptionalPositionalLength) return false; - - for (int i = 0; i < sRequiredPositionalLength; i++) { - Rti sParameter = _Utils.asRti(_Utils.arrayAt(sRequiredPositional, i)); - Rti tParameter = _Utils.asRti(_Utils.arrayAt(tRequiredPositional, i)); - if (!_isSubtype(universe, tParameter, tEnv, sParameter, sEnv)) { - return false; - } - } - - for (int i = 0; i < requiredPositionalDelta; i++) { - Rti sParameter = _Utils.asRti(_Utils.arrayAt(sOptionalPositional, i)); - Rti tParameter = _Utils.asRti( - _Utils.arrayAt(tRequiredPositional, sRequiredPositionalLength + i)); - if (!_isSubtype(universe, tParameter, tEnv, sParameter, sEnv)) { - return false; - } - } - - for (int i = 0; i < tOptionalPositionalLength; i++) { - Rti sParameter = _Utils.asRti( - _Utils.arrayAt(sOptionalPositional, requiredPositionalDelta + i)); - Rti tParameter = _Utils.asRti(_Utils.arrayAt(tOptionalPositional, i)); - if (!_isSubtype(universe, tParameter, tEnv, sParameter, sEnv)) { - return false; - } - } - - var sNamed = _FunctionParameters._getNamed(sParameters); - var tNamed = _FunctionParameters._getNamed(tParameters); - int sNamedLength = _Utils.arrayLength(sNamed); - int tNamedLength = _Utils.arrayLength(tNamed); - - int sIndex = 0; - for (int tIndex = 0; tIndex < tNamedLength; tIndex += 3) { - String tName = _Utils.asString(_Utils.arrayAt(tNamed, tIndex)); - while (true) { - if (sIndex >= sNamedLength) return false; - String sName = _Utils.asString(_Utils.arrayAt(sNamed, sIndex)); - sIndex += 3; - if (_Utils.stringLessThan(tName, sName)) return false; - bool sIsRequired = _Utils.asBool(_Utils.arrayAt(sNamed, sIndex - 2)); - if (_Utils.stringLessThan(sName, tName)) { - if (sIsRequired) return false; - continue; - } - bool tIsRequired = _Utils.asBool(_Utils.arrayAt(tNamed, tIndex + 1)); - if (sIsRequired && !tIsRequired) return false; - Rti sType = _Utils.asRti(_Utils.arrayAt(sNamed, sIndex - 1)); - Rti tType = _Utils.asRti(_Utils.arrayAt(tNamed, tIndex + 2)); - if (!_isSubtype(universe, tType, tEnv, sType, sEnv)) return false; - break; - } - } - while (sIndex < sNamedLength) { - if (_Utils.asBool(_Utils.arrayAt(sNamed, sIndex + 1))) return false; - sIndex += 3; - } - return true; -} - -bool _isInterfaceSubtype( - Object? universe, Rti s, Object? sEnv, Rti t, Object? tEnv) { - String sName = Rti._getInterfaceName(s); - String tName = Rti._getInterfaceName(t); - - // Interface Compositionality: - if (sName == tName) { - var sArgs = Rti._getInterfaceTypeArguments(s); - var tArgs = Rti._getInterfaceTypeArguments(t); - int length = _Utils.arrayLength(sArgs); - assert(length == _Utils.arrayLength(tArgs)); - - var sVariances; - bool? hasVariances; - if (JS_GET_FLAG("VARIANCE")) { - sVariances = _Universe.findTypeParameterVariances(universe, sName); - hasVariances = sVariances != null; - assert(!hasVariances || length == _Utils.arrayLength(sVariances)); - } - - for (int i = 0; i < length; i++) { - Rti sArg = _Utils.asRti(_Utils.arrayAt(sArgs, i)); - Rti tArg = _Utils.asRti(_Utils.arrayAt(tArgs, i)); - if (JS_GET_FLAG("VARIANCE")) { - int sVariance = hasVariances != null - ? _Utils.asInt(_Utils.arrayAt(sVariances, i)) - : Variance.legacyCovariant; - switch (sVariance) { - case Variance.legacyCovariant: - case Variance.covariant: - if (!_isSubtype(universe, sArg, sEnv, tArg, tEnv)) { - return false; - } - break; - case Variance.contravariant: - if (!_isSubtype(universe, tArg, tEnv, sArg, sEnv)) { - return false; - } - break; - case Variance.invariant: - if (!_isSubtype(universe, sArg, sEnv, tArg, tEnv) || - !_isSubtype(universe, tArg, tEnv, sArg, sEnv)) { - return false; - } - break; - default: - throw StateError( - "Unknown variance given for subtype check: $sVariance"); - } - } else { - if (!_isSubtype(universe, sArg, sEnv, tArg, tEnv)) { - return false; - } - } - } - return true; - } - - // The Super-Interface rule says that if [s] has superinterfaces C0,...,Cn, - // then we need to check if for some i, Ci <: [t]. However, this requires us - // to iterate over the superinterfaces. Instead, we can perform case - // analysis on [t]. By this point, [t] can only be Never, a type variable, - // or an interface type. (Bindings do not participate in subtype checks and - // all other cases have been eliminated.) If [t] is not an interface, then - // [s] - isStrongTopType(t) || - isLegacyObjectType(t) || - JS_GET_FLAG('LEGACY') && isObjectType(t); - -bool isStrongTopType(Rti t) { - int kind = Rti._getKind(t); - return kind == Rti.kindDynamic || - kind == Rti.kindVoid || - kind == Rti.kindAny || - kind == Rti.kindErased || - isNullableObjectType(t); -} - -bool isBottomType(Rti t) => - Rti._getKind(t) == Rti.kindNever || JS_GET_FLAG('LEGACY') && isNullType(t); - -bool isObjectType(Rti t) => _Utils.isIdentical(t, TYPE_REF()); -bool isLegacyObjectType(Rti t) => - _Utils.isIdentical(t, LEGACY_TYPE_REF()); -bool isNullableObjectType(Rti t) => _Utils.isIdentical(t, TYPE_REF()); -bool isNullType(Rti t) => - _Utils.isIdentical(t, TYPE_REF()) || - _Utils.isIdentical(t, TYPE_REF()); -bool isFunctionType(Rti t) => _Utils.isIdentical(t, TYPE_REF()); -bool isJsFunctionType(Rti t) => - _Utils.isIdentical(t, TYPE_REF()); - -class _Utils { - static bool asBool(Object? o) => JS('bool', '#', o); - static double asDouble(Object? o) => JS('double', '#', o); - static int asInt(Object? o) => JS('int', '#', o); - static num asNum(Object? o) => JS('num', '#', o); - static String asString(Object? o) => JS('String', '#', o); - static Rti asRti(Object? s) => JS('Rti', '#', s); - static Rti? asRtiOrNull(Object? s) => JS('Rti|Null', '#', s); - - static bool isString(Object? o) => JS('bool', 'typeof # == "string"', o); - static bool isNum(Object? o) => JS('bool', 'typeof # == "number"', o); - - static bool instanceOf(Object? o, Object? constructor) => - JS('bool', '# instanceof #', o, constructor); - - static bool isIdentical(Object? s, Object? t) => JS('bool', '# === #', s, t); - static bool isNotIdentical(Object? s, Object? t) => - JS('bool', '# !== #', s, t); - - static bool isMultipleOf(int n, int d) => JS('bool', '# % # === 0', n, d); - - static JSArray objectKeys(Object? o) => - JS('returns:JSArray;new:true;', 'Object.keys(#)', o); - - static void objectAssign(Object? o, Object? other) { - // TODO(fishythefish): Use `Object.assign()` when IE11 is deprecated. - var keys = objectKeys(other); - int length = arrayLength(keys); - for (int i = 0; i < length; i++) { - String key = asString(arrayAt(keys, i)); - JS('', '#[#] = #[#]', o, key, other, key); - } - } - - static bool isArray(Object? o) => JS('bool', 'Array.isArray(#)', o); - - static int arrayLength(Object? array) => JS('int', '#.length', array); - - static Object? arrayAt(Object? array, int i) => JS('', '#[#]', array, i); - - static void arraySetAt(Object? array, int i, Object? value) { - JS('', '#[#] = #', array, i, value); - } - - static JSArray arrayShallowCopy(Object? array) => - JS('JSArray', '#.slice()', array); - - static JSArray arraySplice(Object? array, int position) => - JS('JSArray', '#.splice(#)', array, position); - - static JSArray arrayConcat(Object? a1, Object? a2) => - JS('JSArray', '#.concat(#)', a1, a2); - - static void arrayPush(Object? array, Object? value) { - JS('', '#.push(#)', array, value); - } - - static String substring(String s, int start, int end) => - JS('String', '#.substring(#, #)', s, start, end); - - static bool stringLessThan(String s1, String s2) => - JS('bool', '# < #', s1, s2); - - static Object? mapGet(Object? cache, Object? key) => - JS('', '#.get(#)', cache, key); - - static void mapSet(Object? cache, Object? key, Object? value) { - JS('', '#.set(#, #)', cache, key, value); - } -} - -// -------- Entry points for testing ------------------------------------------- - -String testingCanonicalRecipe(Rti rti) { - return Rti._getCanonicalRecipe(rti); -} - -String testingRtiToString(Rti rti) { - return _rtiToString(rti, null); -} - -String testingRtiToDebugString(Rti rti) { - return _rtiToDebugString(rti); -} - -Object testingCreateUniverse() { - return _Universe.create(); -} - -void testingAddRules(Object? universe, Object? rules) { - _Universe.addRules(universe, rules); -} - -void testingAddTypeParameterVariances(Object? universe, Object? variances) { - _Universe.addTypeParameterVariances(universe, variances); -} - -bool testingIsSubtype(Object? universe, Rti rti1, Rti rti2) { - return isSubtype(universe, rti1, rti2); -} - -Rti testingUniverseEval(Object? universe, String recipe) { - return _Universe.eval(universe, recipe, true); -} - -void testingUniverseEvalOverride(Object? universe, String recipe, Rti rti) { - var cache = _Universe.evalCache(universe); - _Utils.mapSet(cache, recipe, rti); -} - -Rti testingEnvironmentEval(Object? universe, Rti environment, String recipe) { - return _Universe.evalInEnvironment(universe, environment, recipe); -} - -Rti testingEnvironmentBind(Object? universe, Rti environment, Rti arguments) { - return _Universe.bind(universe, environment, arguments); -} diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/shared/async_await_error_codes.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/shared/async_await_error_codes.dart deleted file mode 100644 index f87406b31b0..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/lib/shared/async_await_error_codes.dart +++ /dev/null @@ -1,10 +0,0 @@ -// 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. - -/// Contains error codes that transformed async/async* functions use to -/// communicate with js_helper functions. - -const int SUCCESS = 0; -const int ERROR = 1; -const int STREAM_WAS_CANCELED = 2; diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/shared/embedded_names.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/shared/embedded_names.dart deleted file mode 100644 index 31b46c5f8c2..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/lib/shared/embedded_names.dart +++ /dev/null @@ -1,454 +0,0 @@ -// Copyright (c) 2014, 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. - -/// Contains the names of globals that are embedded into the output by the -/// compiler. -/// -/// Variables embedded this way should be access with `JS_EMBEDDED_GLOBAL` from -/// the `_foreign_helper` library. -/// -/// This library is shared between the compiler and the runtime system. -library dart2js._embedded_names; - -/// The name of the property that is used to mark a type as typedef. -/// -/// Without reflection typedefs are removed (expanded to their function type) -/// but with reflection an object is needed to have the typedef's name. The -/// object is marked with this property. -/// -/// This property name only lives on internal type-objects and is only used -/// when reflection is enabled. -const TYPEDEF_PREDICATE_PROPERTY_NAME = r"$$isTypedef"; - -/// The name of the property that is used to find the function type of a -/// typedef. -/// -/// Without reflection typedefs are removed (expanded to their function type) -/// but with reflection an object is needed to have the typedef's name. -/// -/// The typedef's object contains a pointer to its function type (as an index -/// into the embedded global [TYPES]) in this property. -/// -/// This property name only lives on internal type-objects and is only used -/// when reflection is enabled. -const TYPEDEF_TYPE_PROPERTY_NAME = r"$typedefType"; - -/// The name of the property that is used to find the native superclass of -/// an extended class. -/// -/// Every class that extends a native class has this property set on its -/// native class. -const NATIVE_SUPERCLASS_TAG_NAME = r"$nativeSuperclassTag"; - -/// The name of the static-function property name. -/// -/// This property is set for all tear-offs of static functions, and provides -/// the static function's unique (potentially minified) name. -const STATIC_FUNCTION_NAME_PROPERTY_NAME = r'$static_name'; - -/// The name of a property on the constructor function of Dart Object -/// and interceptor types, used for caching Rti types. -const CONSTRUCTOR_RTI_CACHE_PROPERTY_NAME = r'$ccache'; - -/// The name of the embedded global for metadata. -/// -/// Use [JsBuiltin.getMetadata] instead of directly accessing this embedded -/// global. -const METADATA = 'metadata'; - -/// A list of types used in the program e.g. for reflection or encoding of -/// function types. -/// -/// Use [JsBuiltin.getType] instead of directly accessing this embedded global. -const TYPES = 'types'; - -/// Returns a function that maps a name of a class to its type. -/// -/// This embedded global is used by the runtime when computing the internal -/// runtime-type-information (rti) object. -const GET_TYPE_FROM_NAME = 'getTypeFromName'; - -/// A JS map from mangled global names to their unmangled names. -/// -/// If the program does not use reflection, this embedded global may be empty -/// (but not null or undefined). -const MANGLED_GLOBAL_NAMES = 'mangledGlobalNames'; - -/// A JS map from mangled instance names to their unmangled names. -/// -/// This embedded global is mainly used for reflection, but is also used to -/// map const-symbols (`const Symbol('x')`) to the mangled instance names. -/// -/// This embedded global may be empty (but not null or undefined). -const MANGLED_NAMES = 'mangledNames'; - -/// A JS map from dispatch tags (usually constructor names of DOM classes) to -/// interceptor class. This map is used to find the correct interceptor for -/// native classes. -/// -/// This embedded global is used for natives. -const INTERCEPTORS_BY_TAG = 'interceptorsByTag'; - -/// A JS map from dispatch tags (usually constructor names of DOM classes) to -/// booleans. Every tag entry of [INTERCEPTORS_BY_TAG] has a corresponding -/// entry in the leaf-tags map. -/// -/// A tag-entry is true, when a class can be treated as leaf class in the -/// hierarchy. That is, even though it might have subclasses, all subclasses -/// have the same code for the used methods. -/// -/// This embedded global is used for natives. -const LEAF_TAGS = 'leafTags'; - -/// A JS function that returns the isolate tag for a given name. -/// -/// This function uses the [ISOLATE_TAG] (below) to construct a name that is -/// unique per isolate. -/// -/// This embedded global is used for natives. -// TODO(floitsch): should we rename this variable to avoid confusion with -// [INTERCEPTORS_BY_TAG] and [LEAF_TAGS]. -const GET_ISOLATE_TAG = 'getIsolateTag'; - -/// A string that is different for each running isolate. -/// -/// When this embedded global is initialized a global variable is used to -/// ensure that no other running isolate uses the same isolate-tag string. -/// -/// This embedded global is used for natives. -// TODO(floitsch): should we rename this variable to avoid confusion with -// [INTERCEPTORS_BY_TAG] and [LEAF_TAGS]. -const ISOLATE_TAG = 'isolateTag'; - -/// An embedded global that contains the property used to store type information -/// on JavaScript Array instances. This is a Symbol (except for IE11, where is -/// is a String). -const ARRAY_RTI_PROPERTY = 'arrayRti'; - -/// This embedded global (a function) returns the isolate-specific dispatch-tag -/// that is used to accelerate interceptor calls. -const DISPATCH_PROPERTY_NAME = "dispatchPropertyName"; - -/// An embedded global that maps a [Type] to the [Interceptor] and constructors -/// for that type. -/// -/// More documentation can be found in the interceptors library (close to its -/// use). -const TYPE_TO_INTERCEPTOR_MAP = "typeToInterceptorMap"; - -/// The current script's URI when the program was loaded. -/// -/// This embedded global is set at startup, just before invoking `main`. -const CURRENT_SCRIPT = 'currentScript'; - -/// Contains a map from load-ids to lists of part indexes. -/// -/// To load the deferred library that is represented by the load-id, the runtime -/// must load all associated URIs (named in DEFERRED_PART_URIS) and initialize -/// all the loaded hunks (DEFERRED_PART_HASHES). -/// -/// This embedded global is only used for deferred loading. -const DEFERRED_LIBRARY_PARTS = 'deferredLibraryParts'; - -/// Contains a list of URIs (Strings), indexed by part. -/// -/// The lists in the DEFERRED_LIBRARY_PARTS map contain indexes into this list. -/// -/// This embedded global is only used for deferred loading. -const DEFERRED_PART_URIS = 'deferredPartUris'; - -/// Contains a list of hashes, indexed by part. -/// -/// The lists in the DEFERRED_LIBRARY_PARTS map contain indexes into this list. -/// -/// The hashes are associated with the URIs of the load-ids (see -/// [DEFERRED_PART_URIS]). They are SHA1 (or similar) hashes of the code that -/// must be loaded. By using cryptographic hashes we can (1) handle loading in -/// the same web page the parts from multiple Dart applications (2) avoid -/// loading similar code multiple times. -/// -/// This embedded global is only used for deferred loading. -const DEFERRED_PART_HASHES = 'deferredPartHashes'; - -/// Initialize a loaded hunk. -/// -/// Once a hunk (the code from a deferred URI) has been loaded it must be -/// initialized. Calling this function with the corresponding hash (see -/// [DEFERRED_LIBRARY_HASHES]) initializes the code. -/// -/// This embedded global is only used for deferred loading. -const INITIALIZE_LOADED_HUNK = 'initializeLoadedHunk'; - -/// Returns, whether a hunk (identified by its hash) has already been loaded. -/// -/// This embedded global is only used for deferred loading. -const IS_HUNK_LOADED = 'isHunkLoaded'; - -/// Returns, whether a hunk (identified by its hash) has already been -/// initialized. -/// -/// This embedded global is only used for deferred loading. -const IS_HUNK_INITIALIZED = 'isHunkInitialized'; - -/// A set (implemented as map to booleans) of hunks (identified by hashes) that -/// have already been initialized. -/// -/// This embedded global is only used for deferred loading. -/// -/// This global is an emitter-internal embedded global, and not used by the -/// runtime. The constant remains in this file to make sure that other embedded -/// globals don't clash with it. -const DEFERRED_INITIALIZED = 'deferredInitialized'; - -/// A 'Universe' object used by 'dart:_rti'. -/// -/// This embedded global is used for --experiment-new-rti. -const RTI_UNIVERSE = 'typeUniverse'; - -/// Returns a function that creates all precompiled functions (in particular -/// constructors). -/// -/// That is, the function returns the array that the full emitter would -/// otherwise build dynamically when it finishes all classes. -/// -/// This constant is only used in CSP mode. -/// -/// This global is an emitter-internal embedded global, and not used by the -/// runtime. The constant remains in this file to make sure that other embedded -/// globals don't clash with it. -const PRECOMPILED = 'precompiled'; - -/// An emitter-internal embedded global. This global is not used by the runtime. -const FINISHED_CLASSES = 'finishedClasses'; - -/// A JavaScript object literal that maps the (minified) JavaScript constructor -/// name (as given by [JsBuiltin.rawRtiToJsConstructorName] to the -/// JavaScript constructor. -/// -/// This embedded global is only used by reflection. -const ALL_CLASSES = 'allClasses'; - -/// A map from element to type information. -/// -/// This embedded global is only used by reflection. -const TYPE_INFORMATION = 'typeInformation'; - -/// A map from statics to their descriptors. -/// -/// This embedded global is only used by reflection. -const STATICS = 'statics'; - -/// An array of library descriptors. -/// -/// The descriptor contains information such as name, uri, classes, ... -/// -/// This embedded global is only used by reflection. -const LIBRARIES = 'libraries'; - -/// A map from lazy statics to their initializers. -/// -/// This embedded global is only used by reflection. -const LAZIES = 'lazies'; - -/// Names that are supported by [JS_GET_NAME]. -// TODO(herhut): Make entries lower case (as in fields) and find a better name. -enum JsGetName { - GETTER_PREFIX, - SETTER_PREFIX, - CALL_PREFIX, - CALL_PREFIX0, - CALL_PREFIX1, - CALL_PREFIX2, - CALL_PREFIX3, - CALL_PREFIX4, - CALL_PREFIX5, - CALL_CATCH_ALL, - REFLECTABLE, - CLASS_DESCRIPTOR_PROPERTY, - REQUIRED_PARAMETER_PROPERTY, - DEFAULT_VALUES_PROPERTY, - CALL_NAME_PROPERTY, - DEFERRED_ACTION_PROPERTY, - - /// Prefix used for generated type argument substitutions on classes. - OPERATOR_AS_PREFIX, - - /// Prefix used for generated type test property on classes. - OPERATOR_IS_PREFIX, - - /// Name used for generated function types on classes and methods. - SIGNATURE_NAME, - - /// Name of JavaScript property used to store runtime-type information on - /// instances of parameterized classes. - RTI_NAME, - - /// Name used to tag a function type. - FUNCTION_TYPE_TAG, - - /// Name used to tag bounds of a generic function type. If bounds are present, - /// the property value is an Array of bounds (the length gives the number of - /// type parameters). If absent, the type is not a generic function type. - FUNCTION_TYPE_GENERIC_BOUNDS_TAG, - - /// Name used to tag void return in function type representations in - /// JavaScript. - FUNCTION_TYPE_VOID_RETURN_TAG, - - /// Name used to tag return types in function type representations in - /// JavaScript. - FUNCTION_TYPE_RETURN_TYPE_TAG, - - /// Name used to tag required parameters in function type representations - /// in JavaScript. - FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG, - - /// Name used to tag optional parameters in function type representations - /// in JavaScript. - FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG, - - /// Name used to tag named parameters in function type representations in - /// JavaScript. - FUNCTION_TYPE_NAMED_PARAMETERS_TAG, - - /// Name used to tag a FutureOr type. - FUTURE_OR_TAG, - - /// Name used to tag type arguments types in FutureOr type representations in - /// JavaScript. - FUTURE_OR_TYPE_ARGUMENT_TAG, - - /// String representation of the type of the Future class. - FUTURE_CLASS_TYPE_NAME, - - /// Field name used for determining if an object or its interceptor has - /// JavaScript indexing behavior. - IS_INDEXABLE_FIELD_NAME, - - /// String representation of the type of the null class. - NULL_CLASS_TYPE_NAME, - - /// String representation of the type of the object class. - OBJECT_CLASS_TYPE_NAME, - - /// String representation of the type of the function class. - FUNCTION_CLASS_TYPE_NAME, - - /// String representation of the type of the JavaScriptFunction class. - JS_FUNCTION_CLASS_TYPE_NAME, - - /// Property name for Rti._as field. - RTI_FIELD_AS, - - /// Property name for Rti._is field. - RTI_FIELD_IS, -} - -enum JsBuiltin { - /// Returns the JavaScript constructor function for Dart's Object class. - /// This can be used for type tests, as in - /// - /// var constructor = JS_BUILTIN('', JsBuiltin.dartObjectConstructor); - /// if (JS('bool', '# instanceof #', obj, constructor)) - /// ... - dartObjectConstructor, - - /// Returns the JavaScript constructor function for the runtime's Closure - /// class, the base class of all closure objects. This can be used for type - /// tests, as in - /// - /// var constructor = JS_BUILTIN('', JsBuiltin.dartClosureConstructor); - /// if (JS('bool', '# instanceof #', obj, constructor)) - /// ... - dartClosureConstructor, - - /// Returns the JavaScript-constructor name given an [isCheckProperty]. - /// - /// This relies on a deterministic encoding of is-check properties (for - /// example `$isFoo` for a class `Foo`). In minified code the returned - /// classname is the minified name of the class. - /// - /// JS_BUILTIN('returns:String;depends:none;effects:none', - /// JsBuiltin.isCheckPropertyToJsConstructorName, - /// isCheckProperty); - isCheckPropertyToJsConstructorName, - - /// Returns true if the given type is a function type. Returns false for - /// the one `Function` type singleton. (See [isFunctionTypeSingleton]). - /// - /// JS_BUILTIN('bool', JsBuiltin.isFunctionType, o) - isFunctionType, - - /// Returns true if the given type is a FutureOr type. - /// - /// JS_BUILTIN('bool', JsBuiltin.isFutureOrType, o) - isFutureOrType, - - /// Returns true if the given type is the `void` type. - /// - /// JS_BUILTIN('bool', JsBuiltin.isVoidType, o) - isVoidType, - - /// Returns true if the given type is the `dynamic` type. - /// - /// JS_BUILTIN('bool', JsBuiltin.isDynamicType, o) - isDynamicType, - - /// Returns true if the given type is a type argument of a js-interop class - /// or a supertype of a js-interop class. - /// - /// JS_BUILTIN('bool', JsBuiltin.isJsInteropTypeArgument, o) - isJsInteropTypeArgument, - - /// Returns the JavaScript-constructor name given an rti encoding. - /// - /// JS_BUILTIN('String', JsBuiltin.rawRtiToJsConstructorName, rti) - rawRtiToJsConstructorName, - - /// Returns the raw runtime type of the given object. The given argument - /// [o] should be the interceptor (for non-Dart objects). - /// - /// JS_BUILTIN('', JsBuiltin.rawRuntimeType, o) - rawRuntimeType, - - /// Returns whether the given type is a subtype of other. - /// - /// The argument `other` is the name of the potential supertype. It is - /// computed by `runtimeTypeToString`; - /// - /// *The `other` name must be passed in before the `type`.* - /// - /// JS_BUILTIN('returns:bool;effects:none;depends:none', - /// JsBuiltin.isSubtype, other, type); - isSubtype, - - /// Returns true if the given type equals the type given as second - /// argument. Use the JS_GET_NAME helpers to get the type representation - /// for various Dart classes. - /// - /// JS_BUILTIN('returns:bool;effects:none;depends:none', - /// JsBuiltin.isFunctionTypeLiteral, type, name); - isGivenTypeRti, - - /// Returns the metadata of the given [index]. - /// - /// JS_BUILTIN('returns:var;effects:none;depends:none', - /// JsBuiltin.getMetadata, index); - getMetadata, - - /// Returns the type of the given [index]. - /// - /// JS_BUILTIN('returns:var;effects:none;depends:none', - /// JsBuiltin.getType, index); - getType, -} - -/// Names of fields of the Rti Universe object. -class RtiUniverseFieldNames { - static String evalCache = 'eC'; - static String typeRules = 'tR'; - static String erasedTypes = 'eT'; - static String typeParameterVariances = 'tPV'; - static String sharedEmptyArray = 'sEA'; -} diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart deleted file mode 100644 index c1838614fa6..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart +++ /dev/null @@ -1,237 +0,0 @@ -// Copyright (c) 2019, 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. - -/// Constants and predicates used for encoding and decoding type recipes. -/// -/// This library is shared between the compiler and the runtime system. -library dart2js._recipe_syntax; - -abstract class Recipe { - Recipe._(); - - // Operators. - - static const int separator = _comma; - static const String separatorString = _commaString; - - static const int toType = _semicolon; - static const String toTypeString = _semicolonString; - - static const int pushErased = _hash; - static const String pushErasedString = _hashString; - static const int pushDynamic = _at; - static const String pushDynamicString = _atString; - static const int pushVoid = _tilde; - static const String pushVoidString = _tildeString; - - static const int wrapStar = _asterisk; - static const String wrapStarString = _asteriskString; - static const int wrapQuestion = _question; - static const String wrapQuestionString = _questionString; - static const int wrapFutureOr = _slash; - static const String wrapFutureOrString = _slashString; - - static const int startTypeArguments = _lessThan; - static const String startTypeArgumentsString = _lessThanString; - static const int endTypeArguments = _greaterThan; - static const String endTypeArgumentsString = _greaterThanString; - - static const int startFunctionArguments = _leftParen; - static const String startFunctionArgumentsString = _leftParenString; - static const int endFunctionArguments = _rightParen; - static const String endFunctionArgumentsString = _rightParenString; - static const int startOptionalGroup = _leftBracket; - static const String startOptionalGroupString = _leftBracketString; - static const int endOptionalGroup = _rightBracket; - static const String endOptionalGroupString = _rightBracketString; - static const int startNamedGroup = _leftBrace; - static const String startNamedGroupString = _leftBraceString; - static const int endNamedGroup = _rightBrace; - static const String endNamedGroupString = _rightBraceString; - static const int nameSeparator = _colon; - static const String nameSeparatorString = _colonString; - static const int requiredNameSeparator = _exclamation; - static const String requiredNameSeparatorString = _exclamationString; - - static const int genericFunctionTypeParameterIndex = _circumflex; - static const String genericFunctionTypeParameterIndexString = - _circumflexString; - - static const int extensionOp = _ampersand; - static const String extensionOpString = _ampersandString; - static const int pushNeverExtension = 0; - static const String pushNeverExtensionString = '$pushNeverExtension'; - static const int pushAnyExtension = 1; - static const String pushAnyExtensionString = '$pushAnyExtension'; - - // Number and name components. - - static bool isDigit(int code) => code >= _digit0 && code <= _digit9; - static int digitValue(int code) => code - _digit0; - - static bool isIdentifierStart(int ch) => - (((ch | 32) - _lowercaseA) & 0xffff) < 26 || - (ch == _underscore) || - (ch == _dollar); - - static const int period = _period; - - // Private names. - - static const int _formfeed = 0x0C; - static const String _formfeedString = '\f'; - - static const int _space = 0x20; - static const String _spaceString = ' '; - static const int _exclamation = 0x21; - static const String _exclamationString = '!'; - static const int _hash = 0x23; - static const String _hashString = '#'; - static const int _dollar = 0x24; - static const String _dollarString = r'$'; - static const int _percent = 0x25; - static const String _percentString = '%'; - static const int _ampersand = 0x26; - static const String _ampersandString = '&'; - static const int _apostrophe = 0x27; - static const String _apostropheString = "'"; - static const int _leftParen = 0x28; - static const String _leftParenString = '('; - static const int _rightParen = 0x29; - static const String _rightParenString = ')'; - static const int _asterisk = 0x2A; - static const String _asteriskString = '*'; - static const int _plus = 0x2B; - static const String _plusString = '+'; - static const int _comma = 0x2C; - static const String _commaString = ','; - static const int _minus = 0x2D; - static const String _minusString = '-'; - static const int _period = 0x2E; - static const String _periodString = '.'; - static const int _slash = 0x2F; - static const String _slashString = '/'; - - static const int _digit0 = 0x30; - static const int _digit9 = 0x39; - - static const int _colon = 0x3A; - static const String _colonString = ':'; - static const int _semicolon = 0x3B; - static const String _semicolonString = ';'; - static const int _lessThan = 0x3C; - static const String _lessThanString = '<'; - static const int _equals = 0x3D; - static const String _equalsString = '='; - static const int _greaterThan = 0x3E; - static const String _greaterThanString = '>'; - static const int _question = 0x3F; - static const String _questionString = '?'; - static const int _at = 0x40; - static const String _atString = '@'; - - static const int _uppercaseA = 0x41; - static const int _uppercaseZ = 0x5A; - - static const int _leftBracket = 0x5B; - static const String _leftBracketString = '['; - static const int _backslash = 0x5C; - static const String _backslashString = r'\'; - static const int _rightBracket = 0x5D; - static const String _rightBracketString = ']'; - static const int _circumflex = 0x5E; - static const String _circumflexString = '^'; - static const int _underscore = 0x5F; - static const String _underscoreString = '_'; - static const int _backtick = 0x60; - static const String _backtickString = '`'; - - static const int _lowercaseA = 0x61; - static const int _lowercaseZ = 0x7A; - - static const int _leftBrace = 0x7B; - static const String _leftBraceString = '{'; - static const int _vertical = 0x7C; - static const String _verticalString = '|'; - static const int _rightBrace = 0x7D; - static const String _rightBraceString = '}'; - static const int _tilde = 0x7E; - static const String _tildeString = '~'; - - static void testEquivalence() { - void test(String label, int charCode, String str) { - if (String.fromCharCode(charCode) != str) { - throw StateError("$label: String.fromCharCode($charCode) != $str"); - } - } - - void testExtension(String label, int op, String str) { - if ('$op' != str) { - throw StateError("$label: $op.toString() != $str"); - } - } - - test("separator", separator, separatorString); - test("toType", toType, toTypeString); - test("pushErased", pushErased, pushErasedString); - test("pushDynamic", pushDynamic, pushDynamicString); - test("pushVoid", pushVoid, pushVoidString); - test("wrapStar", wrapStar, wrapStarString); - test("wrapQuestion", wrapQuestion, wrapQuestionString); - test("wrapFutureOr", wrapFutureOr, wrapFutureOrString); - test("startTypeArguments", startTypeArguments, startTypeArgumentsString); - test("endTypeArguments", endTypeArguments, endTypeArgumentsString); - test("startFunctionArguments", startFunctionArguments, - startFunctionArgumentsString); - test("endFunctionArguments", endFunctionArguments, - endFunctionArgumentsString); - test("startOptionalGroup", startOptionalGroup, startOptionalGroupString); - test("endOptionalGroup", endOptionalGroup, endOptionalGroupString); - test("startNamedGroup", startNamedGroup, startNamedGroupString); - test("endNamedGroup", endNamedGroup, endNamedGroupString); - test("nameSeparator", nameSeparator, nameSeparatorString); - test("requiredNameSeparator", requiredNameSeparator, - requiredNameSeparatorString); - test("genericFunctionTypeParameterIndex", genericFunctionTypeParameterIndex, - genericFunctionTypeParameterIndexString); - test("extensionOp", extensionOp, extensionOpString); - testExtension( - "pushNeverExtension", pushNeverExtension, pushNeverExtensionString); - testExtension("pushAnyExtension", pushAnyExtension, pushAnyExtensionString); - - test("_formfeed", _formfeed, _formfeedString); - test("_space", _space, _spaceString); - test("_exclamation", _exclamation, _exclamationString); - test("_hash", _hash, _hashString); - test("_dollar", _dollar, _dollarString); - test("_percent", _percent, _percentString); - test("_ampersand", _ampersand, _ampersandString); - test("_apostrophe", _apostrophe, _apostropheString); - test("_leftParen", _leftParen, _leftParenString); - test("_rightParen", _rightParen, _rightParenString); - test("_asterisk", _asterisk, _asteriskString); - test("_plus", _plus, _plusString); - test("_comma", _comma, _commaString); - test("_minus", _minus, _minusString); - test("_period", _period, _periodString); - test("_slash", _slash, _slashString); - test("_colon", _colon, _colonString); - test("_semicolon", _semicolon, _semicolonString); - test("_lessThan", _lessThan, _lessThanString); - test("_equals", _equals, _equalsString); - test("_greaterThan", _greaterThan, _greaterThanString); - test("_question", _question, _questionString); - test("_at", _at, _atString); - test("_leftBracket", _leftBracket, _leftBracketString); - test("_backslash", _backslash, _backslashString); - test("_rightBracket", _rightBracket, _rightBracketString); - test("_circumflex", _circumflex, _circumflexString); - test("_underscore", _underscore, _underscoreString); - test("_backtick", _backtick, _backtickString); - test("_leftBrace", _leftBrace, _leftBraceString); - test("_vertical", _vertical, _verticalString); - test("_rightBrace", _rightBrace, _rightBraceString); - test("_tilde", _tilde, _tildeString); - } -} diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/string_helper.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/string_helper.dart deleted file mode 100644 index 3e07cdd0d3a..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/lib/string_helper.dart +++ /dev/null @@ -1,331 +0,0 @@ -// Copyright (c) 2012, 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. - -part of _js_helper; - -stringIndexOfStringUnchecked(receiver, other, startIndex) { - return JS('int', '#.indexOf(#, #)', receiver, other, startIndex); -} - -substring1Unchecked(receiver, startIndex) { - return JS('String', '#.substring(#)', receiver, startIndex); -} - -substring2Unchecked(receiver, startIndex, endIndex) { - return JS('String', '#.substring(#, #)', receiver, startIndex, endIndex); -} - -stringContainsStringUnchecked(receiver, other, startIndex) { - return stringIndexOfStringUnchecked(receiver, other, startIndex) >= 0; -} - -List stringSplitUnchecked(String receiver, pattern) { - return new JSArray.markGrowable(JS( - 'returns:JSExtendableArray;new:true', '#.split(#)', receiver, pattern)); -} - -class StringMatch implements Match { - const StringMatch(int this.start, String this.input, String this.pattern); - - int get end => start + pattern.length; - String operator [](int g) => group(g); - int get groupCount => 0; - - String group(int group_) { - if (group_ != 0) { - throw new RangeError.value(group_); - } - return pattern; - } - - List groups(List groups_) { - List result = []; - for (int g in groups_) { - result.add(group(g)); - } - return result; - } - - final int start; - final String input; - final String pattern; -} - -Iterable allMatchesInStringUnchecked( - String pattern, String string, int startIndex) { - return new _StringAllMatchesIterable(string, pattern, startIndex); -} - -class _StringAllMatchesIterable extends Iterable { - final String _input; - final String _pattern; - final int _index; - - _StringAllMatchesIterable(this._input, this._pattern, this._index); - - Iterator get iterator => - new _StringAllMatchesIterator(_input, _pattern, _index); - - Match get first { - int index = stringIndexOfStringUnchecked(_input, _pattern, _index); - if (index >= 0) { - return new StringMatch(index, _input, _pattern); - } - throw IterableElementError.noElement(); - } -} - -class _StringAllMatchesIterator implements Iterator { - final String _input; - final String _pattern; - int _index; - Match? _current; - - _StringAllMatchesIterator(this._input, this._pattern, this._index); - - bool moveNext() { - if (_index + _pattern.length > _input.length) { - _current = null; - return false; - } - var index = stringIndexOfStringUnchecked(_input, _pattern, _index); - if (index < 0) { - _index = _input.length + 1; - _current = null; - return false; - } - int end = index + _pattern.length; - _current = new StringMatch(index, _input, _pattern); - // Empty match, don't start at same location again. - if (end == _index) end++; - _index = end; - return true; - } - - Match get current => _current!; -} - -stringContainsUnchecked(receiver, other, startIndex) { - if (other is String) { - return stringContainsStringUnchecked(receiver, other, startIndex); - } else if (other is JSSyntaxRegExp) { - return other.hasMatch(receiver.substring(startIndex)); - } else { - var substr = receiver.substring(startIndex); - return other.allMatches(substr).isNotEmpty; - } -} - -String stringReplaceJS(String receiver, jsRegExp, String replacement) { - return JS('String', r'#.replace(#, #)', receiver, jsRegExp, - escapeReplacement(replacement)); -} - -String escapeReplacement(String replacement) { - // The JavaScript `String.prototype.replace` method recognizes replacement - // patterns in the replacement string. Dart does not have that behavior, so - // the replacement patterns need to be escaped. - - // `String.prototype.replace` tends to be slower when there are replacement - // patterns, and the escaping itself uses replacement patterns, so it is - // worthwhile checking for `$` first. - if (stringContainsStringUnchecked(replacement, r'$', 0)) { - return JS('String', r'#.replace(/\$/g, "$$$$")', replacement); - } - return replacement; -} - -stringReplaceFirstRE(receiver, regexp, replacement, startIndex) { - var match = regexp._execGlobal(receiver, startIndex); - if (match == null) return receiver; - var start = match.start; - var end = match.end; - return stringReplaceRangeUnchecked(receiver, start, end, replacement); -} - -/// Returns a string for a RegExp pattern that matches [string]. This is done by -/// escaping all RegExp metacharacters. -quoteStringForRegExp(string) { - // We test and replace essentially the same RegExp because replacement when - // there are replacement patterns is slow enough to be worth avoiding. - if (JS('bool', r'/[[\]{}()*+?.\\^$|]/.test(#)', string)) { - return JS('String', r'#.replace(/[[\]{}()*+?.\\^$|]/g, "\\$&")', string); - } - return string; -} - -stringReplaceAllUnchecked(receiver, pattern, replacement) { - checkString(replacement); - if (pattern is String) { - return stringReplaceAllUncheckedString(receiver, pattern, replacement); - } - - if (pattern is JSSyntaxRegExp) { - var re = regExpGetGlobalNative(pattern); - return stringReplaceJS(receiver, re, replacement); - } - - checkNull(pattern); - // TODO(floitsch): implement generic String.replace (with patterns). - throw "String.replaceAll(Pattern) UNIMPLEMENTED"; -} - -/// Replaces all non-overlapping occurences of [pattern] in [receiver] with -/// [replacement]. This should be replace with -/// (String.prototype.replaceAll)[https://github.com/tc39/proposal-string-replace-all] -/// when available. -String stringReplaceAllUncheckedString( - String receiver, String pattern, String replacement) { - if (pattern == "") { - if (receiver == "") { - return JS('String', '#', replacement); // help type inference. - } - StringBuffer result = new StringBuffer(''); - int length = receiver.length; - result.write(replacement); - for (int i = 0; i < length; i++) { - result.write(receiver[i]); - result.write(replacement); - } - return result.toString(); - } - - if (!const bool.fromEnvironment( - 'dart2js.testing.String.replaceAll.force.regexp')) { - // First check for no match. - int index = stringIndexOfStringUnchecked(receiver, pattern, 0); - if (index < 0) return receiver; - - // The fastest approach in general is to replace with a global RegExp, but - // this requires the receiver string to be long enough to amortize the cost - // of creating the RegExp, and the replacement to have no '$' patterns, - // which tend to make `String.prototype.replace` much slower. In these - // cases, using split-join usually wins. - if (receiver.length < 500 || - stringContainsStringUnchecked(replacement, r'$', 0)) { - return stringReplaceAllUsingSplitJoin(receiver, pattern, replacement); - } - } - var quoted = quoteStringForRegExp(pattern); - var replacer = JS('', "new RegExp(#, 'g')", quoted); - return stringReplaceJS(receiver, replacer, replacement); -} - -String stringReplaceAllUsingSplitJoin(receiver, pattern, replacement) { - return JS('String', '#.split(#).join(#)', receiver, pattern, replacement); -} - -String? _matchString(Match match) => match[0]; -String _stringIdentity(String string) => string; - -stringReplaceAllFuncUnchecked(receiver, pattern, onMatch, onNonMatch) { - if (onMatch == null) onMatch = _matchString; - if (onNonMatch == null) onNonMatch = _stringIdentity; - if (pattern is String) { - return stringReplaceAllStringFuncUnchecked( - receiver, pattern, onMatch, onNonMatch); - } - // Placing the Pattern test here is indistinguishable from placing it at the - // top of the method but it saves an extra check on the `pattern is String` - // path. - if (pattern is! Pattern) { - throw new ArgumentError.value(pattern, 'pattern', 'is not a Pattern'); - } - StringBuffer buffer = new StringBuffer(''); - int startIndex = 0; - for (Match match in pattern.allMatches(receiver)) { - buffer.write(onNonMatch(receiver.substring(startIndex, match.start))); - buffer.write(onMatch(match)); - startIndex = match.end; - } - buffer.write(onNonMatch(receiver.substring(startIndex))); - return buffer.toString(); -} - -stringReplaceAllEmptyFuncUnchecked(receiver, onMatch, onNonMatch) { - // Pattern is the empty string. - StringBuffer buffer = new StringBuffer(''); - int length = receiver.length; - int i = 0; - buffer.write(onNonMatch("")); - while (i < length) { - buffer.write(onMatch(new StringMatch(i, receiver, ""))); - // Special case to avoid splitting a surrogate pair. - int code = receiver.codeUnitAt(i); - if ((code & ~0x3FF) == 0xD800 && length > i + 1) { - // Leading surrogate; - code = receiver.codeUnitAt(i + 1); - if ((code & ~0x3FF) == 0xDC00) { - // Matching trailing surrogate. - buffer.write(onNonMatch(receiver.substring(i, i + 2))); - i += 2; - continue; - } - } - buffer.write(onNonMatch(receiver[i])); - i++; - } - buffer.write(onMatch(new StringMatch(i, receiver, ""))); - buffer.write(onNonMatch("")); - return buffer.toString(); -} - -stringReplaceAllStringFuncUnchecked(receiver, pattern, onMatch, onNonMatch) { - int patternLength = pattern.length; - if (patternLength == 0) { - return stringReplaceAllEmptyFuncUnchecked(receiver, onMatch, onNonMatch); - } - int length = receiver.length; - StringBuffer buffer = new StringBuffer(''); - int startIndex = 0; - while (startIndex < length) { - int position = stringIndexOfStringUnchecked(receiver, pattern, startIndex); - if (position == -1) { - break; - } - buffer.write(onNonMatch(receiver.substring(startIndex, position))); - buffer.write(onMatch(new StringMatch(position, receiver, pattern))); - startIndex = position + patternLength; - } - buffer.write(onNonMatch(receiver.substring(startIndex))); - return buffer.toString(); -} - -stringReplaceFirstUnchecked(receiver, pattern, replacement, int startIndex) { - if (pattern is String) { - int index = stringIndexOfStringUnchecked(receiver, pattern, startIndex); - if (index < 0) return receiver; - int end = index + pattern.length; - return stringReplaceRangeUnchecked(receiver, index, end, replacement); - } - if (pattern is JSSyntaxRegExp) { - return startIndex == 0 - ? stringReplaceJS(receiver, regExpGetNative(pattern), replacement) - : stringReplaceFirstRE(receiver, pattern, replacement, startIndex); - } - checkNull(pattern); - Iterator matches = pattern.allMatches(receiver, startIndex).iterator; - if (!matches.moveNext()) return receiver; - Match match = matches.current; - return receiver.replaceRange(match.start, match.end, replacement); -} - -stringReplaceFirstMappedUnchecked(receiver, pattern, replace, int startIndex) { - Iterator matches = pattern.allMatches(receiver, startIndex).iterator; - if (!matches.moveNext()) return receiver; - Match match = matches.current; - String replacement = "${replace(match)}"; - return receiver.replaceRange(match.start, match.end, replacement); -} - -stringJoinUnchecked(array, separator) { - return JS('String', r'#.join(#)', array, separator); -} - -String stringReplaceRangeUnchecked( - String receiver, int start, int end, String replacement) { - var prefix = JS('String', '#.substring(0, #)', receiver, start); - var suffix = JS('String', '#.substring(#)', receiver, end); - return "$prefix$replacement$suffix"; -} diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/typed_data_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/typed_data_patch.dart deleted file mode 100644 index d1c6a1a19f3..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/lib/typed_data_patch.dart +++ /dev/null @@ -1,190 +0,0 @@ -// Copyright (c) 2013, 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 'dart:_js_helper' show patch; -import 'dart:_native_typed_data'; - -@patch -class ByteData { - @patch - factory ByteData(int length) = NativeByteData; -} - -@patch -class Float32List { - @patch - factory Float32List(int length) = NativeFloat32List; - - @patch - factory Float32List.fromList(List elements) = - NativeFloat32List.fromList; -} - -@patch -class Float64List { - @patch - factory Float64List(int length) = NativeFloat64List; - - @patch - factory Float64List.fromList(List elements) = - NativeFloat64List.fromList; -} - -@patch -class Int16List { - @patch - factory Int16List(int length) = NativeInt16List; - - @patch - factory Int16List.fromList(List elements) = NativeInt16List.fromList; -} - -@patch -class Int32List { - @patch - factory Int32List(int length) = NativeInt32List; - - @patch - factory Int32List.fromList(List elements) = NativeInt32List.fromList; -} - -@patch -class Int8List { - @patch - factory Int8List(int length) = NativeInt8List; - - @patch - factory Int8List.fromList(List elements) = NativeInt8List.fromList; -} - -@patch -class Uint32List { - @patch - factory Uint32List(int length) = NativeUint32List; - - @patch - factory Uint32List.fromList(List elements) = NativeUint32List.fromList; -} - -@patch -class Uint16List { - @patch - factory Uint16List(int length) = NativeUint16List; - - @patch - factory Uint16List.fromList(List elements) = NativeUint16List.fromList; -} - -@patch -class Uint8ClampedList { - @patch - factory Uint8ClampedList(int length) = NativeUint8ClampedList; - - @patch - factory Uint8ClampedList.fromList(List elements) = - NativeUint8ClampedList.fromList; -} - -@patch -class Uint8List { - @patch - factory Uint8List(int length) = NativeUint8List; - - @patch - factory Uint8List.fromList(List elements) = NativeUint8List.fromList; -} - -@patch -class Int64List { - @patch - factory Int64List(int length) { - throw UnsupportedError("Int64List not supported on the web."); - } - - @patch - factory Int64List.fromList(List elements) { - throw UnsupportedError("Int64List not supported on the web."); - } -} - -@patch -class Uint64List { - @patch - factory Uint64List(int length) { - throw UnsupportedError("Uint64List not supported on the web."); - } - - @patch - factory Uint64List.fromList(List elements) { - throw UnsupportedError("Uint64List not supported on the web."); - } -} - -@patch -class Int32x4List { - @patch - factory Int32x4List(int length) = NativeInt32x4List; - - @patch - factory Int32x4List.fromList(List elements) = - NativeInt32x4List.fromList; -} - -@patch -class Float32x4List { - @patch - factory Float32x4List(int length) = NativeFloat32x4List; - - @patch - factory Float32x4List.fromList(List elements) = - NativeFloat32x4List.fromList; -} - -@patch -class Float64x2List { - @patch - factory Float64x2List(int length) = NativeFloat64x2List; - - @patch - factory Float64x2List.fromList(List elements) = - NativeFloat64x2List.fromList; -} - -@patch -class Float32x4 { - @patch - factory Float32x4(double x, double y, double z, double w) = NativeFloat32x4; - @patch - factory Float32x4.splat(double v) = NativeFloat32x4.splat; - @patch - factory Float32x4.zero() = NativeFloat32x4.zero; - @patch - factory Float32x4.fromInt32x4Bits(Int32x4 x) = - NativeFloat32x4.fromInt32x4Bits; - @patch - factory Float32x4.fromFloat64x2(Float64x2 v) = NativeFloat32x4.fromFloat64x2; -} - -@patch -class Int32x4 { - @patch - factory Int32x4(int x, int y, int z, int w) = NativeInt32x4; - @patch - factory Int32x4.bool(bool x, bool y, bool z, bool w) = NativeInt32x4.bool; - @patch - factory Int32x4.fromFloat32x4Bits(Float32x4 x) = - NativeInt32x4.fromFloat32x4Bits; -} - -@patch -class Float64x2 { - @patch - factory Float64x2(double x, double y) = NativeFloat64x2; - @patch - factory Float64x2.splat(double v) = NativeFloat64x2.splat; - @patch - factory Float64x2.zero() = NativeFloat64x2.zero; - @patch - factory Float64x2.fromFloat32x4(Float32x4 v) = NativeFloat64x2.fromFloat32x4; -} diff --git a/sdk_nnbd/lib/_internal/js_runtime/pubspec.yaml b/sdk_nnbd/lib/_internal/js_runtime/pubspec.yaml deleted file mode 100644 index 821aaacda74..00000000000 --- a/sdk_nnbd/lib/_internal/js_runtime/pubspec.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# Note: This package is not meant to be uploaded to pub. This file is used to -# make it easier to develop on dart2js. -name: js_runtime -publish_to: none -environment: - sdk: '>=2.0.0 <3.0.0' diff --git a/sdk_nnbd/lib/_internal/sdk_library_metadata/lib/libraries.dart b/sdk_nnbd/lib/_internal/sdk_library_metadata/lib/libraries.dart deleted file mode 100644 index ab7da7eba9d..00000000000 --- a/sdk_nnbd/lib/_internal/sdk_library_metadata/lib/libraries.dart +++ /dev/null @@ -1,331 +0,0 @@ -// Copyright (c) 2012, 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.5 - -library libraries; - -/** - * A bit flag used by [LibraryInfo] indicating that a library is used by dart2js - */ -const int DART2JS_PLATFORM = 1; - -/** - * A bit flag used by [LibraryInfo] indicating that a library is used by the VM - */ -const int VM_PLATFORM = 2; - -/// The contexts that a library can be used from. -enum Category { - /// Indicates that a library can be used in a browser context. - client, - - /// Indicates that a library can be used in a command line context. - server, - - /// Indicates that a library can be used from embedded devices. - embedded -} - -Category parseCategory(String name) { - switch (name) { - case "Client": - return Category.client; - case "Server": - return Category.server; - case "Embedded": - return Category.embedded; - } - return null; -} - -/// Mapping of "dart:" library name (e.g. "core") to information about that -/// library. -const Map libraries = const { - "async": const LibraryInfo("async/async.dart", - categories: "Client,Server", - maturity: Maturity.STABLE, - dart2jsPatchPath: "_internal/js_runtime/lib/async_patch.dart"), - "collection": const LibraryInfo("collection/collection.dart", - categories: "Client,Server,Embedded", - maturity: Maturity.STABLE, - dart2jsPatchPath: "_internal/js_runtime/lib/collection_patch.dart"), - "convert": const LibraryInfo("convert/convert.dart", - categories: "Client,Server", - maturity: Maturity.STABLE, - dart2jsPatchPath: "_internal/js_runtime/lib/convert_patch.dart"), - "core": const LibraryInfo("core/core.dart", - categories: "Client,Server,Embedded", - maturity: Maturity.STABLE, - dart2jsPatchPath: "_internal/js_runtime/lib/core_patch.dart"), - "developer": const LibraryInfo("developer/developer.dart", - categories: "Client,Server,Embedded", - maturity: Maturity.UNSTABLE, - dart2jsPatchPath: "_internal/js_runtime/lib/developer_patch.dart"), - "ffi": const LibraryInfo("ffi/ffi.dart", - categories: "Server", - // TODO(dacoharkes): Update maturity when we release dart:ffi. - // https://github.com/dart-lang/sdk/issues/34452 - maturity: Maturity.EXPERIMENTAL), - "html": const LibraryInfo("html/dart2js/html_dart2js.dart", - categories: "Client", - maturity: Maturity.WEB_STABLE, - platforms: DART2JS_PLATFORM), - "html_common": const LibraryInfo("html/html_common/html_common.dart", - categories: "Client", - maturity: Maturity.WEB_STABLE, - dart2jsPath: "html/html_common/html_common_dart2js.dart", - documented: false, - implementation: true), - "indexed_db": const LibraryInfo("indexed_db/dart2js/indexed_db_dart2js.dart", - categories: "Client", - maturity: Maturity.WEB_STABLE, - platforms: DART2JS_PLATFORM), - "_http": - const LibraryInfo("_http/http.dart", categories: "", documented: false), - "io": const LibraryInfo("io/io.dart", - categories: "Server", - dart2jsPatchPath: "_internal/js_runtime/lib/io_patch.dart"), - "isolate": const LibraryInfo("isolate/isolate.dart", - categories: "Client,Server", - maturity: Maturity.STABLE, - dart2jsPatchPath: "_internal/js_runtime/lib/isolate_patch.dart"), - "js": const LibraryInfo("js/js.dart", - categories: "Client", - maturity: Maturity.STABLE, - platforms: DART2JS_PLATFORM, - dart2jsPatchPath: "_internal/js_runtime/lib/js_patch.dart"), - "_js": const LibraryInfo("js/_js.dart", - categories: "Client", - dart2jsPatchPath: "js/_js_client.dart", - documented: false, - platforms: DART2JS_PLATFORM), - "js_util": const LibraryInfo("js_util/js_util.dart", - categories: "Client", - maturity: Maturity.STABLE, - platforms: DART2JS_PLATFORM), - "math": const LibraryInfo("math/math.dart", - categories: "Client,Server,Embedded", - maturity: Maturity.STABLE, - dart2jsPatchPath: "_internal/js_runtime/lib/math_patch.dart"), - "mirrors": const LibraryInfo("mirrors/mirrors.dart", - categories: "Client,Server", - maturity: Maturity.UNSTABLE, - dart2jsPatchPath: "_internal/js_runtime/lib/mirrors_patch_cfe.dart"), - "nativewrappers": const LibraryInfo("html/dartium/nativewrappers.dart", - categories: "Client", - implementation: true, - documented: false, - platforms: VM_PLATFORM), - "typed_data": const LibraryInfo("typed_data/typed_data.dart", - categories: "Client,Server,Embedded", - maturity: Maturity.STABLE, - dart2jsPatchPath: "_internal/js_runtime/lib/typed_data_patch.dart"), - "_native_typed_data": const LibraryInfo( - "_internal/js_runtime/lib/native_typed_data.dart", - categories: "", - implementation: true, - documented: false, - platforms: DART2JS_PLATFORM), - "cli": const LibraryInfo("cli/cli.dart", - categories: "Server", platforms: VM_PLATFORM), - "svg": const LibraryInfo("svg/dart2js/svg_dart2js.dart", - categories: "Client", - maturity: Maturity.WEB_STABLE, - platforms: DART2JS_PLATFORM), - "wasm": const LibraryInfo("wasm/wasm.dart", - categories: "Server", maturity: Maturity.EXPERIMENTAL), - "web_audio": const LibraryInfo("web_audio/dart2js/web_audio_dart2js.dart", - categories: "Client", - maturity: Maturity.WEB_STABLE, - platforms: DART2JS_PLATFORM), - "web_gl": const LibraryInfo("web_gl/dart2js/web_gl_dart2js.dart", - categories: "Client", - maturity: Maturity.WEB_STABLE, - platforms: DART2JS_PLATFORM), - "web_sql": const LibraryInfo("web_sql/dart2js/web_sql_dart2js.dart", - categories: "Client", - maturity: Maturity.WEB_STABLE, - platforms: DART2JS_PLATFORM), - "_internal": const LibraryInfo("internal/internal.dart", - categories: "", - documented: false, - dart2jsPatchPath: "_internal/js_runtime/lib/internal_patch.dart"), - "_js_helper": const LibraryInfo("_internal/js_runtime/lib/js_helper.dart", - categories: "", documented: false, platforms: DART2JS_PLATFORM), - "_rti": const LibraryInfo("_internal/js_runtime/lib/rti.dart", - categories: "", documented: false, platforms: DART2JS_PLATFORM), - "_interceptors": const LibraryInfo( - "_internal/js_runtime/lib/interceptors.dart", - categories: "", - documented: false, - platforms: DART2JS_PLATFORM), - "_foreign_helper": const LibraryInfo( - "_internal/js_runtime/lib/foreign_helper.dart", - categories: "", - documented: false, - platforms: DART2JS_PLATFORM), - "_js_names": const LibraryInfo("_internal/js_runtime/lib/js_names.dart", - categories: "", documented: false, platforms: DART2JS_PLATFORM), - "_js_primitives": const LibraryInfo( - "_internal/js_runtime/lib/js_primitives.dart", - categories: "", - documented: false, - platforms: DART2JS_PLATFORM), - "_js_embedded_names": const LibraryInfo( - "_internal/js_runtime/lib/shared/embedded_names.dart", - categories: "", - documented: false, - platforms: DART2JS_PLATFORM), - "_async_await_error_codes": const LibraryInfo( - "_internal/js_runtime/lib/shared/async_await_error_codes.dart", - categories: "", - documented: false, - platforms: DART2JS_PLATFORM), - "_recipe_syntax": const LibraryInfo( - "_internal/js_runtime/lib/shared/recipe_syntax.dart", - categories: "", - documented: false, - platforms: DART2JS_PLATFORM), - "_metadata": const LibraryInfo("html/html_common/metadata.dart", - categories: "", documented: false, platforms: DART2JS_PLATFORM), - "_js_annotations": const LibraryInfo("js/_js_annotations.dart", - categories: "", documented: false, platforms: DART2JS_PLATFORM), -}; - -/** - * Information about a "dart:" library. - */ -class LibraryInfo { - /** - * Path to the library's *.dart file relative to this file. - */ - final String path; - - /** - * The categories in which the library can be used encoded as a - * comma-separated String. - */ - final String _categories; - - /** - * Path to the dart2js library's *.dart file relative to this file - * or null if dart2js uses the common library path defined above. - * Access using the [#getDart2JsPath()] method. - */ - final String dart2jsPath; - - /** - * Path to the dart2js library's patch file relative to this file - * or null if no dart2js patch file associated with this library. - * Access using the [#getDart2JsPatchPath()] method. - */ - final String dart2jsPatchPath; - - /** - * True if this library is documented and should be shown to the user. - */ - final bool documented; - - /** - * Bit flags indicating which platforms consume this library. - * See [DART2JS_LIBRARY] and [VM_LIBRARY]. - */ - final int platforms; - - /** - * True if the library contains implementation details for another library. - * The implication is that these libraries are less commonly used - * and that tools like Dart Editor should not show these libraries - * in a list of all libraries unless the user specifically asks the tool to - * do so. - */ - final bool implementation; - - /** - * States the current maturity of this library. - */ - final Maturity maturity; - - const LibraryInfo(this.path, - {String categories: "", - this.dart2jsPath, - this.dart2jsPatchPath, - this.implementation: false, - this.documented: true, - this.maturity: Maturity.UNSPECIFIED, - this.platforms: DART2JS_PLATFORM | VM_PLATFORM}) - : _categories = categories; - - bool get isDart2jsLibrary => (platforms & DART2JS_PLATFORM) != 0; - bool get isVmLibrary => (platforms & VM_PLATFORM) != 0; - - /** - * The categories in which the library can be used. - * - * If no categories are specified, the library is internal and can not be - * loaded by user code. - */ - List get categories { - // `"".split(,)` returns [""] not [], so we handle that case separately. - if (_categories == "") return const []; - return _categories.split(",").map(parseCategory).toList(); - } - - bool get isInternal => categories.isEmpty; - - /// The original "categories" String that was passed to the constructor. - /// - /// Can be used to construct a slightly modified copy of this LibraryInfo. - String get categoriesString { - return _categories; - } -} - -/** - * Abstraction to capture the maturity of a library. - */ -class Maturity { - final int level; - final String name; - final String description; - - const Maturity(this.level, this.name, this.description); - - String toString() => "$name: $level\n$description\n"; - - static const Maturity DEPRECATED = const Maturity(0, "Deprecated", - "This library will be remove before next major release."); - - static const Maturity EXPERIMENTAL = const Maturity( - 1, - "Experimental", - "This library is experimental and will likely change or be removed\n" - "in future versions."); - - static const Maturity UNSTABLE = const Maturity( - 2, - "Unstable", - "This library is in still changing and have not yet endured\n" - "sufficient real-world testing.\n" - "Backwards-compatibility is NOT guaranteed."); - - static const Maturity WEB_STABLE = const Maturity( - 3, - "Web Stable", - "This library is tracking the DOM evolution as defined by WC3.\n" - "Backwards-compatibility is NOT guaranteed."); - - static const Maturity STABLE = const Maturity( - 4, - "Stable", - "The library is stable. API backwards-compatibility is guaranteed.\n" - "However implementation details might change."); - - static const Maturity LOCKED = const Maturity(5, "Locked", - "This library will not change except when serious bugs are encountered."); - - static const Maturity UNSPECIFIED = const Maturity(-1, "Unspecified", - "The maturity for this library has not been specified."); -} diff --git a/sdk_nnbd/lib/_internal/sdk_library_metadata/pubspec.yaml b/sdk_nnbd/lib/_internal/sdk_library_metadata/pubspec.yaml deleted file mode 100644 index 08b5518b032..00000000000 --- a/sdk_nnbd/lib/_internal/sdk_library_metadata/pubspec.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# Note: This package is not meant to be uploaded to pub. This file is used to -# make it easer to depend on libraries.dart from sdk packages like dart2js. -name: sdk_library_metadata -publish_to: none -environment: - sdk: '>=2.0.0 <3.0.0' diff --git a/sdk_nnbd/lib/_internal/vm/bin/builtin.dart b/sdk_nnbd/lib/_internal/vm/bin/builtin.dart deleted file mode 100644 index 8dcbadf4e7f..00000000000 --- a/sdk_nnbd/lib/_internal/vm/bin/builtin.dart +++ /dev/null @@ -1,601 +0,0 @@ -// Copyright (c) 2012, 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 builtin; - -// NOTE: Do not import 'dart:io' in builtin. -import 'dart:async'; -import 'dart:collection' hide LinkedList, LinkedListEntry; -import 'dart:_internal' hide Symbol; -import 'dart:io'; -import 'dart:convert'; -import 'dart:isolate'; -import 'dart:typed_data'; - -// Embedder sets this to true if the --trace-loading flag was passed on the -// command line. -bool _traceLoading = false; - -// 'print' implementation. -// The standalone embedder registers the closurized _print function with the -// dart:core library. -void _printString(String s) native "Builtin_PrintString"; - -void _print(arg) { - _printString(arg.toString()); -} - -@pragma("vm:entry-point") -_getPrintClosure() => _print; - -// The current working directory when the embedder was launched. -late Uri _workingDirectory; - -// The URI that the root script was loaded from. Remembered so that -// package imports can be resolved relative to it. The root script is the basis -// for the root library in the VM. -Uri? _rootScript; - -// packagesConfig specified for the isolate. -Uri? _packagesConfigUri; - -// Packages are either resolved looking up in a map or resolved from within a -// package root. -bool get _packagesReady => (_packageMap != null) || (_packageError != null); - -// Error string set if there was an error resolving package configuration. -// For example not finding a .packages file or packages/ directory, malformed -// .packages file or any other related error. -String? _packageError = null; - -// The map describing how certain package names are mapped to Uris. -Uri? _packageConfig = null; -Map? _packageMap = null; - -// Special handling for Windows paths so that they are compatible with URI -// handling. -// Embedder sets this to true if we are running on Windows. -@pragma("vm:entry-point") -bool _isWindows = false; - -// Logging from builtin.dart is prefixed with a '*'. -String _logId = (Isolate.current.hashCode % 0x100000).toRadixString(16); -_log(msg) { - _print("* $_logId $msg"); -} - -_sanitizeWindowsPath(path) { - // For Windows we need to massage the paths a bit according to - // http://blogs.msdn.com/b/ie/archive/2006/12/06/file-uris-in-windows.aspx - // - // Convert - // C:\one\two\three - // to - // /C:/one/two/three - - if (_isWindows == false) { - // Do nothing when not running Windows. - return path; - } - - var fixedPath = "${path.replaceAll('\\', '/')}"; - - if ((path.length > 2) && (path[1] == ':')) { - // Path begins with a drive letter. - return '/$fixedPath'; - } - - return fixedPath; -} - -// Given a uri with a 'package' scheme, return a Uri that is prefixed with -// the package root or resolved relative to the package configuration. -Uri _resolvePackageUri(Uri uri) { - assert(uri.scheme == "package"); - assert(_packagesReady); - - if (uri.host.isNotEmpty) { - var path = '${uri.host}${uri.path}'; - var right = 'package:$path'; - var wrong = 'package://$path'; - - throw "URIs using the 'package:' scheme should look like " - "'$right', not '$wrong'."; - } - - var packageNameEnd = uri.path.indexOf('/'); - if (packageNameEnd == 0) { - // Package URIs must have a non-empty package name (not start with "/"). - throw "URIS using the 'package:' scheme should look like " - "'package:packageName${uri.path}', not 'package:${uri.path}'"; - } - if (_traceLoading) { - _log('Resolving package with uri path: ${uri.path}'); - } - var resolvedUri; - final error = _packageError; - if (error != null) { - if (_traceLoading) { - _log("Resolving package with pending resolution error: $error"); - } - throw error; - } else { - if (packageNameEnd < 0) { - // Package URIs must have a path after the package name, even if it's - // just "/". - throw "URIS using the 'package:' scheme should look like " - "'package:${uri.path}/', not 'package:${uri.path}'"; - } - var packageName = uri.path.substring(0, packageNameEnd); - final mapping = _packageMap![packageName]; - if (_traceLoading) { - _log("Mapped '$packageName' package to '$mapping'"); - } - if (mapping == null) { - throw "No mapping for '$packageName' package when resolving '$uri'."; - } - var path; - assert(uri.path.length > packageName.length); - path = uri.path.substring(packageName.length + 1); - if (_traceLoading) { - _log("Path to be resolved in package: $path"); - } - resolvedUri = mapping.resolve(path); - } - if (_traceLoading) { - _log("Resolved '$uri' to '$resolvedUri'."); - } - return resolvedUri; -} - -void _requestPackagesMap(Uri? packageConfig) { - dynamic msg = null; - if (packageConfig != null) { - // Explicitly specified .packages path. - msg = _handlePackagesRequest(_traceLoading, -2, packageConfig); - } else { - // Search for .packages starting at the root script. - msg = _handlePackagesRequest(_traceLoading, -1, _rootScript!); - } - if (_traceLoading) { - _log("Requested packages map for '$_rootScript'."); - } - if (msg is String) { - if (_traceLoading) { - _log("Got failure response on package port: '$msg'"); - } - // Remember the error message. - _packageError = msg; - } else if (msg is List) { - // First entry contains the location of the loaded .packages file. - assert((msg.length % 2) == 0); - assert(msg.length >= 2); - assert(msg[1] == null); - _packageConfig = Uri.parse(msg[0]); - final pmap = new Map(); - _packageMap = pmap; - for (var i = 2; i < msg.length; i += 2) { - // TODO(iposva): Complain about duplicate entries. - pmap[msg[i]] = Uri.parse(msg[i + 1]); - } - if (_traceLoading) { - _log("Setup package map: $_packageMap"); - } - } else { - _packageError = "Bad type of packages reply: ${msg.runtimeType}"; - if (_traceLoading) { - _log(_packageError); - } - } -} - -// The values go from ' ' to DEL and `x` means disallowed. -const String _invalidPackageNameChars = - 'x.xx.x.........x..........x.x.xx...........................xxxx.x..........................xxx.x'; - -bool _isValidPackageName(String packageName) { - const space = 0x20; - const del = 0x7F; - const dot = 0x2e; - const lowerX = 0x78; - for (int i = 0; i < packageName.length; ++i) { - final int char = packageName.codeUnitAt(i); - if (char < space || del < char) { - return false; - } - final int allowed = _invalidPackageNameChars.codeUnitAt(char - space); - assert(allowed == dot || allowed == lowerX); - if (allowed == lowerX) { - return false; - } - } - return true; -} - -_parsePackagesFile(bool traceLoading, Uri packagesFile, String data) { - // The first entry contains the location of the identified .packages file - // instead of a mapping. - final List result = [packagesFile.toString(), null]; - - final lines = LineSplitter.split(data); - for (String line in lines) { - final hashIndex = line.indexOf('#'); - if (hashIndex == 0) { - continue; - } - if (hashIndex > 0) { - line = line.substring(0, hashIndex); - } - line = line.trimRight(); - if (line.isEmpty) { - continue; - } - - final colonIndex = line.indexOf(':'); - if (colonIndex <= 0) { - return 'Line in "$packagesFile" should be of the format ' - '`:" but was: "$line"'; - } - final packageName = line.substring(0, colonIndex); - if (!_isValidPackageName(packageName)) { - return 'Package name in $packagesFile contains disallowed characters (' - 'was: "$packageName")'; - } - - String packageUri = line.substring(colonIndex + 1); - if (traceLoading) { - _log("packageName: $packageName"); - _log("packageUri: $packageUri"); - } - // Ensure the package uri ends with a /. - if (!packageUri.endsWith('/')) { - packageUri += '/'; - } - final resolvedPackageUri = packagesFile.resolve(packageUri).toString(); - if (traceLoading) { - _log("mapping: $packageName -> $resolvedPackageUri"); - } - result.add(packageName); - result.add(resolvedPackageUri); - } - if (traceLoading) { - _log("Parsed packages file at $packagesFile. Sending:\n$result"); - } - return result; -} - -// The .dart_tool/package_config.json format is described in -// -// https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/package-config-file-v2.md -// -// The returned list has the format: -// -// [0] Location of package_config.json file. -// [1] null -// [n*2] Name of n-th package -// [n*2 + 1] Location of n-th package's sources (as a String) -// -List _parsePackageConfig(bool traceLoading, Uri packageConfig, String data) { - final Map packageJson = json.decode(data); - final version = packageJson['configVersion']; - if (version != 2) { - throw 'The package configuration file has an unsupported version.'; - } - // The first entry contains the location of the identified - // .dart_tool/package_config.json file instead of a mapping. - final result = [packageConfig.toString(), null]; - final List packages = packageJson['packages'] ?? []; - for (final Map package in packages) { - String rootUri = package['rootUri']; - if (!rootUri.endsWith('/')) rootUri += '/'; - final String packageName = package['name']; - final String? packageUri = package['packageUri']; - final Uri resolvedRootUri = packageConfig.resolve(rootUri); - final Uri resolvedPackageUri = packageUri != null - ? resolvedRootUri.resolve(packageUri) - : resolvedRootUri; - if (packageUri != null && - !'$resolvedPackageUri'.contains('$resolvedRootUri')) { - throw 'The resolved "packageUri" is not a subdirectory of the "rootUri".'; - } - if (!_isValidPackageName(packageName)) { - throw 'Package name in $packageConfig contains disallowed characters (' - 'was: "$packageName")'; - } - result.add(packageName); - result.add(resolvedPackageUri.toString()); - if (traceLoading) { - _log('Resolved package "$packageName" to be at $resolvedPackageUri'); - } - } - return result; -} - -_findPackagesConfiguration(bool traceLoading, Uri base) { - try { - // Walk up the directory hierarchy to check for the existence of either one - // of - // - .packages (preferred) - // - .dart_tool/package_config.json - var currentDir = new File.fromUri(base).parent; - while (true) { - final dirUri = currentDir.uri; - - // We prefer using `.dart_tool/package_config.json` over `.packages`. - final packageConfig = dirUri.resolve(".dart_tool/package_config.json"); - if (traceLoading) { - _log("Checking for $packageConfig file."); - } - File file = File.fromUri(packageConfig); - bool exists = file.existsSync(); - if (traceLoading) { - _log("$packageConfig exists: $exists"); - } - if (exists) { - final data = utf8.decode(file.readAsBytesSync()); - if (traceLoading) { - _log("Loaded package config file from $packageConfig:$data\n"); - } - return _parsePackageConfig(traceLoading, packageConfig, data); - } - - // We fallback to using `.packages` if it exists. - final packagesFile = dirUri.resolve(".packages"); - if (traceLoading) { - _log("Checking for $packagesFile file."); - } - file = File.fromUri(packagesFile); - exists = file.existsSync(); - if (traceLoading) { - _log("$packagesFile exists: $exists"); - } - if (exists) { - final String data = utf8.decode(file.readAsBytesSync()); - if (traceLoading) { - _log("Loaded packages file from $packagesFile:\n$data"); - } - return _parsePackagesFile(traceLoading, packagesFile, data); - } - - final parentDir = currentDir.parent; - if (dirUri == parentDir.uri) break; - currentDir = parentDir; - } - - if (traceLoading) { - _log("Could not resolve a package configuration from $base"); - } - return "Could not resolve a package configuration for base at $base"; - } catch (e, s) { - if (traceLoading) { - _log("Error loading packages: $e\n$s"); - } - return "Uncaught error ($e) loading packages file."; - } -} - -int _indexOfFirstNonWhitespaceCharacter(String data) { - // Whitespace characters ignored in JSON spec: - // https://tools.ietf.org/html/rfc7159 - const tab = 0x09; - const lf = 0x0A; - const cr = 0x0D; - const space = 0x20; - - int index = 0; - while (index < data.length) { - final int char = data.codeUnitAt(index); - if (char != lf && char != cr && char != space && char != tab) { - break; - } - index++; - } - return index; -} - -bool _canBeValidJson(String data) { - const int openCurly = 0x7B; - final int index = _indexOfFirstNonWhitespaceCharacter(data); - return index < data.length && data.codeUnitAt(index) == openCurly; -} - -_parsePackageConfiguration(bool traceLoading, Uri resource, Uint8List bytes) { - try { - final data = utf8.decode(bytes); - if (_canBeValidJson(data)) { - return _parsePackageConfig(traceLoading, resource, data); - } else { - return _parsePackagesFile(traceLoading, resource, data); - } - } catch (e) { - return "The resource '$resource' is neither a valid '.packages' file nor " - "a valid '.dart_tool/package_config.json' file."; - } -} - -bool _isValidUtf8DataUrl(UriData data) { - final mime = data.mimeType; - if (mime != "text/plain") { - return false; - } - final charset = data.charset; - if (charset != "utf-8" && charset != "US-ASCII") { - return false; - } - return true; -} - -_handlePackagesRequest(bool traceLoading, int tag, Uri resource) { - try { - if (tag == -1) { - if (resource.scheme == '' || resource.scheme == 'file') { - return _findPackagesConfiguration(traceLoading, resource); - } else { - return "Unsupported scheme used to locate .packages file:'$resource'."; - } - } else if (tag == -2) { - if (traceLoading) { - _log("Handling load of packages map: '$resource'."); - } - late Uint8List bytes; - if (resource.scheme == '' || resource.scheme == 'file') { - final file = File.fromUri(resource); - if (!file.existsSync()) { - return "Packages file '$resource' does not exit."; - } - bytes = file.readAsBytesSync(); - } else if (resource.scheme == 'data') { - final uriData = resource.data!; - if (!_isValidUtf8DataUrl(uriData)) { - return "The data resource '$resource' must have a 'text/plain' mime " - "type and a 'utf-8' or 'US-ASCII' charset."; - } - bytes = uriData.contentAsBytes(); - } else { - return "Unknown scheme (${resource.scheme}) for package file at " - "'$resource'."; - } - return _parsePackageConfiguration(traceLoading, resource, bytes); - } else { - return "Unknown packages request tag: $tag for '$resource'."; - } - } catch (e, s) { - if (traceLoading) { - _log("Error handling packages request: $e\n$s"); - } - return "Uncaught error ($e) handling packages request."; - } -} - -// Embedder Entrypoint: -// The embedder calls this method to initial the package resolution state. -// Returns the resolved script URI after it resolves the script uri in the -// current working directory iff the given uri did not specify a scheme -// (e.g. a path to a script file on the command line). -@pragma("vm:entry-point") -String _Init( - String packagesConfig, String workingDirectory, String rootScript) { - if (_traceLoading) { - _log("_Init: $packagesConfig $workingDirectory $rootScript"); - } - - // Register callbacks and hooks with the rest of core libraries. - _setupHooks(); - - // _workingDirectory must be set first. - _workingDirectory = new Uri.directory(workingDirectory); - if (_traceLoading) { - _log('_Init (working directory): $_workingDirectory'); - } - - // setup _rootScript. - if (rootScript != null) { - _rootScript = _resolveScriptUri(rootScript); - assert(rootScript != null); - } - - // If the --packages flag was passed, setup _packagesConfig. - if (packagesConfig != null) { - _packageMap = null; - VMLibraryHooks.packageConfigString = _setPackagesConfig(packagesConfig); - } - - if (_traceLoading) { - _log("_Init returns: ${rootScript.toString()}"); - } - return _rootScript.toString(); -} - -// packagesParam is the value of the --packages command line option. -// It can point to a ".packages" or a ".dart_tool/package_config.json" -// file. -String _setPackagesConfig(String packagesParam) { - // First convert the packages parameter from the command line to a URI which - // can be handled by the loader code. - // TODO(iposva): Consider refactoring the common code below which is almost - // shared with resolution of the root script. - if (_traceLoading) { - _log("Resolving packages config: $packagesParam"); - } - var packagesName = _sanitizeWindowsPath(packagesParam); - var packagesUri = Uri.parse(packagesName); - if (packagesUri.scheme == '') { - // Script does not have a scheme, assume that it is a path, - // resolve it against the working directory. - packagesUri = _workingDirectory.resolveUri(packagesUri); - } - _packagesConfigUri = packagesUri; - if (_traceLoading) { - _log('Resolved packages config to: $packagesUri'); - } - return packagesUri.toString(); -} - -// Resolves the script uri in the current working directory iff the given uri -// did not specify a scheme (e.g. a path to a script file on the command line). -Uri _resolveScriptUri(String scriptName) { - if (_traceLoading) { - _log("Resolving script: $scriptName"); - } - scriptName = _sanitizeWindowsPath(scriptName); - - var scriptUri = Uri.parse(scriptName); - if (scriptUri.scheme == '') { - // Script does not have a scheme, assume that it is a path, - // resolve it against the working directory. - scriptUri = _workingDirectory.resolveUri(scriptUri); - } - - if (_traceLoading) { - _log('Resolved entry point to: $_rootScript'); - } - return scriptUri; -} - -// Register callbacks and hooks with the rest of the core libraries. -@pragma("vm:entry-point") -_setupHooks() { - VMLibraryHooks.packageConfigUriFuture = _getPackageConfigFuture; - VMLibraryHooks.resolvePackageUriFuture = _resolvePackageUriFuture; -} - -Future _getPackageConfigFuture() { - if (_traceLoading) { - _log("Request for package config from user code."); - } - if (!_packagesReady) { - _requestPackagesMap(_packagesConfigUri); - } - // Respond with the packages config (if any) after package resolution. - return Future.value(_packageConfig); -} - -Future _resolvePackageUriFuture(Uri packageUri) { - if (_traceLoading) { - _log("Request for package Uri resolution from user code: $packageUri"); - } - if (packageUri.scheme != "package") { - if (_traceLoading) { - _log("Non-package Uri, returning unmodified: $packageUri"); - } - // Return the incoming parameter if not passed a package: URI. - return Future.value(packageUri); - } - if (!_packagesReady) { - _requestPackagesMap(_packagesConfigUri); - } - Uri? resolvedUri; - try { - resolvedUri = _resolvePackageUri(packageUri); - } catch (e, s) { - if (_traceLoading) { - _log("Exception when resolving package URI: $packageUri:\n$e\n$s"); - } - resolvedUri = null; - } - if (_traceLoading) { - _log("Resolved '$packageUri' to '$resolvedUri'"); - } - return Future.value(resolvedUri); -} diff --git a/sdk_nnbd/lib/_internal/vm/bin/cli_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/cli_patch.dart deleted file mode 100644 index 504a0dbdbe5..00000000000 --- a/sdk_nnbd/lib/_internal/vm/bin/cli_patch.dart +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2017, 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 "dart:_internal" show patch; - -@patch -void _waitForEvent(int timeoutMillis) native "CLI_WaitForEvent"; diff --git a/sdk_nnbd/lib/_internal/vm/bin/common_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/common_patch.dart deleted file mode 100644 index 9899f2e4a5a..00000000000 --- a/sdk_nnbd/lib/_internal/vm/bin/common_patch.dart +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) 2012, 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. - -/// Note: the VM concatenates all patch files into a single patch file. This -/// file is the first patch in "dart:io" which contains all the imports used by -/// patches of that library. We plan to change this when we have a shared front -/// end and simply use parts. - -import "dart:_internal" show VMLibraryHooks, patch, checkNotNullable, ClassID; - -import "dart:async" - show - Completer, - Future, - Stream, - StreamConsumer, - StreamController, - StreamSubscription, - Timer, - Zone, - scheduleMicrotask; - -import "dart:collection" show HashMap; - -import "dart:convert" show Encoding, utf8; - -import "dart:developer" show registerExtension; - -import "dart:isolate" show RawReceivePort, ReceivePort, SendPort; - -import "dart:math" show min; - -import "dart:nativewrappers" show NativeFieldWrapperClass1; - -import "dart:typed_data" show Uint8List; - -/// These are the additional parts of this patch library: -// part "directory_patch.dart"; -// part "eventhandler_patch.dart"; -// part "file_patch.dart"; -// part "file_system_entity_patch.dart"; -// part "filter_patch.dart"; -// part "io_service_patch.dart"; -// part "platform_patch.dart"; -// part "process_patch.dart"; -// part "socket_patch.dart"; -// part "stdio_patch.dart"; -// part "secure_socket_patch.dart"; -// part "sync_socket_patch.dart"; - -@patch -bool _isDirectIOCapableTypedList(List buffer) { - int classID = ClassID.getID(buffer); - return classID == ClassID.cidExternalInt8Array || - classID == ClassID.cidExternalUint8Array || - classID == ClassID.cidExternalUint8ClampedArray || - classID == ClassID.cidInt8Array || - classID == ClassID.cidInt8ArrayView || - classID == ClassID.cidUint8Array || - classID == ClassID.cidUint8ArrayView || - classID == ClassID.cidUint8ClampedArray; -} - -@patch -class _IOCrypto { - @patch - static Uint8List getRandomBytes(int count) native "Crypto_GetRandomBytes"; -} - -@pragma("vm:entry-point", "call") -_setupHooks() { - VMLibraryHooks.eventHandlerSendData = _EventHandler._sendData; - VMLibraryHooks.timerMillisecondClock = _EventHandler._timerMillisecondClock; -} diff --git a/sdk_nnbd/lib/_internal/vm/bin/directory_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/directory_patch.dart deleted file mode 100644 index 7549f72abb4..00000000000 --- a/sdk_nnbd/lib/_internal/vm/bin/directory_patch.dart +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (c) 2012, 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. - -// part of "common_patch.dart"; - -@patch -class _Directory { - @patch - static _current(_Namespace namespace) native "Directory_Current"; - @patch - static _setCurrent(_Namespace namespace, Uint8List rawPath) - native "Directory_SetCurrent"; - @patch - static _createTemp(_Namespace namespace, Uint8List rawPath) - native "Directory_CreateTemp"; - @patch - static String _systemTemp(_Namespace namespace) native "Directory_SystemTemp"; - @patch - static _exists(_Namespace namespace, Uint8List rawPath) - native "Directory_Exists"; - @patch - static _create(_Namespace namespace, Uint8List rawPath) - native "Directory_Create"; - @patch - static _deleteNative(_Namespace namespace, Uint8List rawPath, bool recursive) - native "Directory_Delete"; - @patch - static _rename(_Namespace namespace, Uint8List rawPath, String newPath) - native "Directory_Rename"; - @patch - static void _fillWithDirectoryListing( - _Namespace namespace, - List list, - Uint8List rawPath, - bool recursive, - bool followLinks) native "Directory_FillWithDirectoryListing"; -} - -@patch -class _AsyncDirectoryListerOps { - @patch - factory _AsyncDirectoryListerOps(int pointer) => - new _AsyncDirectoryListerOpsImpl(pointer); -} - -class _AsyncDirectoryListerOpsImpl extends NativeFieldWrapperClass1 - implements _AsyncDirectoryListerOps { - _AsyncDirectoryListerOpsImpl._(); - - factory _AsyncDirectoryListerOpsImpl(int pointer) => - new _AsyncDirectoryListerOpsImpl._().._setPointer(pointer); - - void _setPointer(int pointer) - native "Directory_SetAsyncDirectoryListerPointer"; - int getPointer() native "Directory_GetAsyncDirectoryListerPointer"; -} - -// Corelib 'Uri.base' implementation. -// Uri.base is susceptible to changes in the current working directory. -Uri _uriBaseClosure() { - var result = _Directory._current(_Namespace._namespace); - if (result is OSError) { - throw new FileSystemException( - "Getting current working directory failed", "", result); - } - return new Uri.directory(result); -} - -@pragma("vm:entry-point", "call") -_getUriBaseClosure() => _uriBaseClosure; diff --git a/sdk_nnbd/lib/_internal/vm/bin/eventhandler_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/eventhandler_patch.dart deleted file mode 100644 index 072d9958b2c..00000000000 --- a/sdk_nnbd/lib/_internal/vm/bin/eventhandler_patch.dart +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) 2012, 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. - -// part of "common_patch.dart"; - -@patch -class _EventHandler { - @patch - static void _sendData(Object? sender, SendPort sendPort, int data) - native "EventHandler_SendData"; - - static int _timerMillisecondClock() - native "EventHandler_TimerMillisecondClock"; -} diff --git a/sdk_nnbd/lib/_internal/vm/bin/file_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/file_patch.dart deleted file mode 100644 index 033abea6211..00000000000 --- a/sdk_nnbd/lib/_internal/vm/bin/file_patch.dart +++ /dev/null @@ -1,440 +0,0 @@ -// Copyright (c) 2012, 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. - -// part of "common_patch.dart"; - -@patch -class _File { - @patch - static _exists(_Namespace namespace, Uint8List rawPath) native "File_Exists"; - @patch - static _create(_Namespace namespace, Uint8List rawPath) native "File_Create"; - @patch - static _createLink(_Namespace namespace, Uint8List rawPath, String target) - native "File_CreateLink"; - @patch - static _linkTarget(_Namespace namespace, Uint8List rawPath) - native "File_LinkTarget"; - @patch - static _deleteNative(_Namespace namespace, Uint8List rawPath) - native "File_Delete"; - @patch - static _deleteLinkNative(_Namespace namespace, Uint8List rawPath) - native "File_DeleteLink"; - @patch - static _rename(_Namespace namespace, Uint8List oldPath, String newPath) - native "File_Rename"; - @patch - static _renameLink(_Namespace namespace, Uint8List oldPath, String newPath) - native "File_RenameLink"; - @patch - static _copy(_Namespace namespace, Uint8List oldPath, String newPath) - native "File_Copy"; - @patch - static _lengthFromPath(_Namespace namespace, Uint8List rawPath) - native "File_LengthFromPath"; - @patch - static _lastModified(_Namespace namespace, Uint8List rawPath) - native "File_LastModified"; - @patch - static _setLastModified(_Namespace namespace, Uint8List rawPath, int millis) - native "File_SetLastModified"; - @patch - static _lastAccessed(_Namespace namespace, Uint8List rawPath) - native "File_LastAccessed"; - @patch - static _setLastAccessed(_Namespace namespace, Uint8List rawPath, int millis) - native "File_SetLastAccessed"; - @patch - static _open(_Namespace namespace, Uint8List rawPath, int mode) - native "File_Open"; - @patch - static int _openStdio(int fd) native "File_OpenStdio"; -} - -@patch -class _RandomAccessFileOps { - @patch - factory _RandomAccessFileOps(int pointer) => - new _RandomAccessFileOpsImpl(pointer); -} - -@pragma("vm:entry-point") -class _RandomAccessFileOpsImpl extends NativeFieldWrapperClass1 - implements _RandomAccessFileOps { - _RandomAccessFileOpsImpl._(); - - factory _RandomAccessFileOpsImpl(int pointer) => - new _RandomAccessFileOpsImpl._().._setPointer(pointer); - - void _setPointer(int pointer) native "File_SetPointer"; - - int getPointer() native "File_GetPointer"; - int close() native "File_Close"; - readByte() native "File_ReadByte"; - read(int bytes) native "File_Read"; - readInto(List buffer, int start, int? end) native "File_ReadInto"; - writeByte(int value) native "File_WriteByte"; - writeFrom(List buffer, int start, int? end) native "File_WriteFrom"; - position() native "File_Position"; - setPosition(int position) native "File_SetPosition"; - truncate(int length) native "File_Truncate"; - length() native "File_Length"; - flush() native "File_Flush"; - lock(int lock, int start, int end) native "File_Lock"; -} - -class _WatcherPath { - final int pathId; - final String path; - final int events; - int count = 0; - _WatcherPath(this.pathId, this.path, this.events); -} - -@patch -abstract class _FileSystemWatcher { - void _pathWatchedEnd(); - - static int? _id; - static final Map _idMap = {}; - - final String _path; - final int _events; - final bool _recursive; - - _WatcherPath? _watcherPath; - - final StreamController _broadcastController = - new StreamController.broadcast(); - - @patch - static Stream _watch( - String path, int events, bool recursive) { - if (Platform.isLinux) { - return new _InotifyFileSystemWatcher(path, events, recursive)._stream; - } - if (Platform.isWindows) { - return new _Win32FileSystemWatcher(path, events, recursive)._stream; - } - if (Platform.isMacOS) { - return new _FSEventStreamFileSystemWatcher(path, events, recursive) - ._stream; - } - throw new FileSystemException( - "File system watching is not supported on this platform"); - } - - _FileSystemWatcher._(this._path, this._events, this._recursive) { - if (!isSupported) { - throw new FileSystemException( - "File system watching is not supported on this platform", _path); - } - _broadcastController - ..onListen = _listen - ..onCancel = _cancel; - } - - Stream get _stream => _broadcastController.stream; - - void _listen() { - if (_id == null) { - try { - _id = _initWatcher(); - _newWatcher(); - } on dynamic catch (e) { - _broadcastController.addError(new FileSystemException( - "Failed to initialize file system entity watcher", null, e)); - _broadcastController.close(); - return; - } - } - var pathId; - try { - pathId = - _watchPath(_id!, _Namespace._namespace, _path, _events, _recursive); - } on dynamic catch (e) { - _broadcastController - .addError(new FileSystemException("Failed to watch path", _path, e)); - _broadcastController.close(); - return; - } - if (!_idMap.containsKey(pathId)) { - _idMap[pathId] = new _WatcherPath(pathId, _path, _events); - } - _watcherPath = _idMap[pathId]; - _watcherPath!.count++; - _pathWatched().pipe(_broadcastController); - } - - void _cancel() { - final watcherPath = _watcherPath; - if (watcherPath != null) { - assert(watcherPath.count > 0); - watcherPath.count--; - if (watcherPath.count == 0) { - _unwatchPath(_id!, watcherPath.pathId); - _pathWatchedEnd(); - _idMap.remove(watcherPath.pathId); - } - _watcherPath = null; - } - final id = _id; - if (_idMap.isEmpty && id != null) { - _closeWatcher(id); - _doneWatcher(); - _id = null; - } - } - - // Called when (and after) a new watcher instance is created and available. - void _newWatcher() {} - // Called when a watcher is no longer needed. - void _doneWatcher() {} - // Called when a new path is being watched. - Stream _pathWatched(); - // Called when a path is no longer being watched. - void _donePathWatched() {} - - static _WatcherPath _pathFromPathId(int pathId) { - return _idMap[pathId]!; - } - - static Stream _listenOnSocket(int socketId, int id, int pathId) { - var native = new _NativeSocket.watch(socketId); - var socket = new _RawSocket(native); - return socket.expand((event) { - var stops = []; - var events = []; - var pair = {}; - if (event == RawSocketEvent.read) { - String getPath(event) { - var path = _pathFromPathId(event[4]).path; - if (event[2] != null && event[2].isNotEmpty) { - path += Platform.pathSeparator; - path += event[2]; - } - return path; - } - - bool getIsDir(event) { - if (Platform.isWindows) { - // Windows does not get 'isDir' as part of the event. - // Links should also be skipped. - return FileSystemEntity.isDirectorySync(getPath(event)) && - !FileSystemEntity.isLinkSync(getPath(event)); - } - return (event[0] & FileSystemEvent._isDir) != 0; - } - - void add(id, event) { - if ((event.type & _pathFromPathId(id).events) == 0) return; - events.add([id, event]); - } - - void rewriteMove(event, isDir) { - if (event[3]) { - add(event[4], new FileSystemCreateEvent._(getPath(event), isDir)); - } else { - add(event[4], new FileSystemDeleteEvent._(getPath(event), false)); - } - } - - int eventCount; - do { - eventCount = 0; - for (var event in _readEvents(id, pathId)) { - if (event == null) continue; - eventCount++; - int pathId = event[4]; - if (!_idMap.containsKey(pathId)) { - // Path is no longer being wathed. - continue; - } - bool isDir = getIsDir(event); - var path = getPath(event); - if ((event[0] & FileSystemEvent.create) != 0) { - add(event[4], new FileSystemCreateEvent._(path, isDir)); - } - if ((event[0] & FileSystemEvent.modify) != 0) { - add(event[4], new FileSystemModifyEvent._(path, isDir, true)); - } - if ((event[0] & FileSystemEvent._modifyAttributes) != 0) { - add(event[4], new FileSystemModifyEvent._(path, isDir, false)); - } - if ((event[0] & FileSystemEvent.move) != 0) { - int link = event[1]; - if (link > 0) { - pair.putIfAbsent(pathId, () => {}); - if (pair[pathId].containsKey(link)) { - add( - event[4], - new FileSystemMoveEvent._( - getPath(pair[pathId][link]), isDir, path)); - pair[pathId].remove(link); - } else { - pair[pathId][link] = event; - } - } else { - rewriteMove(event, isDir); - } - } - if ((event[0] & FileSystemEvent.delete) != 0) { - add(event[4], new FileSystemDeleteEvent._(path, false)); - } - if ((event[0] & FileSystemEvent._deleteSelf) != 0) { - add(event[4], new FileSystemDeleteEvent._(path, false)); - // Signal done event. - stops.add([event[4], null]); - } - } - } while (eventCount > 0); - // Be sure to clear this manually, as the sockets are not read through - // the _NativeSocket interface. - native.available = 0; - for (var map in pair.values) { - for (var event in map.values) { - rewriteMove(event, getIsDir(event)); - } - } - } else if (event == RawSocketEvent.closed) { - } else if (event == RawSocketEvent.readClosed) { - // If Directory watcher buffer overflows, it will send an readClosed event. - // Normal closing will cancel stream subscription so that path is - // no longer being watched, not present in _idMap. - if (_idMap.containsKey(pathId)) { - var path = _pathFromPathId(pathId).path; - _idMap.remove(pathId); - if (_idMap.isEmpty && _id != null) { - _closeWatcher(_id!); - _id = null; - } - throw FileSystemException( - 'Directory watcher closed unexpectedly', path); - } - } else { - assert(false); - } - events.addAll(stops); - return events; - }); - } - - @patch - static bool get isSupported native "FileSystemWatcher_IsSupported"; - - static int _initWatcher() native "FileSystemWatcher_InitWatcher"; - static void _closeWatcher(int id) native "FileSystemWatcher_CloseWatcher"; - - static int _watchPath(int id, _Namespace namespace, String path, int events, - bool recursive) native "FileSystemWatcher_WatchPath"; - static void _unwatchPath(int id, int path_id) - native "FileSystemWatcher_UnwatchPath"; - static List _readEvents(int id, int path_id) - native "FileSystemWatcher_ReadEvents"; - static int _getSocketId(int id, int path_id) - native "FileSystemWatcher_GetSocketId"; -} - -class _InotifyFileSystemWatcher extends _FileSystemWatcher { - static final Map _idMap = {}; - static late StreamSubscription _subscription; - - _InotifyFileSystemWatcher(path, events, recursive) - : super._(path, events, recursive); - - void _newWatcher() { - int id = _FileSystemWatcher._id!; - _subscription = - _FileSystemWatcher._listenOnSocket(id, id, 0).listen((event) { - if (_idMap.containsKey(event[0])) { - if (event[1] != null) { - _idMap[event[0]]!.add(event[1]); - } else { - _idMap[event[0]]!.close(); - } - } - }); - } - - void _doneWatcher() { - _subscription.cancel(); - } - - Stream _pathWatched() { - var pathId = _watcherPath!.pathId; - if (!_idMap.containsKey(pathId)) { - _idMap[pathId] = new StreamController.broadcast(); - } - return _idMap[pathId]!.stream; - } - - void _pathWatchedEnd() { - var pathId = _watcherPath!.pathId; - if (!_idMap.containsKey(pathId)) return; - _idMap[pathId]!.close(); - _idMap.remove(pathId); - } -} - -class _Win32FileSystemWatcher extends _FileSystemWatcher { - late StreamSubscription _subscription; - late StreamController _controller; - - _Win32FileSystemWatcher(path, events, recursive) - : super._(path, events, recursive); - - Stream _pathWatched() { - var pathId = _watcherPath!.pathId; - _controller = new StreamController(); - _subscription = - _FileSystemWatcher._listenOnSocket(pathId, 0, pathId).listen((event) { - assert(event[0] == pathId); - if (event[1] != null) { - _controller.add(event[1]); - } else { - _controller.close(); - } - }); - return _controller.stream; - } - - void _pathWatchedEnd() { - _subscription.cancel(); - _controller.close(); - } -} - -class _FSEventStreamFileSystemWatcher extends _FileSystemWatcher { - late StreamSubscription _subscription; - late StreamController _controller; - - _FSEventStreamFileSystemWatcher(path, events, recursive) - : super._(path, events, recursive); - - Stream _pathWatched() { - var pathId = _watcherPath!.pathId; - var socketId = _FileSystemWatcher._getSocketId(0, pathId); - _controller = new StreamController(); - _subscription = - _FileSystemWatcher._listenOnSocket(socketId, 0, pathId).listen((event) { - if (event[1] != null) { - _controller.add(event[1]); - } else { - _controller.close(); - } - }); - return _controller.stream; - } - - void _pathWatchedEnd() { - _subscription.cancel(); - _controller.close(); - } -} - -@pragma("vm:entry-point", "call") -Uint8List _makeUint8ListView(Uint8List source, int offsetInBytes, int length) { - return new Uint8List.view(source.buffer, offsetInBytes, length); -} diff --git a/sdk_nnbd/lib/_internal/vm/bin/file_system_entity_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/file_system_entity_patch.dart deleted file mode 100644 index 973e6b67579..00000000000 --- a/sdk_nnbd/lib/_internal/vm/bin/file_system_entity_patch.dart +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) 2013, 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. - -// part of "common_patch.dart"; - -@patch -class FileStat { - @patch - static _statSync(_Namespace namespace, String path) native "File_Stat"; -} - -@patch -class FileSystemEntity { - @patch - static _getTypeNative(_Namespace namespace, Uint8List rawPath, - bool followLinks) native "File_GetType"; - @patch - static _identicalNative(_Namespace namespace, String path1, String path2) - native "File_AreIdentical"; - @patch - static _resolveSymbolicLinks(_Namespace namespace, Uint8List path) - native "File_ResolveSymbolicLinks"; -} diff --git a/sdk_nnbd/lib/_internal/vm/bin/filter_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/filter_patch.dart deleted file mode 100644 index 06898f4851b..00000000000 --- a/sdk_nnbd/lib/_internal/vm/bin/filter_patch.dart +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) 2013, 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. - -// part of "common_patch.dart"; - -class _FilterImpl extends NativeFieldWrapperClass1 implements RawZLibFilter { - void process(List data, int start, int end) native "Filter_Process"; - - List? processed({bool flush: true, bool end: false}) - native "Filter_Processed"; -} - -class _ZLibInflateFilter extends _FilterImpl { - _ZLibInflateFilter(int windowBits, List? dictionary, bool raw) { - _init(windowBits, dictionary, raw); - } - void _init(int windowBits, List? dictionary, bool raw) - native "Filter_CreateZLibInflate"; -} - -class _ZLibDeflateFilter extends _FilterImpl { - _ZLibDeflateFilter(bool gzip, int level, int windowBits, int memLevel, - int strategy, List? dictionary, bool raw) { - _init(gzip, level, windowBits, memLevel, strategy, dictionary, raw); - } - void _init(bool gzip, int level, int windowBits, int memLevel, int strategy, - List? dictionary, bool raw) native "Filter_CreateZLibDeflate"; -} - -@patch -class RawZLibFilter { - @patch - static RawZLibFilter _makeZLibDeflateFilter( - bool gzip, - int level, - int windowBits, - int memLevel, - int strategy, - List? dictionary, - bool raw) => - new _ZLibDeflateFilter( - gzip, level, windowBits, memLevel, strategy, dictionary, raw); - @patch - static RawZLibFilter _makeZLibInflateFilter( - int windowBits, List? dictionary, bool raw) => - new _ZLibInflateFilter(windowBits, dictionary, raw); -} diff --git a/sdk_nnbd/lib/_internal/vm/bin/io_service_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/io_service_patch.dart deleted file mode 100644 index d54bbf2371a..00000000000 --- a/sdk_nnbd/lib/_internal/vm/bin/io_service_patch.dart +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright (c) 2013, 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. - -// part of "common_patch.dart"; - -class _IOServicePorts { - // We limit the number of IO Service ports per isolate so that we don't - // spawn too many threads all at once, which can crash the VM on Windows. - static const int maxPorts = 32; - List _ports = []; - List _freePorts = []; - Map _usedPorts = new HashMap(); - - _IOServicePorts(); - - SendPort _getPort(int forRequestId) { - if (_freePorts.isEmpty && _usedPorts.length < maxPorts) { - final SendPort port = _newServicePort(); - _ports.add(port); - _freePorts.add(port); - } - if (!_freePorts.isEmpty) { - final SendPort port = _freePorts.removeLast(); - assert(!_usedPorts.containsKey(forRequestId)); - _usedPorts[forRequestId] = port; - return port; - } - // We have already allocated the max number of ports. Re-use an - // existing one. - final SendPort port = _ports[forRequestId % maxPorts]; - _usedPorts[forRequestId] = port; - return port; - } - - void _returnPort(int forRequestId) { - final SendPort port = _usedPorts.remove(forRequestId)!; - if (!_usedPorts.values.contains(port)) { - _freePorts.add(port); - } - } - - static SendPort _newServicePort() native "IOService_NewServicePort"; -} - -@patch -class _IOService { - static _IOServicePorts _servicePorts = new _IOServicePorts(); - static RawReceivePort? _receivePort; - static late SendPort _replyToPort; - static HashMap _messageMap = new HashMap(); - static int _id = 0; - - @patch - static Future _dispatch(int request, List data) { - int id; - do { - id = _getNextId(); - } while (_messageMap.containsKey(id)); - final SendPort servicePort = _servicePorts._getPort(id); - _ensureInitialize(); - final Completer completer = new Completer(); - _messageMap[id] = completer; - try { - servicePort.send([id, _replyToPort, request, data]); - } catch (error) { - _messageMap.remove(id)!.complete(error); - if (_messageMap.length == 0) { - _finalize(); - } - } - return completer.future; - } - - static void _ensureInitialize() { - if (_receivePort == null) { - _receivePort = new RawReceivePort(); - _replyToPort = _receivePort!.sendPort; - _receivePort!.handler = (data) { - assert(data is List && data.length == 2); - _messageMap.remove(data[0])!.complete(data[1]); - _servicePorts._returnPort(data[0]); - if (_messageMap.length == 0) { - _finalize(); - } - }; - } - } - - static void _finalize() { - _id = 0; - _receivePort!.close(); - _receivePort = null; - } - - static int _getNextId() { - if (_id == 0x7FFFFFFF) _id = 0; - return _id++; - } -} diff --git a/sdk_nnbd/lib/_internal/vm/bin/namespace_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/namespace_patch.dart deleted file mode 100644 index 2cf329f2f43..00000000000 --- a/sdk_nnbd/lib/_internal/vm/bin/namespace_patch.dart +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) 2017, 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. - -@pragma("vm:entry-point") -class _NamespaceImpl extends NativeFieldWrapperClass1 implements _Namespace { - _NamespaceImpl._(); - - static _NamespaceImpl _create(_NamespaceImpl namespace, var n) - native "Namespace_Create"; - static int _getPointer(_NamespaceImpl namespace) - native "Namespace_GetPointer"; - static int _getDefault() native "Namespace_GetDefault"; - - // If the platform supports "namespaces", this method is called by the - // embedder with the platform-specific namespace information. - static _NamespaceImpl? _cachedNamespace = null; - static void _setupNamespace(var namespace) { - _cachedNamespace = _create(new _NamespaceImpl._(), namespace); - } - - static _NamespaceImpl get _namespace { - if (_cachedNamespace == null) { - // The embedder has not supplied a namespace before one is needed, so - // instead use a safe-ish default value. - _cachedNamespace = _create(new _NamespaceImpl._(), _getDefault()); - } - return _cachedNamespace!; - } - - static int get _namespacePointer => _getPointer(_namespace); -} - -@patch -@pragma("vm:entry-point") -class _Namespace { - @patch - @pragma("vm:entry-point", "call") - static void _setupNamespace(var namespace) { - _NamespaceImpl._setupNamespace(namespace); - } - - @patch - static _Namespace get _namespace => _NamespaceImpl._namespace; - - @patch - static int get _namespacePointer => _NamespaceImpl._namespacePointer; -} diff --git a/sdk_nnbd/lib/_internal/vm/bin/platform_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/platform_patch.dart deleted file mode 100644 index d187101b2ce..00000000000 --- a/sdk_nnbd/lib/_internal/vm/bin/platform_patch.dart +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) 2012, 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. - -// part of "common_patch.dart"; - -@patch -@pragma("vm:entry-point") -class _Platform { - @patch - static int _numberOfProcessors() native "Platform_NumberOfProcessors"; - @patch - static String _pathSeparator() native "Platform_PathSeparator"; - @patch - static String _operatingSystem() native "Platform_OperatingSystem"; - @patch - static _operatingSystemVersion() native "Platform_OperatingSystemVersion"; - @patch - static _localHostname() native "Platform_LocalHostname"; - @patch - static _executable() native "Platform_ExecutableName"; - @patch - static _resolvedExecutable() native "Platform_ResolvedExecutableName"; - @patch - static _environment() native "Platform_Environment"; - @patch - static List _executableArguments() - native "Platform_ExecutableArguments"; - @patch - static String _version() native "Platform_GetVersion"; - - @patch - static String _localeName() native "Platform_LocaleName"; - - @patch - static String? _packageRoot() => VMLibraryHooks.packageRootString; - @patch - static String? _packageConfig() => VMLibraryHooks.packageConfigString; - - @patch - static Uri _script() => VMLibraryHooks.platformScript; - - // This script singleton is written to by the embedder if applicable. - @pragma("vm:entry-point") - static void set _nativeScript(String path) { - VMLibraryHooks.platformScript = (() { - if (path.startsWith('http:') || - path.startsWith('https:') || - path.startsWith('package:') || - path.startsWith('dart:') || - path.startsWith('data:') || - path.startsWith('file:')) { - return Uri.parse(path); - } else { - return Uri.base.resolveUri(new Uri.file(path)); - } - }); - } -} diff --git a/sdk_nnbd/lib/_internal/vm/bin/process_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/process_patch.dart deleted file mode 100644 index bb86a0d9647..00000000000 --- a/sdk_nnbd/lib/_internal/vm/bin/process_patch.dart +++ /dev/null @@ -1,617 +0,0 @@ -// Copyright (c) 2013, 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. - -// part of "common_patch.dart"; - -@patch -class _WindowsCodePageDecoder { - @patch - static String _decodeBytes(List bytes) native "SystemEncodingToString"; -} - -@patch -class _WindowsCodePageEncoder { - @patch - static List _encodeString(String string) native "StringToSystemEncoding"; -} - -@patch -class Process { - @patch - static Future start(String executable, List arguments, - {String? workingDirectory, - Map? environment, - bool includeParentEnvironment: true, - bool runInShell: false, - ProcessStartMode mode: ProcessStartMode.normal}) { - _ProcessImpl process = new _ProcessImpl( - executable, - arguments, - workingDirectory, - environment, - includeParentEnvironment, - runInShell, - mode); - return process._start(); - } - - @patch - static Future run(String executable, List arguments, - {String? workingDirectory, - Map? environment, - bool includeParentEnvironment: true, - bool runInShell: false, - Encoding? stdoutEncoding: systemEncoding, - Encoding? stderrEncoding: systemEncoding}) { - return _runNonInteractiveProcess( - executable, - arguments, - workingDirectory, - environment, - includeParentEnvironment, - runInShell, - stdoutEncoding, - stderrEncoding); - } - - @patch - static ProcessResult runSync(String executable, List arguments, - {String? workingDirectory, - Map? environment, - bool includeParentEnvironment: true, - bool runInShell: false, - Encoding? stdoutEncoding: systemEncoding, - Encoding? stderrEncoding: systemEncoding}) { - return _runNonInteractiveProcessSync( - executable, - arguments, - workingDirectory, - environment, - includeParentEnvironment, - runInShell, - stdoutEncoding, - stderrEncoding); - } - - @patch - static bool killPid(int pid, [ProcessSignal signal = ProcessSignal.sigterm]) { - // TODO(40614): Remove once non-nullability is sound. - ArgumentError.checkNotNull(signal, "signal"); - return _ProcessUtils._killPid(pid, signal._signalNumber); - } -} - -List<_SignalController?> _signalControllers = new List.filled(32, null); - -class _SignalController { - final ProcessSignal signal; - - final _controller = new StreamController.broadcast(); - var _id; - - _SignalController(this.signal) { - _controller - ..onListen = _listen - ..onCancel = _cancel; - } - - Stream get stream => _controller.stream; - - void _listen() { - var id = _setSignalHandler(signal._signalNumber); - if (id is! int) { - _controller - .addError(new SignalException("Failed to listen for $signal", id)); - return; - } - _id = id; - var socket = new _RawSocket(new _NativeSocket.watchSignal(id)); - socket.listen((event) { - if (event == RawSocketEvent.read) { - var bytes = socket.read()!; - for (int i = 0; i < bytes.length; i++) { - _controller.add(signal); - } - } - }); - } - - void _cancel() { - if (_id != null) { - _clearSignalHandler(signal._signalNumber); - _id = null; - } - } - - static _setSignalHandler(int signal) native "Process_SetSignalHandler"; - static void _clearSignalHandler(int signal) - native "Process_ClearSignalHandler"; -} - -@pragma("vm:entry-point", "call") -Function _getWatchSignalInternal() => _ProcessUtils._watchSignalInternal; - -@patch -class _ProcessUtils { - @patch - static Never _exit(int status) native "Process_Exit"; - @patch - static void _setExitCode(int status) native "Process_SetExitCode"; - @patch - static int _getExitCode() native "Process_GetExitCode"; - @patch - static void _sleep(int millis) native "Process_Sleep"; - @patch - static int _pid(Process? process) native "Process_Pid"; - static bool _killPid(int pid, int signal) native "Process_KillPid"; - @patch - static Stream _watchSignal(ProcessSignal signal) { - if (signal != ProcessSignal.sighup && - signal != ProcessSignal.sigint && - signal != ProcessSignal.sigterm && - (Platform.isWindows || - (signal != ProcessSignal.sigusr1 && - signal != ProcessSignal.sigusr2 && - signal != ProcessSignal.sigwinch))) { - throw new SignalException( - "Listening for signal $signal is not supported"); - } - return _watchSignalInternal(signal); - } - - static Stream _watchSignalInternal(ProcessSignal signal) { - if (_signalControllers[signal._signalNumber] == null) { - _signalControllers[signal._signalNumber] = new _SignalController(signal); - } - return _signalControllers[signal._signalNumber]!.stream; - } -} - -@patch -class ProcessInfo { - @patch - static int get maxRss { - var result = _maxRss(); - if (result is OSError) { - throw result; - } - return result; - } - - @patch - static int get currentRss { - var result = _currentRss(); - if (result is OSError) { - throw result; - } - return result; - } - - static _maxRss() native "ProcessInfo_MaxRSS"; - static _currentRss() native "ProcessInfo_CurrentRSS"; -} - -@pragma("vm:entry-point") -class _ProcessStartStatus { - @pragma("vm:entry-point", "set") - int? _errorCode; // Set to OS error code if process start failed. - @pragma("vm:entry-point", "set") - String? _errorMessage; // Set to OS error message if process start failed. -} - -// The NativeFieldWrapperClass1 can not be used with a mixin, due to missing -// implicit constructor. -class _ProcessImplNativeWrapper extends NativeFieldWrapperClass1 {} - -class _ProcessImpl extends _ProcessImplNativeWrapper implements Process { - static bool connectedResourceHandler = false; - - _ProcessImpl( - String path, - List arguments, - this._workingDirectory, - Map? environment, - bool includeParentEnvironment, - bool runInShell, - this._mode) - : super() { - // TODO(40614): Remove once non-nullability is sound. - ArgumentError.checkNotNull(path, "path"); - ArgumentError.checkNotNull(arguments, "arguments"); - for (int i = 0; i < arguments.length; i++) { - ArgumentError.checkNotNull(arguments[i], "arguments[]"); - } - ArgumentError.checkNotNull(_mode, "mode"); - - if (!connectedResourceHandler) { - registerExtension( - 'ext.dart.io.getProcesses', _ProcessResourceInfo.getStartedProcesses); - registerExtension('ext.dart.io.getProcessById', - _ProcessResourceInfo.getProcessInfoMapById); - connectedResourceHandler = true; - } - - if (runInShell) { - arguments = _getShellArguments(path, arguments); - path = _getShellCommand(); - } - - if (Platform.isWindows && path.contains(' ') && !path.contains('"')) { - // Escape paths that may contain spaces - // Bug: https://github.com/dart-lang/sdk/issues/37751 - _path = '"$path"'; - } else { - _path = path; - } - - _arguments = [ - for (int i = 0; i < arguments.length; i++) - Platform.isWindows - ? _windowsArgumentEscape(arguments[i]) - : arguments[i], - ]; - - _environment = []; - // Ensure that we have a non-null environment. - environment ??= const {}; - environment.forEach((key, value) { - _environment.add('$key=$value'); - }); - if (includeParentEnvironment) { - Platform.environment.forEach((key, value) { - // Do not override keys already set as part of environment. - if (!environment!.containsKey(key)) { - _environment.add('$key=$value'); - } - }); - } - - if (_modeHasStdio(_mode)) { - // stdin going to process. - _stdin = new _StdSink(new _Socket._writePipe().._owner = this); - // stdout coming from process. - _stdout = new _StdStream(new _Socket._readPipe().._owner = this); - // stderr coming from process. - _stderr = new _StdStream(new _Socket._readPipe().._owner = this); - } - if (_modeIsAttached(_mode)) { - _exitHandler = new _Socket._readPipe(); - } - } - - _NativeSocket get _stdinNativeSocket => - (_stdin!._sink as _Socket)._nativeSocket; - _NativeSocket get _stdoutNativeSocket => - (_stdout!._stream as _Socket)._nativeSocket; - _NativeSocket get _stderrNativeSocket => - (_stderr!._stream as _Socket)._nativeSocket; - - static bool _modeIsAttached(ProcessStartMode mode) { - return (mode == ProcessStartMode.normal) || - (mode == ProcessStartMode.inheritStdio); - } - - static bool _modeHasStdio(ProcessStartMode mode) { - return (mode == ProcessStartMode.normal) || - (mode == ProcessStartMode.detachedWithStdio); - } - - static String _getShellCommand() { - if (Platform.isWindows) { - return 'cmd.exe'; - } - return '/bin/sh'; - } - - static List _getShellArguments( - String executable, List arguments) { - List shellArguments = []; - if (Platform.isWindows) { - shellArguments.add('/c'); - shellArguments.add(executable); - for (var arg in arguments) { - shellArguments.add(arg); - } - } else { - var commandLine = new StringBuffer(); - executable = executable.replaceAll("'", "'\"'\"'"); - commandLine.write("'$executable'"); - shellArguments.add("-c"); - for (var arg in arguments) { - arg = arg.replaceAll("'", "'\"'\"'"); - commandLine.write(" '$arg'"); - } - shellArguments.add(commandLine.toString()); - } - return shellArguments; - } - - String _windowsArgumentEscape(String argument) { - if (argument.isEmpty) { - return '""'; - } - var result = argument; - if (argument.contains('\t') || - argument.contains(' ') || - argument.contains('"')) { - // Produce something that the C runtime on Windows will parse - // back as this string. - - // Replace any number of '\' followed by '"' with - // twice as many '\' followed by '\"'. - var backslash = '\\'.codeUnitAt(0); - var sb = new StringBuffer(); - var nextPos = 0; - var quotePos = argument.indexOf('"', nextPos); - while (quotePos != -1) { - var numBackslash = 0; - var pos = quotePos - 1; - while (pos >= 0 && argument.codeUnitAt(pos) == backslash) { - numBackslash++; - pos--; - } - sb.write(argument.substring(nextPos, quotePos - numBackslash)); - for (var i = 0; i < numBackslash; i++) { - sb.write(r'\\'); - } - sb.write(r'\"'); - nextPos = quotePos + 1; - quotePos = argument.indexOf('"', nextPos); - } - sb.write(argument.substring(nextPos, argument.length)); - result = sb.toString(); - - // Add '"' at the beginning and end and replace all '\' at - // the end with two '\'. - sb = new StringBuffer('"'); - sb.write(result); - nextPos = argument.length - 1; - while (argument.codeUnitAt(nextPos) == backslash) { - sb.write('\\'); - nextPos--; - } - sb.write('"'); - result = sb.toString(); - } - - return result; - } - - int _intFromBytes(List bytes, int offset) { - return (bytes[offset] + - (bytes[offset + 1] << 8) + - (bytes[offset + 2] << 16) + - (bytes[offset + 3] << 24)); - } - - Future _start() { - var completer = new Completer(); - if (_modeIsAttached(_mode)) { - _exitCode = new Completer(); - } - // TODO(ager): Make the actual process starting really async instead of - // simulating it with a timer. - Timer.run(() { - var status = new _ProcessStartStatus(); - bool success = _startNative( - _Namespace._namespace, - _path, - _arguments, - _workingDirectory, - _environment, - _mode._mode, - _modeHasStdio(_mode) ? _stdinNativeSocket : null, - _modeHasStdio(_mode) ? _stdoutNativeSocket : null, - _modeHasStdio(_mode) ? _stderrNativeSocket : null, - _modeIsAttached(_mode) ? _exitHandler._nativeSocket : null, - status); - if (!success) { - completer.completeError(new ProcessException( - _path, _arguments, status._errorMessage!, status._errorCode!)); - return; - } - - _started = true; - final resourceInfo = new _ProcessResourceInfo(this); - - // Setup an exit handler to handle internal cleanup and possible - // callback when a process terminates. - if (_modeIsAttached(_mode)) { - int exitDataRead = 0; - final int EXIT_DATA_SIZE = 8; - List exitDataBuffer = new List.filled(EXIT_DATA_SIZE, 0); - _exitHandler.listen((data) { - int exitCode(List ints) { - var code = _intFromBytes(ints, 0); - var negative = _intFromBytes(ints, 4); - assert(negative == 0 || negative == 1); - return (negative == 0) ? code : -code; - } - - void handleExit() { - _ended = true; - _exitCode!.complete(exitCode(exitDataBuffer)); - // Kill stdin, helping hand if the user forgot to do it. - if (_modeHasStdio(_mode)) { - (_stdin!._sink as _Socket).destroy(); - } - resourceInfo.stopped(); - } - - exitDataBuffer.setRange( - exitDataRead, exitDataRead + data.length, data); - exitDataRead += data.length; - if (exitDataRead == EXIT_DATA_SIZE) { - handleExit(); - } - }); - } - - completer.complete(this); - }); - return completer.future; - } - - ProcessResult _runAndWait( - Encoding? stdoutEncoding, Encoding? stderrEncoding) { - var status = new _ProcessStartStatus(); - _exitCode = new Completer(); - bool success = _startNative( - _Namespace._namespace, - _path, - _arguments, - _workingDirectory, - _environment, - ProcessStartMode.normal._mode, - _stdinNativeSocket, - _stdoutNativeSocket, - _stderrNativeSocket, - _exitHandler._nativeSocket, - status); - if (!success) { - throw new ProcessException( - _path, _arguments, status._errorMessage!, status._errorCode!); - } - - final resourceInfo = new _ProcessResourceInfo(this); - - var result = _wait(_stdinNativeSocket, _stdoutNativeSocket, - _stderrNativeSocket, _exitHandler._nativeSocket); - - getOutput(output, encoding) { - if (encoding == null) return output; - return encoding.decode(output); - } - - resourceInfo.stopped(); - - return new ProcessResult( - result[0], - result[1], - getOutput(result[2], stdoutEncoding), - getOutput(result[3], stderrEncoding)); - } - - bool _startNative( - _Namespace namespace, - String path, - List arguments, - String? workingDirectory, - List environment, - int mode, - _NativeSocket? stdin, - _NativeSocket? stdout, - _NativeSocket? stderr, - _NativeSocket? exitHandler, - _ProcessStartStatus status) native "Process_Start"; - - _wait(_NativeSocket? stdin, _NativeSocket? stdout, _NativeSocket? stderr, - _NativeSocket exitHandler) native "Process_Wait"; - - Stream> get stdout => - _stdout ?? (throw StateError("stdio is not connected")); - - Stream> get stderr => - _stderr ?? (throw StateError("stdio is not connected")); - - IOSink get stdin => _stdin ?? (throw StateError("stdio is not connected")); - - Future get exitCode => - _exitCode?.future ?? (throw StateError("Process is detached")); - - bool kill([ProcessSignal signal = ProcessSignal.sigterm]) { - // TODO(40614): Remove once non-nullability is sound. - ArgumentError.checkNotNull(kill, "kill"); - assert(_started); - if (_ended) return false; - return _ProcessUtils._killPid(pid, signal._signalNumber); - } - - int get pid => _ProcessUtils._pid(this); - - late String _path; - late List _arguments; - String? _workingDirectory; - late List _environment; - final ProcessStartMode _mode; - // Private methods of Socket are used by _in, _out, and _err. - _StdSink? _stdin; - _StdStream? _stdout; - _StdStream? _stderr; - late _Socket _exitHandler; - bool _ended = false; - bool _started = false; - Completer? _exitCode; -} - -// _NonInteractiveProcess is a wrapper around an interactive process -// that buffers output so it can be delivered when the process exits. -// _NonInteractiveProcess is used to implement the Process.run -// method. -Future _runNonInteractiveProcess( - String path, - List arguments, - String? workingDirectory, - Map? environment, - bool includeParentEnvironment, - bool runInShell, - Encoding? stdoutEncoding, - Encoding? stderrEncoding) { - // Start the underlying process. - return Process.start(path, arguments, - workingDirectory: workingDirectory, - environment: environment, - includeParentEnvironment: includeParentEnvironment, - runInShell: runInShell) - .then((Process p) { - int pid = p.pid; - - // Make sure the process stdin is closed. - p.stdin.close(); - - // Setup stdout and stderr handling. - Future foldStream(Stream> stream, Encoding? encoding) { - if (encoding == null) { - return stream - .fold( - new BytesBuilder(), (builder, data) => builder..add(data)) - .then((builder) => builder.takeBytes()); - } else { - return stream - .transform(encoding.decoder) - .fold(new StringBuffer(), (buf, data) { - buf.write(data); - return buf; - }).then((sb) => sb.toString()); - } - } - - Future stdout = foldStream(p.stdout, stdoutEncoding); - Future stderr = foldStream(p.stderr, stderrEncoding); - - return Future.wait([p.exitCode, stdout, stderr]).then((result) { - return new ProcessResult(pid, result[0], result[1], result[2]); - }); - }); -} - -ProcessResult _runNonInteractiveProcessSync( - String executable, - List arguments, - String? workingDirectory, - Map? environment, - bool includeParentEnvironment, - bool runInShell, - Encoding? stdoutEncoding, - Encoding? stderrEncoding) { - var process = new _ProcessImpl( - executable, - arguments, - workingDirectory, - environment, - includeParentEnvironment, - runInShell, - ProcessStartMode.normal); - return process._runAndWait(stdoutEncoding, stderrEncoding); -} diff --git a/sdk_nnbd/lib/_internal/vm/bin/secure_socket_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/secure_socket_patch.dart deleted file mode 100644 index 9a0586d6d6c..00000000000 --- a/sdk_nnbd/lib/_internal/vm/bin/secure_socket_patch.dart +++ /dev/null @@ -1,233 +0,0 @@ -// Copyright (c) 2012, 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. - -// part of "common_patch.dart"; - -@patch -class SecureSocket { - @patch - factory SecureSocket._(RawSecureSocket rawSocket) => - new _SecureSocket(rawSocket); -} - -@patch -class _SecureFilter { - @patch - factory _SecureFilter._() => new _SecureFilterImpl._(); -} - -@patch -@pragma("vm:entry-point") -class X509Certificate { - @patch - @pragma("vm:entry-point") - factory X509Certificate._() => new _X509CertificateImpl._(); -} - -class _SecureSocket extends _Socket implements SecureSocket { - _RawSecureSocket? get _raw => super._raw as _RawSecureSocket?; - - _SecureSocket(RawSecureSocket raw) : super(raw); - - void renegotiate( - {bool useSessionCache: true, - bool requestClientCertificate: false, - bool requireClientCertificate: false}) { - _raw!.renegotiate( - useSessionCache: useSessionCache, - requestClientCertificate: requestClientCertificate, - requireClientCertificate: requireClientCertificate); - } - - X509Certificate? get peerCertificate { - if (_raw == null) { - throw new StateError("peerCertificate called on destroyed SecureSocket"); - } - return _raw!.peerCertificate; - } - - String? get selectedProtocol { - if (_raw == null) { - throw new StateError("selectedProtocol called on destroyed SecureSocket"); - } - return _raw!.selectedProtocol; - } -} - -/** - * _SecureFilterImpl wraps a filter that encrypts and decrypts data travelling - * over an encrypted socket. The filter also handles the handshaking - * and certificate verification. - * - * The filter exposes its input and output buffers as Dart objects that - * are backed by an external C array of bytes, so that both Dart code and - * native code can access the same data. - */ -@pragma("vm:entry-point") -class _SecureFilterImpl extends NativeFieldWrapperClass1 - implements _SecureFilter { - // Performance is improved if a full buffer of plaintext fits - // in the encrypted buffer, when encrypted. - // SIZE and ENCRYPTED_SIZE are referenced from C++. - @pragma("vm:entry-point") - static final int SIZE = 8 * 1024; - @pragma("vm:entry-point") - static final int ENCRYPTED_SIZE = 10 * 1024; - - _SecureFilterImpl._() { - buffers = <_ExternalBuffer>[ - for (int i = 0; i < _RawSecureSocket.bufferCount; ++i) - new _ExternalBuffer( - _RawSecureSocket._isBufferEncrypted(i) ? ENCRYPTED_SIZE : SIZE), - ]; - } - - void connect( - String hostName, - SecurityContext context, - bool isServer, - bool requestClientCertificate, - bool requireClientCertificate, - Uint8List protocols) native "SecureSocket_Connect"; - - void destroy() { - buffers = null; - _destroy(); - } - - void _destroy() native "SecureSocket_Destroy"; - - void handshake() native "SecureSocket_Handshake"; - - void rehandshake() => throw new UnimplementedError(); - - int processBuffer(int bufferIndex) => throw new UnimplementedError(); - - String? selectedProtocol() native "SecureSocket_GetSelectedProtocol"; - - void renegotiate(bool useSessionCache, bool requestClientCertificate, - bool requireClientCertificate) native "SecureSocket_Renegotiate"; - - void init() native "SecureSocket_Init"; - - X509Certificate? get peerCertificate native "SecureSocket_PeerCertificate"; - - void registerBadCertificateCallback(Function callback) - native "SecureSocket_RegisterBadCertificateCallback"; - - void registerHandshakeCompleteCallback(Function handshakeCompleteHandler) - native "SecureSocket_RegisterHandshakeCompleteCallback"; - - // This is a security issue, as it exposes a raw pointer to Dart code. - int _pointer() native "SecureSocket_FilterPointer"; - - @pragma("vm:entry-point", "get") - List<_ExternalBuffer>? buffers; -} - -@patch -class SecurityContext { - @patch - factory SecurityContext({bool withTrustedRoots: false}) { - return new _SecurityContext(withTrustedRoots); - } - - @patch - static SecurityContext get defaultContext { - return _SecurityContext.defaultContext; - } - - @patch - static bool get alpnSupported => true; -} - -class _SecurityContext extends NativeFieldWrapperClass1 - implements SecurityContext { - _SecurityContext(bool withTrustedRoots) { - _createNativeContext(); - if (withTrustedRoots) { - _trustBuiltinRoots(); - } - } - - void _createNativeContext() native "SecurityContext_Allocate"; - - static final SecurityContext defaultContext = new _SecurityContext(true); - - void usePrivateKey(String file, {String? password}) { - List bytes = (new File(file)).readAsBytesSync(); - usePrivateKeyBytes(bytes, password: password); - } - - void usePrivateKeyBytes(List keyBytes, {String? password}) - native "SecurityContext_UsePrivateKeyBytes"; - - void setTrustedCertificates(String file, {String? password}) { - List bytes = (new File(file)).readAsBytesSync(); - setTrustedCertificatesBytes(bytes, password: password); - } - - void setTrustedCertificatesBytes(List certBytes, {String? password}) - native "SecurityContext_SetTrustedCertificatesBytes"; - - void useCertificateChain(String file, {String? password}) { - List bytes = (new File(file)).readAsBytesSync(); - useCertificateChainBytes(bytes, password: password); - } - - void useCertificateChainBytes(List chainBytes, {String? password}) - native "SecurityContext_UseCertificateChainBytes"; - - void setClientAuthorities(String file, {String? password}) { - List bytes = (new File(file)).readAsBytesSync(); - setClientAuthoritiesBytes(bytes, password: password); - } - - void setClientAuthoritiesBytes(List authCertBytes, {String? password}) - native "SecurityContext_SetClientAuthoritiesBytes"; - - void setAlpnProtocols(List protocols, bool isServer) { - Uint8List encodedProtocols = - SecurityContext._protocolsToLengthEncoding(protocols); - _setAlpnProtocols(encodedProtocols, isServer); - } - - void _setAlpnProtocols(Uint8List protocols, bool isServer) - native "SecurityContext_SetAlpnProtocols"; - void _trustBuiltinRoots() native "SecurityContext_TrustBuiltinRoots"; -} - -/** - * _X509CertificateImpl wraps an X509 certificate object held by the BoringSSL - * library. It exposes the fields of the certificate object. - */ -class _X509CertificateImpl extends NativeFieldWrapperClass1 - implements X509Certificate { - // The native field must be set manually on a new object, in native code. - // This is done by WrappedX509 in secure_socket.cc. - _X509CertificateImpl._(); - - Uint8List get _der native "X509_Der"; - late final Uint8List der = _der; - - String get _pem native "X509_Pem"; - late final String pem = _pem; - - Uint8List get _sha1 native "X509_Sha1"; - late final Uint8List sha1 = _sha1; - - String get subject native "X509_Subject"; - String get issuer native "X509_Issuer"; - DateTime get startValidity { - return new DateTime.fromMillisecondsSinceEpoch(_startValidity(), - isUtc: true); - } - - DateTime get endValidity { - return new DateTime.fromMillisecondsSinceEpoch(_endValidity(), isUtc: true); - } - - int _startValidity() native "X509_StartValidity"; - int _endValidity() native "X509_EndValidity"; -} diff --git a/sdk_nnbd/lib/_internal/vm/bin/socket_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/socket_patch.dart deleted file mode 100644 index e2bff2fb777..00000000000 --- a/sdk_nnbd/lib/_internal/vm/bin/socket_patch.dart +++ /dev/null @@ -1,2243 +0,0 @@ -// Copyright (c) 2013, 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. - -// part of "common_patch.dart"; - -@patch -class RawServerSocket { - @patch - static Future bind(address, int port, - {int backlog: 0, bool v6Only: false, bool shared: false}) { - return _RawServerSocket.bind(address, port, backlog, v6Only, shared); - } -} - -@patch -class RawSocket { - @patch - static Future connect(dynamic host, int port, - {dynamic sourceAddress, Duration? timeout}) { - return _RawSocket.connect(host, port, sourceAddress, timeout); - } - - @patch - static Future> startConnect(dynamic host, int port, - {dynamic sourceAddress}) { - return _RawSocket.startConnect(host, port, sourceAddress); - } -} - -@patch -class RawSocketOption { - static final List _optionsCache = - List.filled(_RawSocketOptions.values.length, null); - - @patch - static int _getOptionValue(int key) { - if (key > _RawSocketOptions.values.length) { - throw ArgumentError.value(key, 'key'); - } - return _optionsCache[key] ??= _getNativeOptionValue(key); - } - - static int _getNativeOptionValue(int key) - native "RawSocketOption_GetOptionValue"; -} - -@patch -class InternetAddress { - @patch - static InternetAddress get LOOPBACK_IP_V4 { - return _InternetAddress.loopbackIPv4; - } - - @patch - static InternetAddress get LOOPBACK_IP_V6 { - return _InternetAddress.loopbackIPv6; - } - - @patch - static InternetAddress get ANY_IP_V4 { - return _InternetAddress.anyIPv4; - } - - @patch - static InternetAddress get ANY_IP_V6 { - return _InternetAddress.anyIPv6; - } - - @patch - factory InternetAddress(String address, {InternetAddressType? type}) { - return _InternetAddress.fromString(address, type: type); - } - - @patch - factory InternetAddress.fromRawAddress(Uint8List rawAddress, - {InternetAddressType? type}) { - return _InternetAddress.fromRawAddress(rawAddress, type: type); - } - - @patch - static Future> lookup(String host, - {InternetAddressType type: InternetAddressType.any}) { - return _NativeSocket.lookup(host, type: type); - } - - @patch - static InternetAddress _cloneWithNewHost( - InternetAddress address, String host) { - return (address as _InternetAddress)._cloneWithNewHost(host); - } - - @patch - static InternetAddress? tryParse(String address) { - return _InternetAddress.tryParse(address); - } -} - -@patch -class NetworkInterface { - @patch - static bool get listSupported { - return _listSupported(); - } - - @patch - static Future> list( - {bool includeLoopback: false, - bool includeLinkLocal: false, - InternetAddressType type: InternetAddressType.any}) { - return _NativeSocket.listInterfaces( - includeLoopback: includeLoopback, - includeLinkLocal: includeLinkLocal, - type: type); - } - - static bool _listSupported() native "NetworkInterface_ListSupported"; -} - -void _throwOnBadPort(int port) { - // TODO(40614): Remove once non-nullability is sound. - ArgumentError.checkNotNull(port, "port"); - if ((port < 0) || (port > 0xFFFF)) { - throw new ArgumentError("Invalid port $port"); - } -} - -void _throwOnBadTtl(int ttl) { - // TODO(40614): Remove once non-nullability is sound. - ArgumentError.checkNotNull(ttl, "ttl"); - if (ttl < 1 || ttl > 255) { - throw new ArgumentError('Invalid ttl $ttl'); - } -} - -class _InternetAddress implements InternetAddress { - static const int _addressLoopbackIPv4 = 0; - static const int _addressLoopbackIPv6 = 1; - static const int _addressAnyIPv4 = 2; - static const int _addressAnyIPv6 = 3; - static const int _IPv4AddrLength = 4; - static const int _IPv6AddrLength = 16; - - static _InternetAddress loopbackIPv4 = - _InternetAddress.fixed(_addressLoopbackIPv4); - static _InternetAddress loopbackIPv6 = - _InternetAddress.fixed(_addressLoopbackIPv6); - static _InternetAddress anyIPv4 = _InternetAddress.fixed(_addressAnyIPv4); - static _InternetAddress anyIPv6 = _InternetAddress.fixed(_addressAnyIPv6); - - final String address; - final String? _host; - final Uint8List _in_addr; - final int _scope_id; - final InternetAddressType type; - - String get host => _host ?? address; - - Uint8List get rawAddress => new Uint8List.fromList(_in_addr); - - bool get isLoopback { - switch (type) { - case InternetAddressType.IPv4: - return _in_addr[0] == 127; - - case InternetAddressType.IPv6: - for (int i = 0; i < _IPv6AddrLength - 1; i++) { - if (_in_addr[i] != 0) return false; - } - return _in_addr[_IPv6AddrLength - 1] == 1; - - case InternetAddressType.unix: - return false; - } - throw new UnsupportedError("Unexpected address type $type"); - } - - bool get isLinkLocal { - switch (type) { - case InternetAddressType.IPv4: - // Checking for 169.254.0.0/16. - return _in_addr[0] == 169 && _in_addr[1] == 254; - - case InternetAddressType.IPv6: - // Checking for fe80::/10. - return _in_addr[0] == 0xFE && (_in_addr[1] & 0xB0) == 0x80; - - case InternetAddressType.unix: - return false; - } - throw new UnsupportedError("Unexpected address type $type"); - } - - bool get isMulticast { - switch (type) { - case InternetAddressType.IPv4: - // Checking for 224.0.0.0 through 239.255.255.255. - return _in_addr[0] >= 224 && _in_addr[0] < 240; - - case InternetAddressType.IPv6: - // Checking for ff00::/8. - return _in_addr[0] == 0xFF; - - case InternetAddressType.unix: - return false; - } - throw new UnsupportedError("Unexpected address type $type"); - } - - Future reverse() { - if (type == InternetAddressType.unix) { - return Future.value(this); - } - return _NativeSocket.reverseLookup(this); - } - - _InternetAddress(this.type, this.address, this._host, this._in_addr, - [this._scope_id = 0]); - - factory _InternetAddress.fromString(String address, - {InternetAddressType? type}) { - // TODO(40614): Remove once non-nullability is sound. - ArgumentError.checkNotNull(address, 'address'); - if (type == InternetAddressType.unix) { - var rawAddress = FileSystemEntity._toUtf8Array(address); - return _InternetAddress( - InternetAddressType.unix, address, null, rawAddress); - } else { - var in_addr = _parse(address); - if (in_addr == null) { - throw ArgumentError("Invalid internet address $address"); - } - InternetAddressType type = in_addr.length == _IPv4AddrLength - ? InternetAddressType.IPv4 - : InternetAddressType.IPv6; - return _InternetAddress(type, address, null, in_addr); - } - } - - factory _InternetAddress.fromRawAddress(Uint8List rawAddress, - {InternetAddressType? type}) { - if (type == InternetAddressType.unix) { - ArgumentError.checkNotNull(rawAddress, 'rawAddress'); - var rawPath = FileSystemEntity._toNullTerminatedUtf8Array(rawAddress); - var address = FileSystemEntity._toStringFromUtf8Array(rawAddress); - return _InternetAddress(InternetAddressType.unix, address, null, rawPath); - } else { - int type = -1; - if (rawAddress.length == _IPv4AddrLength) { - type = 0; - } else { - if (rawAddress.length != _IPv6AddrLength) { - throw ArgumentError("Invalid internet address ${rawAddress}"); - } - type = 1; - } - var address = _rawAddrToString(rawAddress); - return _InternetAddress( - InternetAddressType._from(type), address, null, rawAddress); - } - } - - static _InternetAddress? tryParse(String address) { - checkNotNullable(address, "address"); - var addressBytes = _parse(address); - if (addressBytes == null) return null; - var type = addressBytes.length == _IPv4AddrLength - ? InternetAddressType.IPv4 - : InternetAddressType.IPv6; - return _InternetAddress(type, address, null, addressBytes); - } - - factory _InternetAddress.fixed(int id) { - switch (id) { - case _addressLoopbackIPv4: - var in_addr = Uint8List(_IPv4AddrLength); - in_addr[0] = 127; - in_addr[_IPv4AddrLength - 1] = 1; - return _InternetAddress( - InternetAddressType.IPv4, "127.0.0.1", null, in_addr); - case _addressLoopbackIPv6: - var in_addr = Uint8List(_IPv6AddrLength); - in_addr[_IPv6AddrLength - 1] = 1; - return _InternetAddress(InternetAddressType.IPv6, "::1", null, in_addr); - case _addressAnyIPv4: - var in_addr = Uint8List(_IPv4AddrLength); - return _InternetAddress( - InternetAddressType.IPv4, "0.0.0.0", "0.0.0.0", in_addr); - case _addressAnyIPv6: - var in_addr = Uint8List(_IPv6AddrLength); - return _InternetAddress(InternetAddressType.IPv6, "::", "::", in_addr); - default: - assert(false); - throw ArgumentError(); - } - } - - // Create a clone of this _InternetAddress replacing the host. - _InternetAddress _cloneWithNewHost(String host) { - return _InternetAddress(type, address, host, Uint8List.fromList(_in_addr)); - } - - bool operator ==(other) { - if (!(other is _InternetAddress)) return false; - if (other.type != type) return false; - if (type == InternetAddressType.unix) { - return address == other.address; - } - bool equals = true; - for (int i = 0; i < _in_addr.length && equals; i++) { - equals = other._in_addr[i] == _in_addr[i]; - } - return equals; - } - - int get hashCode { - if (type == InternetAddressType.unix) { - return address.hashCode; - } - int result = 1; - for (int i = 0; i < _in_addr.length; i++) { - result = (result * 31 + _in_addr[i]) & 0x3FFFFFFF; - } - return result; - } - - String toString() { - return "InternetAddress('$address', ${type.name})"; - } - - static String _rawAddrToString(Uint8List address) - native "InternetAddress_RawAddrToString"; - - static Uint8List? _parse(String address) native "InternetAddress_Parse"; -} - -class _NetworkInterface implements NetworkInterface { - final String name; - final int index; - final List addresses = []; - - _NetworkInterface(this.name, this.index); - - String toString() { - return "NetworkInterface('$name', $addresses)"; - } -} - -// The NativeFieldWrapperClass1 cannot be used with a mixin, due to missing -// implicit constructor. -class _NativeSocketNativeWrapper extends NativeFieldWrapperClass1 {} - -// The _NativeSocket class encapsulates an OS socket. -class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { - // Bit flags used when communicating between the eventhandler and - // dart code. The EVENT flags are used to indicate events of - // interest when sending a message from dart code to the - // eventhandler. When receiving a message from the eventhandler the - // EVENT flags indicate the events that actually happened. The - // COMMAND flags are used to send commands from dart to the - // eventhandler. COMMAND flags are never received from the - // eventhandler. Additional flags are used to communicate other - // information. - static const int readEvent = 0; - static const int writeEvent = 1; - static const int errorEvent = 2; - static const int closedEvent = 3; - static const int destroyedEvent = 4; - static const int firstEvent = readEvent; - static const int lastEvent = destroyedEvent; - static const int eventCount = lastEvent - firstEvent + 1; - - static const int closeCommand = 8; - static const int shutdownReadCommand = 9; - static const int shutdownWriteCommand = 10; - // The lower bits of returnTokenCommand messages contains the number - // of tokens returned. - static const int returnTokenCommand = 11; - static const int setEventMaskCommand = 12; - static const int firstCommand = closeCommand; - static const int lastCommand = setEventMaskCommand; - - // Type flag send to the eventhandler providing additional - // information on the type of the file descriptor. - static const int listeningSocket = 16; - static const int pipeSocket = 17; - static const int typeNormalSocket = 0; - static const int typeListeningSocket = 1 << listeningSocket; - static const int typePipe = 1 << pipeSocket; - static const int typeTypeMask = typeListeningSocket | pipeSocket; - - // Protocol flags. - // Keep in sync with SocketType enum in socket.h. - static const int tcpSocket = 18; - static const int udpSocket = 19; - static const int internalSocket = 20; - static const int internalSignalSocket = 21; - static const int typeTcpSocket = 1 << tcpSocket; - static const int typeUdpSocket = 1 << udpSocket; - static const int typeInternalSocket = 1 << internalSocket; - static const int typeInternalSignalSocket = 1 << internalSignalSocket; - static const int typeProtocolMask = typeTcpSocket | - typeUdpSocket | - typeInternalSocket | - typeInternalSignalSocket; - - // Native port messages. - static const hostNameLookupMessage = 0; - static const listInterfacesMessage = 1; - static const reverseLookupMessage = 2; - - // Protocol flags. - static const int protocolIPv4 = 1 << 0; - static const int protocolIPv6 = 1 << 1; - - static const int normalTokenBatchSize = 8; - static const int listeningTokenBatchSize = 2; - - static const Duration _retryDuration = const Duration(milliseconds: 250); - static const Duration _retryDurationLoopback = - const Duration(milliseconds: 25); - - // Socket close state - bool isClosed = false; - bool isClosing = false; - bool isClosedRead = false; - bool closedReadEventSent = false; - bool isClosedWrite = false; - Completer closeCompleter = new Completer.sync(); - - // Handlers and receive port for socket events from the event handler. - final List eventHandlers = new List.filled(eventCount + 1, null); - RawReceivePort? eventPort; - bool flagsSent = false; - - // The type flags for this socket. - final int typeFlags; - - // Holds the port of the socket, 0 if not known. - int localPort = 0; - - // Holds the address used to connect or bind the socket. - late InternetAddress localAddress; - - // The size of data that is ready to be read, for TCP sockets. - // This might be out-of-date when Read is called. - // The number of pending connections, for Listening sockets. - int available = 0; - - // Only used for UDP sockets. - bool _availableDatagram = false; - - // The number of incoming connnections for Listening socket. - int connections = 0; - - // The count of received event from eventhandler. - int tokens = 0; - - bool sendReadEvents = false; - bool readEventIssued = false; - - bool sendWriteEvents = false; - bool writeEventIssued = false; - bool writeAvailable = false; - - static bool connectedResourceHandler = false; - _SocketResourceInfo? resourceInfo; - - // The owner object is the object that the Socket is being used by, e.g. - // a HttpServer, a WebSocket connection, a process pipe, etc. - Object? owner; - - static Future> lookup(String host, - {InternetAddressType type: InternetAddressType.any}) { - return _IOService._dispatch(_IOService.socketLookup, [host, type._value]) - .then((response) { - if (isErrorResponse(response)) { - throw createError(response, "Failed host lookup: '$host'"); - } else { - return response.skip(1).map((result) { - var type = InternetAddressType._from(result[0]); - return _InternetAddress(type, result[1], host, result[2], result[3]); - }).toList(); - } - }); - } - - static Future reverseLookup(InternetAddress addr) { - return _IOService._dispatch(_IOService.socketReverseLookup, - [(addr as _InternetAddress)._in_addr]).then((response) { - if (isErrorResponse(response)) { - throw createError(response, "Failed reverse host lookup", addr); - } else { - return (addr as _InternetAddress)._cloneWithNewHost(response); - } - }); - } - - static Future> listInterfaces( - {bool includeLoopback: false, - bool includeLinkLocal: false, - InternetAddressType type: InternetAddressType.any}) { - return _IOService._dispatch(_IOService.socketListInterfaces, [type._value]) - .then((response) { - if (isErrorResponse(response)) { - throw createError(response, "Failed listing interfaces"); - } else { - var map = response.skip(1).fold(new Map(), - (map, result) { - var type = InternetAddressType._from(result[0]); - var name = result[3]; - var index = result[4]; - var address = _InternetAddress(type, result[1], "", result[2]); - if (!includeLinkLocal && address.isLinkLocal) return map; - if (!includeLoopback && address.isLoopback) return map; - map.putIfAbsent(name, () => new _NetworkInterface(name, index)); - map[name].addresses.add(address); - return map; - }); - return map.values.toList(); - } - }); - } - - static String escapeLinkLocalAddress(String host) { - // if the host contains escape, host is an IPv6 address with scope ID. - // Remove '25' before feeding into native calls. - int index = host.indexOf('%'); - if (index >= 0) { - if (!checkLinkLocalAddress(host)) { - // The only well defined usage is link-local address. Checks Section 4 of https://tools.ietf.org/html/rfc6874. - // If it is not a valid link-local address and contains escape character, throw an exception. - throw new FormatException( - '${host} is not a valid link-local address but contains %. Scope id should be used as part of link-local address.', - host, - index); - } - if (host.startsWith("25", index + 1)) { - // Remove '25' after '%' if present - host = host.replaceRange(index + 1, index + 3, ''); - } - } - return host; - } - - static bool checkLinkLocalAddress(String host) { - // The shortest possible link-local address is [fe80::1] - if (host.length < 7) return false; - var char = host[2]; - return host.startsWith('fe') && - (char == '8' || char == '9' || char == 'a' || char == 'b'); - } - - static Future> startConnect( - dynamic host, int port, dynamic sourceAddress) { - if (host is String) { - host = escapeLinkLocalAddress(host); - } - _throwOnBadPort(port); - if (sourceAddress != null && sourceAddress is! _InternetAddress) { - if (sourceAddress is String) { - sourceAddress = new InternetAddress(sourceAddress); - } - } - return new Future.value(host).then((host) { - if (host is _InternetAddress) return [host]; - return lookup(host).then((addresses) { - if (addresses.isEmpty) { - throw createError(null, "Failed host lookup: '$host'"); - } - return addresses; - }); - }).then((addresses) { - var completer = new Completer<_NativeSocket>(); - var it = (addresses as List).iterator; - var error = null; - var connecting = new HashMap(); - - void connectNext() { - if (!it.moveNext()) { - if (connecting.isEmpty) { - assert(error != null); - completer.completeError(error); - } - return; - } - final _InternetAddress address = it.current as _InternetAddress; - var socket = new _NativeSocket.normal(address); - var result; - if (sourceAddress == null) { - if (address.type == InternetAddressType.unix) { - result = socket.nativeCreateUnixDomainConnect( - address.address, _Namespace._namespace); - } else { - result = socket.nativeCreateConnect( - address._in_addr, port, address._scope_id); - } - } else { - assert(sourceAddress is _InternetAddress); - if (address.type == InternetAddressType.unix) { - assert(sourceAddress.type == InternetAddressType.unix); - result = socket.nativeCreateUnixDomainBindConnect( - address.address, sourceAddress.address, _Namespace._namespace); - } else { - result = socket.nativeCreateBindConnect(address._in_addr, port, - sourceAddress._in_addr, address._scope_id); - } - } - if (result is OSError) { - // Keep first error, if present. - if (error == null) { - int errorCode = result.errorCode; - if (sourceAddress != null && - errorCode != null && - socket.isBindError(errorCode)) { - error = createError(result, "Bind failed", sourceAddress); - } else { - error = createError(result, "Connection failed", address, port); - } - } - connectNext(); - } else { - // Query the local port for error messages. - try { - socket.port; - } catch (e) { - if (error == null) { - error = createError(e, "Connection failed", address, port); - } - connectNext(); - } - // Set up timer for when we should retry the next address - // (if any). - var duration = - address.isLoopback ? _retryDurationLoopback : _retryDuration; - var timer = new Timer(duration, connectNext); - setupResourceInfo(socket); - - connecting[socket] = timer; - // Setup handlers for receiving the first write event which - // indicate that the socket is fully connected. - socket.setHandlers(write: () { - timer.cancel(); - connecting.remove(socket); - // From 'man 2 connect': - // After select(2) indicates writability, use getsockopt(2) to read - // the SO_ERROR option at level SOL_SOCKET to determine whether - // connect() completed successfully (SO_ERROR is zero) or - // unsuccessfully. - OSError osError = socket.nativeGetError(); - if (osError.errorCode != 0) { - socket.close(); - if (error == null) error = osError; - if (connecting.isEmpty) connectNext(); - return; - } - socket.setListening(read: false, write: false); - completer.complete(socket); - connecting.forEach((s, t) { - t.cancel(); - s.close(); - s.setHandlers(); - s.setListening(read: false, write: false); - }); - connecting.clear(); - }, error: (e, st) { - timer.cancel(); - socket.close(); - // Keep first error, if present. - if (error == null) error = e; - connecting.remove(socket); - if (connecting.isEmpty) connectNext(); - }); - socket.setListening(read: false, write: true); - } - } - - void onCancel() { - connecting.forEach((s, t) { - t.cancel(); - s.close(); - s.setHandlers(); - s.setListening(read: false, write: false); - if (error == null) { - error = createError(null, - "Connection attempt cancelled, host: ${host}, port: ${port}"); - } - }); - connecting.clear(); - if (!completer.isCompleted) { - completer.completeError(error); - } - } - - connectNext(); - return new ConnectionTask<_NativeSocket>._(completer.future, onCancel); - }); - } - - static Future<_NativeSocket> connect( - dynamic host, int port, dynamic sourceAddress, Duration? timeout) { - return startConnect(host, port, sourceAddress) - .then((ConnectionTask<_NativeSocket> task) { - Future<_NativeSocket> socketFuture = task.socket; - if (timeout != null) { - socketFuture = socketFuture.timeout(timeout, onTimeout: () { - task.cancel(); - throw createError( - null, "Connection timed out, host: ${host}, port: ${port}"); - }); - } - return socketFuture; - }); - } - - static Future<_InternetAddress> _resolveHost(dynamic host) async { - if (host is _InternetAddress) { - return host; - } else { - final list = await lookup(host); - if (list.isEmpty) { - throw createError(null, "Failed host lookup: '$host'"); - } - return list.first as _InternetAddress; - } - } - - static Future<_NativeSocket> bind( - host, int port, int backlog, bool v6Only, bool shared) async { - _throwOnBadPort(port); - if (host is String) { - host = escapeLinkLocalAddress(host); - } - final address = await _resolveHost(host); - - var socket = new _NativeSocket.listen(address); - var result; - if (address.type == InternetAddressType.unix) { - var path = address.address; - if (FileSystemEntity.isLinkSync(path)) { - path = Link(path).targetSync(); - } - result = socket.nativeCreateUnixDomainBindListen( - path, backlog, shared, _Namespace._namespace); - } else { - result = socket.nativeCreateBindListen( - address._in_addr, port, backlog, v6Only, shared, address._scope_id); - } - if (result is OSError) { - throw new SocketException("Failed to create server socket", - osError: result, address: address, port: port); - } - if (port != 0) socket.localPort = port; - setupResourceInfo(socket); - socket.connectToEventHandler(); - return socket; - } - - static void setupResourceInfo(_NativeSocket socket) { - socket.resourceInfo = new _SocketResourceInfo(socket); - } - - static Future<_NativeSocket> bindDatagram( - host, int port, bool reuseAddress, bool reusePort, int ttl) async { - _throwOnBadPort(port); - _throwOnBadTtl(ttl); - - final address = await _resolveHost(host); - - var socket = new _NativeSocket.datagram(address); - var result = socket.nativeCreateBindDatagram( - address._in_addr, port, reuseAddress, reusePort, ttl); - if (result is OSError) { - throw new SocketException("Failed to create datagram socket", - osError: result, address: address, port: port); - } - if (port != 0) socket.localPort = port; - setupResourceInfo(socket); - return socket; - } - - _NativeSocket.datagram(this.localAddress) - : typeFlags = typeNormalSocket | typeUdpSocket; - - _NativeSocket.normal(this.localAddress) - : typeFlags = typeNormalSocket | typeTcpSocket; - - _NativeSocket.listen(this.localAddress) - : typeFlags = typeListeningSocket | typeTcpSocket { - isClosedWrite = true; - } - - _NativeSocket.pipe() : typeFlags = typePipe; - - _NativeSocket._watchCommon(int id, int type) - : typeFlags = typeNormalSocket | type { - isClosedWrite = true; - nativeSetSocketId(id, typeFlags); - } - - _NativeSocket.watchSignal(int id) - : this._watchCommon(id, typeInternalSignalSocket); - - _NativeSocket.watch(int id) : this._watchCommon(id, typeInternalSocket); - - bool get isListening => (typeFlags & typeListeningSocket) != 0; - bool get isPipe => (typeFlags & typePipe) != 0; - bool get isInternal => (typeFlags & typeInternalSocket) != 0; - bool get isInternalSignal => (typeFlags & typeInternalSignalSocket) != 0; - bool get isTcp => (typeFlags & typeTcpSocket) != 0; - bool get isUdp => (typeFlags & typeUdpSocket) != 0; - - Map _toJSON(bool ref) => throw new UnimplementedError(); - String get _serviceTypePath => throw new UnimplementedError(); - String get _serviceTypeName => throw new UnimplementedError(); - - Uint8List? read(int? count) { - if (count != null && count <= 0) { - throw ArgumentError("Illegal length $count"); - } - if (isClosing || isClosed) return null; - try { - Uint8List? list; - if (count != null) { - list = nativeRead(count); - available = nativeAvailable(); - } else { - // If count is null, read as many bytes as possible. - // Loop here to ensure bytes that arrived while this read was - // issued are also read. - BytesBuilder builder = BytesBuilder(); - do { - assert(available > 0); - list = nativeRead(available); - if (list == null) { - break; - } - builder.add(list); - available = nativeAvailable(); - } while (available > 0); - if (builder.isEmpty) { - list = null; - } else { - list = builder.toBytes(); - } - } - final resourceInformation = resourceInfo; - assert(resourceInformation != null || - isPipe || - isInternal || - isInternalSignal); - if (list != null) { - if (resourceInformation != null) { - resourceInformation.totalRead += list.length; - } - } - if (resourceInformation != null) { - resourceInformation.didRead(); - } - if (!const bool.fromEnvironment("dart.vm.product")) { - _SocketProfile.collectStatistic( - nativeGetSocketId(), _SocketProfileType.readBytes, list?.length); - } - return list; - } catch (e) { - reportError(e, StackTrace.current, "Read failed"); - return null; - } - } - - Datagram? receive() { - if (isClosing || isClosed) return null; - try { - Datagram? result = nativeRecvFrom(); - if (result != null) { - final resourceInformation = resourceInfo; - if (resourceInformation != null) { - resourceInformation.totalRead += result.data.length; - } - } - final resourceInformation = resourceInfo; - if (resourceInformation != null) { - resourceInformation.didRead(); - } - if (!const bool.fromEnvironment("dart.vm.product")) { - _SocketProfile.collectStatistic(nativeGetSocketId(), - _SocketProfileType.readBytes, result?.data.length); - } - _availableDatagram = nativeAvailableDatagram(); - return result; - } catch (e) { - reportError(e, StackTrace.current, "Receive failed"); - return null; - } - } - - static int _fixOffset(int? offset) => offset ?? 0; - - int write(List buffer, int offset, int? bytes) { - // TODO(40614): Remove once non-nullability is sound. - offset = _fixOffset(offset); - if (bytes == null) { - if (offset > buffer.length) { - throw new RangeError.value(offset); - } - bytes = buffer.length - offset; - } - if (offset < 0) throw new RangeError.value(offset); - if (bytes < 0) throw new RangeError.value(bytes); - if ((offset + bytes) > buffer.length) { - throw new RangeError.value(offset + bytes); - } - if (isClosing || isClosed) return 0; - if (bytes == 0) return 0; - try { - _BufferAndStart bufferAndStart = - _ensureFastAndSerializableByteData(buffer, offset, offset + bytes); - if (!const bool.fromEnvironment("dart.vm.product")) { - _SocketProfile.collectStatistic( - nativeGetSocketId(), - _SocketProfileType.writeBytes, - bufferAndStart.buffer.length - bufferAndStart.start); - } - int result = - nativeWrite(bufferAndStart.buffer, bufferAndStart.start, bytes); - // The result may be negative, if we forced a short write for testing - // purpose. In such case, don't mark writeAvailable as false, as we don't - // know if we'll receive an event. It's better to just retry. - if (result >= 0 && result < bytes) { - writeAvailable = false; - } - // Negate the result, as stated above. - if (result < 0) result = -result; - final resourceInformation = resourceInfo; - assert(resourceInformation != null || - isPipe || - isInternal || - isInternalSignal); - if (resourceInformation != null) { - resourceInformation.addWrite(result); - } - return result; - } catch (e) { - StackTrace st = StackTrace.current; - scheduleMicrotask(() => reportError(e, st, "Write failed")); - return 0; - } - } - - int send(List buffer, int offset, int bytes, InternetAddress address, - int port) { - _throwOnBadPort(port); - if (isClosing || isClosed) return 0; - try { - _BufferAndStart bufferAndStart = - _ensureFastAndSerializableByteData(buffer, offset, bytes); - if (!const bool.fromEnvironment("dart.vm.product")) { - _SocketProfile.collectStatistic( - nativeGetSocketId(), - _SocketProfileType.writeBytes, - bufferAndStart.buffer.length - bufferAndStart.start); - } - int result = nativeSendTo(bufferAndStart.buffer, bufferAndStart.start, - bytes, (address as _InternetAddress)._in_addr, port); - final resourceInformation = resourceInfo; - assert(resourceInformation != null || - isPipe || - isInternal || - isInternalSignal); - if (resourceInformation != null) { - resourceInformation.addWrite(result); - } - return result; - } catch (e) { - StackTrace st = StackTrace.current; - scheduleMicrotask(() => reportError(e, st, "Send failed")); - return 0; - } - } - - _NativeSocket? accept() { - // Don't issue accept if we're closing. - if (isClosing || isClosed) return null; - assert(connections > 0); - connections--; - tokens++; - returnTokens(listeningTokenBatchSize); - var socket = new _NativeSocket.normal(address); - if (nativeAccept(socket) != true) return null; - socket.localPort = localPort; - setupResourceInfo(socket); - final resourceInformation = resourceInfo; - assert(resourceInformation != null || - isPipe || - isInternal || - isInternalSignal); - if (resourceInformation != null) { - // We track this as read one byte. - resourceInformation.addRead(1); - } - return socket; - } - - int get port { - if (localAddress.type == InternetAddressType.unix) return 0; - if (localPort != 0) return localPort; - if (isClosing || isClosed) throw const SocketException.closed(); - return localPort = nativeGetPort(); - } - - int get remotePort { - if (localAddress.type == InternetAddressType.unix) return 0; - if (isClosing || isClosed) throw const SocketException.closed(); - return nativeGetRemotePeer()[1]; - } - - InternetAddress get address => localAddress; - - InternetAddress get remoteAddress { - if (isClosing || isClosed) throw const SocketException.closed(); - var result = nativeGetRemotePeer(); - var addr = result[0]; - var type = new InternetAddressType._from(addr[0]); - if (type == InternetAddressType.unix) { - return _InternetAddress.fromString(addr[1], - type: InternetAddressType.unix); - } - return _InternetAddress(type, addr[1], null, addr[2]); - } - - void issueReadEvent() { - if (closedReadEventSent) return; - if (readEventIssued) return; - readEventIssued = true; - void issue() { - readEventIssued = false; - if (isClosing) return; - if (!sendReadEvents) return; - if (stopRead()) { - if (isClosedRead && !closedReadEventSent) { - if (isClosedWrite) close(); - var handler = eventHandlers[closedEvent]; - if (handler == null) return; - closedReadEventSent = true; - handler(); - } - return; - } - var handler = eventHandlers[readEvent]; - if (handler == null) return; - readEventIssued = true; - handler(); - scheduleMicrotask(issue); - } - - scheduleMicrotask(issue); - } - - bool stopRead() { - if (isUdp) { - return !_availableDatagram; - } else { - return available == 0; - } - } - - void issueWriteEvent({bool delayed: true}) { - if (writeEventIssued) return; - if (!writeAvailable) return; - void issue() { - writeEventIssued = false; - if (!writeAvailable) return; - if (isClosing) return; - if (!sendWriteEvents) return; - sendWriteEvents = false; - var handler = eventHandlers[writeEvent]; - if (handler == null) return; - handler(); - } - - if (delayed) { - writeEventIssued = true; - scheduleMicrotask(issue); - } else { - issue(); - } - } - - // Multiplexes socket events to the socket handlers. - void multiplex(Object eventsObj) { - // TODO(paulberry): when issue #31305 is fixed, we should be able to simply - // declare `events` as a `covariant int` parameter. - int events = eventsObj as int; - for (int i = firstEvent; i <= lastEvent; i++) { - if (((events & (1 << i)) != 0)) { - if ((i == closedEvent || i == readEvent) && isClosedRead) continue; - if (isClosing && i != destroyedEvent) continue; - if (i == closedEvent && !isListening && !isClosing && !isClosed) { - isClosedRead = true; - issueReadEvent(); - continue; - } - - if (i == writeEvent) { - writeAvailable = true; - issueWriteEvent(delayed: false); - continue; - } - - if (i == readEvent) { - if (isListening) { - connections++; - } else { - if (isUdp) { - _availableDatagram = nativeAvailableDatagram(); - } else { - available = nativeAvailable(); - } - issueReadEvent(); - continue; - } - } - - var handler = eventHandlers[i]; - if (i == destroyedEvent) { - assert(isClosing); - assert(!isClosed); - final resourceInformation = resourceInfo; - assert(resourceInformation != null || - isPipe || - isInternal || - isInternalSignal); - if (resourceInformation != null) { - _SocketResourceInfo.SocketClosed(resourceInformation); - } - isClosed = true; - closeCompleter.complete(); - disconnectFromEventHandler(); - if (handler != null) handler(); - continue; - } - - if (i == errorEvent) { - if (!isClosing) { - reportError(nativeGetError(), null, ""); - } - } else if (!isClosed) { - // If the connection is closed right after it's accepted, there's a - // chance the close-handler is not set. - if (handler != null) handler(); - } - } - } - if (!isListening) { - tokens++; - returnTokens(normalTokenBatchSize); - } - } - - void returnTokens(int tokenBatchSize) { - if (!isClosing && !isClosed) { - assert(eventPort != null); - // Return in batches. - if (tokens == tokenBatchSize) { - assert(tokens < (1 << firstCommand)); - sendToEventHandler((1 << returnTokenCommand) | tokens); - tokens = 0; - } - } - } - - void setHandlers({read, write, error, closed, destroyed}) { - eventHandlers[readEvent] = read; - eventHandlers[writeEvent] = write; - eventHandlers[errorEvent] = error; - eventHandlers[closedEvent] = closed; - eventHandlers[destroyedEvent] = destroyed; - } - - void setListening({bool read: true, bool write: true}) { - sendReadEvents = read; - sendWriteEvents = write; - if (read) issueReadEvent(); - if (write) issueWriteEvent(); - if (!flagsSent && !isClosing) { - flagsSent = true; - int flags = 1 << setEventMaskCommand; - if (!isClosedRead) flags |= 1 << readEvent; - if (!isClosedWrite) flags |= 1 << writeEvent; - sendToEventHandler(flags); - } - } - - Future close() { - if (!isClosing && !isClosed) { - sendToEventHandler(1 << closeCommand); - isClosing = true; - } - return closeCompleter.future; - } - - void shutdown(SocketDirection direction) { - if (!isClosing && !isClosed) { - switch (direction) { - case SocketDirection.receive: - shutdownRead(); - break; - case SocketDirection.send: - shutdownWrite(); - break; - case SocketDirection.both: - close(); - break; - default: - throw new ArgumentError(direction); - } - } - } - - void shutdownWrite() { - if (!isClosing && !isClosed) { - if (closedReadEventSent) { - close(); - } else { - sendToEventHandler(1 << shutdownWriteCommand); - } - isClosedWrite = true; - } - } - - void shutdownRead() { - if (!isClosing && !isClosed) { - if (isClosedWrite) { - close(); - } else { - sendToEventHandler(1 << shutdownReadCommand); - } - isClosedRead = true; - } - } - - void sendToEventHandler(int data) { - int fullData = (typeFlags & typeTypeMask) | data; - assert(!isClosing); - connectToEventHandler(); - _EventHandler._sendData(this, eventPort!.sendPort, fullData); - } - - void connectToEventHandler() { - assert(!isClosed); - if (eventPort == null) { - eventPort = new RawReceivePort(multiplex); - } - if (!connectedResourceHandler) { - registerExtension( - 'ext.dart.io.getOpenSockets', _SocketResourceInfo.getOpenSockets); - registerExtension('ext.dart.io.getSocketByID', - _SocketResourceInfo.getSocketInfoMapByID); - - connectedResourceHandler = true; - } - } - - void disconnectFromEventHandler() { - eventPort!.close(); - eventPort = null; - // Now that we don't track this Socket anymore, we can clear the owner - // field. - owner = null; - } - - // Check whether this is an error response from a native port call. - static bool isErrorResponse(response) { - return response is List && response[0] != _successResponse; - } - - // Create the appropriate error/exception from different returned - // error objects. - static createError(error, String message, - [InternetAddress? address, int? port]) { - if (error is OSError) { - return new SocketException(message, - osError: error, address: address, port: port); - } else if (error is List) { - assert(isErrorResponse(error)); - switch (error[0]) { - case _illegalArgumentResponse: - return new ArgumentError(); - case _osErrorResponse: - return new SocketException(message, - osError: new OSError(error[2], error[1]), - address: address, - port: port); - default: - return new Exception("Unknown error"); - } - } else { - return new SocketException(message, address: address, port: port); - } - } - - void reportError(error, StackTrace? st, String message) { - var e = - createError(error, message, isUdp || isTcp ? address : null, localPort); - // Invoke the error handler if any. - if (eventHandlers[errorEvent] != null) { - eventHandlers[errorEvent](e, st); - } - // For all errors we close the socket - close(); - } - - dynamic getOption(SocketOption option) { - // TODO(40614): Remove once non-nullability is sound. - ArgumentError.checkNotNull(option, "option"); - var result = nativeGetOption(option._value, address.type._value); - if (result is OSError) throw result; - return result; - } - - bool setOption(SocketOption option, value) { - // TODO(40614): Remove once non-nullability is sound. - ArgumentError.checkNotNull(option, "option"); - nativeSetOption(option._value, address.type._value, value); - return true; - } - - Uint8List getRawOption(RawSocketOption option) { - // TODO(40614): Remove once non-nullability is sound. - ArgumentError.checkNotNull(option, "option"); - ArgumentError.checkNotNull(option.value, "option.value"); - nativeGetRawOption(option.level, option.option, option.value); - return option.value; - } - - void setRawOption(RawSocketOption option) { - // TODO(40614): Remove once non-nullability is sound. - ArgumentError.checkNotNull(option, "option"); - ArgumentError.checkNotNull(option.value, "option.value"); - nativeSetRawOption(option.level, option.option, option.value); - } - - InternetAddress? multicastAddress( - InternetAddress addr, NetworkInterface? interface) { - // On Mac OS using the interface index for joining IPv4 multicast groups - // is not supported. Here the IP address of the interface is needed. - if (Platform.isMacOS && addr.type == InternetAddressType.IPv4) { - if (interface != null) { - for (int i = 0; i < interface.addresses.length; i++) { - if (interface.addresses[i].type == InternetAddressType.IPv4) { - return interface.addresses[i]; - } - } - // No IPv4 address found on the interface. - throw new SocketException( - "The network interface does not have an address " - "of the same family as the multicast address"); - } else { - // Default to the ANY address if no interface is specified. - return InternetAddress.anyIPv4; - } - } else { - return null; - } - } - - void joinMulticast(InternetAddress addr, NetworkInterface? interface) { - final interfaceAddr = - multicastAddress(addr, interface) as _InternetAddress?; - var interfaceIndex = interface == null ? 0 : interface.index; - nativeJoinMulticast((addr as _InternetAddress)._in_addr, - interfaceAddr?._in_addr, interfaceIndex); - } - - void leaveMulticast(InternetAddress addr, NetworkInterface? interface) { - final interfaceAddr = - multicastAddress(addr, interface) as _InternetAddress?; - var interfaceIndex = interface == null ? 0 : interface.index; - nativeLeaveMulticast((addr as _InternetAddress)._in_addr, - interfaceAddr?._in_addr, interfaceIndex); - } - - void nativeSetSocketId(int id, int typeFlags) native "Socket_SetSocketId"; - int nativeAvailable() native "Socket_Available"; - bool nativeAvailableDatagram() native "Socket_AvailableDatagram"; - Uint8List? nativeRead(int len) native "Socket_Read"; - Datagram? nativeRecvFrom() native "Socket_RecvFrom"; - int nativeWrite(List buffer, int offset, int bytes) - native "Socket_WriteList"; - int nativeSendTo(List buffer, int offset, int bytes, Uint8List address, - int port) native "Socket_SendTo"; - nativeCreateConnect(Uint8List addr, int port, int scope_id) - native "Socket_CreateConnect"; - nativeCreateUnixDomainConnect(String addr, _Namespace namespace) - native "Socket_CreateUnixDomainConnect"; - nativeCreateBindConnect(Uint8List addr, int port, Uint8List sourceAddr, - int scope_id) native "Socket_CreateBindConnect"; - nativeCreateUnixDomainBindConnect(String addr, String sourceAddr, - _Namespace namespace) native "Socket_CreateUnixDomainBindConnect"; - bool isBindError(int errorNumber) native "SocketBase_IsBindError"; - nativeCreateBindListen(Uint8List addr, int port, int backlog, bool v6Only, - bool shared, int scope_id) native "ServerSocket_CreateBindListen"; - nativeCreateUnixDomainBindListen(String addr, int backlog, bool shared, - _Namespace namespace) native "ServerSocket_CreateUnixDomainBindListen"; - nativeCreateBindDatagram(Uint8List addr, int port, bool reuseAddress, - bool reusePort, int ttl) native "Socket_CreateBindDatagram"; - bool nativeAccept(_NativeSocket socket) native "ServerSocket_Accept"; - int nativeGetPort() native "Socket_GetPort"; - List nativeGetRemotePeer() native "Socket_GetRemotePeer"; - int nativeGetSocketId() native "Socket_GetSocketId"; - OSError nativeGetError() native "Socket_GetError"; - nativeGetOption(int option, int protocol) native "Socket_GetOption"; - void nativeGetRawOption(int level, int option, Uint8List data) - native "Socket_GetRawOption"; - void nativeSetOption(int option, int protocol, value) - native "Socket_SetOption"; - void nativeSetRawOption(int level, int option, Uint8List data) - native "Socket_SetRawOption"; - void nativeJoinMulticast(Uint8List addr, Uint8List? interfaceAddr, - int interfaceIndex) native "Socket_JoinMulticast"; - void nativeLeaveMulticast(Uint8List addr, Uint8List? interfaceAddr, - int interfaceIndex) native "Socket_LeaveMulticast"; -} - -class _RawServerSocket extends Stream implements RawServerSocket { - final _NativeSocket _socket; - StreamController? _controller; - bool _v6Only; - - static Future<_RawServerSocket> bind( - address, int port, int backlog, bool v6Only, bool shared) { - _throwOnBadPort(port); - if (backlog < 0) throw new ArgumentError("Invalid backlog $backlog"); - return _NativeSocket.bind(address, port, backlog, v6Only, shared) - .then((socket) => new _RawServerSocket(socket, v6Only)); - } - - _RawServerSocket(this._socket, this._v6Only); - - StreamSubscription listen(void onData(RawSocket event)?, - {Function? onError, void onDone()?, bool? cancelOnError}) { - if (_controller != null) { - throw new StateError("Stream was already listened to"); - } - var zone = Zone.current; - final controller = _controller = new StreamController( - sync: true, - onListen: _onSubscriptionStateChange, - onCancel: _onSubscriptionStateChange, - onPause: _onPauseStateChange, - onResume: _onPauseStateChange); - _socket.setHandlers( - read: zone.bindCallbackGuarded(() { - while (_socket.connections > 0) { - var socket = _socket.accept(); - if (socket == null) return; - if (!const bool.fromEnvironment("dart.vm.product")) { - _SocketProfile.collectNewSocket(socket.nativeGetSocketId(), - _tcpSocket, socket.address, socket.port); - } - controller.add(_RawSocket(socket)); - if (controller.isPaused) return; - } - }), - error: zone.bindBinaryCallbackGuarded((Object e, StackTrace? st) { - controller.addError(e, st); - controller.close(); - }), - destroyed: () => controller.close()); - return controller.stream.listen(onData, - onError: onError, onDone: onDone, cancelOnError: cancelOnError); - } - - int get port => _socket.port; - - InternetAddress get address => _socket.address; - - Future close() { - return _socket.close().then((_) => this); - } - - void _pause() { - _socket.setListening(read: false, write: false); - } - - void _resume() { - _socket.setListening(read: true, write: false); - } - - void _onSubscriptionStateChange() { - if (_controller!.hasListener) { - _resume(); - } else { - _socket.close(); - } - } - - void _onPauseStateChange() { - if (_controller!.isPaused) { - _pause(); - } else { - _resume(); - } - } - - void set _owner(owner) { - _socket.owner = owner; - } -} - -class _RawSocket extends Stream implements RawSocket { - final _NativeSocket _socket; - final _controller = new StreamController(sync: true); - bool _readEventsEnabled = true; - bool _writeEventsEnabled = true; - - // Flag to handle Ctrl-D closing of stdio on Mac OS. - bool _isMacOSTerminalInput = false; - - static Future connect( - dynamic host, int port, dynamic sourceAddress, Duration? timeout) { - return _NativeSocket.connect(host, port, sourceAddress, timeout) - .then((socket) { - if (!const bool.fromEnvironment("dart.vm.product")) { - _SocketProfile.collectNewSocket( - socket.nativeGetSocketId(), _tcpSocket, socket.address, port); - } - return _RawSocket(socket); - }); - } - - static Future> startConnect( - dynamic host, int port, dynamic sourceAddress) { - return _NativeSocket.startConnect(host, port, sourceAddress) - .then((ConnectionTask<_NativeSocket> nativeTask) { - final Future<_RawSocket> raw = - nativeTask.socket.then((_NativeSocket nativeSocket) { - if (!const bool.fromEnvironment("dart.vm.product")) { - _SocketProfile.collectNewSocket(nativeSocket.nativeGetSocketId(), - _tcpSocket, nativeSocket.address, port); - } - return _RawSocket(nativeSocket); - }); - return ConnectionTask<_RawSocket>._(raw, nativeTask._onCancel); - }); - } - - _RawSocket(this._socket) { - var zone = Zone.current; - _controller - ..onListen = _onSubscriptionStateChange - ..onCancel = _onSubscriptionStateChange - ..onPause = _onPauseStateChange - ..onResume = _onPauseStateChange; - _socket.setHandlers( - read: () => _controller.add(RawSocketEvent.read), - write: () { - // The write event handler is automatically disabled by the - // event handler when it fires. - writeEventsEnabled = false; - _controller.add(RawSocketEvent.write); - }, - closed: () => _controller.add(RawSocketEvent.readClosed), - destroyed: () { - _controller.add(RawSocketEvent.closed); - _controller.close(); - }, - error: zone.bindBinaryCallbackGuarded((Object e, StackTrace? st) { - _controller.addError(e, st); - _socket.close(); - })); - } - - factory _RawSocket._writePipe() { - var native = new _NativeSocket.pipe(); - native.isClosedRead = true; - native.closedReadEventSent = true; - return new _RawSocket(native); - } - - factory _RawSocket._readPipe(int? fd) { - var native = new _NativeSocket.pipe(); - native.isClosedWrite = true; - if (fd != null) _getStdioHandle(native, fd); - var result = new _RawSocket(native); - if (fd != null) { - var socketType = _StdIOUtils._nativeSocketType(result._socket); - result._isMacOSTerminalInput = - Platform.isMacOS && socketType == _stdioHandleTypeTerminal; - } - return result; - } - - StreamSubscription listen(void onData(RawSocketEvent event)?, - {Function? onError, void onDone()?, bool? cancelOnError}) { - return _controller.stream.listen(onData, - onError: onError, onDone: onDone, cancelOnError: cancelOnError); - } - - int available() => _socket.available; - - Uint8List? read([int? len]) { - if (_isMacOSTerminalInput) { - var available = this.available(); - if (available == 0) return null; - var data = _socket.read(len); - if (data == null || data.length < available) { - // Reading less than available from a Mac OS terminal indicate Ctrl-D. - // This is interpreted as read closed. - scheduleMicrotask(() => _controller.add(RawSocketEvent.readClosed)); - } - return data; - } else { - return _socket.read(len); - } - } - - int write(List buffer, [int offset = 0, int? count]) => - _socket.write(buffer, offset, count); - - Future close() => _socket.close().then((_) { - if (!const bool.fromEnvironment("dart.vm.product")) { - _SocketProfile.collectStatistic( - _socket.nativeGetSocketId(), _SocketProfileType.endTime); - } - return this; - }); - - void shutdown(SocketDirection direction) => _socket.shutdown(direction); - - int get port => _socket.port; - - int get remotePort => _socket.remotePort; - - InternetAddress get address => _socket.address; - - InternetAddress get remoteAddress => _socket.remoteAddress; - - bool get readEventsEnabled => _readEventsEnabled; - void set readEventsEnabled(bool value) { - if (value != _readEventsEnabled) { - _readEventsEnabled = value; - if (!_controller.isPaused) _resume(); - } - } - - bool get writeEventsEnabled => _writeEventsEnabled; - void set writeEventsEnabled(bool value) { - if (value != _writeEventsEnabled) { - _writeEventsEnabled = value; - if (!_controller.isPaused) _resume(); - } - } - - bool setOption(SocketOption option, bool enabled) => - _socket.setOption(option, enabled); - - Uint8List getRawOption(RawSocketOption option) => - _socket.getRawOption(option); - void setRawOption(RawSocketOption option) => _socket.setRawOption(option); - - _pause() { - _socket.setListening(read: false, write: false); - } - - void _resume() { - _socket.setListening(read: _readEventsEnabled, write: _writeEventsEnabled); - } - - void _onPauseStateChange() { - if (_controller.isPaused) { - _pause(); - } else { - _resume(); - } - } - - void _onSubscriptionStateChange() { - if (_controller.hasListener) { - _resume(); - } else { - _socket.close(); - } - } - - void set _owner(owner) { - _socket.owner = owner; - } -} - -@patch -class ServerSocket { - @patch - static Future _bind(address, int port, - {int backlog: 0, bool v6Only: false, bool shared: false}) { - return _ServerSocket.bind(address, port, backlog, v6Only, shared); - } -} - -class _ServerSocket extends Stream implements ServerSocket { - final _socket; - - static Future<_ServerSocket> bind( - address, int port, int backlog, bool v6Only, bool shared) { - return _RawServerSocket.bind(address, port, backlog, v6Only, shared) - .then((socket) => new _ServerSocket(socket)); - } - - _ServerSocket(this._socket); - - StreamSubscription listen(void onData(Socket event)?, - {Function? onError, void onDone()?, bool? cancelOnError}) { - return _socket.map((rawSocket) => new _Socket(rawSocket)).listen( - onData, - onError: onError, - onDone: onDone, - cancelOnError: cancelOnError); - } - - int get port => _socket.port; - - InternetAddress get address => _socket.address; - - Future close() => - _socket.close().then((_) => this); - - void set _owner(owner) { - _socket._owner = owner; - } -} - -@patch -class Socket { - @patch - static Future _connect(dynamic host, int port, - {dynamic sourceAddress, Duration? timeout}) { - return RawSocket.connect(host, port, - sourceAddress: sourceAddress, timeout: timeout) - .then((socket) => new _Socket(socket)); - } - - @patch - static Future> _startConnect(dynamic host, int port, - {dynamic sourceAddress}) { - return RawSocket.startConnect(host, port, sourceAddress: sourceAddress) - .then((rawTask) { - Future socket = - rawTask.socket.then((rawSocket) => new _Socket(rawSocket)); - return new ConnectionTask._(socket, rawTask._onCancel); - }); - } -} - -class _SocketStreamConsumer extends StreamConsumer> { - StreamSubscription? subscription; - final _Socket socket; - int? offset; - List? buffer; - bool paused = false; - Completer? streamCompleter; - - _SocketStreamConsumer(this.socket); - - Future addStream(Stream> stream) { - socket._ensureRawSocketSubscription(); - final completer = streamCompleter = new Completer(); - if (socket._raw != null) { - subscription = stream.listen((data) { - assert(!paused); - assert(buffer == null); - buffer = data; - offset = 0; - try { - write(); - } catch (e) { - socket.destroy(); - stop(); - done(e); - } - }, onError: (error, [stackTrace]) { - socket.destroy(); - done(error, stackTrace); - }, onDone: () { - done(); - }, cancelOnError: true); - } - return completer.future; - } - - Future close() { - socket._consumerDone(); - return new Future.value(socket); - } - - void write() { - final sub = subscription; - if (sub == null) return; - // Write as much as possible. - offset = - offset! + socket._write(buffer!, offset!, buffer!.length - offset!); - if (offset! < buffer!.length) { - if (!paused) { - paused = true; - sub.pause(); - } - socket._enableWriteEvent(); - } else { - buffer = null; - if (paused) { - paused = false; - sub.resume(); - } - } - } - - void done([error, stackTrace]) { - final completer = streamCompleter; - if (completer != null) { - if (error != null) { - completer.completeError(error, stackTrace); - } else { - completer.complete(socket); - } - streamCompleter = null; - } - } - - void stop() { - final sub = subscription; - if (sub == null) return; - sub.cancel(); - subscription = null; - paused = false; - socket._disableWriteEvent(); - } -} - -class _Socket extends Stream implements Socket { - RawSocket? _raw; // Set to null when the raw socket is closed. - bool _closed = false; // Set to true when the raw socket is closed. - final _controller = new StreamController(sync: true); - bool _controllerClosed = false; - late _SocketStreamConsumer _consumer; - late IOSink _sink; - StreamSubscription? _subscription; - var _detachReady; - - _Socket(RawSocket raw) : _raw = raw { - _controller - ..onListen = _onSubscriptionStateChange - ..onCancel = _onSubscriptionStateChange - ..onPause = _onPauseStateChange - ..onResume = _onPauseStateChange; - _consumer = new _SocketStreamConsumer(this); - _sink = new IOSink(_consumer); - - // Disable read events until there is a subscription. - raw.readEventsEnabled = false; - - // Disable write events until the consumer needs it for pending writes. - raw.writeEventsEnabled = false; - } - - factory _Socket._writePipe() { - return new _Socket(new _RawSocket._writePipe()); - } - - factory _Socket._readPipe([int? fd]) { - return new _Socket(new _RawSocket._readPipe(fd)); - } - - // Note: this code seems a bit suspicious because _raw can be _RawSocket and - // it can be _RawSecureSocket because _SecureSocket extends _Socket - // and these two types are incompatible because _RawSecureSocket._socket - // is Socket and not _NativeSocket. - _NativeSocket get _nativeSocket => (_raw as _RawSocket)._socket; - - StreamSubscription listen(void onData(Uint8List event)?, - {Function? onError, void onDone()?, bool? cancelOnError}) { - return _controller.stream.listen(onData, - onError: onError, onDone: onDone, cancelOnError: cancelOnError); - } - - Encoding get encoding => _sink.encoding; - - void set encoding(Encoding value) { - _sink.encoding = value; - } - - void write(Object? obj) => _sink.write(obj); - - void writeln([Object? obj = ""]) => _sink.writeln(obj); - - void writeCharCode(int charCode) => _sink.writeCharCode(charCode); - - void writeAll(Iterable objects, [String sep = ""]) => - _sink.writeAll(objects, sep); - - void add(List bytes) => _sink.add(bytes); - - void addError(Object error, [StackTrace? stackTrace]) { - throw new UnsupportedError("Cannot send errors on sockets"); - } - - Future addStream(Stream> stream) { - return _sink.addStream(stream); - } - - Future flush() => _sink.flush(); - - Future close() => _sink.close(); - - Future get done => _sink.done; - - void destroy() { - // Destroy can always be called to get rid of a socket. - if (_raw == null) return; - _consumer.stop(); - _closeRawSocket(); - _controllerClosed = true; - _controller.close(); - } - - bool setOption(SocketOption option, bool enabled) { - final raw = _raw; - if (raw == null) throw const SocketException.closed(); - return raw.setOption(option, enabled); - } - - Uint8List getRawOption(RawSocketOption option) { - final raw = _raw; - if (raw == null) throw const SocketException.closed(); - return raw.getRawOption(option); - } - - void setRawOption(RawSocketOption option) { - final raw = _raw; - if (raw == null) throw const SocketException.closed(); - raw.setRawOption(option); - } - - int get port { - final raw = _raw; - if (raw == null) throw const SocketException.closed(); - return raw.port; - } - - InternetAddress get address { - final raw = _raw; - if (raw == null) throw const SocketException.closed(); - return raw.address; - } - - int get remotePort { - final raw = _raw; - if (raw == null) throw const SocketException.closed(); - return raw.remotePort; - } - - InternetAddress get remoteAddress { - final raw = _raw; - if (raw == null) throw const SocketException.closed(); - return raw.remoteAddress; - } - - Future _detachRaw() { - _detachReady = new Completer(); - _sink.close(); - return _detachReady.future.then((_) { - assert(_consumer.buffer == null); - var raw = _raw; - _raw = null; - return [raw, _subscription]; - }); - } - - // Ensure a subscription on the raw socket. Both the stream and the - // consumer needs a subscription as they share the error and done - // events from the raw socket. - void _ensureRawSocketSubscription() { - final raw = _raw; - if (_subscription == null && raw != null) { - _subscription = raw.listen(_onData, - onError: _onError, onDone: _onDone, cancelOnError: true); - } - } - - _closeRawSocket() { - var raw = _raw!; - _raw = null; - _closed = true; - raw.close(); - } - - void _onSubscriptionStateChange() { - final raw = _raw; - if (_controller.hasListener) { - _ensureRawSocketSubscription(); - // Enable read events for providing data to subscription. - if (raw != null) { - raw.readEventsEnabled = true; - } - } else { - _controllerClosed = true; - if (raw != null) { - raw.shutdown(SocketDirection.receive); - } - } - } - - void _onPauseStateChange() { - _raw?.readEventsEnabled = !_controller.isPaused; - } - - void _onData(event) { - switch (event) { - case RawSocketEvent.read: - if (_raw == null) break; - var buffer = _raw!.read(); - if (buffer != null) _controller.add(buffer); - break; - case RawSocketEvent.write: - _consumer.write(); - break; - case RawSocketEvent.readClosed: - _controllerClosed = true; - _controller.close(); - break; - } - } - - void _onDone() { - if (!_controllerClosed) { - _controllerClosed = true; - _controller.close(); - } - _consumer.done(); - } - - void _onError(error, stackTrace) { - if (!_controllerClosed) { - _controllerClosed = true; - _controller.addError(error, stackTrace); - _controller.close(); - } - _consumer.done(error, stackTrace); - } - - int _write(List data, int offset, int length) { - final raw = _raw; - if (raw != null) { - return raw.write(data, offset, length); - } - return 0; - } - - void _enableWriteEvent() { - _raw?.writeEventsEnabled = true; - } - - void _disableWriteEvent() { - _raw?.writeEventsEnabled = false; - } - - void _consumerDone() { - if (_detachReady != null) { - _detachReady.complete(null); - } else { - final raw = _raw; - if (raw != null) { - raw.shutdown(SocketDirection.send); - _disableWriteEvent(); - } - } - } - - void set _owner(owner) { - // Note: _raw can be _RawSocket and _RawSecureSocket which are two - // incompatible types. - (_raw as dynamic)._owner = owner; - } -} - -@patch -class RawDatagramSocket { - @patch - static Future bind(host, int port, - {bool reuseAddress: true, bool reusePort: false, int ttl: 1}) { - return _RawDatagramSocket.bind(host, port, reuseAddress, reusePort, ttl); - } -} - -class _RawDatagramSocket extends Stream - implements RawDatagramSocket { - _NativeSocket _socket; - late StreamController _controller; - bool _readEventsEnabled = true; - bool _writeEventsEnabled = true; - - _RawDatagramSocket(this._socket) { - var zone = Zone.current; - _controller = new StreamController( - sync: true, - onListen: _onSubscriptionStateChange, - onCancel: _onSubscriptionStateChange, - onPause: _onPauseStateChange, - onResume: _onPauseStateChange); - _socket.setHandlers( - read: () => _controller.add(RawSocketEvent.read), - write: () { - // The write event handler is automatically disabled by the - // event handler when it fires. - writeEventsEnabled = false; - _controller.add(RawSocketEvent.write); - }, - closed: () => _controller.add(RawSocketEvent.readClosed), - destroyed: () { - _controller.add(RawSocketEvent.closed); - _controller.close(); - }, - error: zone.bindBinaryCallbackGuarded((Object e, StackTrace? st) { - _controller.addError(e, st); - _socket.close(); - })); - } - - static Future bind( - host, int port, bool reuseAddress, bool reusePort, int ttl) { - _throwOnBadPort(port); - _throwOnBadTtl(ttl); - return _NativeSocket.bindDatagram(host, port, reuseAddress, reusePort, ttl) - .then((socket) { - if (!const bool.fromEnvironment("dart.vm.product")) { - _SocketProfile.collectNewSocket( - socket.nativeGetSocketId(), _udpSocket, socket.address, port); - } - return _RawDatagramSocket(socket); - }); - } - - StreamSubscription listen(void onData(RawSocketEvent event)?, - {Function? onError, void onDone()?, bool? cancelOnError}) { - return _controller.stream.listen(onData, - onError: onError, onDone: onDone, cancelOnError: cancelOnError); - } - - Future close() => _socket.close().then((_) { - if (!const bool.fromEnvironment("dart.vm.product")) { - _SocketProfile.collectStatistic( - _socket.nativeGetSocketId(), _SocketProfileType.endTime); - } - return this; - }); - - int send(List buffer, InternetAddress address, int port) => - _socket.send(buffer, 0, buffer.length, address, port); - - Datagram? receive() { - return _socket.receive(); - } - - void joinMulticast(InternetAddress group, [NetworkInterface? interface]) { - _socket.joinMulticast(group, interface); - } - - void leaveMulticast(InternetAddress group, [NetworkInterface? interface]) { - _socket.leaveMulticast(group, interface); - } - - bool get readEventsEnabled => _readEventsEnabled; - void set readEventsEnabled(bool value) { - if (value != _readEventsEnabled) { - _readEventsEnabled = value; - if (!_controller.isPaused) _resume(); - } - } - - bool get writeEventsEnabled => _writeEventsEnabled; - void set writeEventsEnabled(bool value) { - if (value != _writeEventsEnabled) { - _writeEventsEnabled = value; - if (!_controller.isPaused) _resume(); - } - } - - bool get multicastLoopback => - _socket.getOption(SocketOption._ipMulticastLoop); - void set multicastLoopback(bool value) => - _socket.setOption(SocketOption._ipMulticastLoop, value); - - int get multicastHops => _socket.getOption(SocketOption._ipMulticastHops); - void set multicastHops(int value) => - _socket.setOption(SocketOption._ipMulticastHops, value); - - NetworkInterface get multicastInterface => throw UnimplementedError(); - void set multicastInterface(NetworkInterface? value) => - throw UnimplementedError(); - - bool get broadcastEnabled => _socket.getOption(SocketOption._ipBroadcast); - void set broadcastEnabled(bool value) => - _socket.setOption(SocketOption._ipBroadcast, value); - - int get port => _socket.port; - - InternetAddress get address => _socket.address; - - _pause() { - _socket.setListening(read: false, write: false); - } - - void _resume() { - _socket.setListening(read: _readEventsEnabled, write: _writeEventsEnabled); - } - - void _onPauseStateChange() { - if (_controller.isPaused) { - _pause(); - } else { - _resume(); - } - } - - void _onSubscriptionStateChange() { - if (_controller.hasListener) { - _resume(); - } else { - _socket.close(); - } - } - - Uint8List getRawOption(RawSocketOption option) => - _socket.getRawOption(option); - void setRawOption(RawSocketOption option) => _socket.setRawOption(option); -} - -@pragma("vm:entry-point", "call") -Datagram _makeDatagram( - Uint8List data, String address, Uint8List in_addr, int port, int type) { - return new Datagram( - data, - _InternetAddress(InternetAddressType._from(type), address, null, in_addr), - port); -} diff --git a/sdk_nnbd/lib/_internal/vm/bin/stdio_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/stdio_patch.dart deleted file mode 100644 index bc3222151a8..00000000000 --- a/sdk_nnbd/lib/_internal/vm/bin/stdio_patch.dart +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright (c) 2013, 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. - -// part of "common_patch.dart"; - -@patch -class _StdIOUtils { - @patch - static Stdin _getStdioInputStream(int fd) { - final type = _getStdioHandleType(fd); - if (type is OSError) { - throw FileSystemException( - "Failed to get type of stdio handle (fd $fd)", "", type); - } - switch (type) { - case _stdioHandleTypeTerminal: - case _stdioHandleTypePipe: - case _stdioHandleTypeSocket: - case _stdioHandleTypeOther: - return new Stdin._(new _Socket._readPipe(fd), fd); - case _stdioHandleTypeFile: - return new Stdin._(new _FileStream.forStdin(), fd); - } - throw new UnsupportedError("Unexpected handle type $type"); - } - - @patch - static _getStdioOutputStream(int fd) { - final type = _getStdioHandleType(fd); - if (type is OSError) { - throw FileSystemException( - "Failed to get type of stdio handle (fd $fd)", "", type); - } - return new Stdout._(new IOSink(new _StdConsumer(fd)), fd); - } - - @patch - static int? _socketType(Socket socket) { - if (socket is _Socket) return _nativeSocketType(socket._nativeSocket); - return null; - } - - static int _nativeSocketType(_NativeSocket nativeSocket) { - var result = _getSocketType(nativeSocket); - if (result is OSError) { - throw new FileSystemException("Error retrieving socket type", "", result); - } - return result; - } - - @patch - static _getStdioHandleType(int fd) native "File_GetStdioHandleType"; -} - -@patch -class Stdin { - @patch - int readByteSync() { - var result = _readByte(_fd); - if (result is OSError) { - throw new StdinException("Error reading byte from stdin", result); - } - return result; - } - - @patch - bool get echoMode { - var result = _echoMode(_fd); - if (result is OSError) { - throw new StdinException("Error getting terminal echo mode", result); - } - return result; - } - - @patch - void set echoMode(bool enabled) { - if (!_EmbedderConfig._maySetEchoMode) { - throw new UnsupportedError( - "This embedder disallows setting Stdin.echoMode"); - } - var result = _setEchoMode(_fd, enabled); - if (result is OSError) { - throw new StdinException("Error setting terminal echo mode", result); - } - } - - @patch - bool get lineMode { - var result = _lineMode(_fd); - if (result is OSError) { - throw new StdinException("Error getting terminal line mode", result); - } - return result; - } - - @patch - void set lineMode(bool enabled) { - if (!_EmbedderConfig._maySetLineMode) { - throw new UnsupportedError( - "This embedder disallows setting Stdin.lineMode"); - } - var result = _setLineMode(_fd, enabled); - if (result is OSError) { - throw new StdinException("Error setting terminal line mode", result); - } - } - - @patch - bool get supportsAnsiEscapes { - var result = _supportsAnsiEscapes(_fd); - if (result is OSError) { - throw new StdinException("Error determining ANSI support", result); - } - return result; - } - - static _echoMode(int fd) native "Stdin_GetEchoMode"; - static _setEchoMode(int fd, bool enabled) native "Stdin_SetEchoMode"; - static _lineMode(int fd) native "Stdin_GetLineMode"; - static _setLineMode(int fd, bool enabled) native "Stdin_SetLineMode"; - static _readByte(int fd) native "Stdin_ReadByte"; - static _supportsAnsiEscapes(int fd) native "Stdin_AnsiSupported"; -} - -@patch -class Stdout { - @patch - bool _hasTerminal(int fd) { - try { - _terminalSize(fd); - return true; - } catch (_) { - return false; - } - } - - @patch - int _terminalColumns(int fd) => _terminalSize(fd)[0]; - @patch - int _terminalLines(int fd) => _terminalSize(fd)[1]; - - static List _terminalSize(int fd) { - var size = _getTerminalSize(fd); - if (size is! List) { - throw new StdoutException("Could not get terminal size", size); - } - return size; - } - - static _getTerminalSize(int fd) native "Stdout_GetTerminalSize"; - - @patch - static bool _supportsAnsiEscapes(int fd) { - var result = _getAnsiSupported(fd); - if (result is! bool) { - throw new StdoutException("Error determining ANSI support", result); - } - return result; - } - - static _getAnsiSupported(int fd) native "Stdout_AnsiSupported"; -} - -bool _getStdioHandle(_NativeSocket socket, int num) - native "Socket_GetStdioHandle"; -_getSocketType(_NativeSocket nativeSocket) native "Socket_GetType"; diff --git a/sdk_nnbd/lib/_internal/vm/bin/sync_socket_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/sync_socket_patch.dart deleted file mode 100644 index f60244944af..00000000000 --- a/sdk_nnbd/lib/_internal/vm/bin/sync_socket_patch.dart +++ /dev/null @@ -1,331 +0,0 @@ -// Copyright (c) 2017, 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. - -// part of "common_patch.dart"; - -@patch -class RawSynchronousSocket { - @patch - static RawSynchronousSocket connectSync(host, int port) { - return _RawSynchronousSocket.connectSync(host, port); - } -} - -class _RawSynchronousSocket implements RawSynchronousSocket { - final _NativeSynchronousSocket _socket; - - _RawSynchronousSocket(this._socket); - - static RawSynchronousSocket connectSync(host, int port) { - _throwOnBadPort(port); - return new _RawSynchronousSocket( - _NativeSynchronousSocket.connectSync(host, port)); - } - - InternetAddress get address => _socket.address; - int get port => _socket.port; - InternetAddress get remoteAddress => _socket.remoteAddress; - int get remotePort => _socket.remotePort; - - int available() => _socket.available; - - void closeSync() => _socket.closeSync(); - - int readIntoSync(List buffer, [int start = 0, int? end]) => - _socket.readIntoSync(buffer, start, end); - - List? readSync(int bytes) => _socket.readSync(bytes); - - void shutdown(SocketDirection direction) => _socket.shutdown(direction); - - void writeFromSync(List buffer, [int start = 0, int? end]) => - _socket.writeFromSync(buffer, start, end); -} - -// The NativeFieldWrapperClass1 can not be used with a mixin, due to missing -// implicit constructor. -class _NativeSynchronousSocketNativeWrapper extends NativeFieldWrapperClass1 {} - -// The _NativeSynchronousSocket class encapsulates a synchronous OS socket. -class _NativeSynchronousSocket extends _NativeSynchronousSocketNativeWrapper { - // Socket close state. - bool isClosed = false; - bool isClosedRead = false; - bool isClosedWrite = false; - - // Holds the address used to connect the socket. - late InternetAddress localAddress; - - // Holds the port of the socket, 0 if not known. - int localPort = 0; - - // Always set by setupResourceInfo called by connectSync. - late _SocketResourceInfo resourceInfo; - - static _NativeSynchronousSocket connectSync(host, int port) { - if (host == null) { - throw new ArgumentError("Parameter host cannot be null"); - } - late List<_InternetAddress> addresses; - var error = null; - if (host is _InternetAddress) { - addresses = [host]; - } else { - try { - addresses = lookup(host); - } catch (e) { - error = e; - } - if (error != null || addresses == null || addresses.isEmpty) { - throw createError(error, "Failed host lookup: '$host'"); - } - } - var it = addresses.iterator; - _NativeSynchronousSocket connectNext() { - if (!it.moveNext()) { - // Could not connect. Throw the first connection error we encountered. - assert(error != null); - throw error; - } - var address = it.current; - var socket = new _NativeSynchronousSocket(); - socket.localAddress = address; - var result = socket._nativeCreateConnectSync(address._in_addr, port); - if (result is OSError) { - // Keep first error, if present. - if (error == null) { - error = createError(result, "Connection failed", address, port); - } - return connectNext(); - } else { - // Query the local port, for error messages. - try { - socket.port; - } catch (e) { - if (error == null) { - error = createError(e, "Connection failed", address, port); - } - return connectNext(); - } - setupResourceInfo(socket); - } - return socket; - } - - return connectNext(); - } - - InternetAddress get address => localAddress; - int get available => _nativeAvailable(); - - int get port { - if (localPort != 0) { - return localPort; - } - if (isClosed) { - throw const SocketException.closed(); - } - var result = _nativeGetPort(); - if (result is OSError) { - throw result; - } - return localPort = result; - } - - InternetAddress get remoteAddress { - if (isClosed) { - throw const SocketException.closed(); - } - var result = _nativeGetRemotePeer(); - if (result is OSError) { - throw result; - } - var addr = result[0]; - var type = InternetAddressType._from(addr[0]); - if (type == InternetAddressType.unix) { - return _InternetAddress.fromString(addr[1], - type: InternetAddressType.unix); - } - return _InternetAddress(type, addr[1], null, addr[2]); - } - - int get remotePort { - if (isClosed) { - throw const SocketException.closed(); - } - var result = _nativeGetRemotePeer(); - if (result is OSError) { - throw result; - } - return result[1]; - } - - void closeSync() { - if (!isClosed) { - _nativeCloseSync(); - _SocketResourceInfo.SocketClosed(resourceInfo); - isClosed = true; - } - } - - // Create the appropriate error/exception from different returned - // error objects. - static createError(error, String message, - [InternetAddress? address, int? port]) { - if (error is OSError) { - return new SocketException(message, - osError: error, address: address, port: port); - } else { - return new SocketException(message, address: address, port: port); - } - } - - static List<_InternetAddress> lookup(String host, - {InternetAddressType type: InternetAddressType.ANY}) { - var response = _nativeLookupRequest(host, type._value); - if (response is OSError) { - throw response; - } - return <_InternetAddress>[ - for (int i = 0; i < response.length; ++i) - new _InternetAddress(InternetAddressType._from(response[i][0]), - response[i][1], host, response[i][2]), - ]; - } - - int readIntoSync(List buffer, int start, int? end) { - // TODO(40614): Remove once non-nullability is sound. - ArgumentError.checkNotNull(buffer, "buffer"); - ArgumentError.checkNotNull(start, "start"); - _checkAvailable(); - if (isClosedRead) { - throw new SocketException("Socket is closed for reading"); - } - end = RangeError.checkValidRange(start, end, buffer.length); - if (end == start) { - return 0; - } - var result = _nativeReadInto(buffer, start, end - start); - if (result is OSError) { - throw new SocketException("readIntoSync failed", osError: result); - } - resourceInfo.addRead(result); - return result; - } - - List? readSync(int len) { - _checkAvailable(); - if (isClosedRead) { - throw new SocketException("Socket is closed for reading"); - } - - if ((len != null) && (len < 0)) { - throw new ArgumentError("Illegal length $len"); - } - if (len == 0) { - return null; - } - var result = _nativeRead(len); - if (result is OSError) { - throw result; - } - if (result is List) { - resourceInfo.totalRead += result.length; - } - resourceInfo.didRead(); - return result; - } - - static void setupResourceInfo(_NativeSynchronousSocket socket) { - socket.resourceInfo = new _SocketResourceInfo(socket); - } - - void shutdown(SocketDirection direction) { - if (isClosed) { - return; - } - switch (direction) { - case SocketDirection.receive: - shutdownRead(); - break; - case SocketDirection.send: - shutdownWrite(); - break; - case SocketDirection.both: - closeSync(); - break; - default: - throw new ArgumentError(direction); - } - } - - void shutdownRead() { - if (isClosed || isClosedRead) { - return; - } - if (isClosedWrite) { - closeSync(); - } else { - _nativeShutdownRead(); - } - isClosedRead = true; - } - - void shutdownWrite() { - if (isClosed || isClosedWrite) { - return; - } - if (isClosedRead) { - closeSync(); - } else { - _nativeShutdownWrite(); - } - isClosedWrite = true; - } - - void writeFromSync(List buffer, int start, int? end) { - // TODO(40614): Remove once non-nullability is sound. - ArgumentError.checkNotNull(buffer, "buffer"); - ArgumentError.checkNotNull(start, "start"); - _checkAvailable(); - if (isClosedWrite) { - throw new SocketException("Socket is closed for writing"); - } - end = RangeError.checkValidRange(start, end, buffer.length); - if (end == start) { - return; - } - _BufferAndStart bufferAndStart = - _ensureFastAndSerializableByteData(buffer, start, end); - var result = _nativeWrite(bufferAndStart.buffer, bufferAndStart.start, - end - (start - bufferAndStart.start)); - if (result is OSError) { - throw new SocketException("writeFromSync failed", osError: result); - } - resourceInfo.addWrite(result); - } - - void _checkAvailable() { - if (isClosed) { - throw const SocketException.closed(); - } - } - - // Native method declarations. - static _nativeLookupRequest(host, int type) - native "SynchronousSocket_LookupRequest"; - _nativeCreateConnectSync(host, int port) - native "SynchronousSocket_CreateConnectSync"; - _nativeAvailable() native "SynchronousSocket_Available"; - _nativeCloseSync() native "SynchronousSocket_CloseSync"; - int _nativeGetPort() native "SynchronousSocket_GetPort"; - List _nativeGetRemotePeer() native "SynchronousSocket_GetRemotePeer"; - _nativeRead(int len) native "SynchronousSocket_Read"; - _nativeReadInto(List buffer, int offset, int bytes) - native "SynchronousSocket_ReadList"; - _nativeShutdownRead() native "SynchronousSocket_ShutdownRead"; - _nativeShutdownWrite() native "SynchronousSocket_ShutdownWrite"; - _nativeWrite(List buffer, int offset, int bytes) - native "SynchronousSocket_WriteList"; -} diff --git a/sdk_nnbd/lib/_internal/vm/bin/vmservice_io.dart b/sdk_nnbd/lib/_internal/vm/bin/vmservice_io.dart deleted file mode 100644 index aea026bebfc..00000000000 --- a/sdk_nnbd/lib/_internal/vm/bin/vmservice_io.dart +++ /dev/null @@ -1,266 +0,0 @@ -// Copyright (c) 2013, 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 vmservice_io; - -import 'dart:async'; -import 'dart:convert'; -import 'dart:io'; -import 'dart:_vmservice'; - -part 'vmservice_server.dart'; - -// The TCP ip/port that the HTTP server listens on. -@pragma('vm:entry-point') -int _port = 0; -@pragma('vm:entry-point') -String _ip = ''; -// Should the HTTP server auto start? -@pragma('vm:entry-point') -bool _autoStart = false; -// Should the HTTP server require an auth code? -@pragma('vm:entry-point') -bool _authCodesDisabled = false; -// Should the HTTP server run in devmode? -@pragma('vm:entry-point') -bool _originCheckDisabled = false; -// Location of file to output VM service connection info. -@pragma('vm:entry-point') -String? _serviceInfoFilename; -@pragma('vm:entry-point') -bool _isWindows = false; -@pragma('vm:entry-point') -bool _isFuchsia = false; -@pragma('vm:entry-point') -var _signalWatch = null; -var _signalSubscription; -@pragma("vm:entry-point") -bool _enableServicePortFallback = false; - -// HTTP server. -Server? server; -Future? serverFuture; - -Server _lazyServerBoot() { - var localServer = server; - if (localServer != null) { - return localServer; - } - // Lazily create service. - final service = VMService(); - // Lazily create server. - localServer = Server(service, _ip, _port, _originCheckDisabled, - _authCodesDisabled, _serviceInfoFilename, _enableServicePortFallback); - server = localServer; - return localServer; -} - -Future cleanupCallback() async { - // Cancel the sigquit subscription. - if (_signalSubscription != null) { - await _signalSubscription.cancel(); - _signalSubscription = null; - } - final localServer = server; - if (localServer != null) { - try { - await localServer.cleanup(true); - } catch (e, st) { - print('Error in vm-service shutdown: $e\n$st\n'); - } - } - if (_registerSignalHandlerTimer != null) { - _registerSignalHandlerTimer!.cancel(); - _registerSignalHandlerTimer = null; - } - // Call out to embedder's shutdown callback. - _shutdown(); -} - -Future createTempDirCallback(String base) async { - final temp = await Directory.systemTemp.createTemp(base); - // Underneath the temporary directory, create a directory with the - // same name as the DevFS name [base]. - final fsUri = temp.uri.resolveUri(Uri.directory(base)); - await Directory.fromUri(fsUri).create(); - return fsUri; -} - -Future deleteDirCallback(Uri path) async => - await Directory.fromUri(path).delete(recursive: true); - -class PendingWrite { - PendingWrite(this.uri, this.bytes); - final completer = Completer(); - final Uri uri; - final List bytes; - - Future write() async { - final file = File.fromUri(uri); - final parent_directory = file.parent; - await parent_directory.create(recursive: true); - if (await file.exists()) { - await file.delete(); - } - await file.writeAsBytes(bytes); - completer.complete(); - WriteLimiter._writeCompleted(); - } -} - -class WriteLimiter { - static final pendingWrites = []; - - // non-rooted Android devices have a very low limit for the number of - // open files. Artificially cap ourselves to 16. - static const kMaxOpenWrites = 16; - static int openWrites = 0; - - static Future scheduleWrite(Uri path, List bytes) async { - // Create a new pending write. - final pw = PendingWrite(path, bytes); - pendingWrites.add(pw); - _maybeWriteFiles(); - return pw.completer.future; - } - - static _maybeWriteFiles() { - while (openWrites < kMaxOpenWrites) { - if (pendingWrites.length > 0) { - final pw = pendingWrites.removeLast(); - pw.write(); - openWrites++; - } else { - break; - } - } - } - - static _writeCompleted() { - openWrites--; - assert(openWrites >= 0); - _maybeWriteFiles(); - } -} - -Future writeFileCallback(Uri path, List bytes) async => - WriteLimiter.scheduleWrite(path, bytes); - -Future writeStreamFileCallback(Uri path, Stream> bytes) async { - final file = File.fromUri(path); - final parent_directory = file.parent; - await parent_directory.create(recursive: true); - if (await file.exists()) { - await file.delete(); - } - final sink = await file.openWrite(); - await sink.addStream(bytes); - await sink.close(); -} - -Future> readFileCallback(Uri path) async => - await File.fromUri(path).readAsBytes(); - -Future>> listFilesCallback(Uri dirPath) async { - final dir = Directory.fromUri(dirPath); - final dirPathStr = dirPath.path; - final stream = dir.list(recursive: true); - final result = >[]; - await for (var fileEntity in stream) { - final filePath = Uri.file(fileEntity.path).path; - final stat = await fileEntity.stat(); - if (stat.type == FileSystemEntityType.file && - filePath.startsWith(dirPathStr)) { - final map = {}; - map['name'] = '/' + filePath.substring(dirPathStr.length); - map['size'] = stat.size; - map['modified'] = stat.modified.millisecondsSinceEpoch; - result.add(map); - } - } - return result; -} - -Uri? serverInformationCallback() => _lazyServerBoot().serverAddress; - -Future webServerControlCallback(bool enable) async { - final _server = _lazyServerBoot(); - if (_server.running != enable) { - if (enable) { - await _server.startup(); - } else { - await _server.shutdown(true); - } - } - return _server.serverAddress; -} - -void webServerAcceptNewWebSocketConnections(bool enable) { - final _server = _lazyServerBoot(); - _server.acceptNewWebSocketConnections = enable; -} - -void _clearFuture(_) { - serverFuture = null; -} - -_onSignal(ProcessSignal signal) { - if (serverFuture != null) { - // Still waiting. - return; - } - final _server = _lazyServerBoot(); - // Toggle HTTP server. - if (_server.running) { - _server.shutdown(true).then(_clearFuture); - } else { - _server.startup().then(_clearFuture); - } -} - -Timer? _registerSignalHandlerTimer; - -_registerSignalHandler() { - _registerSignalHandlerTimer = null; - if (_signalWatch == null) { - // Cannot register for signals. - return; - } - if (_isWindows || _isFuchsia) { - // Cannot register for signals on Windows or Fuchsia. - return; - } - _signalSubscription = _signalWatch(ProcessSignal.sigquit).listen(_onSignal); -} - -@pragma('vm:entry-point', !const bool.fromEnvironment('dart.vm.product')) -main() { - // Set embedder hooks. - VMServiceEmbedderHooks.cleanup = cleanupCallback; - VMServiceEmbedderHooks.createTempDir = createTempDirCallback; - VMServiceEmbedderHooks.deleteDir = deleteDirCallback; - VMServiceEmbedderHooks.writeFile = writeFileCallback; - VMServiceEmbedderHooks.writeStreamFile = writeStreamFileCallback; - VMServiceEmbedderHooks.readFile = readFileCallback; - VMServiceEmbedderHooks.listFiles = listFilesCallback; - VMServiceEmbedderHooks.serverInformation = serverInformationCallback; - VMServiceEmbedderHooks.webServerControl = webServerControlCallback; - VMServiceEmbedderHooks.acceptNewWebSocketConnections = - webServerAcceptNewWebSocketConnections; - // Always instantiate the vmservice object so that the exit message - // can be delivered and waiting loaders can be cancelled. - VMService(); - if (_autoStart) { - final _server = _lazyServerBoot(); - _server.startup(); - // It's just here to push an event on the event loop so that we invoke the - // scheduled microtasks. - Timer.run(() {}); - } - // Register signal handler after a small delay to avoid stalling main - // isolate startup. - _registerSignalHandlerTimer = Timer(shortDelay, _registerSignalHandler); -} - -_shutdown() native 'VMServiceIO_Shutdown'; diff --git a/sdk_nnbd/lib/_internal/vm/bin/vmservice_server.dart b/sdk_nnbd/lib/_internal/vm/bin/vmservice_server.dart deleted file mode 100644 index 26f1bfa86aa..00000000000 --- a/sdk_nnbd/lib/_internal/vm/bin/vmservice_server.dart +++ /dev/null @@ -1,511 +0,0 @@ -// Copyright (c) 2013, 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. - -part of vmservice_io; - -final bool silentObservatory = bool.fromEnvironment('SILENT_OBSERVATORY'); - -void serverPrint(String s) { - if (silentObservatory) { - // We've been requested to be silent. - return; - } - print(s); -} - -class WebSocketClient extends Client { - static const int parseErrorCode = 4000; - static const int binaryMessageErrorCode = 4001; - static const int notMapErrorCode = 4002; - static const int idErrorCode = 4003; - final WebSocket socket; - - WebSocketClient(this.socket, VMService service) : super(service) { - socket.listen((message) => onWebSocketMessage(message)); - socket.done.then((_) => close()); - } - - disconnect() { - if (socket != null) { - socket.close(); - } - } - - void onWebSocketMessage(message) { - if (message is String) { - Map map; - try { - map = json.decode(message); - } catch (e) { - socket.close(parseErrorCode, 'Message parse error: $e'); - return; - } - if (map is! Map) { - socket.close(notMapErrorCode, 'Message must be a JSON map.'); - return; - } - try { - final rpc = Message.fromJsonRpc(this, map); - switch (rpc.type) { - case MessageType.Request: - onRequest(rpc); - break; - case MessageType.Notification: - onNotification(rpc); - break; - case MessageType.Response: - onResponse(rpc); - break; - } - } on dynamic catch (e) { - socket.close(idErrorCode, e.message); - } - } else { - socket.close(binaryMessageErrorCode, 'Message must be a string.'); - } - } - - void post(Response? result) { - if (result == null) { - // The result of a notification event. Do nothing. - return; - } - try { - switch (result.kind) { - case ResponsePayloadKind.String: - case ResponsePayloadKind.Binary: - socket.add(result.payload); - break; - case ResponsePayloadKind.Utf8String: - socket.addUtf8Text(result.payload); - break; - } - } on StateError catch (_) { - // VM has shutdown, do nothing. - return; - } - } - - Map toJson() => { - ...super.toJson(), - 'type': 'WebSocketClient', - 'socket': '$socket', - }; -} - -class HttpRequestClient extends Client { - static final jsonContentType = - ContentType('application', 'json', charset: 'utf-8'); - final HttpRequest request; - - HttpRequestClient(this.request, VMService service) - : super(service, sendEvents: false); - - disconnect() { - request.response.close(); - close(); - } - - void post(Response? result) { - if (result == null) { - // The result of a notification event. Nothing to do other than close the - // connection. - close(); - return; - } - - HttpResponse response = request.response; - // We closed the connection for bad origins earlier. - response.headers.add('Access-Control-Allow-Origin', '*'); - response.headers.contentType = jsonContentType; - switch (result.kind) { - case ResponsePayloadKind.String: - response.write(result.payload); - break; - case ResponsePayloadKind.Utf8String: - response.add(result.payload); - break; - case ResponsePayloadKind.Binary: - throw 'Can not handle binary responses'; - } - response.close(); - close(); - } - - Map toJson() { - final map = super.toJson(); - map['type'] = 'HttpRequestClient'; - map['request'] = '$request'; - return map; - } -} - -class Server { - static const WEBSOCKET_PATH = '/ws'; - static const ROOT_REDIRECT_PATH = '/index.html'; - - final VMService _service; - final String _ip; - final bool _originCheckDisabled; - final bool _authCodesDisabled; - final bool _enableServicePortFallback; - final String? _serviceInfoFilename; - HttpServer? _server; - bool get running => _server != null; - bool acceptNewWebSocketConnections = true; - int _port = -1; - - /// Returns the server address including the auth token. - Uri? get serverAddress { - if (!running) { - return null; - } - final server = _server!; - final ip = server.address.address; - final port = server.port; - final path = !_authCodesDisabled ? '$serviceAuthToken/' : '/'; - return Uri(scheme: 'http', host: ip, port: port, path: path); - } - - // On Fuchsia, authentication codes are disabled by default. To enable, the authentication token - // would have to be written into the hub alongside the port number. - Server( - this._service, - this._ip, - this._port, - this._originCheckDisabled, - bool authCodesDisabled, - this._serviceInfoFilename, - this._enableServicePortFallback) - : _authCodesDisabled = (authCodesDisabled || Platform.isFuchsia); - - bool _isAllowedOrigin(String origin) { - Uri uri; - try { - uri = Uri.parse(origin); - } catch (_) { - return false; - } - - // Explicitly add localhost and 127.0.0.1 on any port (necessary for - // adb port forwarding). - if ((uri.host == 'localhost') || - (uri.host == '::1') || - (uri.host == '127.0.0.1')) { - return true; - } - - final server = _server!; - if ((uri.port == server.port) && - ((uri.host == server.address.address) || - (uri.host == server.address.host))) { - return true; - } - - return false; - } - - bool _originCheck(HttpRequest request) { - if (_originCheckDisabled) { - // Always allow. - return true; - } - // First check the web-socket specific origin. - List? origins = request.headers['Sec-WebSocket-Origin']; - if (origins == null) { - // Fall back to the general Origin field. - origins = request.headers['Origin']; - } - if (origins == null) { - // No origin sent. This is a non-browser client or a same-origin request. - return true; - } - for (final origin in origins) { - if (_isAllowedOrigin(origin)) { - return true; - } - } - return false; - } - - /// Checks the [requestUri] for the service auth token and returns the path - /// as a String. If the service auth token check fails, returns null. - /// Returns a Uri if a redirect is required. - dynamic _checkAuthTokenAndGetPath(Uri requestUri) { - if (_authCodesDisabled) { - return requestUri.path == '/' ? ROOT_REDIRECT_PATH : requestUri.path; - } - final List requestPathSegments = requestUri.pathSegments; - if (requestPathSegments.isEmpty) { - // Malformed. - return null; - } - // Check that we were given the auth token. - final authToken = requestPathSegments[0]; - if (authToken != serviceAuthToken) { - // Malformed. - return null; - } - // Missing a trailing '/'. We'll need to redirect to serve - // ROOT_REDIRECT_PATH correctly, otherwise the response is misinterpreted. - if (requestPathSegments.length == 1) { - // requestPathSegments is unmodifiable. Copy it. - final pathSegments = List.from(requestPathSegments); - - // Adding an empty string to the path segments results in the path having - // a trailing '/'. - pathSegments.add(''); - - return requestUri.replace(pathSegments: pathSegments); - } - // Construct the actual request path by chopping off the auth token. - return (requestPathSegments[1] == '') - ? ROOT_REDIRECT_PATH - : '/${requestPathSegments.sublist(1).join('/')}'; - } - - Future _requestHandler(HttpRequest request) async { - if (!_originCheck(request)) { - // This is a cross origin attempt to connect - request.response.statusCode = HttpStatus.forbidden; - request.response.write('forbidden origin'); - request.response.close(); - return; - } - if (request.method == 'PUT') { - // PUT requests are forwarded to DevFS for processing. - - List fsNameList; - List? fsPathList; - List? fsPathBase64List; - List? fsUriBase64List; - Object? fsName; - Object? fsPath; - Uri? fsUri; - - try { - // Extract the fs name and fs path from the request headers. - fsNameList = request.headers['dev_fs_name']!; - fsName = fsNameList[0]; - - // Prefer Uri encoding first. - fsUriBase64List = request.headers['dev_fs_uri_b64']; - if ((fsUriBase64List != null) && (fsUriBase64List.length > 0)) { - final decodedFsUri = utf8.decode(base64.decode(fsUriBase64List[0])); - fsUri = Uri.parse(decodedFsUri); - } - - // Fallback to path encoding. - if (fsUri == null) { - fsPathList = request.headers['dev_fs_path']; - fsPathBase64List = request.headers['dev_fs_path_b64']; - // If the 'dev_fs_path_b64' header field was sent, use that instead. - if ((fsPathBase64List != null) && fsPathBase64List.isNotEmpty) { - fsPath = utf8.decode(base64.decode(fsPathBase64List[0])); - } else if (fsPathList != null && fsPathList.isNotEmpty) { - fsPath = fsPathList[0]; - } - } - } catch (e) {/* ignore */} - - String result; - try { - result = await _service.devfs.handlePutStream(fsName, fsPath, fsUri, - request.cast>().transform(gzip.decoder)); - } catch (e) { - request.response.statusCode = HttpStatus.internalServerError; - request.response.write(e); - request.response.close(); - return; - } - - if (result != null) { - request.response.headers.contentType = - HttpRequestClient.jsonContentType; - request.response.write(result); - } - request.response.close(); - return; - } - if (request.method != 'GET') { - // Not a GET request. Do nothing. - request.response.statusCode = HttpStatus.methodNotAllowed; - request.response.write('method not allowed'); - request.response.close(); - return; - } - - final result = _checkAuthTokenAndGetPath(request.uri); - if (result == null) { - // Either no authentication code was provided when one was expected or an - // incorrect authentication code was provided. - request.response.statusCode = HttpStatus.forbidden; - request.response.write('missing or invalid authentication code'); - request.response.close(); - return; - } else if (result is Uri) { - // The URI contains the valid auth token but is missing a trailing '/'. - // Redirect to the same URI with the trailing '/' to correctly serve - // index.html. - request.response.redirect(result); - return; - } - - final String path = result; - if (path == WEBSOCKET_PATH) { - if (acceptNewWebSocketConnections) { - WebSocketTransformer.upgrade(request, - compression: CompressionOptions.compressionOff) - .then((WebSocket webSocket) { - WebSocketClient(webSocket, _service); - }); - } else { - // Forward the websocket connection request to DDS. - request.response.redirect(_service.ddsUri!); - } - return; - } - - if (assets == null) { - request.response.headers.contentType = ContentType.text; - request.response.write('This VM was built without the Observatory UI.'); - request.response.close(); - return; - } - final asset = assets[path]; - if (asset != null) { - // Serving up a static asset (e.g. .css, .html, .png). - request.response.headers.contentType = ContentType.parse(asset.mimeType); - request.response.add(asset.data); - request.response.close(); - return; - } - // HTTP based service request. - final client = HttpRequestClient(request, _service); - final message = Message.fromUri( - client, Uri(path: path, queryParameters: request.uri.queryParameters)); - client.onRequest(message); // exception free, no need to try catch - } - - Future _dumpServiceInfoToFile(String serviceInfoFilenameLocal) async { - final serviceInfo = { - 'uri': serverAddress.toString(), - }; - final file = File.fromUri(Uri.parse(serviceInfoFilenameLocal)); - return file.writeAsString(json.encode(serviceInfo)); - } - - Future startup() async { - if (_server != null) { - // Already running. - return this; - } - - // Startup HTTP server. - var pollError; - var pollStack; - Future poll() async { - try { - var address; - var addresses = await InternetAddress.lookup(_ip); - // Prefer IPv4 addresses. - for (int i = 0; i < addresses.length; i++) { - address = addresses[i]; - if (address.type == InternetAddressType.IPv4) break; - } - _server = await HttpServer.bind(address, _port); - return true; - } catch (e, st) { - pollError = e; - pollStack = st; - return false; - } - } - - // poll for the network for ~10 seconds. - int attempts = 0; - final maxAttempts = 10; - while (!await poll()) { - attempts++; - serverPrint('Observatory server failed to start after $attempts tries'); - if (attempts > maxAttempts) { - serverPrint('Could not start Observatory HTTP server:\n' - '$pollError\n$pollStack\n'); - _notifyServerState(''); - onServerAddressChange(null); - return this; - } - if (_port != 0 && _enableServicePortFallback && attempts >= 3) { - _port = 0; - serverPrint('Falling back to automatic port selection'); - } - await Future.delayed(const Duration(seconds: 1)); - } - if (_service.isExiting) { - serverPrint('Observatory HTTP server exiting before listening as ' - 'vm service has received exit request\n'); - await shutdown(true); - return this; - } - final server = _server!; - server.listen(_requestHandler, cancelOnError: true); - serverPrint('Observatory listening on $serverAddress'); - if (Platform.isFuchsia) { - // Create a file with the port number. - final tmp = Directory.systemTemp.path; - final path = '$tmp/dart.services/${server.port}'; - serverPrint('Creating $path'); - File(path)..createSync(recursive: true); - } - final serviceInfoFilenameLocal = _serviceInfoFilename; - if (serviceInfoFilenameLocal != null && - serviceInfoFilenameLocal.isNotEmpty) { - await _dumpServiceInfoToFile(serviceInfoFilenameLocal); - } - // Server is up and running. - _notifyServerState(serverAddress.toString()); - onServerAddressChange('$serverAddress'); - return this; - } - - Future cleanup(bool force) { - final serverLocal = _server; - if (serverLocal == null) { - return Future.value(); - } - if (Platform.isFuchsia) { - // Remove the file with the port number. - final tmp = Directory.systemTemp.path; - final path = '$tmp/dart.services/${serverLocal.port}'; - serverPrint('Deleting $path'); - File(path)..deleteSync(); - } - return serverLocal.close(force: force); - } - - Future shutdown(bool forced) { - if (_server == null) { - // Not started. - return Future.value(this); - } - - // Shutdown HTTP server and subscription. - Uri oldServerAddress = serverAddress!; - return cleanup(forced).then((_) { - serverPrint('Observatory no longer listening on $oldServerAddress'); - _server = null; - _notifyServerState(''); - onServerAddressChange(null); - return this; - }).catchError((e, st) { - _server = null; - serverPrint('Could not shutdown Observatory HTTP server:\n$e\n$st\n'); - _notifyServerState(''); - onServerAddressChange(null); - return this; - }); - } -} - -void _notifyServerState(String uri) native 'VMServiceIO_NotifyServerState'; diff --git a/sdk_nnbd/lib/_internal/vm/lib/array.dart b/sdk_nnbd/lib/_internal/vm/lib/array.dart deleted file mode 100644 index 53048413284..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/array.dart +++ /dev/null @@ -1,268 +0,0 @@ -// Copyright (c) 2012, 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. - -// part of "core_patch.dart"; - -@pragma("vm:entry-point") -class _List extends FixedLengthListBase { - @pragma("vm:exact-result-type", - [_List, "result-type-uses-passed-type-arguments"]) - @pragma("vm:prefer-inline") - factory _List(length) native "List_allocate"; - - E operator [](int index) native "List_getIndexed"; - - void operator []=(int index, E value) { - _setIndexed(index, value); - } - - void _setIndexed(int index, E value) native "List_setIndexed"; - - @pragma("vm:exact-result-type", "dart:core#_Smi") - @pragma("vm:prefer-inline") - int get length native "List_getLength"; - - @pragma("vm:prefer-inline") - _List _slice(int start, int count, bool needsTypeArgument) { - if (count <= 64) { - final result = needsTypeArgument ? new _List(count) : new _List(count); - for (int i = 0; i < result.length; i++) { - result[i] = this[start + i]; - } - return result; - } else { - return _sliceInternal(start, count, needsTypeArgument); - } - } - - _List _sliceInternal(int start, int count, bool needsTypeArgument) - native "List_slice"; - - // List interface. - void setRange(int start, int end, Iterable iterable, [int skipCount = 0]) { - if (start < 0 || start > this.length) { - throw new RangeError.range(start, 0, this.length); - } - if (end < start || end > this.length) { - throw new RangeError.range(end, start, this.length); - } - int length = end - start; - if (length == 0) return; - if (identical(this, iterable)) { - Lists.copy(this, skipCount, this, start, length); - } else if (ClassID.getID(iterable) == ClassID.cidArray) { - final _List iterableAsList = unsafeCast<_List>(iterable); - Lists.copy(iterableAsList, skipCount, this, start, length); - } else if (iterable is List) { - Lists.copy(iterable, skipCount, this, start, length); - } else { - Iterator it = iterable.iterator; - while (skipCount > 0) { - if (!it.moveNext()) return; - skipCount--; - } - for (int i = start; i < end; i++) { - if (!it.moveNext()) return; - this[i] = it.current; - } - } - } - - void setAll(int index, Iterable iterable) { - if (index < 0 || index > this.length) { - throw new RangeError.range(index, 0, this.length, "index"); - } - List iterableAsList; - if (identical(this, iterable)) { - iterableAsList = this; - } else if (ClassID.getID(iterable) == ClassID.cidArray) { - iterableAsList = unsafeCast<_List>(iterable); - } else if (iterable is List) { - iterableAsList = iterable; - } else { - for (var value in iterable) { - this[index++] = value; - } - return; - } - int length = iterableAsList.length; - if (index + length > this.length) { - throw new RangeError.range(index + length, 0, this.length); - } - Lists.copy(iterableAsList, 0, this, index, length); - } - - List sublist(int start, [int? end]) { - final int listLength = this.length; - final int actualEnd = RangeError.checkValidRange(start, end, listLength); - int length = actualEnd - start; - if (length == 0) return []; - var result = new _GrowableList._withData(_slice(start, length, false)); - result._setLength(length); - return result; - } - - // Iterable interface. - - @pragma("vm:prefer-inline") - void forEach(f(E element)) { - final length = this.length; - for (int i = 0; i < length; i++) { - f(this[i]); - } - } - - @pragma("vm:prefer-inline") - Iterator get iterator { - return new _FixedSizeArrayIterator(this); - } - - E get first { - if (length > 0) return this[0]; - throw IterableElementError.noElement(); - } - - E get last { - if (length > 0) return this[length - 1]; - throw IterableElementError.noElement(); - } - - E get single { - if (length == 1) return this[0]; - if (length == 0) throw IterableElementError.noElement(); - throw IterableElementError.tooMany(); - } - - List toList({bool growable: true}) { - var length = this.length; - if (length > 0) { - _List result = _slice(0, length, !growable); - if (growable) { - return new _GrowableList._withData(result).._setLength(length); - } - return unsafeCast<_List>(result); - } - // _GrowableList._withData must not be called with empty list. - return growable ? [] : new _List(0); - } -} - -// This is essentially the same class as _List, but it does not -// permit any modification of array elements from Dart code. We use -// this class for arrays constructed from Dart array literals. -// TODO(hausner): We should consider the trade-offs between two -// classes (and inline cache misses) versus a field in the native -// implementation (checks when modifying). We should keep watching -// the inline cache misses. -@pragma("vm:entry-point") -class _ImmutableList extends UnmodifiableListBase { - factory _ImmutableList._uninstantiable() { - throw new UnsupportedError( - "ImmutableArray can only be allocated by the VM"); - } - - factory _ImmutableList._from(List from, int offset, int length) - native "ImmutableList_from"; - - E operator [](int index) native "List_getIndexed"; - - @pragma("vm:exact-result-type", "dart:core#_Smi") - @pragma("vm:prefer-inline") - int get length native "List_getLength"; - - List sublist(int start, [int? end]) { - final int actualEnd = RangeError.checkValidRange(start, end, this.length); - int length = actualEnd - start; - if (length == 0) return []; - final list = new _List(length); - for (int i = 0; i < length; i++) { - list[i] = this[start + i]; - } - final result = new _GrowableList._withData(list); - result._setLength(length); - return result; - } - - // Collection interface. - - @pragma("vm:prefer-inline") - void forEach(f(E element)) { - final length = this.length; - for (int i = 0; i < length; i++) { - f(this[i]); - } - } - - @pragma("vm:prefer-inline") - Iterator get iterator { - return new _FixedSizeArrayIterator(this); - } - - E get first { - if (length > 0) return this[0]; - throw IterableElementError.noElement(); - } - - E get last { - if (length > 0) return this[length - 1]; - throw IterableElementError.noElement(); - } - - E get single { - if (length == 1) return this[0]; - if (length == 0) throw IterableElementError.noElement(); - throw IterableElementError.tooMany(); - } - - List toList({bool growable: true}) { - final int length = this.length; - if (length > 0) { - if (growable) { - final list = new _List(length); - for (int i = 0; i < length; i++) { - list[i] = this[i]; - } - return _GrowableList._withData(list).._setLength(length); - } else { - final list = new _List(length); - for (int i = 0; i < length; i++) { - list[i] = this[i]; - } - return list; - } - } - return growable ? [] : new _List(0); - } -} - -// Iterator for arrays with fixed size. -class _FixedSizeArrayIterator implements Iterator { - final List _array; - final int _length; // Cache array length for faster access. - int _index; - E? _current; - - _FixedSizeArrayIterator(List array) - : _array = array, - _length = array.length, - _index = 0 { - assert(array is _List || array is _ImmutableList); - } - - E get current { - final cur = _current; - return (cur != null) ? cur : cur as E; - } - - @pragma("vm:prefer-inline") - bool moveNext() { - if (_index >= _length) { - _current = null; - return false; - } - _current = _array[_index]; - _index++; - return true; - } -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/array_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/array_patch.dart deleted file mode 100644 index ef181bee908..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/array_patch.dart +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright (c) 2012, 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. - -// part of "core_patch.dart"; - -@patch -class List { - @patch - factory List.empty({bool growable = false}) { - return growable ? [] : _List(0); - } - - @patch - factory List([int? length]) native "List_new"; - - @patch - factory List.filled(int length, E fill, {bool growable: false}) { - // All error handling on the length parameter is done at the implementation - // of new _List. - var result = growable ? new _GrowableList(length) : new _List(length); - if (fill != null) { - for (int i = 0; i < length; i++) { - result[i] = fill; - } - } - return result; - } - - @patch - factory List.from(Iterable elements, {bool growable: true}) { - if (elements is EfficientLengthIterable) { - int length = elements.length; - var list = growable ? new _GrowableList(length) : new _List(length); - if (length > 0) { - // Avoid creating iterator unless necessary. - int i = 0; - for (var element in elements) { - list[i++] = element; - } - } - return list; - } - // If elements is an Iterable, we won't need a type-test for each - // element. In the "common case" that elements is an Iterable, this - // replaces a type-test on every element with a single type-test before - // starting the loop. - if (elements is Iterable) { - List list = new _GrowableList(0); - for (E e in elements) { - list.add(e); - } - if (growable) return list; - return makeListFixedLength(list); - } else { - List list = new _GrowableList(0); - for (E e in elements) { - list.add(e); - } - if (growable) return list; - return makeListFixedLength(list); - } - } - - @patch - factory List.of(Iterable elements, {bool growable: true}) { - // TODO(32937): Specialize to benefit from known element type. - return List.from(elements, growable: growable); - } - - @patch - @pragma("vm:prefer-inline") - factory List.generate(int length, E generator(int index), - {bool growable = true}) { - final List result = - growable ? new _GrowableList(length) : new _List(length); - for (int i = 0; i < result.length; ++i) { - result[i] = generator(i); - } - return result; - } - - @patch - factory List.unmodifiable(Iterable elements) { - final result = new List.from(elements, growable: false); - return makeFixedListUnmodifiable(result); - } - - // Factory constructing a mutable List from a parser generated List literal. - // [elements] contains elements that are already type checked. - @pragma("vm:entry-point", "call") - factory List._fromLiteral(List elements) { - if (elements.isEmpty) { - return new _GrowableList(0); - } - final result = new _GrowableList._withData(unsafeCast<_List>(elements)); - result._setLength(elements.length); - return result; - } -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/async_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/async_patch.dart deleted file mode 100644 index c3201d3a13a..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/async_patch.dart +++ /dev/null @@ -1,334 +0,0 @@ -// 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. - -/// Note: the VM concatenates all patch files into a single patch file. This -/// file is the first patch in "dart:async" which contains all the imports used -/// by patches of that library. We plan to change this when we have a shared -/// front end and simply use parts. - -import "dart:_internal" show VMLibraryHooks, patch; - -/// These are the additional parts of this patch library: -// part "deferred_load_patch.dart"; -// part "schedule_microtask_patch.dart"; -// part "timer_patch.dart"; - -// Equivalent of calling FATAL from C++ code. -_fatal(msg) native "DartAsync_fatal"; - -class _AsyncAwaitCompleter implements Completer { - @pragma("vm:entry-point") - final _future = new _Future(); - @pragma("vm:entry-point") - bool isSync; - - @pragma("vm:entry-point") - _AsyncAwaitCompleter() : isSync = false; - - @pragma("vm:entry-point") - void complete([FutureOr? value]) { - // All paths require that if value is null, null as T succeeds. - value = (value == null) ? value as T : value; - if (!isSync) { - _future._asyncComplete(value); - } else if (value is Future) { - assert(!_future._isComplete); - _future._chainFuture(value); - } else { - // TODO(40014): Remove cast when type promotion works. - _future._completeWithValue(value as T); - } - } - - void completeError(Object e, [StackTrace? st]) { - st ??= AsyncError.defaultStackTrace(e); - if (isSync) { - _future._completeError(e, st); - } else { - _future._asyncCompleteError(e, st); - } - } - - @pragma("vm:entry-point") - void start(void Function() f) { - f(); - isSync = true; - } - - Future get future => _future; - bool get isCompleted => !_future._mayComplete; -} - -// We need to pass the value as first argument and leave the second and third -// arguments empty (used for error handling). -dynamic Function(dynamic) _asyncThenWrapperHelper( - dynamic Function(dynamic) continuation) { - // Any function that is used as an asynchronous callback must be registered - // in the current Zone. Normally, this is done by the future when a - // callback is registered (for example with `.then` or `.catchError`). In our - // case we want to reuse the same callback multiple times and therefore avoid - // the multiple registrations. For our internal futures (`_Future`) we can - // use the shortcut-version of `.then`, and skip the registration. However, - // that means that the continuation must be registered by us. - // - // Furthermore, we know that the root-zone doesn't actually do anything and - // we can therefore skip the registration call for it. - // - // Note, that the continuation accepts up to three arguments. If the current - // zone is the root zone, we don't wrap the continuation, and a bad - // `Future` implementation could potentially invoke the callback with the - // wrong number of arguments. - if (Zone.current == Zone.root) return continuation; - return Zone.current.registerUnaryCallback(continuation); -} - -// We need to pass the exception and stack trace objects as second and third -// parameter to the continuation. -dynamic Function(Object, StackTrace) _asyncErrorWrapperHelper( - dynamic Function(dynamic, dynamic, StackTrace) continuation) { - // See comments of `_asyncThenWrapperHelper`. - dynamic errorCallback(Object e, StackTrace s) => continuation(null, e, s); - if (Zone.current == Zone.root) return errorCallback; - return Zone.current - .registerBinaryCallback(errorCallback); -} - -/// Registers the [thenCallback] and [errorCallback] on the given [object]. -/// -/// If [object] is not a future, then it is wrapped into one. -/// -/// Returns the result of registering with `.then`. -Future _awaitHelper(var object, dynamic Function(dynamic) thenCallback, - dynamic Function(dynamic, StackTrace) errorCallback, Function awaiter) { - late _Future future; - if (object is! Future) { - future = new _Future().._setValue(object); - } else if (object is _Future) { - future = object; - } else { - return object.then(thenCallback, onError: errorCallback); - } - // `object` is a `_Future`. - // - // Since the callbacks have been registered in the current zone (see - // [_asyncThenWrapperHelper] and [_asyncErrorWrapperHelper]), we can avoid - // another registration and directly invoke the no-zone-registration `.then`. - // - // We can only do this for our internal futures (the default implementation of - // all futures that are constructed by the `dart:async` library). - future._awaiter = awaiter; - return future._thenAwait(thenCallback, errorCallback); -} - -// Called as part of the 'await for (...)' construct. Registers the -// awaiter on the stream. -void _asyncStarListenHelper(var object, var awaiter) { - if (object is! _StreamImpl) { - return; - } - // `object` is a `_StreamImpl`. - object._awaiter = awaiter; -} - -@pragma("vm:entry-point", "call") -void _asyncStarMoveNextHelper(var stream) { - if (stream is! _StreamImpl) { - return; - } - // stream is a _StreamImpl. - final generator = stream._generator; - if (generator == null) { - // No generator registered, this isn't an async* Stream. - return; - } - _moveNextDebuggerStepCheck(generator); -} - -// _AsyncStarStreamController is used by the compiler to implement -// async* generator functions. -@pragma("vm:entry-point") -class _AsyncStarStreamController { - @pragma("vm:entry-point") - StreamController controller; - Function asyncStarBody; - bool isAdding = false; - bool onListenReceived = false; - bool isScheduled = false; - bool isSuspendedAtYield = false; - _Future? cancellationFuture = null; - - Stream get stream { - final Stream local = controller.stream; - if (local is _StreamImpl) { - local._generator = asyncStarBody; - } - return local; - } - - void runBody() { - isScheduled = false; - isSuspendedAtYield = false; - asyncStarBody(); - } - - void scheduleGenerator() { - if (isScheduled || controller.isPaused || isAdding) { - return; - } - isScheduled = true; - scheduleMicrotask(runBody); - } - - // Adds element to stream, returns true if the caller should terminate - // execution of the generator. - // - // TODO(hausner): Per spec, the generator should be suspended before - // exiting when the stream is closed. We could add a getter like this: - // get isCancelled => controller.hasListener; - // The generator would translate a 'yield e' statement to - // controller.add(e); - // suspend; - // if (controller.isCancelled) return; - bool add(T event) { - if (!onListenReceived) _fatal("yield before stream is listened to"); - if (isSuspendedAtYield) _fatal("unexpected yield"); - // If stream is cancelled, tell caller to exit the async generator. - if (!controller.hasListener) { - return true; - } - controller.add(event); - scheduleGenerator(); - isSuspendedAtYield = true; - return false; - } - - // Adds the elements of stream into this controller's stream. - // The generator will be scheduled again when all of the - // elements of the added stream have been consumed. - // Returns true if the caller should terminate - // execution of the generator. - bool addStream(Stream stream) { - if (!onListenReceived) _fatal("yield before stream is listened to"); - // If stream is cancelled, tell caller to exit the async generator. - if (!controller.hasListener) return true; - isAdding = true; - var whenDoneAdding = controller.addStream(stream, cancelOnError: false); - whenDoneAdding.then((_) { - isAdding = false; - scheduleGenerator(); - if (!isScheduled) isSuspendedAtYield = true; - }); - return false; - } - - void addError(Object error, StackTrace stackTrace) { - // TODO(40614): Remove once non-nullability is sound. - ArgumentError.checkNotNull(error, "error"); - final future = cancellationFuture; - if ((future != null) && future._mayComplete) { - // If the stream has been cancelled, complete the cancellation future - // with the error. - future._completeError(error, stackTrace); - return; - } - // If stream is cancelled, tell caller to exit the async generator. - if (!controller.hasListener) return; - controller.addError(error, stackTrace); - // No need to schedule the generator body here. This code is only - // called from the catch clause of the implicit try-catch-finally - // around the generator body. That is, we are on the error path out - // of the generator and do not need to run the generator again. - } - - close() { - final future = cancellationFuture; - if ((future != null) && future._mayComplete) { - // If the stream has been cancelled, complete the cancellation future - // with the error. - future._completeWithValue(null); - } - controller.close(); - } - - _AsyncStarStreamController(this.asyncStarBody) - : controller = new StreamController() { - controller.onListen = this.onListen; - controller.onResume = this.onResume; - controller.onCancel = this.onCancel; - } - - onListen() { - assert(!onListenReceived); - onListenReceived = true; - scheduleGenerator(); - } - - onResume() { - if (isSuspendedAtYield) { - scheduleGenerator(); - } - } - - onCancel() { - if (controller.isClosed) { - return null; - } - if (cancellationFuture == null) { - cancellationFuture = new _Future(); - // Only resume the generator if it is suspended at a yield. - // Cancellation does not affect an async generator that is - // suspended at an await. - if (isSuspendedAtYield) { - scheduleGenerator(); - } - } - return cancellationFuture; - } -} - -@patch -void _rethrow(Object error, StackTrace stackTrace) native "Async_rethrow"; - -@patch -class _Future { - /// The closure implementing the async[*]-body that is `await`ing this future. - Function? _awaiter; -} - -@patch -class _StreamImpl { - /// The closure implementing the async[*]-body that is `await`ing this future. - Function? _awaiter; - - /// The closure implementing the async-generator body that is creating events - /// for this stream. - Function? _generator; -} - -@pragma("vm:entry-point", "call") -void _completeOnAsyncReturn(Completer completer, Object value) { - completer.complete(value); -} - -/// Returns a [StackTrace] object containing the synchronous prefix for this -/// asynchronous method. -// -// This method is recognized. It performs a runtime call if -// FLAG_causal_async_stacks is enabled or returns `null` otherwise. -@pragma("vm:prefer-inline") -Object _asyncStackTraceHelper(Function async_op) - native "StackTrace_asyncStackTraceHelper"; - -// This method is asm intrinsified. -@pragma("vm:entry-point", "call") -void _clearAsyncThreadStackTrace() - native "StackTrace_clearAsyncThreadStackTrace"; - -// This method is asm intrinsified. -@pragma("vm:entry-point", "call") -void _setAsyncThreadStackTrace(StackTrace stackTrace) - native "StackTrace_setAsyncThreadStackTrace"; - -void _moveNextDebuggerStepCheck(Function async_op) - native "AsyncStarMoveNext_debuggerStepCheck"; diff --git a/sdk_nnbd/lib/_internal/vm/lib/bigint_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/bigint_patch.dart deleted file mode 100644 index 5cc0befd8ee..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/bigint_patch.dart +++ /dev/null @@ -1,2853 +0,0 @@ -// Copyright (c) 2017, 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. - -// part of dart.core; - -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -/* - * Copyright (c) 2003-2005 Tom Wu - * Copyright (c) 2012 Adam Singer (adam@solvr.io) - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL, - * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER - * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF - * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * In addition, the following condition applies: - * - * All redistributions must retain an intact copy of this copyright notice - * and disclaimer. - */ - -@patch -class BigInt implements Comparable { - @patch - static BigInt get zero => _BigIntImpl.zero; - @patch - static BigInt get one => _BigIntImpl.one; - @patch - static BigInt get two => _BigIntImpl.two; - - @patch - static BigInt parse(String source, {int? radix}) => - _BigIntImpl.parse(source, radix: radix); - - @patch - static BigInt? tryParse(String source, {int? radix}) => - _BigIntImpl._tryParse(source, radix: radix); - - @patch - factory BigInt.from(num value) => new _BigIntImpl.from(value); -} - -int _max(int a, int b) => a > b ? a : b; -int _min(int a, int b) => a < b ? a : b; - -/// Allocate a new digits list of even length. -Uint32List _newDigits(int length) => new Uint32List(length + (length & 1)); - -/** - * An implementation for the arbitrarily large integer. - * - * The integer number is represented by a sign, an array of 32-bit unsigned - * integers in little endian format, and a number of used digits in that array. - */ -class _BigIntImpl implements BigInt { - // Bits per digit. - static const int _digitBits = 32; - static const int _digitBase = 1 << _digitBits; - static const int _digitMask = (1 << _digitBits) - 1; - - // Bits per half digit. - static const int _halfDigitBits = _digitBits >> 1; - static const int _halfDigitMask = (1 << _halfDigitBits) - 1; - - static final _BigIntImpl zero = new _BigIntImpl._fromInt(0); - static final _BigIntImpl one = new _BigIntImpl._fromInt(1); - static final _BigIntImpl two = new _BigIntImpl._fromInt(2); - - static final _BigIntImpl _minusOne = -one; - static final _BigIntImpl _oneDigitMask = new _BigIntImpl._fromInt(_digitMask); - static final _BigIntImpl _twoDigitMask = (one << (2 * _digitBits)) - one; - static final _BigIntImpl _oneBillion = new _BigIntImpl._fromInt(1000000000); - static const int _minInt = -0x8000000000000000; - static const int _maxInt = 0x7fffffffffffffff; - - /// Certain methods of _BigIntImpl class are intrinsified by the VM - /// depending on the runtime flags. They return number of processed - /// digits (2) which is different from non-intrinsic implementation (1). - /// This flag is used to confuse constant propagation at compile time and - /// avoid propagating return value to the callers. It should not be - /// evaluated to a constant. - /// Note that [_isIntrinsified] is still false if intrinsification occurs, - /// so it should be used only inside methods which are replaced by - /// intrinsification. - static final bool _isIntrinsified = - new bool.fromEnvironment('dart.vm.not.a.compile.time.constant'); - - // Result cache for last _divRem call. - static Uint32List? _lastDividendDigits; - static int? _lastDividendUsed; - static Uint32List? _lastDivisorDigits; - static int? _lastDivisorUsed; - static late Uint32List _lastQuoRemDigits; - static late int _lastQuoRemUsed; - static late int _lastRemUsed; - static late int _lastRem_nsh; - - /// Whether this bigint is negative. - final bool _isNegative; - - /// The unsigned digits of this bigint. - /// - /// The least significant digit is in slot 0. - /// The list may have more digits than needed. That is, `_digits.length` may - /// be strictly greater than `_used`. - /// Also, `_digits.length` must always be even, because intrinsics on 64-bit - /// platforms may process a digit pair as a 64-bit value. - final Uint32List _digits; - - /// The number of used entries in [_digits]. - /// - /// To avoid reallocating [Uint32List]s, lists that are too big are not - /// replaced, but `_used` reflects the smaller number of digits actually used. - /// - /// Note that functions shortening an existing list of digits to a smaller - /// `_used` number of digits must ensure that the highermost pair of digits - /// is correct when read as a 64-bit value by intrinsics. Therefore, if the - /// smaller '_used' number is odd, the high digit of that pair must be - /// explicitly cleared, i.e. _digits[_used] = 0, which cannot result in an - /// out of bounds access, since the length of the list is guaranteed to be - /// even. - final int _used; - - /** - * Parses [source] as a, possibly signed, integer literal and returns its - * value. - * - * The [source] must be a non-empty sequence of base-[radix] digits, - * optionally prefixed with a minus or plus sign ('-' or '+'). - * - * The [radix] must be in the range 2..36. The digits used are - * first the decimal digits 0..9, and then the letters 'a'..'z' with - * values 10 through 35. Also accepts upper-case letters with the same - * values as the lower-case ones. - * - * If no [radix] is given then it defaults to 10. In this case, the [source] - * digits may also start with `0x`, in which case the number is interpreted - * as a hexadecimal literal, which effectively means that the `0x` is ignored - * and the radix is instead set to 16. - * - * For any int `n` and radix `r`, it is guaranteed that - * `n == int.parse(n.toRadixString(r), radix: r)`. - * - * Throws a [FormatException] if the [source] is not a valid integer literal, - * optionally prefixed by a sign. - */ - static _BigIntImpl parse(String source, {int? radix}) { - var result = _tryParse(source, radix: radix); - if (result == null) { - throw new FormatException("Could not parse BigInt", source); - } - return result; - } - - /// Parses a decimal bigint literal. - /// - /// The [source] must not contain leading or trailing whitespace. - static _BigIntImpl _parseDecimal(String source, bool isNegative) { - const _0 = 48; - - int part = 0; - _BigIntImpl result = zero; - // Read in the source 9 digits at a time. - // The first part may have a few leading virtual '0's to make the remaining - // parts all have exactly 9 digits. - int digitInPartCount = 9 - unsafeCast(source.length.remainder(9)); - if (digitInPartCount == 9) digitInPartCount = 0; - for (int i = 0; i < source.length; i++) { - part = part * 10 + source.codeUnitAt(i) - _0; - if (++digitInPartCount == 9) { - result = result * _oneBillion + new _BigIntImpl._fromInt(part); - part = 0; - digitInPartCount = 0; - } - } - if (isNegative) return -result; - return result; - } - - /// Returns the value of a given source digit. - /// - /// Source digits between "0" and "9" (inclusive) return their decimal value. - /// - /// Source digits between "a" and "z", or "A" and "Z" (inclusive) return - /// 10 + their position in the ASCII alphabet. - /// - /// The incoming [codeUnit] must be an ASCII code-unit. - static int _codeUnitToRadixValue(int codeUnit) { - // We know that the characters must be ASCII as otherwise the - // regexp wouldn't have matched. Lowercasing by doing `| 0x20` is thus - // guaranteed to be a safe operation, since it preserves digits - // and lower-cases ASCII letters. - const int _0 = 48; - const int _9 = 57; - const int _a = 97; - if (_0 <= codeUnit && codeUnit <= _9) return codeUnit - _0; - codeUnit |= 0x20; - var result = codeUnit - _a + 10; - return result; - } - - /// Parses the given [source] string, starting at [startPos], as a hex - /// literal. - /// - /// If [isNegative] is true, negates the result before returning it. - /// - /// The [source] (substring) must be a valid hex literal. - static _BigIntImpl? _parseHex(String source, int startPos, bool isNegative) { - int hexCharsPerDigit = _digitBits ~/ 4; - int sourceLength = source.length - startPos; - int used = (sourceLength + hexCharsPerDigit - 1) ~/ hexCharsPerDigit; - var digits = _newDigits(used); - - int lastDigitLength = sourceLength - (used - 1) * hexCharsPerDigit; - int digitIndex = used - 1; - int i = startPos; - int digit = 0; - for (int j = 0; j < lastDigitLength; j++) { - var value = _codeUnitToRadixValue(source.codeUnitAt(i++)); - if (value >= 16) return null; - digit = digit * 16 + value; - } - digits[digitIndex--] = digit; - - while (i < source.length) { - digit = 0; - for (int j = 0; j < hexCharsPerDigit; j++) { - var value = _codeUnitToRadixValue(source.codeUnitAt(i++)); - if (value >= 16) return null; - digit = digit * 16 + value; - } - digits[digitIndex--] = digit; - } - if (used == 1 && digits[0] == 0) return zero; - return new _BigIntImpl._(isNegative, used, digits); - } - - /// Parses the given [source] as a [radix] literal. - /// - /// The [source] will be checked for invalid characters. If it is invalid, - /// this function returns `null`. - static _BigIntImpl? _parseRadix(String source, int radix, bool isNegative) { - var result = zero; - var base = new _BigIntImpl._fromInt(radix); - for (int i = 0; i < source.length; i++) { - var value = _codeUnitToRadixValue(source.codeUnitAt(i)); - if (value >= radix) return null; - result = result * base + new _BigIntImpl._fromInt(value); - } - if (isNegative) return -result; - return result; - } - - /// Tries to parse the given [source] as a [radix] literal. - /// - /// Returns the parsed big integer, or `null` if it failed. - /// - /// If the [radix] is `null` accepts decimal literals or `0x` hex literals. - static _BigIntImpl? _tryParse(String source, {int? radix}) { - if (source == "") return null; - - final match = _parseRE.firstMatch(source); - int signIndex = 1; - int hexIndex = 3; - int decimalIndex = 4; - int nonDecimalHexIndex = 5; - if (match == null) return null; - - final bool isNegative = match[signIndex] == "-"; - - final String? decimalMatch = match[decimalIndex]; - final String? hexMatch = match[hexIndex]; - final String? nonDecimalMatch = match[nonDecimalHexIndex]; - - if (radix == null) { - if (decimalMatch != null) { - // Cannot fail because we know that the digits are all decimal. - return _parseDecimal(decimalMatch, isNegative); - } - if (hexMatch != null) { - // Cannot fail because we know that the digits are all hex. - return _parseHex(hexMatch, 2, isNegative); - } - return null; - } - - if (radix < 2 || radix > 36) { - throw new RangeError.range(radix, 2, 36, 'radix'); - } - if (radix == 10 && decimalMatch != null) { - return _parseDecimal(decimalMatch, isNegative); - } - if (radix == 16) { - final match = decimalMatch ?? nonDecimalMatch; - if (match != null) { - return _parseHex(match, 0, isNegative); - } - } - - // The RegExp guarantees that one of the 3 matches is non-null. - final nonNullMatch = (decimalMatch ?? nonDecimalMatch ?? hexMatch)!; - return _parseRadix(nonNullMatch, radix, isNegative); - } - - static RegExp _parseRE = RegExp( - r'^\s*([+-]?)((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$', - caseSensitive: false); - - /// Finds the amount significant digits in the provided [digits] array. - static int _normalize(int used, Uint32List digits) { - while (used > 0 && digits[used - 1] == 0) used--; - return used; - } - - /// Factory returning an instance initialized with the given field values. - /// If the [digits] array contains leading 0s, the [used] value is adjusted - /// accordingly. The [digits] array is not modified. - _BigIntImpl._(bool isNegative, int used, Uint32List digits) - : this._normalized(isNegative, _normalize(used, digits), digits); - - _BigIntImpl._normalized(bool isNegative, this._used, this._digits) - : _isNegative = _used == 0 ? false : isNegative { - assert(_digits.length.isEven); - assert(_used.isEven || _digits[_used] == 0); // Leading zero for 64-bit. - } - - /// Whether this big integer is zero. - bool get _isZero => _used == 0; - - /// Allocates an array of the given [length] and copies the [digits] in the - /// range [from] to [to-1], starting at index 0, followed by leading zero - /// digits. - static Uint32List _cloneDigits( - Uint32List digits, int from, int to, int length) { - var resultDigits = _newDigits(length); - var n = to - from; - for (var i = 0; i < n; i++) { - resultDigits[i] = digits[from + i]; - } - return resultDigits; - } - - /// Allocates a big integer from the provided [value] number. - factory _BigIntImpl.from(num value) { - if (value == 0) return zero; - if (value == 1) return one; - if (value == 2) return two; - - if (value.abs() < 0x100000000) { - return new _BigIntImpl._fromInt(value.toInt()); - } - if (value is double) { - return new _BigIntImpl._fromDouble(value); - } - return new _BigIntImpl._fromInt(value as int); - } - - factory _BigIntImpl._fromInt(int value) { - bool isNegative = value < 0; - assert(_digitBits == 32); - var digits = _newDigits(2); - if (isNegative) { - // Handle the min 64-bit value differently, since its negation is not - // positive. - if (value == _minInt) { - digits[1] = 0x80000000; - return new _BigIntImpl._(true, 2, digits); - } - value = -value; - } - if (value < _digitBase) { - digits[0] = value; - return new _BigIntImpl._(isNegative, 1, digits); - } - digits[0] = value & _digitMask; - digits[1] = value >> _digitBits; - return new _BigIntImpl._(isNegative, 2, digits); - } - - /// An 8-byte Uint8List we can reuse for [_fromDouble] to avoid generating - /// garbage. - static final Uint8List _bitsForFromDouble = new Uint8List(8); - - factory _BigIntImpl._fromDouble(double value) { - const int exponentBias = 1075; - - if (value.isNaN || value.isInfinite) { - throw new ArgumentError("Value must be finite: $value"); - } - bool isNegative = value < 0; - if (isNegative) value = -value; - - value = value.floorToDouble(); - if (value == 0) return zero; - - var bits = _bitsForFromDouble; - for (int i = 0; i < 8; i++) { - bits[i] = 0; - } - bits.buffer.asByteData().setFloat64(0, value, Endian.little); - // The exponent is in bits 53..63. - var biasedExponent = (bits[7] << 4) + (bits[6] >> 4); - var exponent = biasedExponent - exponentBias; - - assert(_digitBits == 32); - // The significant bits are in 0 .. 52. - var unshiftedDigits = _newDigits(2); - unshiftedDigits[0] = - (bits[3] << 24) + (bits[2] << 16) + (bits[1] << 8) + bits[0]; - // Don't forget to add the hidden bit. - unshiftedDigits[1] = - ((0x10 | (bits[6] & 0xF)) << 16) + (bits[5] << 8) + bits[4]; - - var unshiftedBig = new _BigIntImpl._normalized(false, 2, unshiftedDigits); - _BigIntImpl absResult = unshiftedBig; - if (exponent < 0) { - absResult = unshiftedBig >> -exponent; - } else if (exponent > 0) { - absResult = unshiftedBig << exponent; - } - if (isNegative) return -absResult; - return absResult; - } - - /** - * Return the negative value of this integer. - * - * The result of negating an integer always has the opposite sign, except - * for zero, which is its own negation. - */ - _BigIntImpl operator -() { - if (_used == 0) return this; - return new _BigIntImpl._(!_isNegative, _used, _digits); - } - - /** - * Returns the absolute value of this integer. - * - * For any integer `x`, the result is the same as `x < 0 ? -x : x`. - */ - _BigIntImpl abs() => _isNegative ? -this : this; - - /// Returns this << n*_digitBits. - _BigIntImpl _dlShift(int n) { - final used = _used; - if (used == 0) { - return zero; - } - final resultUsed = used + n; - final digits = _digits; - final resultDigits = _newDigits(resultUsed); - for (int i = used - 1; i >= 0; i--) { - resultDigits[i + n] = digits[i]; - } - return new _BigIntImpl._(_isNegative, resultUsed, resultDigits); - } - - /// Same as [_dlShift] but works on the decomposed big integers. - /// - /// Returns `resultUsed`. - /// - /// `resultDigits[0..resultUsed-1] = xDigits[0..xUsed-1] << n*_digitBits`. - static int _dlShiftDigits( - Uint32List xDigits, int xUsed, int n, Uint32List resultDigits) { - if (xUsed == 0) { - return 0; - } - if (n == 0 && identical(resultDigits, xDigits)) { - return xUsed; - } - final resultUsed = xUsed + n; - assert(resultDigits.length >= resultUsed + (resultUsed & 1)); - for (int i = xUsed - 1; i >= 0; i--) { - resultDigits[i + n] = xDigits[i]; - } - for (int i = n - 1; i >= 0; i--) { - resultDigits[i] = 0; - } - if (resultUsed.isOdd) { - resultDigits[resultUsed] = 0; - } - return resultUsed; - } - - /// Returns `this >> n*_digitBits`. - _BigIntImpl _drShift(int n) { - final used = _used; - if (used == 0) { - return zero; - } - final resultUsed = used - n; - if (resultUsed <= 0) { - return _isNegative ? _minusOne : zero; - } - final digits = _digits; - final resultDigits = _newDigits(resultUsed); - for (var i = n; i < used; i++) { - resultDigits[i - n] = digits[i]; - } - final result = new _BigIntImpl._(_isNegative, resultUsed, resultDigits); - if (_isNegative) { - // Round down if any bit was shifted out. - for (var i = 0; i < n; i++) { - if (digits[i] != 0) { - return result - one; - } - } - } - return result; - } - - /// Same as [_drShift] but works on the decomposed big integers. - /// - /// Returns `resultUsed`. - /// - /// `resultDigits[0..resultUsed-1] = xDigits[0..xUsed-1] >> n*_digitBits`. - static int _drShiftDigits( - Uint32List xDigits, int xUsed, int n, Uint32List resultDigits) { - final resultUsed = xUsed - n; - if (resultUsed <= 0) { - return 0; - } - assert(resultDigits.length >= resultUsed + (resultUsed & 1)); - for (var i = n; i < xUsed; i++) { - resultDigits[i - n] = xDigits[i]; - } - if (resultUsed.isOdd) { - resultDigits[resultUsed] = 0; - } - return resultUsed; - } - - /// Shifts the digits of [xDigits] into the right place in [resultDigits]. - /// - /// `resultDigits[ds..xUsed+ds] = xDigits[0..xUsed-1] << (n % _digitBits)` - /// where `ds = n ~/ _digitBits` - /// - /// Does *not* clear digits below ds. - /// - /// Note: This function may be intrinsified. - @pragma("vm:never-inline") - static void _lsh( - Uint32List xDigits, int xUsed, int n, Uint32List resultDigits) { - assert(xUsed > 0); - final digitShift = n ~/ _digitBits; - final bitShift = n % _digitBits; - final carryBitShift = _digitBits - bitShift; - final bitMask = (1 << carryBitShift) - 1; - var carry = 0; - for (int i = xUsed - 1; i >= 0; i--) { - final digit = xDigits[i]; - resultDigits[i + digitShift + 1] = (digit >> carryBitShift) | carry; - carry = (digit & bitMask) << bitShift; - } - resultDigits[digitShift] = carry; - } - - /** - * Shift the bits of this integer to the left by [shiftAmount]. - * - * Shifting to the left makes the number larger, effectively multiplying - * the number by `pow(2, shiftIndex)`. - * - * There is no limit on the size of the result. It may be relevant to - * limit intermediate values by using the "and" operator with a suitable - * mask. - * - * It is an error if [shiftAmount] is negative. - */ - _BigIntImpl operator <<(int shiftAmount) { - if (shiftAmount < 0) { - throw new ArgumentError("shift-amount must be positive $shiftAmount"); - } - if (_isZero) return this; - final digitShift = shiftAmount ~/ _digitBits; - final bitShift = shiftAmount % _digitBits; - if (bitShift == 0) { - return _dlShift(digitShift); - } - // Need one extra digit to hold bits shifted by bitShift. - var resultUsed = _used + digitShift + 1; - // The 64-bit intrinsic requires one extra pair to work with. - var resultDigits = _newDigits(resultUsed + 1); - _lsh(_digits, _used, shiftAmount, resultDigits); - return new _BigIntImpl._(_isNegative, resultUsed, resultDigits); - } - - /// resultDigits[0..resultUsed-1] = xDigits[0..xUsed-1] << n. - /// Returns resultUsed. - static int _lShiftDigits( - Uint32List xDigits, int xUsed, int n, Uint32List resultDigits) { - final digitsShift = n ~/ _digitBits; - final bitShift = n % _digitBits; - if (bitShift == 0) { - return _dlShiftDigits(xDigits, xUsed, digitsShift, resultDigits); - } - // Need one extra digit to hold bits shifted by bitShift. - var resultUsed = xUsed + digitsShift + 1; - // The 64-bit intrinsic requires one extra pair to work with. - assert(resultDigits.length >= resultUsed + 2 - (resultUsed & 1)); - _lsh(xDigits, xUsed, n, resultDigits); - var i = digitsShift; - while (--i >= 0) { - resultDigits[i] = 0; - } - if (resultDigits[resultUsed - 1] == 0) { - resultUsed--; // Clamp result. - } else if (resultUsed.isOdd) { - resultDigits[resultUsed] = 0; - } - return resultUsed; - } - - /// resultDigits[0..resultUsed-1] = xDigits[0..xUsed-1] >> n. - /// - /// Note: This function may be intrinsified. - @pragma("vm:never-inline") - static void _rsh( - Uint32List xDigits, int xUsed, int n, Uint32List resultDigits) { - assert(xUsed > 0); - final digitsShift = n ~/ _digitBits; - final bitShift = n % _digitBits; - final carryBitShift = _digitBits - bitShift; - final bitMask = (1 << bitShift) - 1; - var carry = xDigits[digitsShift] >> bitShift; - final last = xUsed - digitsShift - 1; - for (var i = 0; i < last; i++) { - final digit = xDigits[i + digitsShift + 1]; - resultDigits[i] = ((digit & bitMask) << carryBitShift) | carry; - carry = digit >> bitShift; - } - resultDigits[last] = carry; - } - - /** - * Shift the bits of this integer to the right by [shiftAmount]. - * - * Shifting to the right makes the number smaller and drops the least - * significant bits, effectively doing an integer division by - *`pow(2, shiftIndex)`. - * - * It is an error if [shiftAmount] is negative. - */ - _BigIntImpl operator >>(int shiftAmount) { - if (shiftAmount < 0) { - throw new ArgumentError("shift-amount must be positive $shiftAmount"); - } - if (_isZero) return this; - final digitShift = shiftAmount ~/ _digitBits; - final bitShift = shiftAmount % _digitBits; - if (bitShift == 0) { - return _drShift(digitShift); - } - final used = _used; - final resultUsed = used - digitShift; - if (resultUsed <= 0) { - return _isNegative ? _minusOne : zero; - } - final digits = _digits; - final resultDigits = _newDigits(resultUsed); - _rsh(digits, used, shiftAmount, resultDigits); - final result = new _BigIntImpl._(_isNegative, resultUsed, resultDigits); - if (_isNegative) { - // Round down if any bit was shifted out. - if ((digits[digitShift] & ((1 << bitShift) - 1)) != 0) { - return result - one; - } - for (var i = 0; i < digitShift; i++) { - if (digits[i] != 0) { - return result - one; - } - } - } - return result; - } - - /// resultDigits[0..resultUsed-1] = xDigits[0..xUsed-1] >> n. - /// Returns resultUsed. - static int _rShiftDigits( - Uint32List xDigits, int xUsed, int n, Uint32List resultDigits) { - final digitShift = n ~/ _digitBits; - final bitShift = n % _digitBits; - if (bitShift == 0) { - return _drShiftDigits(xDigits, xUsed, digitShift, resultDigits); - } - var resultUsed = xUsed - digitShift; - if (resultUsed <= 0) { - return 0; - } - assert(resultDigits.length >= resultUsed + (resultUsed & 1)); - _rsh(xDigits, xUsed, n, resultDigits); - if (resultDigits[resultUsed - 1] == 0) { - resultUsed--; // Clamp result. - } else if (resultUsed.isOdd) { - resultDigits[resultUsed] = 0; - } - return resultUsed; - } - - /// Compares this to [other] taking the absolute value of both operands. - /// - /// Returns 0 if abs(this) == abs(other); a positive number if - /// abs(this) > abs(other); and a negative number if abs(this) < abs(other). - int _absCompare(BigInt bigInt) { - final other = _ensureSystemBigInt(bigInt, 'bigInt'); - return _compareDigits(_digits, _used, other._digits, other._used); - } - - /** - * Compares this to `other`. - * - * Returns a negative number if `this` is less than `other`, zero if they are - * equal, and a positive number if `this` is greater than `other`. - */ - int compareTo(BigInt bigInt) { - final other = _ensureSystemBigInt(bigInt, 'bigInt'); - if (_isNegative == other._isNegative) { - var result = _absCompare(other); - // Use 0 - result to avoid negative zero in JavaScript. - return _isNegative ? 0 - result : result; - } - return _isNegative ? -1 : 1; - } - - /// Compares `digits[0..used-1]` with `otherDigits[0..otherUsed-1]`. - /// - /// Returns 0 if equal; a positive number if larger; - /// and a negative number if smaller. - static int _compareDigits( - Uint32List digits, int used, Uint32List otherDigits, int otherUsed) { - var result = used - otherUsed; - if (result == 0) { - for (int i = used - 1; i >= 0; i--) { - result = digits[i] - otherDigits[i]; - if (result != 0) return result; - } - } - return result; - } - - /// resultDigits[0..used] = digits[0..used-1] + otherDigits[0..otherUsed-1]. - /// used >= otherUsed > 0. - /// - /// Note: This function may be intrinsified. - @pragma("vm:never-inline") - static void _absAdd(Uint32List digits, int used, Uint32List otherDigits, - int otherUsed, Uint32List resultDigits) { - assert(used >= otherUsed && otherUsed > 0); - var carry = 0; - for (var i = 0; i < otherUsed; i++) { - carry += digits[i] + otherDigits[i]; - resultDigits[i] = carry & _digitMask; - carry >>= _digitBits; - } - for (var i = otherUsed; i < used; i++) { - carry += digits[i]; - resultDigits[i] = carry & _digitMask; - carry >>= _digitBits; - } - resultDigits[used] = carry; - } - - /// resultDigits[0..used-1] = digits[0..used-1] - otherDigits[0..otherUsed-1]. - /// used >= otherUsed > 0. - /// - /// Note: This function may be intrinsified. - @pragma("vm:never-inline") - static void _absSub(Uint32List digits, int used, Uint32List otherDigits, - int otherUsed, Uint32List resultDigits) { - assert(used >= otherUsed && otherUsed > 0); - var carry = 0; - for (var i = 0; i < otherUsed; i++) { - carry += digits[i] - otherDigits[i]; - resultDigits[i] = carry & _digitMask; - carry >>= _digitBits; - } - for (var i = otherUsed; i < used; i++) { - carry += digits[i]; - resultDigits[i] = carry & _digitMask; - carry >>= _digitBits; - } - } - - /// Returns `abs(this) + abs(other)` with sign set according to [isNegative]. - _BigIntImpl _absAddSetSign(_BigIntImpl other, bool isNegative) { - var used = _used; - var otherUsed = other._used; - if (used < otherUsed) { - return other._absAddSetSign(this, isNegative); - } - if (used == 0) { - assert(!isNegative); - return zero; - } - if (otherUsed == 0) { - return _isNegative == isNegative ? this : -this; - } - var resultUsed = used + 1; - var resultDigits = _newDigits(resultUsed); - _absAdd(_digits, used, other._digits, otherUsed, resultDigits); - return new _BigIntImpl._(isNegative, resultUsed, resultDigits); - } - - /// Returns `abs(this) - abs(other)` with sign set according to [isNegative]. - /// - /// Requirement: `abs(this) >= abs(other)`. - _BigIntImpl _absSubSetSign(_BigIntImpl other, bool isNegative) { - assert(_absCompare(other) >= 0); - var used = _used; - if (used == 0) { - assert(!isNegative); - return zero; - } - var otherUsed = other._used; - if (otherUsed == 0) { - return _isNegative == isNegative ? this : -this; - } - var resultDigits = _newDigits(used); - _absSub(_digits, used, other._digits, otherUsed, resultDigits); - return new _BigIntImpl._(isNegative, used, resultDigits); - } - - /// Returns `abs(this) & abs(other)` with sign set according to [isNegative]. - _BigIntImpl _absAndSetSign(_BigIntImpl other, bool isNegative) { - var resultUsed = _min(_used, other._used); - var digits = _digits; - var otherDigits = other._digits; - var resultDigits = _newDigits(resultUsed); - for (var i = 0; i < resultUsed; i++) { - resultDigits[i] = digits[i] & otherDigits[i]; - } - return new _BigIntImpl._(isNegative, resultUsed, resultDigits); - } - - /// Returns `abs(this) &~ abs(other)` with sign set according to [isNegative]. - _BigIntImpl _absAndNotSetSign(_BigIntImpl other, bool isNegative) { - var resultUsed = _used; - var digits = _digits; - var otherDigits = other._digits; - var resultDigits = _newDigits(resultUsed); - var m = _min(resultUsed, other._used); - for (var i = 0; i < m; i++) { - resultDigits[i] = digits[i] & ~otherDigits[i]; - } - for (var i = m; i < resultUsed; i++) { - resultDigits[i] = digits[i]; - } - return new _BigIntImpl._(isNegative, resultUsed, resultDigits); - } - - /// Returns `abs(this) | abs(other)` with sign set according to [isNegative]. - _BigIntImpl _absOrSetSign(_BigIntImpl other, bool isNegative) { - var used = _used; - var otherUsed = other._used; - var resultUsed = _max(used, otherUsed); - var digits = _digits; - var otherDigits = other._digits; - var resultDigits = _newDigits(resultUsed); - var l, m; - if (used < otherUsed) { - l = other; - m = used; - } else { - l = this; - m = otherUsed; - } - for (var i = 0; i < m; i++) { - resultDigits[i] = digits[i] | otherDigits[i]; - } - var lDigits = l._digits; - for (var i = m; i < resultUsed; i++) { - resultDigits[i] = lDigits[i]; - } - return new _BigIntImpl._(isNegative, resultUsed, resultDigits); - } - - /// Returns `abs(this) ^ abs(other)` with sign set according to [isNegative]. - _BigIntImpl _absXorSetSign(_BigIntImpl other, bool isNegative) { - var used = _used; - var otherUsed = other._used; - var resultUsed = _max(used, otherUsed); - var digits = _digits; - var otherDigits = other._digits; - var resultDigits = _newDigits(resultUsed); - var l, m; - if (used < otherUsed) { - l = other; - m = used; - } else { - l = this; - m = otherUsed; - } - for (var i = 0; i < m; i++) { - resultDigits[i] = digits[i] ^ otherDigits[i]; - } - var lDigits = l._digits; - for (var i = m; i < resultUsed; i++) { - resultDigits[i] = lDigits[i]; - } - return new _BigIntImpl._(isNegative, resultUsed, resultDigits); - } - - /** - * Bit-wise and operator. - * - * Treating both `this` and [other] as sufficiently large two's component - * integers, the result is a number with only the bits set that are set in - * both `this` and [other] - * - * Of both operands are negative, the result is negative, otherwise - * the result is non-negative. - */ - _BigIntImpl operator &(BigInt bigInt) { - final other = _ensureSystemBigInt(bigInt, 'bigInt'); - if (_isZero || other._isZero) return zero; - if (_isNegative == other._isNegative) { - if (_isNegative) { - // (-this) & (-other) == ~(this-1) & ~(other-1) - // == ~((this-1) | (other-1)) - // == -(((this-1) | (other-1)) + 1) - _BigIntImpl this1 = _absSubSetSign(one, true); - _BigIntImpl other1 = other._absSubSetSign(one, true); - // Result cannot be zero if this and other are negative. - return this1._absOrSetSign(other1, true)._absAddSetSign(one, true); - } - return _absAndSetSign(other, false); - } - // _isNegative != other._isNegative - var p, n; - if (_isNegative) { - p = other; - n = this; - } else { - // & is symmetric. - p = this; - n = other; - } - // p & (-n) == p & ~(n-1) == p &~ (n-1) - var n1 = n._absSubSetSign(one, false); - return p._absAndNotSetSign(n1, false); - } - - /** - * Bit-wise or operator. - * - * Treating both `this` and [other] as sufficiently large two's component - * integers, the result is a number with the bits set that are set in either - * of `this` and [other] - * - * If both operands are non-negative, the result is non-negative, - * otherwise the result us negative. - */ - _BigIntImpl operator |(BigInt bigInt) { - final other = _ensureSystemBigInt(bigInt, 'bigInt'); - if (_isZero) return other; - if (other._isZero) return this; - if (_isNegative == other._isNegative) { - if (_isNegative) { - // (-this) | (-other) == ~(this-1) | ~(other-1) - // == ~((this-1) & (other-1)) - // == -(((this-1) & (other-1)) + 1) - var this1 = _absSubSetSign(one, true); - var other1 = other._absSubSetSign(one, true); - // Result cannot be zero if this and a are negative. - return this1._absAndSetSign(other1, true)._absAddSetSign(one, true); - } - return _absOrSetSign(other, false); - } - // _neg != a._neg - var p, n; - if (_isNegative) { - p = other; - n = this; - } else { - // | is symmetric. - p = this; - n = other; - } - // p | (-n) == p | ~(n-1) == ~((n-1) &~ p) == -(~((n-1) &~ p) + 1) - var n1 = n._absSubSetSign(one, true); - // Result cannot be zero if only one of this or a is negative. - return n1._absAndNotSetSign(p, true)._absAddSetSign(one, true); - } - - /** - * Bit-wise exclusive-or operator. - * - * Treating both `this` and [other] as sufficiently large two's component - * integers, the result is a number with the bits set that are set in one, - * but not both, of `this` and [other] - * - * If the operands have the same sign, the result is non-negative, - * otherwise the result is negative. - */ - _BigIntImpl operator ^(BigInt bigInt) { - final other = _ensureSystemBigInt(bigInt, 'bigInt'); - if (_isZero) return other; - if (other._isZero) return this; - if (_isNegative == other._isNegative) { - if (_isNegative) { - // (-this) ^ (-other) == ~(this-1) ^ ~(other-1) == (this-1) ^ (other-1) - var this1 = _absSubSetSign(one, true); - var other1 = other._absSubSetSign(one, true); - return this1._absXorSetSign(other1, false); - } - return _absXorSetSign(other, false); - } - // _isNegative != a._isNegative - var p, n; - if (_isNegative) { - p = other; - n = this; - } else { - // ^ is symmetric. - p = this; - n = other; - } - // p ^ (-n) == p ^ ~(n-1) == ~(p ^ (n-1)) == -((p ^ (n-1)) + 1) - var n1 = n._absSubSetSign(one, true); - // Result cannot be zero if only one of this or a is negative. - return p._absXorSetSign(n1, true)._absAddSetSign(one, true); - } - - /** - * The bit-wise negate operator. - * - * Treating `this` as a sufficiently large two's component integer, - * the result is a number with the opposite bits set. - * - * This maps any integer `x` to `-x - 1`. - */ - _BigIntImpl operator ~() { - if (_isZero) return _minusOne; - if (_isNegative) { - // ~(-this) == ~(~(this-1)) == this-1 - return _absSubSetSign(one, false); - } - // ~this == -this-1 == -(this+1) - // Result cannot be zero if this is positive. - return _absAddSetSign(one, true); - } - - /// Addition operator. - _BigIntImpl operator +(BigInt bigInt) { - final other = _ensureSystemBigInt(bigInt, 'bigInt'); - if (_isZero) return other; - if (other._isZero) return this; - var isNegative = _isNegative; - if (isNegative == other._isNegative) { - // this + other == this + other - // (-this) + (-other) == -(this + other) - return _absAddSetSign(other, isNegative); - } - // this + (-other) == this - other == -(this - other) - // (-this) + other == other - this == -(this - other) - if (_absCompare(other) >= 0) { - return _absSubSetSign(other, isNegative); - } - return other._absSubSetSign(this, !isNegative); - } - - /// Subtraction operator. - _BigIntImpl operator -(BigInt bigInt) { - final other = _ensureSystemBigInt(bigInt, 'bigInt'); - if (_isZero) return -other; - if (other._isZero) return this; - var isNegative = _isNegative; - if (isNegative != other._isNegative) { - // this - (-other) == this + other - // (-this) - other == -(this + other) - return _absAddSetSign(other, isNegative); - } - // this - other == this - a == -(this - other) - // (-this) - (-other) == other - this == -(this - other) - if (_absCompare(other) >= 0) { - return _absSubSetSign(other, isNegative); - } - return other._absSubSetSign(this, !isNegative); - } - - /// Multiplies `xDigits[xIndex]` with `multiplicandDigits` and adds the result - /// to `accumulatorDigits`. - /// - /// The `multiplicandDigits` in the range `i` to `i`+`n`-1 are the - /// multiplicand digits. - /// - /// The `accumulatorDigits` in the range `j` to `j`+`n`-1 are the accumulator - /// digits. - /// - /// Concretely: - /// `accumulatorDigits[j..j+n] += xDigits[xIndex] * m_digits[i..i+n-1]`. - /// Returns 1. - /// - /// Note: This function may be intrinsified. Intrinsics on 64-bit platforms - /// process digit pairs at even indices and returns 2. - @pragma("vm:exact-result-type", "dart:core#_Smi") - @pragma("vm:never-inline") - static int _mulAdd( - Uint32List xDigits, - int xIndex, - Uint32List multiplicandDigits, - int i, - Uint32List accumulatorDigits, - int j, - int n) { - int x = xDigits[xIndex]; - if (x == 0) { - // No-op if x is 0. - return _isIntrinsified ? 2 : 1; - } - int carry = 0; - int xl = x & _halfDigitMask; - int xh = x >> _halfDigitBits; - while (--n >= 0) { - int ml = multiplicandDigits[i] & _halfDigitMask; - int mh = multiplicandDigits[i++] >> _halfDigitBits; - int ph = xh * ml + mh * xl; - int pl = xl * ml + - ((ph & _halfDigitMask) << _halfDigitBits) + - accumulatorDigits[j] + - carry; - carry = (pl >> _digitBits) + (ph >> _halfDigitBits) + xh * mh; - accumulatorDigits[j++] = pl & _digitMask; - } - while (carry != 0) { - int l = accumulatorDigits[j] + carry; - carry = l >> _digitBits; - accumulatorDigits[j++] = l & _digitMask; - } - return _isIntrinsified ? 2 : 1; - } - - /// Multiplies `xDigits[i]` with `xDigits` and adds the result to - /// `accumulatorDigits`. - /// - /// The `xDigits` in the range `i` to `used`-1 are the multiplicand digits. - /// - /// The `accumulatorDigits` in the range 2*`i` to `i`+`used`-1 are the - /// accumulator digits. - /// - /// Concretely: - /// `accumulatorDigits[2*i..i+used-1] += xDigits[i]*xDigits[i] + - /// 2*xDigits[i]*xDigits[i+1..used-1]`. - /// Returns 1. - /// - /// Note: This function may be intrinsified. Intrinsics on 64-bit platforms - /// process digit pairs at even indices and returns 2. - @pragma("vm:exact-result-type", "dart:core#_Smi") - @pragma("vm:never-inline") - static int _sqrAdd( - Uint32List xDigits, int i, Uint32List acculumatorDigits, int used) { - int x = xDigits[i]; - if (x == 0) return _isIntrinsified ? 2 : 1; - int j = 2 * i; - int carry = 0; - int xl = x & _halfDigitMask; - int xh = x >> _halfDigitBits; - int ph = 2 * xh * xl; - int pl = xl * xl + - ((ph & _halfDigitMask) << _halfDigitBits) + - acculumatorDigits[j]; - carry = (pl >> _digitBits) + (ph >> _halfDigitBits) + xh * xh; - acculumatorDigits[j] = pl & _digitMask; - x <<= 1; - xl = x & _halfDigitMask; - xh = x >> _halfDigitBits; - int n = used - i - 1; - int k = i + 1; - j++; - while (--n >= 0) { - int l = xDigits[k] & _halfDigitMask; - int h = xDigits[k++] >> _halfDigitBits; - int ph = xh * l + h * xl; - int pl = xl * l + - ((ph & _halfDigitMask) << _halfDigitBits) + - acculumatorDigits[j] + - carry; - carry = (pl >> _digitBits) + (ph >> _halfDigitBits) + xh * h; - acculumatorDigits[j++] = pl & _digitMask; - } - carry += acculumatorDigits[i + used]; - if (carry >= _digitBase) { - acculumatorDigits[i + used] = carry - _digitBase; - acculumatorDigits[i + used + 1] = 1; - } else { - acculumatorDigits[i + used] = carry; - } - return _isIntrinsified ? 2 : 1; - } - - /// Multiplication operator. - _BigIntImpl operator *(BigInt bigInt) { - final other = _ensureSystemBigInt(bigInt, 'bigInt'); - var used = _used; - var otherUsed = other._used; - if (used == 0 || otherUsed == 0) { - return zero; - } - var resultUsed = used + otherUsed; - var digits = _digits; - var otherDigits = other._digits; - var resultDigits = _newDigits(resultUsed); - var i = 0; - while (i < otherUsed) { - i += _mulAdd(otherDigits, i, digits, 0, resultDigits, i, used); - } - return new _BigIntImpl._( - _isNegative != other._isNegative, resultUsed, resultDigits); - } - - // resultDigits[0..resultUsed-1] = - // xDigits[0..xUsed-1]*otherDigits[0..otherUsed-1]. - // Returns resultUsed = xUsed + otherUsed. - static int _mulDigits(Uint32List xDigits, int xUsed, Uint32List otherDigits, - int otherUsed, Uint32List resultDigits) { - var resultUsed = xUsed + otherUsed; - var i = resultUsed + (resultUsed & 1); - assert(resultDigits.length >= i); - while (--i >= 0) { - resultDigits[i] = 0; - } - i = 0; - while (i < otherUsed) { - i += _mulAdd(otherDigits, i, xDigits, 0, resultDigits, i, xUsed); - } - return resultUsed; - } - - // resultDigits[0..resultUsed-1] = xDigits[0..xUsed-1]^2. - // Returns resultUsed = 2*xUsed. - static int _sqrDigits( - Uint32List xDigits, int xUsed, Uint32List resultDigits) { - var resultUsed = 2 * xUsed; - assert(resultDigits.length >= resultUsed); - // Since resultUsed is even, no need for a leading zero for - // 64-bit processing. - var i = resultUsed; - while (--i >= 0) { - resultDigits[i] = 0; - } - i = 0; - while (i < xUsed - 1) { - i += _sqrAdd(xDigits, i, resultDigits, xUsed); - } - // The last step is already done if digit pairs were processed above. - if (i < xUsed) { - _mulAdd(xDigits, i, xDigits, i, resultDigits, 2 * i, 1); - } - return resultUsed; - } - - // Indices of the arguments of _estimateQuotientDigit. - // For 64-bit processing by intrinsics on 64-bit platforms, the top digit pair - // of the divisor is provided in the args array, and a 64-bit estimated - // quotient is returned. However, on 32-bit platforms, the low 32-bit digit is - // ignored and only one 32-bit digit is returned as the estimated quotient. - static const int _divisorLowTopDigit = 0; // Low digit of top pair of divisor. - static const int _divisorTopDigit = 1; // Top digit of divisor. - static const int _quotientDigit = 2; // Estimated quotient. - static const int _quotientHighDigit = 3; // High digit of estimated quotient. - - /// Estimate `args[_quotientDigit] = digits[i-1..i] ~/ args[_divisorTopDigit]` - /// Returns 1. - /// - /// Note: This function may be intrinsified. Intrinsics on 64-bit platforms - /// process a digit pair (i always odd): - /// Estimate `args[_quotientDigit.._quotientHighDigit] = digits[i-3..i] ~/ - /// args[_divisorLowTopDigit.._divisorTopDigit]`. - /// Returns 2. - @pragma("vm:exact-result-type", "dart:core#_Smi") - @pragma("vm:never-inline") - static int _estimateQuotientDigit(Uint32List args, Uint32List digits, int i) { - // Verify that digit pairs are accessible for 64-bit processing. - assert(digits.length >= 4); - if (digits[i] == args[_divisorTopDigit]) { - args[_quotientDigit] = _digitMask; - } else { - // Chop off one bit, since a Mint cannot hold 2 digits. - var quotientDigit = - ((digits[i] << (_digitBits - 1)) | (digits[i - 1] >> 1)) ~/ - (args[_divisorTopDigit] >> 1); - if (quotientDigit > _digitMask) { - args[_quotientDigit] = _digitMask; - } else { - args[_quotientDigit] = quotientDigit; - } - } - return _isIntrinsified ? 2 : 1; - } - - /// Returns `trunc(this / other)`, with `other != 0`. - _BigIntImpl _div(BigInt bigInt) { - final other = _ensureSystemBigInt(bigInt, 'bigInt'); - assert(other._used > 0); - if (_used < other._used) { - return zero; - } - _divRem(other); - // Return quotient, i.e. - // _lastQuoRem_digits[_lastRem_used.._lastQuoRem_used-1] with proper sign. - var lastQuo_used = _lastQuoRemUsed - _lastRemUsed; - var quo_digits = _cloneDigits( - _lastQuoRemDigits, _lastRemUsed, _lastQuoRemUsed, lastQuo_used); - var quo = new _BigIntImpl._(false, lastQuo_used, quo_digits); - if ((_isNegative != other._isNegative) && (quo._used > 0)) { - quo = -quo; - } - return quo; - } - - /// Returns `this - other * trunc(this / other)`, with `other != 0`. - _BigIntImpl _rem(BigInt bigInt) { - final other = _ensureSystemBigInt(bigInt, 'bigInt'); - assert(other._used > 0); - if (_used < other._used) { - return this; - } - _divRem(other); - // Return remainder, i.e. - // denormalized _lastQuoRem_digits[0.._lastRem_used-1] with proper sign. - var remDigits = - _cloneDigits(_lastQuoRemDigits, 0, _lastRemUsed, _lastRemUsed); - var rem = new _BigIntImpl._(false, _lastRemUsed, remDigits); - if (_lastRem_nsh > 0) { - rem = rem >> _lastRem_nsh; // Denormalize remainder. - } - if (_isNegative && (rem._used > 0)) { - rem = -rem; - } - return rem; - } - - /// Computes this ~/ other and this.remainder(other). - /// - /// Stores the result in [_lastQuoRemDigits], [_lastQuoRemUsed] and - /// [_lastRemUsed]. The [_lastQuoRemDigits] contains the digits of *both*, the - /// quotient and the remainder. - /// - /// Caches the input to avoid doing the work again when users write - /// `a ~/ b` followed by a `a % b`. - void _divRem(_BigIntImpl other) { - // Check if result is already cached. - if ((this._used == _lastDividendUsed) && - (other._used == _lastDivisorUsed) && - identical(this._digits, _lastDividendDigits) && - identical(other._digits, _lastDivisorDigits)) { - return; - } - assert(_used >= other._used); - - var nsh = _digitBits - other._digits[other._used - 1].bitLength; - // For 64-bit processing, make sure other has an even number of digits. - if (other._used.isOdd) { - nsh += _digitBits; - } - // Concatenated positive quotient and normalized positive remainder. - // The resultDigits can have at most one more digit than the dividend. - Uint32List resultDigits; - int resultUsed; - // Normalized positive divisor (referred to as 'y'). - // The normalized divisor has the most-significant bit of its most - // significant digit set. - // This makes estimating the quotient easier. - Uint32List yDigits; - int yUsed; - if (nsh > 0) { - // Extra digits for normalization, also used for possible _mulAdd carry. - var numExtraDigits = (nsh + _digitBits - 1) ~/ _digitBits + 1; - yDigits = _newDigits(other._used + numExtraDigits); - yUsed = _lShiftDigits(other._digits, other._used, nsh, yDigits); - resultDigits = _newDigits(_used + numExtraDigits); - resultUsed = _lShiftDigits(_digits, _used, nsh, resultDigits); - } else { - yDigits = other._digits; - yUsed = other._used; - // Extra digit to hold possible _mulAdd carry. - resultDigits = _cloneDigits(_digits, 0, _used, _used + 1); - resultUsed = _used; - } - Uint32List args = _newDigits(4); - args[_divisorLowTopDigit] = yDigits[yUsed - 2]; - args[_divisorTopDigit] = yDigits[yUsed - 1]; - // For 64-bit processing, make sure yUsed, i, and j are even. - assert(yUsed.isEven); - var i = resultUsed + (resultUsed & 1); - var j = i - yUsed; - // tmpDigits is a temporary array of i (even resultUsed) digits. - var tmpDigits = _newDigits(i); - var tmpUsed = _dlShiftDigits(yDigits, yUsed, j, tmpDigits); - // Explicit first division step in case normalized dividend is larger or - // equal to shifted normalized divisor. - if (_compareDigits(resultDigits, resultUsed, tmpDigits, tmpUsed) >= 0) { - assert(i == resultUsed); - resultDigits[resultUsed++] = 1; // Quotient = 1. - // Subtract divisor from remainder. - _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits); - } else { - // Account for possible carry in _mulAdd step. - resultDigits[resultUsed++] = 0; - } - if (resultUsed.isOdd) { - resultDigits[resultUsed] = 0; // Leading zero for 64-bit processing. - } - // Negate y so we can later use _mulAdd instead of non-existent _mulSub. - var nyDigits = _newDigits(yUsed + 2); - nyDigits[yUsed] = 1; - _absSub(nyDigits, yUsed + 1, yDigits, yUsed, nyDigits); - // nyDigits is read-only and has yUsed digits (possibly including several - // leading zeros) plus a leading zero for 64-bit processing. - // resultDigits is modified during iteration. - // resultDigits[0..yUsed-1] is the current remainder. - // resultDigits[yUsed..resultUsed-1] is the current quotient. - --i; - while (j > 0) { - var d0 = _estimateQuotientDigit(args, resultDigits, i); - j -= d0; - var d1 = - _mulAdd(args, _quotientDigit, nyDigits, 0, resultDigits, j, yUsed); - // _estimateQuotientDigit and _mulAdd must agree on the number of digits - // to process. - assert(d0 == d1); - if (d0 == 1) { - if (resultDigits[i] < args[_quotientDigit]) { - // Reusing the already existing tmpDigits array. - var tmpUsed = _dlShiftDigits(nyDigits, yUsed, j, tmpDigits); - _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits); - while (resultDigits[i] < --args[_quotientDigit]) { - _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits); - } - } - } else { - assert(d0 == 2); - assert(resultDigits[i] <= args[_quotientHighDigit]); - if (resultDigits[i] < args[_quotientHighDigit] || - resultDigits[i - 1] < args[_quotientDigit]) { - // Reusing the already existing tmpDigits array. - var tmpUsed = _dlShiftDigits(nyDigits, yUsed, j, tmpDigits); - _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits); - if (args[_quotientDigit] == 0) { - --args[_quotientHighDigit]; - } - --args[_quotientDigit]; - assert(resultDigits[i] <= args[_quotientHighDigit]); - while (resultDigits[i] < args[_quotientHighDigit] || - resultDigits[i - 1] < args[_quotientDigit]) { - _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits); - if (args[_quotientDigit] == 0) { - --args[_quotientHighDigit]; - } - --args[_quotientDigit]; - assert(resultDigits[i] <= args[_quotientHighDigit]); - } - } - } - i -= d0; - } - // Cache result. - _lastDividendDigits = _digits; - _lastDividendUsed = _used; - _lastDivisorDigits = other._digits; - _lastDivisorUsed = other._used; - _lastQuoRemDigits = resultDigits; - _lastQuoRemUsed = resultUsed; - _lastRemUsed = yUsed; - _lastRem_nsh = nsh; - } - - // Customized version of _rem() minimizing allocations for use in reduction. - // Input: - // xDigits[0..xUsed-1]: positive dividend. - // yDigits[0..yUsed-1]: normalized positive divisor. - // nyDigits[0..yUsed-1]: negated yDigits. - // nsh: normalization shift amount. - // args: top y digit(s) and place holder for estimated quotient digit(s). - // tmpDigits: temp array of 2*yUsed digits. - // resultDigits: result digits array large enough to temporarily hold - // concatenated quotient and normalized remainder. - // Output: - // resultDigits[0..resultUsed-1]: positive remainder. - // Returns resultUsed. - static int _remDigits( - Uint32List xDigits, - int xUsed, - Uint32List yDigits, - int yUsed, - Uint32List nyDigits, - int nsh, - Uint32List args, - Uint32List tmpDigits, - Uint32List resultDigits) { - // Initialize resultDigits to normalized positive dividend. - var resultUsed = _lShiftDigits(xDigits, xUsed, nsh, resultDigits); - // For 64-bit processing, make sure yUsed, i, and j are even. - assert(yUsed.isEven); - var i = resultUsed + (resultUsed & 1); - var j = i - yUsed; - var tmpUsed = _dlShiftDigits(yDigits, yUsed, j, tmpDigits); - // Explicit first division step in case normalized dividend is larger or - // equal to shifted normalized divisor. - if (_compareDigits(resultDigits, resultUsed, tmpDigits, tmpUsed) >= 0) { - assert(i == resultUsed); - resultDigits[resultUsed++] = 1; // Quotient = 1. - // Subtract divisor from remainder. - _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits); - } else { - // Account for possible carry in _mulAdd step. - resultDigits[resultUsed++] = 0; - } - if (resultUsed.isOdd) { - resultDigits[resultUsed] = 0; // Leading zero for 64-bit processing. - } - // Negated yDigits passed in nyDigits allow the use of _mulAdd instead of - // unimplemented _mulSub. - // nyDigits is read-only and has yUsed digits (possibly including several - // leading zeros) plus a leading zero for 64-bit processing. - // resultDigits is modified during iteration. - // resultDigits[0..yUsed-1] is the current remainder. - // resultDigits[yUsed..resultUsed-1] is the current quotient. - --i; - while (j > 0) { - var d0 = _estimateQuotientDigit(args, resultDigits, i); - j -= d0; - var d1 = - _mulAdd(args, _quotientDigit, nyDigits, 0, resultDigits, j, yUsed); - // _estimateQuotientDigit and _mulAdd must agree on the number of digits - // to process. - assert(d0 == d1); - if (d0 == 1) { - if (resultDigits[i] < args[_quotientDigit]) { - var tmpUsed = _dlShiftDigits(nyDigits, yUsed, j, tmpDigits); - _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits); - while (resultDigits[i] < --args[_quotientDigit]) { - _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits); - } - } - } else { - assert(d0 == 2); - assert(resultDigits[i] <= args[_quotientHighDigit]); - if ((resultDigits[i] < args[_quotientHighDigit]) || - (resultDigits[i - 1] < args[_quotientDigit])) { - var tmpUsed = _dlShiftDigits(nyDigits, yUsed, j, tmpDigits); - _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits); - if (args[_quotientDigit] == 0) { - --args[_quotientHighDigit]; - } - --args[_quotientDigit]; - assert(resultDigits[i] <= args[_quotientHighDigit]); - while ((resultDigits[i] < args[_quotientHighDigit]) || - (resultDigits[i - 1] < args[_quotientDigit])) { - _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits); - if (args[_quotientDigit] == 0) { - --args[_quotientHighDigit]; - } - --args[_quotientDigit]; - assert(resultDigits[i] <= args[_quotientHighDigit]); - } - } - } - i -= d0; - } - // Return remainder, i.e. denormalized resultDigits[0..yUsed-1]. - resultUsed = yUsed; - if (nsh > 0) { - // Denormalize remainder. - resultUsed = _rShiftDigits(resultDigits, resultUsed, nsh, resultDigits); - } - return resultUsed; - } - - int get hashCode { - // This is the [Jenkins hash function][1] but using masking to keep - // values in SMI range. - // - // [1]: http://en.wikipedia.org/wiki/Jenkins_hash_function - - int combine(int hash, int value) { - hash = 0x1fffffff & (hash + value); - hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10)); - return hash ^ (hash >> 6); - } - - int finish(int hash) { - hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3)); - hash = hash ^ (hash >> 11); - return 0x1fffffff & (hash + ((0x00003fff & hash) << 15)); - } - - if (_isZero) return 6707; // Just a random number. - var hash = _isNegative ? 83585 : 429689; // Also random. - for (int i = 0; i < _used; i++) { - hash = combine(hash, _digits[i]); - } - return finish(hash); - } - - /** - * Test whether this value is numerically equal to `other`. - * - * If [other] is a [_BigIntImpl] returns whether the two operands have the - * same value. - * - * Returns false if `other` is not a [_BigIntImpl]. - */ - bool operator ==(Object other) => - other is _BigIntImpl && compareTo(other) == 0; - - /** - * Returns the minimum number of bits required to store this big integer. - * - * The number of bits excludes the sign bit, which gives the natural length - * for non-negative (unsigned) values. Negative values are complemented to - * return the bit position of the first bit that differs from the sign bit. - * - * To find the number of bits needed to store the value as a signed value, - * add one, i.e. use `x.bitLength + 1`. - * - * ``` - * x.bitLength == (-x-1).bitLength - * - * new BigInt.from(3).bitLength == 2; // 00000011 - * new BigInt.from(2).bitLength == 2; // 00000010 - * new BigInt.from(1).bitLength == 1; // 00000001 - * new BigInt.from(0).bitLength == 0; // 00000000 - * new BigInt.from(-1).bitLength == 0; // 11111111 - * new BigInt.from(-2).bitLength == 1; // 11111110 - * new BigInt.from(-3).bitLength == 2; // 11111101 - * new BigInt.from(-4).bitLength == 2; // 11111100 - * ``` - */ - int get bitLength { - if (_used == 0) return 0; - if (_isNegative) return (~this).bitLength; - return _digitBits * (_used - 1) + _digits[_used - 1].bitLength; - } - - /** - * Truncating division operator. - * - * Performs a truncating integer division, where the remainder is discarded. - * - * The remainder can be computed using the [remainder] method. - * - * Examples: - * ``` - * var seven = new BigInt.from(7); - * var three = new BigInt.from(3); - * seven ~/ three; // => 2 - * (-seven) ~/ three; // => -2 - * seven ~/ -three; // => -2 - * seven.remainder(three); // => 1 - * (-seven).remainder(three); // => -1 - * seven.remainder(-three); // => 1 - * ``` - */ - _BigIntImpl operator ~/(BigInt bigInt) { - final other = _ensureSystemBigInt(bigInt, 'bigInt'); - if (other._used == 0) { - throw const IntegerDivisionByZeroException(); - } - return _div(other); - } - - /** - * Returns the remainder of the truncating division of `this` by [other]. - * - * The result `r` of this operation satisfies: - * `this == (this ~/ other) * other + r`. - * As a consequence the remainder `r` has the same sign as the divider `this`. - */ - _BigIntImpl remainder(BigInt bigInt) { - final other = _ensureSystemBigInt(bigInt, 'bigInt'); - if (other._used == 0) { - throw const IntegerDivisionByZeroException(); - } - return _rem(other); - } - - /// Division operator. - double operator /(BigInt other) => this.toDouble() / other.toDouble(); - - /** Relational less than operator. */ - bool operator <(BigInt other) => compareTo(other) < 0; - - /** Relational less than or equal operator. */ - bool operator <=(BigInt other) => compareTo(other) <= 0; - - /** Relational greater than operator. */ - bool operator >(BigInt other) => compareTo(other) > 0; - - /** Relational greater than or equal operator. */ - bool operator >=(BigInt other) => compareTo(other) >= 0; - - /** - * Euclidean modulo operator. - * - * Returns the remainder of the Euclidean division. The Euclidean division of - * two integers `a` and `b` yields two integers `q` and `r` such that - * `a == b * q + r` and `0 <= r < b.abs()`. - * - * The sign of the returned value `r` is always positive. - * - * See [remainder] for the remainder of the truncating division. - */ - _BigIntImpl operator %(BigInt bigInt) { - final other = _ensureSystemBigInt(bigInt, 'bigInt'); - if (other._used == 0) { - throw const IntegerDivisionByZeroException(); - } - var result = _rem(other); - if (result._isNegative) { - if (other._isNegative) { - result = result - other; - } else { - result = result + other; - } - } - return result; - } - - /** - * Returns the sign of this big integer. - * - * Returns 0 for zero, -1 for values less than zero and - * +1 for values greater than zero. - */ - int get sign { - if (_used == 0) return 0; - return _isNegative ? -1 : 1; - } - - /// Whether this big integer is even. - bool get isEven => _used == 0 || (_digits[0] & 1) == 0; - - /// Whether this big integer is odd. - bool get isOdd => !isEven; - - /// Whether this number is negative. - bool get isNegative => _isNegative; - - _BigIntImpl pow(int exponent) { - if (exponent < 0) { - throw new ArgumentError("Exponent must not be negative: $exponent"); - } - if (exponent == 0) return one; - - // Exponentiation by squaring. - var result = one; - var base = this; - while (exponent != 0) { - if ((exponent & 1) == 1) { - result *= base; - } - exponent >>= 1; - // Skip unnecessary operation. - if (exponent != 0) { - base *= base; - } - } - return result; - } - - /** - * Returns this integer to the power of [exponent] modulo [modulus]. - * - * The [exponent] must be non-negative and [modulus] must be - * positive. - */ - _BigIntImpl modPow(BigInt bigExponent, BigInt bigModulus) { - final exponent = _ensureSystemBigInt(bigExponent, 'bigExponent'); - final modulus = _ensureSystemBigInt(bigModulus, 'bigModulus'); - if (exponent._isNegative) { - throw new ArgumentError("exponent must be positive: $exponent"); - } - if (modulus <= zero) { - throw new ArgumentError("modulus must be strictly positive: $modulus"); - } - if (exponent._isZero) return one; - - final exponentBitlen = exponent.bitLength; - if (exponentBitlen <= 0) return one; - final bool cannotUseMontgomery = modulus.isEven || abs() >= modulus; - if (cannotUseMontgomery || exponentBitlen < 64) { - _BigIntReduction z = (cannotUseMontgomery || exponentBitlen < 8) - ? new _BigIntClassicReduction(modulus) - : new _BigIntMontgomeryReduction(modulus); - var resultDigits = _newDigits(2 * z._normModulusUsed + 2); - var result2Digits = _newDigits(2 * z._normModulusUsed + 2); - var gDigits = _newDigits(z._normModulusUsed); - var gUsed = z._convert(this, gDigits); - // Initialize result with g. - // Copy leading zero if any. - for (int j = gUsed + (gUsed & 1) - 1; j >= 0; j--) { - resultDigits[j] = gDigits[j]; - } - var resultUsed = gUsed; - var result2Used; - for (int i = exponentBitlen - 2; i >= 0; i--) { - result2Used = z._sqr(resultDigits, resultUsed, result2Digits); - if (exponent._digits[i ~/ _digitBits] & (1 << (i % _digitBits)) != 0) { - resultUsed = - z._mul(result2Digits, result2Used, gDigits, gUsed, resultDigits); - } else { - // Swap result and result2. - var tmpDigits = resultDigits; - var tmpUsed = resultUsed; - resultDigits = result2Digits; - resultUsed = result2Used; - result2Digits = tmpDigits; - result2Used = tmpUsed; - } - } - return z._revert(resultDigits, resultUsed); - } - late int k; - if (exponentBitlen < 18) - k = 1; - else if (exponentBitlen < 48) - k = 3; - else if (exponentBitlen < 144) - k = 4; - else if (exponentBitlen < 768) - k = 5; - else - k = 6; - _BigIntReduction z = new _BigIntMontgomeryReduction(modulus); - var n = 3; - final int k1 = k - 1; - final km = (1 << k) - 1; - List gDigits = new List.filled(km + 1, null); - List gUsed = new List.filled(km + 1, null); - gDigits[1] = _newDigits(z._normModulusUsed); - gUsed[1] = z._convert(this, gDigits[1]); - if (k > 1) { - var g2Digits = _newDigits(2 * z._normModulusUsed + 2); - var g2Used = z._sqr(gDigits[1], gUsed[1], g2Digits); - while (n <= km) { - gDigits[n] = _newDigits(2 * z._normModulusUsed + 2); - gUsed[n] = - z._mul(g2Digits, g2Used, gDigits[n - 2], gUsed[n - 2], gDigits[n]); - n += 2; - } - } - var w; - var isOne = true; - var resultDigits = one._digits; - var resultUsed = one._used; - var result2Digits = _newDigits(2 * z._normModulusUsed + 2); - var result2Used; - var exponentDigits = exponent._digits; - var j = exponent._used - 1; - int i = exponentDigits[j].bitLength - 1; - while (j >= 0) { - if (i >= k1) { - w = (exponentDigits[j] >> (i - k1)) & km; - } else { - w = (exponentDigits[j] & ((1 << (i + 1)) - 1)) << (k1 - i); - if (j > 0) { - w |= exponentDigits[j - 1] >> (_digitBits + i - k1); - } - } - n = k; - while ((w & 1) == 0) { - w >>= 1; - --n; - } - if ((i -= n) < 0) { - i += _digitBits; - --j; - } - if (isOne) { - // r == 1, don't bother squaring or multiplying it. - resultDigits = _newDigits(2 * z._normModulusUsed + 2); - resultUsed = gUsed[w]; - var gwDigits = gDigits[w]; - var ri = resultUsed + (resultUsed & 1); // Copy leading zero if any. - while (--ri >= 0) { - resultDigits[ri] = gwDigits[ri]; - } - isOne = false; - } else { - while (n > 1) { - result2Used = z._sqr(resultDigits, resultUsed, result2Digits); - resultUsed = z._sqr(result2Digits, result2Used, resultDigits); - n -= 2; - } - if (n > 0) { - result2Used = z._sqr(resultDigits, resultUsed, result2Digits); - } else { - var swapDigits = resultDigits; - var swapUsed = resultUsed; - resultDigits = result2Digits; - resultUsed = result2Used; - result2Digits = swapDigits; - result2Used = swapUsed; - } - resultUsed = z._mul( - result2Digits, result2Used, gDigits[w], gUsed[w], resultDigits); - } - while (j >= 0 && (exponentDigits[j] & (1 << i)) == 0) { - result2Used = z._sqr(resultDigits, resultUsed, result2Digits); - var swapDigits = resultDigits; - var swapUsed = resultUsed; - resultDigits = result2Digits; - resultUsed = result2Used; - result2Digits = swapDigits; - result2Used = swapUsed; - if (--i < 0) { - i = _digitBits - 1; - --j; - } - } - } - assert(!isOne); - return z._revert(resultDigits, resultUsed); - } - - // If inv is false, returns gcd(x, y). - // If inv is true and gcd(x, y) = 1, returns d, so that c*x + d*y = 1. - // If inv is true and gcd(x, y) != 1, throws Exception("Not coprime"). - static _BigIntImpl _binaryGcd(_BigIntImpl x, _BigIntImpl y, bool inv) { - var xDigits = x._digits; - var yDigits = y._digits; - var xUsed = x._used; - var yUsed = y._used; - var maxUsed = _max(xUsed, yUsed); - final maxLen = maxUsed + (maxUsed & 1); - xDigits = _cloneDigits(xDigits, 0, xUsed, maxLen); - yDigits = _cloneDigits(yDigits, 0, yUsed, maxLen); - int shiftAmount = 0; - if (inv) { - if ((yUsed == 1) && (yDigits[0] == 1)) return one; - if ((yUsed == 0) || (yDigits[0].isEven && xDigits[0].isEven)) { - throw new Exception("Not coprime"); - } - } else { - if (x._isZero) { - throw new ArgumentError.value(0, "this", "must not be zero"); - } - if (y._isZero) { - throw new ArgumentError.value(0, "other", "must not be zero"); - } - if (((xUsed == 1) && (xDigits[0] == 1)) || - ((yUsed == 1) && (yDigits[0] == 1))) return one; - while (((xDigits[0] & 1) == 0) && ((yDigits[0] & 1) == 0)) { - _rsh(xDigits, xUsed, 1, xDigits); - _rsh(yDigits, yUsed, 1, yDigits); - shiftAmount++; - } - if (shiftAmount >= _digitBits) { - var digitShiftAmount = shiftAmount ~/ _digitBits; - xUsed -= digitShiftAmount; - yUsed -= digitShiftAmount; - maxUsed -= digitShiftAmount; - } - if ((yDigits[0] & 1) == 1) { - // Swap x and y. - var tmpDigits = xDigits; - var tmpUsed = xUsed; - xDigits = yDigits; - xUsed = yUsed; - yDigits = tmpDigits; - yUsed = tmpUsed; - } - } - var uDigits = _cloneDigits(xDigits, 0, xUsed, maxLen); - var vDigits = _cloneDigits(yDigits, 0, yUsed, maxLen + 2); // +2 for lsh. - final bool ac = (xDigits[0] & 1) == 0; - - // Variables a, b, c, and d require one more digit. - final abcdUsed = maxUsed + 1; - final abcdLen = abcdUsed + (abcdUsed & 1) + 2; // +2 to satisfy _absAdd. - - bool aIsNegative = false; - bool cIsNegative = false; - late final Uint32List aDigits, cDigits; - if (ac) { - aDigits = _newDigits(abcdLen); - aDigits[0] = 1; - cDigits = _newDigits(abcdLen); - } - final Uint32List bDigits = _newDigits(abcdLen); - final Uint32List dDigits = _newDigits(abcdLen); - bool bIsNegative = false; - bool dIsNegative = false; - dDigits[0] = 1; - - while (true) { - while ((uDigits[0] & 1) == 0) { - _rsh(uDigits, maxUsed, 1, uDigits); - if (ac) { - if (((aDigits[0] & 1) == 1) || ((bDigits[0] & 1) == 1)) { - // a += y - if (aIsNegative) { - if ((aDigits[maxUsed] != 0) || - (_compareDigits(aDigits, maxUsed, yDigits, maxUsed)) > 0) { - _absSub(aDigits, abcdUsed, yDigits, maxUsed, aDigits); - } else { - _absSub(yDigits, maxUsed, aDigits, maxUsed, aDigits); - aIsNegative = false; - } - } else { - _absAdd(aDigits, abcdUsed, yDigits, maxUsed, aDigits); - } - // b -= x - if (bIsNegative) { - _absAdd(bDigits, abcdUsed, xDigits, maxUsed, bDigits); - } else if ((bDigits[maxUsed] != 0) || - (_compareDigits(bDigits, maxUsed, xDigits, maxUsed) > 0)) { - _absSub(bDigits, abcdUsed, xDigits, maxUsed, bDigits); - } else { - _absSub(xDigits, maxUsed, bDigits, maxUsed, bDigits); - bIsNegative = true; - } - } - _rsh(aDigits, abcdUsed, 1, aDigits); - } else if ((bDigits[0] & 1) == 1) { - // b -= x - if (bIsNegative) { - _absAdd(bDigits, abcdUsed, xDigits, maxUsed, bDigits); - } else if ((bDigits[maxUsed] != 0) || - (_compareDigits(bDigits, maxUsed, xDigits, maxUsed) > 0)) { - _absSub(bDigits, abcdUsed, xDigits, maxUsed, bDigits); - } else { - _absSub(xDigits, maxUsed, bDigits, maxUsed, bDigits); - bIsNegative = true; - } - } - _rsh(bDigits, abcdUsed, 1, bDigits); - } - while ((vDigits[0] & 1) == 0) { - _rsh(vDigits, maxUsed, 1, vDigits); - if (ac) { - if (((cDigits[0] & 1) == 1) || ((dDigits[0] & 1) == 1)) { - // c += y - if (cIsNegative) { - if ((cDigits[maxUsed] != 0) || - (_compareDigits(cDigits, maxUsed, yDigits, maxUsed) > 0)) { - _absSub(cDigits, abcdUsed, yDigits, maxUsed, cDigits); - } else { - _absSub(yDigits, maxUsed, cDigits, maxUsed, cDigits); - cIsNegative = false; - } - } else { - _absAdd(cDigits, abcdUsed, yDigits, maxUsed, cDigits); - } - // d -= x - if (dIsNegative) { - _absAdd(dDigits, abcdUsed, xDigits, maxUsed, dDigits); - } else if ((dDigits[maxUsed] != 0) || - (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) { - _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits); - } else { - _absSub(xDigits, maxUsed, dDigits, maxUsed, dDigits); - dIsNegative = true; - } - } - _rsh(cDigits, abcdUsed, 1, cDigits); - } else if ((dDigits[0] & 1) == 1) { - // d -= x - if (dIsNegative) { - _absAdd(dDigits, abcdUsed, xDigits, maxUsed, dDigits); - } else if ((dDigits[maxUsed] != 0) || - (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) { - _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits); - } else { - _absSub(xDigits, maxUsed, dDigits, maxUsed, dDigits); - dIsNegative = true; - } - } - _rsh(dDigits, abcdUsed, 1, dDigits); - } - if (_compareDigits(uDigits, maxUsed, vDigits, maxUsed) >= 0) { - // u -= v - _absSub(uDigits, maxUsed, vDigits, maxUsed, uDigits); - if (ac) { - // a -= c - if (aIsNegative == cIsNegative) { - var a_cmp_c = _compareDigits(aDigits, abcdUsed, cDigits, abcdUsed); - if (a_cmp_c > 0) { - _absSub(aDigits, abcdUsed, cDigits, abcdUsed, aDigits); - } else { - _absSub(cDigits, abcdUsed, aDigits, abcdUsed, aDigits); - aIsNegative = !aIsNegative && (a_cmp_c != 0); - } - } else { - _absAdd(aDigits, abcdUsed, cDigits, abcdUsed, aDigits); - } - } - // b -= d - if (bIsNegative == dIsNegative) { - var b_cmp_d = _compareDigits(bDigits, abcdUsed, dDigits, abcdUsed); - if (b_cmp_d > 0) { - _absSub(bDigits, abcdUsed, dDigits, abcdUsed, bDigits); - } else { - _absSub(dDigits, abcdUsed, bDigits, abcdUsed, bDigits); - bIsNegative = !bIsNegative && (b_cmp_d != 0); - } - } else { - _absAdd(bDigits, abcdUsed, dDigits, abcdUsed, bDigits); - } - } else { - // v -= u - _absSub(vDigits, maxUsed, uDigits, maxUsed, vDigits); - if (ac) { - // c -= a - if (cIsNegative == aIsNegative) { - var c_cmp_a = _compareDigits(cDigits, abcdUsed, aDigits, abcdUsed); - if (c_cmp_a > 0) { - _absSub(cDigits, abcdUsed, aDigits, abcdUsed, cDigits); - } else { - _absSub(aDigits, abcdUsed, cDigits, abcdUsed, cDigits); - cIsNegative = !cIsNegative && (c_cmp_a != 0); - } - } else { - _absAdd(cDigits, abcdUsed, aDigits, abcdUsed, cDigits); - } - } - // d -= b - if (dIsNegative == bIsNegative) { - var d_cmp_b = _compareDigits(dDigits, abcdUsed, bDigits, abcdUsed); - if (d_cmp_b > 0) { - _absSub(dDigits, abcdUsed, bDigits, abcdUsed, dDigits); - } else { - _absSub(bDigits, abcdUsed, dDigits, abcdUsed, dDigits); - dIsNegative = !dIsNegative && (d_cmp_b != 0); - } - } else { - _absAdd(dDigits, abcdUsed, bDigits, abcdUsed, dDigits); - } - } - // Exit loop if u == 0. - var i = maxUsed; - while ((i > 0) && (uDigits[i - 1] == 0)) --i; - if (i == 0) break; - } - if (!inv) { - if (shiftAmount > 0) { - maxUsed = _lShiftDigits(vDigits, maxUsed, shiftAmount, vDigits); - } - return new _BigIntImpl._(false, maxUsed, vDigits); - } - // No inverse if v != 1. - var i = maxUsed - 1; - while ((i > 0) && (vDigits[i] == 0)) --i; - if ((i != 0) || (vDigits[0] != 1)) { - throw new Exception("Not coprime"); - } - - if (dIsNegative) { - while ((dDigits[maxUsed] != 0) || - (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) { - // d += x, d still negative - _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits); - } - // d += x - _absSub(xDigits, maxUsed, dDigits, maxUsed, dDigits); - dIsNegative = false; - } else { - while ((dDigits[maxUsed] != 0) || - (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) >= 0)) { - // d -= x - _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits); - } - } - return new _BigIntImpl._(false, maxUsed, dDigits); - } - - /** - * Returns the modular multiplicative inverse of this big integer - * modulo [modulus]. - * - * The [modulus] must be positive. - * - * It is an error if no modular inverse exists. - */ - // Returns 1/this % modulus, with modulus > 0. - _BigIntImpl modInverse(BigInt bigInt) { - final modulus = _ensureSystemBigInt(bigInt, 'bigInt'); - if (modulus <= zero) { - throw new ArgumentError("Modulus must be strictly positive: $modulus"); - } - if (modulus == one) return zero; - var tmp = this; - if (tmp._isNegative || (tmp._absCompare(modulus) >= 0)) { - tmp %= modulus; - } - return _binaryGcd(modulus, tmp, true); - } - - /** - * Returns the greatest common divisor of this big integer and [other]. - * - * If either number is non-zero, the result is the numerically greatest - * integer dividing both `this` and `other`. - * - * The greatest common divisor is independent of the order, - * so `x.gcd(y)` is always the same as `y.gcd(x)`. - * - * For any integer `x`, `x.gcd(x)` is `x.abs()`. - * - * If both `this` and `other` is zero, the result is also zero. - */ - _BigIntImpl gcd(BigInt bigInt) { - final other = _ensureSystemBigInt(bigInt, 'bigInt'); - if (_isZero) return other.abs(); - if (other._isZero) return this.abs(); - return _binaryGcd(this, other, false); - } - - /** - * Returns the least significant [width] bits of this big integer as a - * non-negative number (i.e. unsigned representation). The returned value has - * zeros in all bit positions higher than [width]. - * - * ``` - * new BigInt.from(-1).toUnsigned(5) == 31 // 11111111 -> 00011111 - * ``` - * - * This operation can be used to simulate arithmetic from low level languages. - * For example, to increment an 8 bit quantity: - * - * ``` - * q = (q + 1).toUnsigned(8); - * ``` - * - * `q` will count from `0` up to `255` and then wrap around to `0`. - * - * If the input fits in [width] bits without truncation, the result is the - * same as the input. The minimum width needed to avoid truncation of `x` is - * given by `x.bitLength`, i.e. - * - * ``` - * x == x.toUnsigned(x.bitLength); - * ``` - */ - _BigIntImpl toUnsigned(int width) { - return this & ((one << width) - one); - } - - /** - * Returns the least significant [width] bits of this integer, extending the - * highest retained bit to the sign. This is the same as truncating the value - * to fit in [width] bits using an signed 2-s complement representation. The - * returned value has the same bit value in all positions higher than [width]. - * - * ``` - * var big15 = new BigInt.from(15); - * var big16 = new BigInt.from(16); - * var big239 = new BigInt.from(239); - * V--sign bit-V - * big16.toSigned(5) == -big16 // 00010000 -> 11110000 - * big239.toSigned(5) == big15 // 11101111 -> 00001111 - * ^ ^ - * ``` - * - * This operation can be used to simulate arithmetic from low level languages. - * For example, to increment an 8 bit signed quantity: - * - * ``` - * q = (q + 1).toSigned(8); - * ``` - * - * `q` will count from `0` up to `127`, wrap to `-128` and count back up to - * `127`. - * - * If the input value fits in [width] bits without truncation, the result is - * the same as the input. The minimum width needed to avoid truncation of `x` - * is `x.bitLength + 1`, i.e. - * - * ``` - * x == x.toSigned(x.bitLength + 1); - * ``` - */ - _BigIntImpl toSigned(int width) { - // The value of binary number weights each bit by a power of two. The - // twos-complement value weights the sign bit negatively. We compute the - // value of the negative weighting by isolating the sign bit with the - // correct power of two weighting and subtracting it from the value of the - // lower bits. - var signMask = one << (width - 1); - return (this & (signMask - one)) - (this & signMask); - } - - bool get isValidInt { - assert(_digitBits == 32); - return _used < 2 || - (_used == 2 && - (_digits[1] < 0x80000000 || - (_isNegative && _digits[1] == 0x80000000 && _digits[0] == 0))); - } - - int toInt() { - assert(_digitBits == 32); - if (_used == 0) return 0; - if (_used == 1) return _isNegative ? -_digits[0] : _digits[0]; - if (_used == 2 && _digits[1] < 0x80000000) { - var result = (_digits[1] << _digitBits) | _digits[0]; - return _isNegative ? -result : result; - } - return _isNegative ? _minInt : _maxInt; - } - - /** - * Returns this [_BigIntImpl] as a [double]. - * - * If the number is not representable as a [double], an - * approximation is returned. For numerically large integers, the - * approximation may be infinite. - */ - double toDouble() { - const int exponentBias = 1075; - // There are 11 bits for the exponent. - // 2047 (all bits set to 1) is reserved for infinity and NaN. - // When storing the exponent in the 11 bits, it is biased by exponentBias - // to support negative exponents. - const int maxDoubleExponent = 2046 - exponentBias; - if (_isZero) return 0.0; - - // We fill the 53 bits little-endian. - var resultBits = new Uint8List(8); - - var length = _digitBits * (_used - 1) + _digits[_used - 1].bitLength; - if (length > maxDoubleExponent + 53) { - return _isNegative ? double.negativeInfinity : double.infinity; - } - - // The most significant bit is for the sign. - if (_isNegative) resultBits[7] = 0x80; - - // Write the exponent into bits 1..12: - var biasedExponent = length - 53 + exponentBias; - resultBits[6] = (biasedExponent & 0xF) << 4; - resultBits[7] |= biasedExponent >> 4; - - int cachedBits = 0; - int cachedBitsLength = 0; - int digitIndex = _used - 1; - int readBits(int n) { - // Ensure that we have enough bits in [cachedBits]. - while (cachedBitsLength < n) { - int nextDigit; - int nextDigitLength = _digitBits; // May get updated. - if (digitIndex < 0) { - nextDigit = 0; - digitIndex--; - } else { - nextDigit = _digits[digitIndex]; - if (digitIndex == _used - 1) nextDigitLength = nextDigit.bitLength; - digitIndex--; - } - cachedBits = (cachedBits << nextDigitLength) + nextDigit; - cachedBitsLength += nextDigitLength; - } - // Read the top [n] bits. - var result = cachedBits >> (cachedBitsLength - n); - // Remove the bits from the cache. - cachedBits -= result << (cachedBitsLength - n); - cachedBitsLength -= n; - return result; - } - - // The first leading 1 bit is implicit in the double-representation and can - // be discarded. - var leadingBits = readBits(5) & 0xF; - resultBits[6] |= leadingBits; - - for (int i = 5; i >= 0; i--) { - // Get the remaining 48 bits. - resultBits[i] = readBits(8); - } - - void roundUp() { - // Simply consists of adding 1 to the whole 64 bit "number". - // It will update the exponent, if necessary. - // It might even round up to infinity (which is what we want). - var carry = 1; - for (int i = 0; i < 8; i++) { - if (carry == 0) break; - var sum = resultBits[i] + carry; - resultBits[i] = sum & 0xFF; - carry = sum >> 8; - } - } - - if (readBits(1) == 1) { - if (resultBits[0].isOdd) { - // Rounds to even all the time. - roundUp(); - } else { - // Round up, if there is at least one other digit that is not 0. - if (cachedBits != 0) { - // There is already one in the cachedBits. - roundUp(); - } else { - for (int i = digitIndex; i >= 0; i--) { - if (_digits[i] != 0) { - roundUp(); - break; - } - } - } - } - } - return resultBits.buffer.asByteData().getFloat64(0, Endian.little); - } - - /** - * Returns a String-representation of this integer. - * - * The returned string is parsable by [parse]. - * For any `_BigIntImpl` `i`, it is guaranteed that - * `i == _BigIntImpl.parse(i.toString())`. - */ - String toString() { - if (_used == 0) return "0"; - if (_used == 1) { - if (_isNegative) return (-_digits[0]).toString(); - return _digits[0].toString(); - } - - // Generate in chunks of 9 digits. - // The chunks are in reversed order. - var decimalDigitChunks = []; - var rest = isNegative ? -this : this; - while (rest._used > 1) { - var digits9 = rest.remainder(_oneBillion).toString(); - decimalDigitChunks.add(digits9); - var zeros = 9 - digits9.length; - if (zeros == 8) { - decimalDigitChunks.add("00000000"); - } else { - if (zeros >= 4) { - zeros -= 4; - decimalDigitChunks.add("0000"); - } - if (zeros >= 2) { - zeros -= 2; - decimalDigitChunks.add("00"); - } - if (zeros >= 1) { - decimalDigitChunks.add("0"); - } - } - rest = rest ~/ _oneBillion; - } - decimalDigitChunks.add(rest._digits[0].toString()); - if (_isNegative) decimalDigitChunks.add("-"); - return decimalDigitChunks.reversed.join(); - } - - int _toRadixCodeUnit(int digit) { - const int _0 = 48; - const int _a = 97; - if (digit < 10) return _0 + digit; - return _a + digit - 10; - } - - /** - * Converts [this] to a string representation in the given [radix]. - * - * In the string representation, lower-case letters are used for digits above - * '9', with 'a' being 10 an 'z' being 35. - * - * The [radix] argument must be an integer in the range 2 to 36. - */ - String toRadixString(int radix) { - if (radix > 36) throw new RangeError.range(radix, 2, 36); - - if (_used == 0) return "0"; - - if (_used == 1) { - var digitString = _digits[0].toRadixString(radix); - if (_isNegative) return "-" + digitString; - return digitString; - } - - if (radix == 16) return _toHexString(); - - var base = new _BigIntImpl._fromInt(radix); - var reversedDigitCodeUnits = []; - var rest = this.abs(); - while (!rest._isZero) { - var digit = rest.remainder(base).toInt(); - rest = rest ~/ base; - reversedDigitCodeUnits.add(_toRadixCodeUnit(digit)); - } - var digitString = new String.fromCharCodes(reversedDigitCodeUnits.reversed); - if (_isNegative) return "-" + digitString; - return digitString; - } - - String _toHexString() { - var chars = []; - for (int i = 0; i < _used - 1; i++) { - int chunk = _digits[i]; - for (int j = 0; j < (_digitBits ~/ 4); j++) { - chars.add(_toRadixCodeUnit(chunk & 0xF)); - chunk >>= 4; - } - } - var msbChunk = _digits[_used - 1]; - while (msbChunk != 0) { - chars.add(_toRadixCodeUnit(msbChunk & 0xF)); - msbChunk >>= 4; - } - if (_isNegative) { - const _dash = 45; - chars.add(_dash); - } - return new String.fromCharCodes(chars.reversed); - } - - static _BigIntImpl _ensureSystemBigInt(BigInt bigInt, String parameterName) { - if (bigInt is _BigIntImpl) return bigInt; - throw ArgumentError.value( - bigInt, parameterName, "Must be a platform BigInt"); - } -} - -// Interface for modular reduction. -abstract class _BigIntReduction { - int get _normModulusUsed; - // Return the number of digits used by resultDigits. - int _convert(_BigIntImpl x, Uint32List resultDigits); - int _mul(Uint32List xDigits, int xUsed, Uint32List yDigits, int yUsed, - Uint32List resultDigits); - int _sqr(Uint32List xDigits, int xUsed, Uint32List resultDigits); - - // Return x reverted to _BigIntImpl. - _BigIntImpl _revert(Uint32List xDigits, int xUsed); -} - -// Montgomery reduction on _BigIntImpl. -class _BigIntMontgomeryReduction implements _BigIntReduction { - final _BigIntImpl _modulus; - final int _normModulusUsed; // Even if processing 64-bit (digit pairs). - final Uint32List _modulusDigits; - final Uint32List _args; - final int _digitsPerStep; // Number of digits processed in one step. 1 or 2. - static const int _xDigit = 0; // Index of digit of x. - static const int _xHighDigit = 1; // Index of high digit of x (64-bit only). - static const int _rhoDigit = 2; // Index of digit of rho. - static const int _rhoHighDigit = 3; // Index of high digit of rho (64-bit). - static const int _muDigit = 4; // Index of mu. - static const int _muHighDigit = 5; // Index of high 32-bits of mu (64-bit). - - factory _BigIntMontgomeryReduction(_BigIntImpl modulus) { - final Uint32List modulusDigits = modulus._digits; - final Uint32List args = _newDigits(6); - - // Determine if we can process digit pairs by calling an intrinsic. - final int digitsPerStep = _mulMod(args, args, 0); - args[_xDigit] = modulusDigits[0]; - - int normModulusUsed = modulus._used; - if (digitsPerStep == 1) { - _invDigit(args); - } else { - assert(digitsPerStep == 2); - normModulusUsed += modulus._used & 1; - args[_xHighDigit] = modulusDigits[1]; - _invDigitPair(args); - } - return _BigIntMontgomeryReduction._( - modulus, normModulusUsed, modulusDigits, args, digitsPerStep); - } - - _BigIntMontgomeryReduction._(this._modulus, this._normModulusUsed, - this._modulusDigits, this._args, this._digitsPerStep); - - // Calculates -1/x % _digitBase, x is 32-bit digit. - // xy == 1 (mod m) - // xy = 1+km - // xy(2-xy) = (1+km)(1-km) - // x(y(2-xy)) = 1-k^2 m^2 - // x(y(2-xy)) == 1 (mod m^2) - // if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 - // Should reduce x and y(2-xy) by m^2 at each step to keep size bounded. - // - // Operation: - // args[_rhoDigit] = 1/args[_xDigit] mod _digitBase. - static void _invDigit(Uint32List args) { - var x = args[_xDigit]; - var y = x & 3; // y == 1/x mod 2^2 - y = (y * (2 - (x & 0xf) * y)) & 0xf; // y == 1/x mod 2^4 - y = (y * (2 - (x & 0xff) * y)) & 0xff; // y == 1/x mod 2^8 - y = (y * (2 - (((x & 0xffff) * y) & 0xffff))) & 0xffff; // y == 1/x mod 2^16 - y = (y * (2 - x * y % _BigIntImpl._digitBase)) % _BigIntImpl._digitBase; - // y == 1/x mod _digitBase - y = -y; // We really want the negative inverse. - args[_rhoDigit] = y & _BigIntImpl._digitMask; - assert(((x * y) & _BigIntImpl._digitMask) == _BigIntImpl._digitMask); - } - - // Calculates -1/x % _digitBase^2, x is a pair of 32-bit digits. - // Operation: - // args[_rhoDigit.._rhoHighDigit] = - // 1/args[_xDigit.._xHighDigit] mod _digitBase^2. - static void _invDigitPair(Uint32List args) { - var xl = args[_xDigit]; // Lower 32-bit digit of x. - var y = xl & 3; // y == 1/x mod 2^2 - y = (y * (2 - (xl & 0xf) * y)) & 0xf; // y == 1/x mod 2^4 - y = (y * (2 - (xl & 0xff) * y)) & 0xff; // y == 1/x mod 2^8 - y = (y * (2 - (((xl & 0xffff) * y) & 0xffff))) & 0xffff; - // y == 1/x mod 2^16 - y = (y * (2 - ((xl * y) & 0xffffffff))) & 0xffffffff; // y == 1/x mod 2^32 - var x = (args[_xHighDigit] << _BigIntImpl._digitBits) | xl; - y *= 2 - x * y; // Masking with 2^64-1 is implied by 64-bit arithmetic. - // y == 1/x mod _digitBase^2 - y = -y; // We really want the negative inverse. - args[_rhoDigit] = y & _BigIntImpl._digitMask; - args[_rhoHighDigit] = - (y >> _BigIntImpl._digitBits) & _BigIntImpl._digitMask; - assert(x * y == -1); - } - - // Operation: - // args[_muDigit] = args[_rhoDigit]*digits[i] mod _digitBase. - // Returns 1. - // Note: Intrinsics on 64-bit platforms process digit pairs at even indices: - // args[_muDigit.._muHighDigit] = - // args[_rhoDigit.._rhoHighDigit] * digits[i..i+1] mod _digitBase^2. - // Returns 2. - @pragma("vm:exact-result-type", "dart:core#_Smi") - @pragma("vm:never-inline") - static int _mulMod(Uint32List args, Uint32List digits, int i) { - var rhol = args[_rhoDigit] & _BigIntImpl._halfDigitMask; - var rhoh = args[_rhoDigit] >> _BigIntImpl._halfDigitBits; - var dh = digits[i] >> _BigIntImpl._halfDigitBits; - var dl = digits[i] & _BigIntImpl._halfDigitMask; - args[_muDigit] = (dl * rhol + - (((dl * rhoh + dh * rhol) & _BigIntImpl._halfDigitMask) << - _BigIntImpl._halfDigitBits)) & - _BigIntImpl._digitMask; - return _BigIntImpl._isIntrinsified ? 2 : 1; - } - - // result = x*R mod _modulus. - // Returns resultUsed. - int _convert(_BigIntImpl x, Uint32List resultDigits) { - // Montgomery reduction only works if abs(x) < _modulus. - assert(x.abs() < _modulus); - assert(_digitsPerStep == 1 || _normModulusUsed.isEven); - var result = x.abs()._dlShift(_normModulusUsed)._rem(_modulus); - if (x._isNegative && !result._isNegative && result._used > 0) { - result = _modulus - result; - } - var used = result._used; - var digits = result._digits; - var i = used + (used & 1); - while (--i >= 0) { - resultDigits[i] = digits[i]; - } - return used; - } - - _BigIntImpl _revert(Uint32List xDigits, int xUsed) { - // Reserve enough digits for modulus squaring and accumulator carry. - var resultDigits = _newDigits(2 * _normModulusUsed + 2); - var i = xUsed + (xUsed & 1); - while (--i >= 0) { - resultDigits[i] = xDigits[i]; - } - var resultUsed = _reduce(resultDigits, xUsed); - return new _BigIntImpl._(false, resultUsed, resultDigits); - } - - // x = x/R mod _modulus. - // Returns xUsed. - int _reduce(Uint32List xDigits, int xUsed) { - while (xUsed < 2 * _normModulusUsed + 2) { - // Pad x so _mulAdd has enough room later for a possible carry. - xDigits[xUsed++] = 0; - } - var i = 0; - while (i < _normModulusUsed) { - var d = _mulMod(_args, xDigits, i); - assert(d == _digitsPerStep); - d = _BigIntImpl._mulAdd( - _args, _muDigit, _modulusDigits, 0, xDigits, i, _normModulusUsed); - assert(d == _digitsPerStep); - i += d; - } - // Clamp x. - while (xUsed > 0 && xDigits[xUsed - 1] == 0) { - --xUsed; - } - xUsed = _BigIntImpl._drShiftDigits(xDigits, xUsed, i, xDigits); - if (_BigIntImpl._compareDigits( - xDigits, xUsed, _modulusDigits, _normModulusUsed) >= - 0) { - _BigIntImpl._absSub( - xDigits, xUsed, _modulusDigits, _normModulusUsed, xDigits); - } - // Clamp x. - while (xUsed > 0 && xDigits[xUsed - 1] == 0) { - --xUsed; - } - return xUsed; - } - - int _sqr(Uint32List xDigits, int xUsed, Uint32List resultDigits) { - var resultUsed = _BigIntImpl._sqrDigits(xDigits, xUsed, resultDigits); - return _reduce(resultDigits, resultUsed); - } - - int _mul(Uint32List xDigits, int xUsed, Uint32List yDigits, int yUsed, - Uint32List resultDigits) { - var resultUsed = - _BigIntImpl._mulDigits(xDigits, xUsed, yDigits, yUsed, resultDigits); - return _reduce(resultDigits, resultUsed); - } -} - -// Modular reduction using "classic" algorithm. -class _BigIntClassicReduction implements _BigIntReduction { - final _BigIntImpl _modulus; // Modulus. - int _normModulusUsed; - _BigIntImpl _normModulus; // Normalized _modulus. - Uint32List _normModulusDigits; - Uint32List _negNormModulusDigits; // Negated _normModulus digits. - int _modulusNsh; // Normalization shift amount. - Uint32List _args; // Top _normModulus digit(s) and place holder for estimated - // quotient digit(s). - Uint32List _tmpDigits; // Temporary digits used during reduction. - - factory _BigIntClassicReduction(_BigIntImpl modulus) { - // Preprocess arguments to _remDigits. - int nsh = - _BigIntImpl._digitBits - modulus._digits[modulus._used - 1].bitLength; - // For 64-bit processing, make sure _negNormModulusDigits has an even number - // of digits. - if (modulus._used.isOdd) { - nsh += _BigIntImpl._digitBits; - } - final _BigIntImpl normModulus = modulus << nsh; - final int normModulusUsed = normModulus._used; - final Uint32List normModulusDigits = normModulus._digits; - assert(normModulusUsed.isEven); - - final Uint32List args = _newDigits(4); - args[_BigIntImpl._divisorLowTopDigit] = - normModulusDigits[normModulusUsed - 2]; - args[_BigIntImpl._divisorTopDigit] = normModulusDigits[normModulusUsed - 1]; - // Negate normModulus so we can use _mulAdd instead of - // unimplemented _mulSub. - final _BigIntImpl negNormModulus = - _BigIntImpl.one._dlShift(normModulusUsed) - normModulus; - late Uint32List negNormModulusDigits; - if (negNormModulus._used < normModulusUsed) { - negNormModulusDigits = _BigIntImpl._cloneDigits( - negNormModulus._digits, 0, normModulusUsed, normModulusUsed); - } else { - negNormModulusDigits = negNormModulus._digits; - } - // negNormModulusDigits is read-only and has normModulusUsed digits (possibly - // including several leading zeros) plus a leading zero for 64-bit - // processing. - final Uint32List tmpDigits = _newDigits(2 * normModulusUsed); - - return _BigIntClassicReduction._(modulus, normModulusUsed, normModulus, - normModulusDigits, negNormModulusDigits, nsh, args, tmpDigits); - } - - _BigIntClassicReduction._( - this._modulus, - this._normModulusUsed, - this._normModulus, - this._normModulusDigits, - this._negNormModulusDigits, - this._modulusNsh, - this._args, - this._tmpDigits); - - int _convert(_BigIntImpl x, Uint32List resultDigits) { - var digits; - var used; - if (x._isNegative || x._absCompare(_modulus) >= 0) { - var remainder = x._rem(_modulus); - if (x._isNegative && remainder._used > 0) { - assert(remainder._isNegative); - remainder += _modulus; - } - assert(!remainder._isNegative); - used = remainder._used; - digits = remainder._digits; - } else { - used = x._used; - digits = x._digits; - } - var i = used + (used & 1); // Copy leading zero if any. - while (--i >= 0) { - resultDigits[i] = digits[i]; - } - return used; - } - - _BigIntImpl _revert(Uint32List xDigits, int xUsed) { - return new _BigIntImpl._(false, xUsed, xDigits); - } - - int _reduce(Uint32List xDigits, int xUsed) { - if (xUsed < _modulus._used) { - return xUsed; - } - // The function _BigIntImpl._remDigits(...) is optimized for reduction and - // equivalent to calling - // 'convert(revert(xDigits, xUsed)._rem(_normModulus), xDigits);' - return _BigIntImpl._remDigits( - xDigits, - xUsed, - _normModulusDigits, - _normModulusUsed, - _negNormModulusDigits, - _modulusNsh, - _args, - _tmpDigits, - xDigits); - } - - int _sqr(Uint32List xDigits, int xUsed, Uint32List resultDigits) { - var resultUsed = _BigIntImpl._sqrDigits(xDigits, xUsed, resultDigits); - return _reduce(resultDigits, resultUsed); - } - - int _mul(Uint32List xDigits, int xUsed, Uint32List yDigits, int yUsed, - Uint32List resultDigits) { - var resultUsed = - _BigIntImpl._mulDigits(xDigits, xUsed, yDigits, yUsed, resultDigits); - return _reduce(resultDigits, resultUsed); - } -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/bool_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/bool_patch.dart deleted file mode 100644 index d627d467125..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/bool_patch.dart +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) 2012, 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. - -// part of "core_patch.dart"; - -@patch -@pragma("vm:entry-point") -class bool { - @patch - const factory bool.fromEnvironment(String name, {bool defaultValue: false}) - native "Bool_fromEnvironment"; - - @patch - const factory bool.hasEnvironment(String name) native "Bool_hasEnvironment"; - - @patch - int get hashCode => this ? 1231 : 1237; - - int get _identityHashCode => this ? 1231 : 1237; -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/class_id.dart b/sdk_nnbd/lib/_internal/vm/lib/class_id.dart deleted file mode 100644 index ff9d0b6d329..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/class_id.dart +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) 2014, 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. - -// part of "internal_patch.dart"; - -@pragma("vm:entry-point") -class ClassID { - @pragma("vm:entry-point") - @pragma("vm:exact-result-type", "dart:core#_Smi") - static int getID(Object value) native "ClassID_getID"; - - // VM injects class id constants into this class. -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/class_id_fasta.dart b/sdk_nnbd/lib/_internal/vm/lib/class_id_fasta.dart deleted file mode 100644 index c81bd60f69a..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/class_id_fasta.dart +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) 2017, 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. - -// part of "internal_patch.dart"; - -@pragma("vm:entry-point") -class ClassID { - @pragma("vm:entry-point", "call") - @pragma("vm:exact-result-type", "dart:core#_Smi") - static int getID(Object value) native "ClassID_getID"; - - @pragma("vm:entry-point") - static final int cidArray = 0; - @pragma("vm:entry-point") - static final int cidExternalOneByteString = 0; - @pragma("vm:entry-point") - static final int cidGrowableObjectArray = 0; - @pragma("vm:entry-point") - static final int cidImmutableArray = 0; - @pragma("vm:entry-point") - static final int cidOneByteString = 0; - @pragma("vm:entry-point") - static final int cidTwoByteString = 0; - @pragma("vm:entry-point") - static final int cidUint8ArrayView = 0; - @pragma("vm:entry-point") - static final int cidUint8Array = 0; - @pragma("vm:entry-point") - static final int cidInt8ArrayView = 0; - @pragma("vm:entry-point") - static final int cidInt8Array = 0; - @pragma("vm:entry-point") - static final int cidExternalUint8Array = 0; - @pragma("vm:entry-point") - static final int cidExternalInt8Array = 0; - @pragma("vm:entry-point") - static final int cidUint8ClampedArray = 0; - @pragma("vm:entry-point") - static final int cidExternalUint8ClampedArray = 0; -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/collection_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/collection_patch.dart deleted file mode 100644 index 1307fb71b83..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/collection_patch.dart +++ /dev/null @@ -1,921 +0,0 @@ -// Copyright (c) 2013, 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. - -/// Note: the VM concatenates all patch files into a single patch file. This -/// file is the first patch in "dart:collection" which contains all the imports -/// used by patches of that library. We plan to change this when we have a -/// shared front end and simply use parts. - -import "dart:_internal" as internal; - -import "dart:_internal" show patch, IterableElementError; - -import "dart:typed_data" show Uint32List; - -class _TypeTest { - bool test(v) => v is T; -} - -/// These are the additional parts of this patch library: -// part "compact_hash.dart"; - -@patch -class HashMap { - @patch - factory HashMap( - {bool equals(K key1, K key2)?, - int hashCode(K key)?, - bool isValidKey(potentialKey)?}) { - if (isValidKey == null) { - if (hashCode == null) { - if (equals == null) { - return new _HashMap(); - } - hashCode = _defaultHashCode; - } else { - if (identical(identityHashCode, hashCode) && - identical(identical, equals)) { - return new _IdentityHashMap(); - } - equals ??= _defaultEquals; - } - } else { - hashCode ??= _defaultHashCode; - equals ??= _defaultEquals; - } - return new _CustomHashMap(equals, hashCode, isValidKey); - } - - @patch - factory HashMap.identity() => new _IdentityHashMap(); - - Set _newKeySet(); -} - -const int _MODIFICATION_COUNT_MASK = 0x3fffffff; - -class _HashMap extends MapBase implements HashMap { - static const int _INITIAL_CAPACITY = 8; - - int _elementCount = 0; - var _buckets = List<_HashMapEntry?>.filled(_INITIAL_CAPACITY, null); - int _modificationCount = 0; - - int get length => _elementCount; - bool get isEmpty => _elementCount == 0; - bool get isNotEmpty => _elementCount != 0; - - Iterable get keys => new _HashMapKeyIterable(this); - Iterable get values => new _HashMapValueIterable(this); - - bool containsKey(Object? key) { - final hashCode = key.hashCode; - final buckets = _buckets; - final index = hashCode & (buckets.length - 1); - var entry = buckets[index]; - while (entry != null) { - if (hashCode == entry.hashCode && entry.key == key) return true; - entry = entry.next; - } - return false; - } - - bool containsValue(Object? value) { - final buckets = _buckets; - final length = buckets.length; - for (int i = 0; i < length; i++) { - var entry = buckets[i]; - while (entry != null) { - if (entry.value == value) return true; - entry = entry.next; - } - } - return false; - } - - V? operator [](Object? key) { - final hashCode = key.hashCode; - final buckets = _buckets; - final index = hashCode & (buckets.length - 1); - var entry = buckets[index]; - while (entry != null) { - if (hashCode == entry.hashCode && entry.key == key) { - return entry.value; - } - entry = entry.next; - } - return null; - } - - void operator []=(K key, V value) { - final hashCode = key.hashCode; - final buckets = _buckets; - final length = buckets.length; - final index = hashCode & (length - 1); - var entry = buckets[index]; - while (entry != null) { - if (hashCode == entry.hashCode && entry.key == key) { - entry.value = value; - return; - } - entry = entry.next; - } - _addEntry(buckets, index, length, key, value, hashCode); - } - - V putIfAbsent(K key, V ifAbsent()) { - final hashCode = key.hashCode; - final buckets = _buckets; - final length = buckets.length; - final index = hashCode & (length - 1); - var entry = buckets[index]; - while (entry != null) { - if (hashCode == entry.hashCode && entry.key == key) { - return entry.value; - } - entry = entry.next; - } - final stamp = _modificationCount; - final V value = ifAbsent(); - if (stamp == _modificationCount) { - _addEntry(buckets, index, length, key, value, hashCode); - } else { - this[key] = value; - } - return value; - } - - void addAll(Map other) { - other.forEach((K key, V value) { - this[key] = value; - }); - } - - void forEach(void action(K key, V value)) { - final stamp = _modificationCount; - final buckets = _buckets; - final length = buckets.length; - for (int i = 0; i < length; i++) { - var entry = buckets[i]; - while (entry != null) { - action(entry.key, entry.value); - if (stamp != _modificationCount) { - throw new ConcurrentModificationError(this); - } - entry = entry.next; - } - } - } - - V? remove(Object? key) { - final hashCode = key.hashCode; - final buckets = _buckets; - final index = hashCode & (buckets.length - 1); - var entry = buckets[index]; - _HashMapEntry? previous = null; - while (entry != null) { - final next = entry.next; - if (hashCode == entry.hashCode && entry.key == key) { - _removeEntry(entry, previous, index); - _elementCount--; - _modificationCount = - (_modificationCount + 1) & _MODIFICATION_COUNT_MASK; - return entry.value; - } - previous = entry; - entry = next; - } - return null; - } - - void clear() { - _buckets = new List.filled(_INITIAL_CAPACITY, null); - if (_elementCount > 0) { - _elementCount = 0; - _modificationCount = (_modificationCount + 1) & _MODIFICATION_COUNT_MASK; - } - } - - void _removeEntry(_HashMapEntry entry, - _HashMapEntry? previousInBucket, int bucketIndex) { - if (previousInBucket == null) { - _buckets[bucketIndex] = entry.next; - } else { - previousInBucket.next = entry.next; - } - } - - void _addEntry(List<_HashMapEntry?> buckets, int index, int length, - K key, V value, int hashCode) { - final entry = new _HashMapEntry(key, value, hashCode, buckets[index]); - buckets[index] = entry; - final newElements = _elementCount + 1; - _elementCount = newElements; - // If we end up with more than 75% non-empty entries, we - // resize the backing store. - if ((newElements << 2) > ((length << 1) + length)) _resize(); - _modificationCount = (_modificationCount + 1) & _MODIFICATION_COUNT_MASK; - } - - void _resize() { - final oldBuckets = _buckets; - final oldLength = oldBuckets.length; - final newLength = oldLength << 1; - final newBuckets = new List<_HashMapEntry?>.filled(newLength, null); - for (int i = 0; i < oldLength; i++) { - var entry = oldBuckets[i]; - while (entry != null) { - final next = entry.next; - final hashCode = entry.hashCode; - final index = hashCode & (newLength - 1); - entry.next = newBuckets[index]; - newBuckets[index] = entry; - entry = next; - } - } - _buckets = newBuckets; - } - - Set _newKeySet() => new _HashSet(); -} - -class _CustomHashMap extends _HashMap { - final _Equality _equals; - final _Hasher _hashCode; - final _Predicate _validKey; - _CustomHashMap(this._equals, this._hashCode, _Predicate? validKey) - : _validKey = (validKey != null) ? validKey : new _TypeTest().test; - - bool containsKey(Object? key) { - if (!_validKey(key)) return false; - K lkey = key as K; - final hashCode = _hashCode(lkey); - final buckets = _buckets; - final index = hashCode & (buckets.length - 1); - var entry = buckets[index]; - while (entry != null) { - if (hashCode == entry.hashCode && _equals(entry.key, lkey)) return true; - entry = entry.next; - } - return false; - } - - V? operator [](Object? key) { - if (!_validKey(key)) return null; - K lkey = key as K; - final hashCode = _hashCode(lkey); - final buckets = _buckets; - final index = hashCode & (buckets.length - 1); - var entry = buckets[index]; - while (entry != null) { - if (hashCode == entry.hashCode && _equals(entry.key, lkey)) { - return entry.value; - } - entry = entry.next; - } - return null; - } - - void operator []=(K key, V value) { - final hashCode = _hashCode(key); - final buckets = _buckets; - final length = buckets.length; - final index = hashCode & (length - 1); - var entry = buckets[index]; - while (entry != null) { - if (hashCode == entry.hashCode && _equals(entry.key, key)) { - entry.value = value; - return; - } - entry = entry.next; - } - _addEntry(buckets, index, length, key, value, hashCode); - } - - V putIfAbsent(K key, V ifAbsent()) { - final hashCode = _hashCode(key); - final buckets = _buckets; - final length = buckets.length; - final index = hashCode & (length - 1); - var entry = buckets[index]; - while (entry != null) { - if (hashCode == entry.hashCode && _equals(entry.key, key)) { - return entry.value; - } - entry = entry.next; - } - int stamp = _modificationCount; - V value = ifAbsent(); - if (stamp == _modificationCount) { - _addEntry(buckets, index, length, key, value, hashCode); - } else { - this[key] = value; - } - return value; - } - - V? remove(Object? key) { - if (!_validKey(key)) return null; - K lkey = key as K; - final hashCode = _hashCode(lkey); - final buckets = _buckets; - final index = hashCode & (buckets.length - 1); - var entry = buckets[index]; - _HashMapEntry? previous = null; - while (entry != null) { - final next = entry.next; - if (hashCode == entry.hashCode && _equals(entry.key, lkey)) { - _removeEntry(entry, previous, index); - _elementCount--; - _modificationCount = - (_modificationCount + 1) & _MODIFICATION_COUNT_MASK; - return entry.value; - } - previous = entry; - entry = next; - } - return null; - } - - Set _newKeySet() => new _CustomHashSet(_equals, _hashCode, _validKey); -} - -class _IdentityHashMap extends _HashMap { - bool containsKey(Object? key) { - final hashCode = identityHashCode(key); - final buckets = _buckets; - final index = hashCode & (buckets.length - 1); - var entry = buckets[index]; - while (entry != null) { - if (hashCode == entry.hashCode && identical(entry.key, key)) return true; - entry = entry.next; - } - return false; - } - - V? operator [](Object? key) { - final hashCode = identityHashCode(key); - final buckets = _buckets; - final index = hashCode & (buckets.length - 1); - var entry = buckets[index]; - while (entry != null) { - if (hashCode == entry.hashCode && identical(entry.key, key)) { - return entry.value; - } - entry = entry.next; - } - return null; - } - - void operator []=(K key, V value) { - final hashCode = identityHashCode(key); - final buckets = _buckets; - final length = buckets.length; - final index = hashCode & (length - 1); - var entry = buckets[index]; - while (entry != null) { - if (hashCode == entry.hashCode && identical(entry.key, key)) { - entry.value = value; - return; - } - entry = entry.next; - } - _addEntry(buckets, index, length, key, value, hashCode); - } - - V putIfAbsent(K key, V ifAbsent()) { - final hashCode = identityHashCode(key); - final buckets = _buckets; - final length = buckets.length; - final index = hashCode & (length - 1); - var entry = buckets[index]; - while (entry != null) { - if (hashCode == entry.hashCode && identical(entry.key, key)) { - return entry.value; - } - entry = entry.next; - } - final stamp = _modificationCount; - V value = ifAbsent(); - if (stamp == _modificationCount) { - _addEntry(buckets, index, length, key, value, hashCode); - } else { - this[key] = value; - } - return value; - } - - V? remove(Object? key) { - final hashCode = identityHashCode(key); - final buckets = _buckets; - final index = hashCode & (buckets.length - 1); - var entry = buckets[index]; - _HashMapEntry? previous = null; - while (entry != null) { - final next = entry.next; - if (hashCode == entry.hashCode && identical(entry.key, key)) { - _removeEntry(entry, previous, index); - _elementCount--; - _modificationCount = - (_modificationCount + 1) & _MODIFICATION_COUNT_MASK; - return entry.value; - } - previous = entry; - entry = next; - } - return null; - } - - Set _newKeySet() => new _IdentityHashSet(); -} - -class _HashMapEntry { - final K key; - V value; - final int hashCode; - _HashMapEntry? next; - _HashMapEntry(this.key, this.value, this.hashCode, this.next); -} - -abstract class _HashMapIterable - extends internal.EfficientLengthIterable { - final _HashMap _map; - _HashMapIterable(this._map); - int get length => _map.length; - bool get isEmpty => _map.isEmpty; - bool get isNotEmpty => _map.isNotEmpty; -} - -class _HashMapKeyIterable extends _HashMapIterable { - _HashMapKeyIterable(_HashMap map) : super(map); - Iterator get iterator => new _HashMapKeyIterator(_map); - bool contains(Object? key) => _map.containsKey(key); - void forEach(void action(K key)) { - _map.forEach((K key, _) { - action(key); - }); - } - - Set toSet() => _map._newKeySet()..addAll(this); -} - -class _HashMapValueIterable extends _HashMapIterable { - _HashMapValueIterable(_HashMap map) : super(map); - Iterator get iterator => new _HashMapValueIterator(_map); - bool contains(Object? value) => _map.containsValue(value); - void forEach(void action(V value)) { - _map.forEach((_, V value) { - action(value); - }); - } -} - -abstract class _HashMapIterator implements Iterator { - final _HashMap _map; - final int _stamp; - - int _index = 0; - _HashMapEntry? _entry; - - _HashMapIterator(this._map) : _stamp = _map._modificationCount; - - bool moveNext() { - if (_stamp != _map._modificationCount) { - throw new ConcurrentModificationError(_map); - } - var entry = _entry; - if (entry != null) { - final next = entry.next; - if (next != null) { - _entry = next; - return true; - } - _entry = null; - } - final buckets = _map._buckets; - final length = buckets.length; - for (int i = _index; i < length; i++) { - entry = buckets[i]; - if (entry != null) { - _index = i + 1; - _entry = entry; - return true; - } - } - _index = length; - return false; - } -} - -class _HashMapKeyIterator extends _HashMapIterator { - _HashMapKeyIterator(_HashMap map) : super(map); - K get current => _entry!.key; -} - -class _HashMapValueIterator extends _HashMapIterator { - _HashMapValueIterator(_HashMap map) : super(map); - V get current => _entry!.value; -} - -@patch -class HashSet { - @patch - factory HashSet( - {bool equals(E e1, E e2)?, - int hashCode(E e)?, - bool isValidKey(potentialKey)?}) { - if (isValidKey == null) { - if (hashCode == null) { - if (equals == null) { - return new _HashSet(); - } - hashCode = _defaultHashCode; - } else { - if (identical(identityHashCode, hashCode) && - identical(identical, equals)) { - return new _IdentityHashSet(); - } - equals ??= _defaultEquals; - } - } else { - hashCode ??= _defaultHashCode; - equals ??= _defaultEquals; - } - return new _CustomHashSet(equals, hashCode, isValidKey); - } - - @patch - factory HashSet.identity() => new _IdentityHashSet(); -} - -class _HashSet extends _SetBase implements HashSet { - static const int _INITIAL_CAPACITY = 8; - - var _buckets = List<_HashSetEntry?>.filled(_INITIAL_CAPACITY, null); - int _elementCount = 0; - int _modificationCount = 0; - - bool _equals(Object? e1, Object? e2) => e1 == e2; - int _hashCode(Object? e) => e.hashCode; - - static Set _newEmpty() => new _HashSet(); - - // Iterable. - - Iterator get iterator => new _HashSetIterator(this); - - int get length => _elementCount; - - bool get isEmpty => _elementCount == 0; - - bool get isNotEmpty => _elementCount != 0; - - bool contains(Object? object) { - int index = _hashCode(object) & (_buckets.length - 1); - var entry = _buckets[index]; - while (entry != null) { - if (_equals(entry.key, object)) return true; - entry = entry.next; - } - return false; - } - - E? lookup(Object? object) { - int index = _hashCode(object) & (_buckets.length - 1); - var entry = _buckets[index]; - while (entry != null) { - var key = entry.key; - if (_equals(key, object)) return key; - entry = entry.next; - } - return null; - } - - E get first { - for (int i = 0; i < _buckets.length; i++) { - var entry = _buckets[i]; - if (entry != null) { - return entry.key; - } - } - throw IterableElementError.noElement(); - } - - E get last { - for (int i = _buckets.length - 1; i >= 0; i--) { - var entry = _buckets[i]; - if (entry != null) { - var nextEntry = entry.next; - while (nextEntry != null) { - entry = nextEntry; - nextEntry = nextEntry.next; - } - return entry!.key; - } - } - throw IterableElementError.noElement(); - } - - // Set. - - bool add(E element) { - final hashCode = _hashCode(element); - final index = hashCode & (_buckets.length - 1); - var entry = _buckets[index]; - while (entry != null) { - if (_equals(entry.key, element)) return false; - entry = entry.next; - } - _addEntry(element, hashCode, index); - return true; - } - - void addAll(Iterable objects) { - for (E object in objects) { - add(object); - } - } - - bool _remove(Object? object, int hashCode) { - final index = hashCode & (_buckets.length - 1); - var entry = _buckets[index]; - _HashSetEntry? previous = null; - while (entry != null) { - if (_equals(entry.key, object)) { - final next = entry.remove(); - if (previous == null) { - _buckets[index] = next; - } else { - previous.next = next; - } - _elementCount--; - _modificationCount = - (_modificationCount + 1) & _MODIFICATION_COUNT_MASK; - return true; - } - previous = entry; - entry = entry.next; - } - return false; - } - - bool remove(Object? object) => _remove(object, _hashCode(object)); - - void removeAll(Iterable objectsToRemove) { - for (Object? object in objectsToRemove) { - _remove(object, _hashCode(object)); - } - } - - void _filterWhere(bool test(E element), bool removeMatching) { - int length = _buckets.length; - for (int index = 0; index < length; index++) { - var entry = _buckets[index]; - _HashSetEntry? previous = null; - while (entry != null) { - int modificationCount = _modificationCount; - bool testResult = test(entry.key); - if (modificationCount != _modificationCount) { - throw new ConcurrentModificationError(this); - } - if (testResult == removeMatching) { - final next = entry.remove(); - if (previous == null) { - _buckets[index] = next; - } else { - previous.next = next; - } - _elementCount--; - _modificationCount = - (_modificationCount + 1) & _MODIFICATION_COUNT_MASK; - entry = next; - } else { - previous = entry; - entry = entry.next; - } - } - } - } - - void removeWhere(bool test(E element)) { - _filterWhere(test, true); - } - - void retainWhere(bool test(E element)) { - _filterWhere(test, false); - } - - void clear() { - _buckets = List<_HashSetEntry?>.filled(_INITIAL_CAPACITY, null); - if (_elementCount > 0) { - _elementCount = 0; - _modificationCount = (_modificationCount + 1) & _MODIFICATION_COUNT_MASK; - } - } - - void _addEntry(E key, int hashCode, int index) { - _buckets[index] = new _HashSetEntry(key, hashCode, _buckets[index]); - int newElements = _elementCount + 1; - _elementCount = newElements; - int length = _buckets.length; - // If we end up with more than 75% non-empty entries, we - // resize the backing store. - if ((newElements << 2) > ((length << 1) + length)) _resize(); - _modificationCount = (_modificationCount + 1) & _MODIFICATION_COUNT_MASK; - } - - void _resize() { - final oldLength = _buckets.length; - final newLength = oldLength << 1; - final oldBuckets = _buckets; - final newBuckets = List<_HashSetEntry?>.filled(newLength, null); - for (int i = 0; i < oldLength; i++) { - var entry = oldBuckets[i]; - while (entry != null) { - final next = entry.next; - int newIndex = entry.hashCode & (newLength - 1); - entry.next = newBuckets[newIndex]; - newBuckets[newIndex] = entry; - entry = next; - } - } - _buckets = newBuckets; - } - - HashSet _newSet() => new _HashSet(); - HashSet _newSimilarSet() => new _HashSet(); -} - -class _IdentityHashSet extends _HashSet { - int _hashCode(Object? e) => identityHashCode(e); - bool _equals(Object? e1, Object? e2) => identical(e1, e2); - - HashSet _newSet() => new _IdentityHashSet(); - HashSet _newSimilarSet() => new _IdentityHashSet(); -} - -class _CustomHashSet extends _HashSet { - final _Equality _equality; - final _Hasher _hasher; - final _Predicate _validKey; - _CustomHashSet(this._equality, this._hasher, _Predicate? validKey) - : _validKey = (validKey != null) ? validKey : new _TypeTest().test; - - bool remove(Object? element) { - if (!_validKey(element)) return false; - return super.remove(element); - } - - bool contains(Object? element) { - if (!_validKey(element)) return false; - return super.contains(element); - } - - E? lookup(Object? element) { - if (!_validKey(element)) return null; - return super.lookup(element); - } - - bool containsAll(Iterable elements) { - for (Object? element in elements) { - if (!_validKey(element) || !this.contains(element)) return false; - } - return true; - } - - void removeAll(Iterable elements) { - for (Object? element in elements) { - if (_validKey(element)) { - super._remove(element, _hashCode(element)); - } - } - } - - bool _equals(Object? e1, Object? e2) => _equality(e1 as E, e2 as E); - int _hashCode(Object? e) => _hasher(e as E); - - HashSet _newSet() => new _CustomHashSet(_equality, _hasher, _validKey); - HashSet _newSimilarSet() => new _HashSet(); -} - -class _HashSetEntry { - final E key; - final int hashCode; - _HashSetEntry? next; - _HashSetEntry(this.key, this.hashCode, this.next); - - _HashSetEntry? remove() { - final result = next; - next = null; - return result; - } -} - -class _HashSetIterator implements Iterator { - final _HashSet _set; - final int _modificationCount; - int _index = 0; - _HashSetEntry? _next; - E? _current; - - _HashSetIterator(this._set) : _modificationCount = _set._modificationCount; - - bool moveNext() { - if (_modificationCount != _set._modificationCount) { - throw new ConcurrentModificationError(_set); - } - var localNext = _next; - if (localNext != null) { - _current = localNext.key; - _next = localNext.next; - return true; - } - final buckets = _set._buckets; - while (_index < buckets.length) { - localNext = buckets[_index]; - _index = _index + 1; - if (localNext != null) { - _current = localNext.key; - _next = localNext.next; - return true; - } - } - _current = null; - return false; - } - - E get current { - final cur = _current; - return (cur != null) ? cur : cur as E; - } -} - -/** - * A hash-based map that iterates keys and values in key insertion order. - * This is never actually instantiated any more - the constructor always - * returns an instance of _CompactLinkedHashMap or _InternalLinkedHashMap, - * which despite the names do not use links (but are insertion-ordered as if - * they did). - */ -@patch -class LinkedHashMap { - @patch - factory LinkedHashMap( - {bool equals(K key1, K key2)?, - int hashCode(K key)?, - bool isValidKey(potentialKey)?}) { - if (isValidKey == null) { - if (hashCode == null) { - if (equals == null) { - return new _InternalLinkedHashMap(); - } - hashCode = _defaultHashCode; - } else { - if (identical(identityHashCode, hashCode) && - identical(identical, equals)) { - return new _CompactLinkedIdentityHashMap(); - } - equals ??= _defaultEquals; - } - } else { - hashCode ??= _defaultHashCode; - equals ??= _defaultEquals; - } - return new _CompactLinkedCustomHashMap(equals, hashCode, isValidKey); - } - - @patch - factory LinkedHashMap.identity() => new _CompactLinkedIdentityHashMap(); -} - -@patch -class LinkedHashSet { - @patch - factory LinkedHashSet( - {bool equals(E e1, E e2)?, - int hashCode(E e)?, - bool isValidKey(potentialKey)?}) { - if (isValidKey == null) { - if (hashCode == null) { - if (equals == null) { - return new _CompactLinkedHashSet(); - } - hashCode = _defaultHashCode; - } else { - if (identical(identityHashCode, hashCode) && - identical(identical, equals)) { - return new _CompactLinkedIdentityHashSet(); - } - equals ??= _defaultEquals; - } - } else { - hashCode ??= _defaultHashCode; - equals ??= _defaultEquals; - } - return new _CompactLinkedCustomHashSet(equals, hashCode, isValidKey); - } - - @patch - factory LinkedHashSet.identity() => new _CompactLinkedIdentityHashSet(); -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/compact_hash.dart b/sdk_nnbd/lib/_internal/vm/lib/compact_hash.dart deleted file mode 100644 index 67ba9b2f202..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/compact_hash.dart +++ /dev/null @@ -1,668 +0,0 @@ -// 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. - -// part of "collection_patch.dart"; - -// Hash table with open addressing that separates the index from keys/values. - -// This function takes care of rehashing of the linked hashmaps in [objects]. We -// do this eagerly after snapshot deserialization. -@pragma("vm:entry-point", "call") -void _rehashObjects(List objects) { - final int length = objects.length; - for (int i = 0; i < length; ++i) { - objects[i]._regenerateIndex(); - } -} - -abstract class _HashFieldBase { - // Each occupied entry in _index is a fixed-size integer that encodes a pair: - // [ hash pattern for key | index of entry in _data ] - // The hash pattern is based on hashCode, but is guaranteed to be non-zero. - // The length of _index is always a power of two, and there is always at - // least one unoccupied entry. - // NOTE: When maps are deserialized, their _index and _hashMask is regenerated - // eagerly by _regenerateIndex. - Uint32List _index = new Uint32List(_HashBase._INITIAL_INDEX_SIZE); - - // Cached in-place mask for the hash pattern component. - int _hashMask = _HashBase._indexSizeToHashMask(_HashBase._INITIAL_INDEX_SIZE); - - // Fixed-length list of keys (set) or key/value at even/odd indices (map). - List _data; - - // Length of _data that is used (i.e., keys + values for a map). - int _usedData = 0; - - // Number of deleted keys. - int _deletedKeys = 0; - - // Note: All fields are initialized in a single constructor so that the VM - // recognizes they cannot hold null values. This makes a big (20%) performance - // difference on some operations. - _HashFieldBase(int dataSize) : this._data = new List.filled(dataSize, null); -} - -// Base class for VM-internal classes; keep in sync with _HashFieldBase. -abstract class _HashVMBase { - @pragma("vm:exact-result-type", "dart:typed_data#_Uint32List") - @pragma("vm:prefer-inline") - Uint32List get _index native "LinkedHashMap_getIndex"; - @pragma("vm:prefer-inline") - void set _index(Uint32List value) native "LinkedHashMap_setIndex"; - - @pragma("vm:exact-result-type", "dart:core#_Smi") - @pragma("vm:prefer-inline") - int get _hashMask native "LinkedHashMap_getHashMask"; - @pragma("vm:prefer-inline") - void set _hashMask(int value) native "LinkedHashMap_setHashMask"; - - @pragma("vm:exact-result-type", "dart:core#_List") - @pragma("vm:prefer-inline") - List get _data native "LinkedHashMap_getData"; - @pragma("vm:prefer-inline") - void set _data(List value) native "LinkedHashMap_setData"; - - @pragma("vm:exact-result-type", "dart:core#_Smi") - @pragma("vm:prefer-inline") - int get _usedData native "LinkedHashMap_getUsedData"; - @pragma("vm:prefer-inline") - void set _usedData(int value) native "LinkedHashMap_setUsedData"; - - @pragma("vm:exact-result-type", "dart:core#_Smi") - @pragma("vm:prefer-inline") - int get _deletedKeys native "LinkedHashMap_getDeletedKeys"; - @pragma("vm:prefer-inline") - void set _deletedKeys(int value) native "LinkedHashMap_setDeletedKeys"; -} - -// This mixin can be applied to _HashFieldBase or _HashVMBase (for -// normal and VM-internalized classes, respectiveley), which provide the -// actual fields/accessors that this mixin assumes. -// TODO(koda): Consider moving field comments to _HashFieldBase. -abstract class _HashBase implements _HashVMBase { - // The number of bits used for each component is determined by table size. - // The length of _index is twice the number of entries in _data, and both - // are doubled when _data is full. Thus, _index will have a max load factor - // of 1/2, which enables one more bit to be used for the hash. - // TODO(koda): Consider growing _data by factor sqrt(2), twice as often. - static const int _INITIAL_INDEX_BITS = 3; - static const int _INITIAL_INDEX_SIZE = 1 << (_INITIAL_INDEX_BITS + 1); - - // Unused and deleted entries are marked by 0 and 1, respectively. - static const int _UNUSED_PAIR = 0; - static const int _DELETED_PAIR = 1; - - // On 32-bit, the top bits are wasted to avoid Mint allocation. - // TODO(koda): Reclaim the bits by making the compiler treat hash patterns - // as unsigned words. - static int _indexSizeToHashMask(int indexSize) { - int indexBits = indexSize.bitLength - 2; - return internal.is64Bit - ? (1 << (32 - indexBits)) - 1 - : (1 << (30 - indexBits)) - 1; - } - - static int _hashPattern(int fullHash, int hashMask, int size) { - final int maskedHash = fullHash & hashMask; - // TODO(koda): Consider keeping bit length and use left shift. - return (maskedHash == 0) ? (size >> 1) : maskedHash * (size >> 1); - } - - // Linear probing. - static int _firstProbe(int fullHash, int sizeMask) { - final int i = fullHash & sizeMask; - // Light, fast shuffle to mitigate bad hashCode (e.g., sequential). - return ((i << 1) + i) & sizeMask; - } - - static int _nextProbe(int i, int sizeMask) => (i + 1) & sizeMask; - - // A self-loop is used to mark a deleted key or value. - static bool _isDeleted(List data, Object? keyOrValue) => - identical(keyOrValue, data); - static void _setDeletedAt(List data, int d) { - data[d] = data; - } - - // Concurrent modification detection relies on this checksum monotonically - // increasing between reallocations of _data. - int get _checkSum => _usedData + _deletedKeys; - bool _isModifiedSince(List oldData, int oldCheckSum) => - !identical(_data, oldData) || (_checkSum != oldCheckSum); - - int get length; -} - -class _OperatorEqualsAndHashCode { - int _hashCode(e) => e.hashCode; - bool _equals(e1, e2) => e1 == e2; -} - -class _IdenticalAndIdentityHashCode { - int _hashCode(e) => identityHashCode(e); - bool _equals(e1, e2) => identical(e1, e2); -} - -// VM-internalized implementation of a default-constructed LinkedHashMap. -@pragma("vm:entry-point") -class _InternalLinkedHashMap extends _HashVMBase - with - MapMixin, - _LinkedHashMapMixin, - _HashBase, - _OperatorEqualsAndHashCode - implements LinkedHashMap { - _InternalLinkedHashMap() { - _index = new Uint32List(_HashBase._INITIAL_INDEX_SIZE); - _hashMask = _HashBase._indexSizeToHashMask(_HashBase._INITIAL_INDEX_SIZE); - _data = new List.filled(_HashBase._INITIAL_INDEX_SIZE, null); - _usedData = 0; - _deletedKeys = 0; - } -} - -abstract class _LinkedHashMapMixin implements _HashBase { - int _hashCode(e); - bool _equals(e1, e2); - int get _checkSum; - bool _isModifiedSince(List oldData, int oldCheckSum); - - int get length => (_usedData >> 1) - _deletedKeys; - bool get isEmpty => length == 0; - bool get isNotEmpty => !isEmpty; - - void _rehash() { - if ((_deletedKeys << 2) > _usedData) { - // TODO(koda): Consider shrinking. - // TODO(koda): Consider in-place compaction and more costly CME check. - _init(_index.length, _hashMask, _data, _usedData); - } else { - // TODO(koda): Support 32->64 bit transition (and adjust _hashMask). - _init(_index.length << 1, _hashMask >> 1, _data, _usedData); - } - } - - void clear() { - if (!isEmpty) { - _init(_HashBase._INITIAL_INDEX_SIZE, _hashMask, null, 0); - } - } - - // Allocate new _index and _data, and optionally copy existing contents. - void _init(int size, int hashMask, List? oldData, int oldUsed) { - assert(size & (size - 1) == 0); - assert(_HashBase._UNUSED_PAIR == 0); - _index = new Uint32List(size); - _hashMask = hashMask; - _data = new List.filled(size, null); - _usedData = 0; - _deletedKeys = 0; - if (oldData != null) { - for (int i = 0; i < oldUsed; i += 2) { - var key = oldData[i]; - if (!_HashBase._isDeleted(oldData, key)) { - // TODO(koda): While there are enough hash bits, avoid hashCode calls. - this[key] = oldData[i + 1]; - } - } - } - } - - // This method is called by [_rehashObjects] (see above). - void _regenerateIndex() { - _index = new Uint32List(_data.length); - assert(_hashMask == 0); - _hashMask = _HashBase._indexSizeToHashMask(_index.length); - final int tmpUsed = _usedData; - _usedData = 0; - for (int i = 0; i < tmpUsed; i += 2) { - this[_data[i]] = _data[i + 1]; - } - } - - void _insert(K key, V value, int hashPattern, int i) { - if (_usedData == _data.length) { - _rehash(); - this[key] = value; - } else { - assert(1 <= hashPattern && hashPattern < (1 << 32)); - final int index = _usedData >> 1; - assert((index & hashPattern) == 0); - _index[i] = hashPattern | index; - _data[_usedData++] = key; - _data[_usedData++] = value; - } - } - - // If key is present, returns the index of the value in _data, else returns - // the negated insertion point in _index. - int _findValueOrInsertPoint(K key, int fullHash, int hashPattern, int size) { - final int sizeMask = size - 1; - final int maxEntries = size >> 1; - int i = _HashBase._firstProbe(fullHash, sizeMask); - int firstDeleted = -1; - int pair = _index[i]; - while (pair != _HashBase._UNUSED_PAIR) { - if (pair == _HashBase._DELETED_PAIR) { - if (firstDeleted < 0) { - firstDeleted = i; - } - } else { - final int entry = hashPattern ^ pair; - if (entry < maxEntries) { - final int d = entry << 1; - if (_equals(key, _data[d])) { - return d + 1; - } - } - } - i = _HashBase._nextProbe(i, sizeMask); - pair = _index[i]; - } - return firstDeleted >= 0 ? -firstDeleted : -i; - } - - void operator []=(K key, V value) { - final int size = _index.length; - final int fullHash = _hashCode(key); - final int hashPattern = _HashBase._hashPattern(fullHash, _hashMask, size); - final int d = _findValueOrInsertPoint(key, fullHash, hashPattern, size); - if (d > 0) { - _data[d] = value; - } else { - final int i = -d; - _insert(key, value, hashPattern, i); - } - } - - V putIfAbsent(K key, V ifAbsent()) { - final int size = _index.length; - final int fullHash = _hashCode(key); - final int hashPattern = _HashBase._hashPattern(fullHash, _hashMask, size); - final int d = _findValueOrInsertPoint(key, fullHash, hashPattern, size); - if (d > 0) { - return _data[d]; - } - // 'ifAbsent' is allowed to modify the map. - List oldData = _data; - int oldCheckSum = _checkSum; - V value = ifAbsent(); - if (_isModifiedSince(oldData, oldCheckSum)) { - this[key] = value; - } else { - final int i = -d; - _insert(key, value, hashPattern, i); - } - return value; - } - - V? remove(Object? key) { - final int size = _index.length; - final int sizeMask = size - 1; - final int maxEntries = size >> 1; - final int fullHash = _hashCode(key); - final int hashPattern = _HashBase._hashPattern(fullHash, _hashMask, size); - int i = _HashBase._firstProbe(fullHash, sizeMask); - int pair = _index[i]; - while (pair != _HashBase._UNUSED_PAIR) { - if (pair != _HashBase._DELETED_PAIR) { - final int entry = hashPattern ^ pair; - if (entry < maxEntries) { - final int d = entry << 1; - if (_equals(key, _data[d])) { - _index[i] = _HashBase._DELETED_PAIR; - _HashBase._setDeletedAt(_data, d); - V value = _data[d + 1]; - _HashBase._setDeletedAt(_data, d + 1); - ++_deletedKeys; - return value; - } - } - } - i = _HashBase._nextProbe(i, sizeMask); - pair = _index[i]; - } - return null; - } - - // If key is absent, return _data (which is never a value). - Object? _getValueOrData(Object? key) { - final int size = _index.length; - final int sizeMask = size - 1; - final int maxEntries = size >> 1; - final int fullHash = _hashCode(key); - final int hashPattern = _HashBase._hashPattern(fullHash, _hashMask, size); - int i = _HashBase._firstProbe(fullHash, sizeMask); - int pair = _index[i]; - while (pair != _HashBase._UNUSED_PAIR) { - if (pair != _HashBase._DELETED_PAIR) { - final int entry = hashPattern ^ pair; - if (entry < maxEntries) { - final int d = entry << 1; - if (_equals(key, _data[d])) { - return _data[d + 1]; - } - } - } - i = _HashBase._nextProbe(i, sizeMask); - pair = _index[i]; - } - return _data; - } - - bool containsKey(Object? key) => !identical(_data, _getValueOrData(key)); - - V? operator [](Object? key) { - var v = _getValueOrData(key); - return identical(_data, v) ? null : internal.unsafeCast(v); - } - - bool containsValue(Object? value) { - for (var v in values) { - // Spec. says this should always use "==", also for identity maps, etc. - if (v == value) { - return true; - } - } - return false; - } - - void forEach(void f(K key, V value)) { - var ki = keys.iterator; - var vi = values.iterator; - while (ki.moveNext()) { - vi.moveNext(); - f(ki.current, vi.current); - } - } - - Iterable get keys => - new _CompactIterable(this, _data, _usedData, -2, 2); - Iterable get values => - new _CompactIterable(this, _data, _usedData, -1, 2); -} - -class _CompactLinkedIdentityHashMap extends _HashFieldBase - with - MapMixin, - _LinkedHashMapMixin, - _HashBase, - _IdenticalAndIdentityHashCode - implements LinkedHashMap { - _CompactLinkedIdentityHashMap() : super(_HashBase._INITIAL_INDEX_SIZE); -} - -class _CompactLinkedCustomHashMap extends _HashFieldBase - with MapMixin, _LinkedHashMapMixin, _HashBase - implements LinkedHashMap { - final _equality; - final _hasher; - final _validKey; - - // TODO(koda): Ask gbracha why I cannot have fields _equals/_hashCode. - int _hashCode(e) => _hasher(e); - bool _equals(e1, e2) => _equality(e1, e2); - - bool containsKey(Object? o) => _validKey(o) ? super.containsKey(o) : false; - V? operator [](Object? o) => _validKey(o) ? super[o] : null; - V? remove(Object? o) => _validKey(o) ? super.remove(o) : null; - - _CompactLinkedCustomHashMap(this._equality, this._hasher, validKey) - : _validKey = (validKey != null) ? validKey : new _TypeTest().test, - super(_HashBase._INITIAL_INDEX_SIZE); -} - -// Iterates through _data[_offset + _step], _data[_offset + 2*_step], ... -// and checks for concurrent modification. -class _CompactIterable extends Iterable { - final _HashBase _table; - final List _data; - final int _len; - final int _offset; - final int _step; - - _CompactIterable( - this._table, this._data, this._len, this._offset, this._step); - - Iterator get iterator => - new _CompactIterator(_table, _data, _len, _offset, _step); - - int get length => _table.length; - bool get isEmpty => length == 0; - bool get isNotEmpty => !isEmpty; -} - -class _CompactIterator implements Iterator { - final _HashBase _table; - final List _data; - final int _len; - int _offset; - final int _step; - final int _checkSum; - E? _current; - - _CompactIterator( - _HashBase table, this._data, this._len, this._offset, this._step) - : _table = table, - _checkSum = table._checkSum; - - bool moveNext() { - if (_table._isModifiedSince(_data, _checkSum)) { - throw new ConcurrentModificationError(_table); - } - do { - _offset += _step; - } while (_offset < _len && _HashBase._isDeleted(_data, _data[_offset])); - if (_offset < _len) { - _current = internal.unsafeCast(_data[_offset]); - return true; - } else { - _current = null; - return false; - } - } - - E get current { - final cur = _current; - return (cur != null) ? cur : cur as E; - } -} - -// Set implementation, analogous to _CompactLinkedHashMap. -@pragma('vm:entry-point') -class _CompactLinkedHashSet extends _HashFieldBase - with _HashBase, _OperatorEqualsAndHashCode, SetMixin - implements LinkedHashSet { - _CompactLinkedHashSet() : super(_HashBase._INITIAL_INDEX_SIZE >> 1) { - assert(_HashBase._UNUSED_PAIR == 0); - } - - static Set _newEmpty() => new _CompactLinkedHashSet(); - - Set cast() => Set.castFrom(this, newSet: _newEmpty); - int get length => _usedData - _deletedKeys; - - E get first { - for (int offset = 0; offset < _usedData; offset++) { - Object? current = _data[offset]; - if (!_HashBase._isDeleted(_data, current)) { - return current as E; - } - } - throw IterableElementError.noElement(); - } - - E get last { - for (int offset = _usedData - 1; offset >= 0; offset--) { - Object? current = _data[offset]; - if (!_HashBase._isDeleted(_data, current)) { - return current as E; - } - } - throw IterableElementError.noElement(); - } - - void _rehash() { - if ((_deletedKeys << 1) > _usedData) { - _init(_index.length, _hashMask, _data, _usedData); - } else { - _init(_index.length << 1, _hashMask >> 1, _data, _usedData); - } - } - - void clear() { - if (!isEmpty) { - _init(_HashBase._INITIAL_INDEX_SIZE, _hashMask, null, 0); - } - } - - void _init(int size, int hashMask, List? oldData, int oldUsed) { - _index = new Uint32List(size); - _hashMask = hashMask; - _data = new List.filled(size >> 1, null); - _usedData = 0; - _deletedKeys = 0; - if (oldData != null) { - for (int i = 0; i < oldUsed; i += 1) { - var key = oldData[i]; - if (!_HashBase._isDeleted(oldData, key)) { - add(key); - } - } - } - } - - bool add(E key) { - final int size = _index.length; - final int sizeMask = size - 1; - final int maxEntries = size >> 1; - final int fullHash = _hashCode(key); - final int hashPattern = _HashBase._hashPattern(fullHash, _hashMask, size); - int i = _HashBase._firstProbe(fullHash, sizeMask); - int firstDeleted = -1; - int pair = _index[i]; - while (pair != _HashBase._UNUSED_PAIR) { - if (pair == _HashBase._DELETED_PAIR) { - if (firstDeleted < 0) { - firstDeleted = i; - } - } else { - final int d = hashPattern ^ pair; - if (d < maxEntries && _equals(key, _data[d])) { - return false; - } - } - i = _HashBase._nextProbe(i, sizeMask); - pair = _index[i]; - } - if (_usedData == _data.length) { - _rehash(); - add(key); - } else { - final int insertionPoint = (firstDeleted >= 0) ? firstDeleted : i; - assert(1 <= hashPattern && hashPattern < (1 << 32)); - assert((hashPattern & _usedData) == 0); - _index[insertionPoint] = hashPattern | _usedData; - _data[_usedData++] = key; - } - return true; - } - - // If key is absent, return _data (which is never a value). - Object? _getKeyOrData(Object? key) { - final int size = _index.length; - final int sizeMask = size - 1; - final int maxEntries = size >> 1; - final int fullHash = _hashCode(key); - final int hashPattern = _HashBase._hashPattern(fullHash, _hashMask, size); - int i = _HashBase._firstProbe(fullHash, sizeMask); - int pair = _index[i]; - while (pair != _HashBase._UNUSED_PAIR) { - if (pair != _HashBase._DELETED_PAIR) { - final int d = hashPattern ^ pair; - if (d < maxEntries && _equals(key, _data[d])) { - return _data[d]; // Note: Must return the existing key. - } - } - i = _HashBase._nextProbe(i, sizeMask); - pair = _index[i]; - } - return _data; - } - - E? lookup(Object? key) { - var k = _getKeyOrData(key); - return identical(_data, k) ? null : internal.unsafeCast(k); - } - - bool contains(Object? key) => !identical(_data, _getKeyOrData(key)); - - bool remove(Object? key) { - final int size = _index.length; - final int sizeMask = size - 1; - final int maxEntries = size >> 1; - final int fullHash = _hashCode(key); - final int hashPattern = _HashBase._hashPattern(fullHash, _hashMask, size); - int i = _HashBase._firstProbe(fullHash, sizeMask); - int pair = _index[i]; - while (pair != _HashBase._UNUSED_PAIR) { - if (pair != _HashBase._DELETED_PAIR) { - final int d = hashPattern ^ pair; - if (d < maxEntries && _equals(key, _data[d])) { - _index[i] = _HashBase._DELETED_PAIR; - _HashBase._setDeletedAt(_data, d); - ++_deletedKeys; - return true; - } - } - i = _HashBase._nextProbe(i, sizeMask); - pair = _index[i]; - } - return false; - } - - Iterator get iterator => - new _CompactIterator(this, _data, _usedData, -1, 1); - - // Returns a set of the same type, although this - // is not required by the spec. (For instance, always using an identity set - // would be technically correct, albeit surprising.) - Set toSet() => new _CompactLinkedHashSet()..addAll(this); - - // This method is called by [_rehashObjects] (see above). - void _regenerateIndex() { - _rehash(); - } -} - -class _CompactLinkedIdentityHashSet extends _CompactLinkedHashSet - with _IdenticalAndIdentityHashCode { - Set toSet() => new _CompactLinkedIdentityHashSet()..addAll(this); - - static Set _newEmpty() => new _CompactLinkedIdentityHashSet(); - - Set cast() => Set.castFrom(this, newSet: _newEmpty); -} - -class _CompactLinkedCustomHashSet extends _CompactLinkedHashSet { - final _equality; - final _hasher; - final _validKey; - - int _hashCode(e) => _hasher(e); - bool _equals(e1, e2) => _equality(e1, e2); - - bool contains(Object? o) => _validKey(o) ? super.contains(o) : false; - E? lookup(Object? o) => _validKey(o) ? super.lookup(o) : null; - bool remove(Object? o) => _validKey(o) ? super.remove(o) : false; - - _CompactLinkedCustomHashSet(this._equality, this._hasher, validKey) - : _validKey = (validKey != null) ? validKey : new _TypeTest().test; - - Set cast() => Set.castFrom(this); - Set toSet() => - new _CompactLinkedCustomHashSet(_equality, _hasher, _validKey) - ..addAll(this); -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/convert_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/convert_patch.dart deleted file mode 100644 index 6f823376fb8..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/convert_patch.dart +++ /dev/null @@ -1,2055 +0,0 @@ -// Copyright (c) 2014, 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. - -/// Note: the VM concatenates all patch files into a single patch file. This -/// file is the first patch in "dart:convert" which contains all the imports -/// used by patches of that library. We plan to change this when we have a -/// shared front end and simply use parts. - -import "dart:_internal" - show - allocateOneByteString, - allocateTwoByteString, - ClassID, - copyRangeFromUint8ListToOneByteString, - patch, - POWERS_OF_TEN, - unsafeCast, - writeIntoOneByteString, - writeIntoTwoByteString; - -import "dart:typed_data" show Uint8List, Uint16List; - -/// This patch library has no additional parts. - -// JSON conversion. - -@patch -dynamic _parseJson( - String source, Object? Function(Object? key, Object? value)? reviver) { - _BuildJsonListener listener; - if (reviver == null) { - listener = new _BuildJsonListener(); - } else { - listener = new _ReviverJsonListener(reviver); - } - var parser = new _JsonStringParser(listener); - parser.chunk = source; - parser.chunkEnd = source.length; - parser.parse(0); - parser.close(); - return listener.result; -} - -@patch -class Utf8Decoder { - @patch - Converter, T> fuse(Converter next) { - if (next is JsonDecoder) { - return new _JsonUtf8Decoder( - (next as JsonDecoder)._reviver, this._allowMalformed) - as dynamic/*=Converter, T>*/; - } - // TODO(lrn): Recognize a fused decoder where the next step is JsonDecoder. - return super.fuse(next); - } - - // Allow intercepting of UTF-8 decoding when built-in lists are passed. - @patch - static String? _convertIntercepted( - bool allowMalformed, List codeUnits, int start, int? end) { - return null; // This call was not intercepted. - } -} - -class _JsonUtf8Decoder extends Converter, Object> { - final Object? Function(Object? key, Object? value)? _reviver; - final bool _allowMalformed; - - _JsonUtf8Decoder(this._reviver, this._allowMalformed); - - Object convert(List input) { - var parser = _JsonUtf8DecoderSink._createParser(_reviver, _allowMalformed); - parser.chunk = input; - parser.chunkEnd = input.length; - parser.parse(0); - parser.close(); - return parser.result; - } - - ByteConversionSink startChunkedConversion(Sink sink) { - return new _JsonUtf8DecoderSink(_reviver, sink, _allowMalformed); - } -} - -//// Implementation /////////////////////////////////////////////////////////// - -// Simple API for JSON parsing. - -/** - * Listener for parsing events from [_ChunkedJsonParser]. - */ -abstract class _JsonListener { - void handleString(String value) {} - void handleNumber(num value) {} - void handleBool(bool value) {} - void handleNull() {} - void beginObject() {} - void propertyName() {} - void propertyValue() {} - void endObject() {} - void beginArray() {} - void arrayElement() {} - void endArray() {} - - /** - * Read out the final result of parsing a JSON string. - * - * Must only be called when the entire input has been parsed. - */ - dynamic get result; -} - -/** - * A [_JsonListener] that builds data objects from the parser events. - * - * This is a simple stack-based object builder. It keeps the most recently - * seen value in a variable, and uses it depending on the following event. - */ -class _BuildJsonListener extends _JsonListener { - /** - * Stack used to handle nested containers. - * - * The current container is pushed on the stack when a new one is - * started. If the container is a [Map], there is also a current [key] - * which is also stored on the stack. - */ - final List stack = []; - /** The current [Map] or [List] being built. */ - dynamic currentContainer; - /** The most recently read property key. */ - String key = ''; - /** The most recently read value. */ - dynamic value; - - /** Pushes the currently active container (and key, if a [Map]). */ - void pushContainer() { - if (currentContainer is Map) stack.add(key); - stack.add(currentContainer); - } - - /** Pops the top container from the [stack], including a key if applicable. */ - void popContainer() { - value = currentContainer; - currentContainer = stack.removeLast(); - if (currentContainer is Map) key = stack.removeLast() as String; - } - - void handleString(String value) { - this.value = value; - } - - void handleNumber(num value) { - this.value = value; - } - - void handleBool(bool value) { - this.value = value; - } - - void handleNull() { - this.value = null; - } - - void beginObject() { - pushContainer(); - currentContainer = {}; - } - - void propertyName() { - key = value; - value = null; - } - - void propertyValue() { - Map map = currentContainer; - map[key] = value; - key = ''; - value = null; - } - - void endObject() { - popContainer(); - } - - void beginArray() { - pushContainer(); - currentContainer = []; - } - - void arrayElement() { - currentContainer.add(value); - value = null; - } - - void endArray() { - popContainer(); - } - - /** Read out the final result of parsing a JSON string. */ - dynamic get result { - assert(currentContainer == null); - return value; - } -} - -class _ReviverJsonListener extends _BuildJsonListener { - final Object? Function(Object? key, Object? value) reviver; - _ReviverJsonListener(this.reviver); - - void arrayElement() { - List list = currentContainer; - value = reviver(list.length, value); - super.arrayElement(); - } - - void propertyValue() { - value = reviver(key, value); - super.propertyValue(); - } - - dynamic get result { - return reviver(null, value); - } -} - -/** - * Buffer holding parts of a numeral. - * - * The buffer contains the characters of a JSON number. - * These are all ASCII, so an [Uint8List] is used as backing store. - * - * This buffer is used when a JSON number is split between separate chunks. - * - */ -class _NumberBuffer { - static const int minCapacity = 16; - static const int kDefaultOverhead = 5; - Uint8List list; - int length = 0; - _NumberBuffer(int initialCapacity) - : list = new Uint8List(_initialCapacity(initialCapacity)); - - int get capacity => list.length; - - // Pick an initial capacity greater than the first part's size. - // The typical use case has two parts, this is the attempt at - // guessing the size of the second part without overdoing it. - // The default estimate of the second part is [kDefaultOverhead], - // then round to multiplum of four, and return the result, - // or [minCapacity] if that is greater. - static int _initialCapacity(int minCapacity) { - minCapacity += kDefaultOverhead; - if (minCapacity < minCapacity) return minCapacity; - minCapacity = (minCapacity + 3) & ~3; // Round to multiple of four. - return minCapacity; - } - - // Grows to the exact size asked for. - void ensureCapacity(int newCapacity) { - Uint8List list = this.list; - if (newCapacity <= list.length) return; - Uint8List newList = new Uint8List(newCapacity); - newList.setRange(0, list.length, list, 0); - this.list = newList; - } - - String getString() { - String result = new String.fromCharCodes(list, 0, length); - return result; - } - - // TODO(lrn): See if parsing of numbers can be abstracted to something - // not only working on strings, but also on char-code lists, without lossing - // performance. - num parseNum() => num.parse(getString()); - double parseDouble() => double.parse(getString()); -} - -/** - * Chunked JSON parser. - * - * Receives inputs in chunks, gives access to individual parts of the input, - * and stores input state between chunks. - * - * Implementations include [String] and UTF-8 parsers. - */ -abstract class _ChunkedJsonParser { - // A simple non-recursive state-based parser for JSON. - // - // Literal values accepted in states ARRAY_EMPTY, ARRAY_COMMA, OBJECT_COLON - // and strings also in OBJECT_EMPTY, OBJECT_COMMA. - // VALUE STRING : , } ] Transitions to - // EMPTY X X -> END - // ARRAY_EMPTY X X @ -> ARRAY_VALUE / pop - // ARRAY_VALUE @ @ -> ARRAY_COMMA / pop - // ARRAY_COMMA X X -> ARRAY_VALUE - // OBJECT_EMPTY X @ -> OBJECT_KEY / pop - // OBJECT_KEY @ -> OBJECT_COLON - // OBJECT_COLON X X -> OBJECT_VALUE - // OBJECT_VALUE @ @ -> OBJECT_COMMA / pop - // OBJECT_COMMA X -> OBJECT_KEY - // END - // Starting a new array or object will push the current state. The "pop" - // above means restoring this state and then marking it as an ended value. - // X means generic handling, @ means special handling for just that - // state - that is, values are handled generically, only punctuation - // cares about the current state. - // Values for states are chosen so bits 0 and 1 tell whether - // a string/value is allowed, and setting bits 0 through 2 after a value - // gets to the next state (not empty, doesn't allow a value). - - // State building-block constants. - static const int TOP_LEVEL = 0; - static const int INSIDE_ARRAY = 1; - static const int INSIDE_OBJECT = 2; - static const int AFTER_COLON = 3; // Always inside object. - - static const int ALLOW_STRING_MASK = 8; // Allowed if zero. - static const int ALLOW_VALUE_MASK = 4; // Allowed if zero. - static const int ALLOW_VALUE = 0; - static const int STRING_ONLY = 4; - static const int NO_VALUES = 12; - - // Objects and arrays are "empty" until their first property/element. - // At this position, they may either have an entry or a close-bracket. - static const int EMPTY = 0; - static const int NON_EMPTY = 16; - static const int EMPTY_MASK = 16; // Empty if zero. - - // Actual states : Context | Is empty? | Next? - static const int STATE_INITIAL = TOP_LEVEL | EMPTY | ALLOW_VALUE; - static const int STATE_END = TOP_LEVEL | NON_EMPTY | NO_VALUES; - - static const int STATE_ARRAY_EMPTY = INSIDE_ARRAY | EMPTY | ALLOW_VALUE; - static const int STATE_ARRAY_VALUE = INSIDE_ARRAY | NON_EMPTY | NO_VALUES; - static const int STATE_ARRAY_COMMA = INSIDE_ARRAY | NON_EMPTY | ALLOW_VALUE; - - static const int STATE_OBJECT_EMPTY = INSIDE_OBJECT | EMPTY | STRING_ONLY; - static const int STATE_OBJECT_KEY = INSIDE_OBJECT | NON_EMPTY | NO_VALUES; - static const int STATE_OBJECT_COLON = AFTER_COLON | NON_EMPTY | ALLOW_VALUE; - static const int STATE_OBJECT_VALUE = AFTER_COLON | NON_EMPTY | NO_VALUES; - static const int STATE_OBJECT_COMMA = INSIDE_OBJECT | NON_EMPTY | STRING_ONLY; - - // Bits set in state after successfully reading a value. - // This transitions the state to expect the next punctuation. - static const int VALUE_READ_BITS = NON_EMPTY | NO_VALUES; - - // Character code constants. - static const int BACKSPACE = 0x08; - static const int TAB = 0x09; - static const int NEWLINE = 0x0a; - static const int CARRIAGE_RETURN = 0x0d; - static const int FORM_FEED = 0x0c; - static const int SPACE = 0x20; - static const int QUOTE = 0x22; - static const int PLUS = 0x2b; - static const int COMMA = 0x2c; - static const int MINUS = 0x2d; - static const int DECIMALPOINT = 0x2e; - static const int SLASH = 0x2f; - static const int CHAR_0 = 0x30; - static const int CHAR_9 = 0x39; - static const int COLON = 0x3a; - static const int CHAR_E = 0x45; - static const int LBRACKET = 0x5b; - static const int BACKSLASH = 0x5c; - static const int RBRACKET = 0x5d; - static const int CHAR_a = 0x61; - static const int CHAR_b = 0x62; - static const int CHAR_e = 0x65; - static const int CHAR_f = 0x66; - static const int CHAR_l = 0x6c; - static const int CHAR_n = 0x6e; - static const int CHAR_r = 0x72; - static const int CHAR_s = 0x73; - static const int CHAR_t = 0x74; - static const int CHAR_u = 0x75; - static const int LBRACE = 0x7b; - static const int RBRACE = 0x7d; - - // State of partial value at chunk split. - static const int NO_PARTIAL = 0; - static const int PARTIAL_STRING = 1; - static const int PARTIAL_NUMERAL = 2; - static const int PARTIAL_KEYWORD = 3; - static const int MASK_PARTIAL = 3; - - // Partial states for numerals. Values can be |'ed with PARTIAL_NUMERAL. - static const int NUM_SIGN = 0; // After initial '-'. - static const int NUM_ZERO = 4; // After '0' as first digit. - static const int NUM_DIGIT = 8; // After digit, no '.' or 'e' seen. - static const int NUM_DOT = 12; // After '.'. - static const int NUM_DOT_DIGIT = 16; // After a decimal digit (after '.'). - static const int NUM_E = 20; // After 'e' or 'E'. - static const int NUM_E_SIGN = 24; // After '-' or '+' after 'e' or 'E'. - static const int NUM_E_DIGIT = 28; // After exponent digit. - static const int NUM_SUCCESS = 32; // Never stored as partial state. - - // Partial states for strings. - static const int STR_PLAIN = 0; // Inside string, but not escape. - static const int STR_ESCAPE = 4; // After '\'. - static const int STR_U = 16; // After '\u' and 0-3 hex digits. - static const int STR_U_COUNT_SHIFT = 2; // Hex digit count in bits 2-3. - static const int STR_U_VALUE_SHIFT = 5; // Hex digit value in bits 5+. - - // Partial states for keywords. - static const int KWD_TYPE_MASK = 12; - static const int KWD_TYPE_SHIFT = 2; - static const int KWD_NULL = 0; // Prefix of "null" seen. - static const int KWD_TRUE = 4; // Prefix of "true" seen. - static const int KWD_FALSE = 8; // Prefix of "false" seen. - static const int KWD_BOM = 12; // Prefix of BOM seen. - static const int KWD_COUNT_SHIFT = 4; // Prefix length in bits 4+. - - // Mask used to mask off two lower bits. - static const int TWO_BIT_MASK = 3; - - final _JsonListener listener; - - // The current parsing state. - int state = STATE_INITIAL; - List states = []; - - /** - * Stores tokenizer state between chunks. - * - * This state is stored when a chunk stops in the middle of a - * token (string, numeral, boolean or null). - * - * The partial state is used to continue parsing on the next chunk. - * The previous chunk is not retained, any data needed are stored in - * this integer, or in the [buffer] field as a string-building buffer - * or a [_NumberBuffer]. - * - * Prefix state stored in [prefixState] as bits. - * - * ..00 : No partial value (NO_PARTIAL). - * - * ..00001 : Partial string, not inside escape. - * ..00101 : Partial string, after '\'. - * ..vvvv1dd01 : Partial \u escape. - * The 'dd' bits (2-3) encode the number of hex digits seen. - * Bits 5-16 encode the value of the hex digits seen so far. - * - * ..0ddd10 : Partial numeral. - * The `ddd` bits store the parts of in the numeral seen so - * far, as the constants `NUM_*` defined above. - * The characters of the numeral are stored in [buffer] - * as a [_NumberBuffer]. - * - * ..0ddd0011 : Partial 'null' keyword. - * ..0ddd0111 : Partial 'true' keyword. - * ..0ddd1011 : Partial 'false' keyword. - * ..0ddd1111 : Partial UTF-8 BOM byte seqeuence ("\xEF\xBB\xBF"). - * For all keywords, the `ddd` bits encode the number - * of letters seen. - * The BOM byte sequence is only used by [_JsonUtf8Parser], - * and only at the very beginning of input. - */ - int partialState = NO_PARTIAL; - - /** - * Extra data stored while parsing a primitive value. - * May be set during parsing, always set at chunk end if a value is partial. - * - * May contain a string buffer while parsing strings. - */ - dynamic buffer = null; - - _ChunkedJsonParser(this.listener); - - /** - * Push the current parse [state] on a stack. - * - * State is pushed when a new array or object literal starts, - * so the parser can go back to the correct value when the literal ends. - */ - void saveState(int state) { - states.add(state); - } - - /** - * Restore a state pushed with [saveState]. - */ - int restoreState() { - return states.removeLast(); // Throws if empty. - } - - /** - * Finalizes the parsing. - * - * Throws if the source read so far doesn't end up with a complete - * parsed value. That means it must not be inside a list or object - * literal, and any partial value read should also be a valid complete - * value. - * - * The only valid partial state is a number that ends in a digit, and - * only if the number is the entire JSON value being parsed - * (otherwise it would be inside a list or object). - * Such a number will be completed. Any other partial state is an error. - */ - void close() { - if (partialState != NO_PARTIAL) { - int partialType = partialState & MASK_PARTIAL; - if (partialType == PARTIAL_NUMERAL) { - int numState = partialState & ~MASK_PARTIAL; - // A partial number might be a valid number if we know it's done. - // There is an unnecessary overhead if input is a single number, - // but this is assumed to be rare. - _NumberBuffer buffer = this.buffer; - this.buffer = null; - finishChunkNumber(numState, 0, 0, buffer); - } else if (partialType == PARTIAL_STRING) { - fail(chunkEnd, "Unterminated string"); - } else { - assert(partialType == PARTIAL_KEYWORD); - fail(chunkEnd); // Incomplete literal. - } - } - if (state != STATE_END) { - fail(chunkEnd); - } - } - - /** - * Read out the result after successfully closing the parser. - * - * The parser is closed by calling [close] or calling [addSourceChunk] with - * `true` as second (`isLast`) argument. - */ - dynamic get result { - return listener.result; - } - - /** Sets the current source chunk. */ - void set chunk(T source); - - /** - * Length of current chunk. - * - * The valid arguments to [getChar] are 0 .. `chunkEnd - 1`. - */ - int get chunkEnd; - - /** - * Returns the chunk itself. - * - * Only used by [fail] to include the chunk in the thrown [FormatException]. - */ - T get chunk; - - /** - * Get charcacter/code unit of current chunk. - * - * The [index] must be non-negative and less than `chunkEnd`. - * In practive, [index] will be no smaller than the `start` argument passed - * to [parse]. - */ - int getChar(int index); - - /** - * Copy ASCII characters from start to end of chunk into a list. - * - * Used for number buffer (always copies ASCII, so encoding is not important). - */ - void copyCharsToList(int start, int end, List target, int offset); - - /** - * Build a string using input code units. - * - * Creates a string buffer and enables adding characters and slices - * to that buffer. - * The buffer is stored in the [buffer] field. If the string is unterminated, - * the same buffer is used to continue parsing in the next chunk. - */ - void beginString(); - /** - * Add single character code to string being built. - * - * Used for unparsed escape sequences. - */ - void addCharToString(int charCode); - - /** - * Adds slice of current chunk to string being built. - * - * The [start] positions is inclusive, [end] is exclusive. - */ - void addSliceToString(int start, int end); - - /** Finalizes the string being built and returns it as a String. */ - String endString(); - - /** - * Extracts a literal string from a slice of the current chunk. - * - * No interpretation of the content is performed, except for converting - * the source format to string. - * This can be implemented more or less efficiently depending on the - * underlying source. - * - * This is used for string literals that contain no escapes. - * - * The [bits] integer is an upper bound on the code point in the range - * from `start` to `end`. - * Usually found by doing bitwise or of all the values. - * The function may choose to optimize depending on the value. - */ - String getString(int start, int end, int bits); - - /** - * Parse a slice of the current chunk as a number. - * - * Since integers have a maximal value, and we don't track the value - * in the buffer, a sequence of digits can be either an int or a double. - * The `num.parse` function does the right thing. - * - * The format is expected to be correct. - */ - num parseNum(int start, int end) { - const int asciiBits = 0x7f; // Number literals are ASCII only. - return num.parse(getString(start, end, asciiBits)); - } - - /** - * Parse a slice of the current chunk as a double. - * - * The format is expected to be correct. - * This is used by [parseNumber] when the double value cannot be - * built exactly during parsing. - */ - double parseDouble(int start, int end) { - const int asciiBits = 0x7f; // Double literals are ASCII only. - return double.parse(getString(start, end, asciiBits)); - } - - /** - * Continues parsing a partial value. - */ - int parsePartial(int position) { - if (position == chunkEnd) return position; - int partialState = this.partialState; - assert(partialState != NO_PARTIAL); - int partialType = partialState & MASK_PARTIAL; - this.partialState = NO_PARTIAL; - partialState = partialState & ~MASK_PARTIAL; - assert(partialType != 0); - if (partialType == PARTIAL_STRING) { - position = parsePartialString(position, partialState); - } else if (partialType == PARTIAL_NUMERAL) { - position = parsePartialNumber(position, partialState); - } else if (partialType == PARTIAL_KEYWORD) { - position = parsePartialKeyword(position, partialState); - } - return position; - } - - /** - * Parses the remainder of a number into the number buffer. - * - * Syntax is checked while pasing. - * Starts at position, which is expected to be the start of the chunk, - * and returns the index of the first non-number-literal character found, - * or chunkEnd if the entire chunk is a valid number continuation. - * Throws if a syntax error is detected. - */ - int parsePartialNumber(int position, int state) { - int start = position; - // Primitive implementation, can be optimized. - _NumberBuffer buffer = this.buffer; - this.buffer = null; - int end = chunkEnd; - toBailout: - { - if (position == end) break toBailout; - int char = getChar(position); - int digit = char ^ CHAR_0; - if (state == NUM_SIGN) { - if (digit <= 9) { - if (digit == 0) { - state = NUM_ZERO; - } else { - state = NUM_DIGIT; - } - position++; - if (position == end) break toBailout; - char = getChar(position); - digit = char ^ CHAR_0; - } else { - fail(position); - } - } - if (state == NUM_ZERO) { - // JSON does not allow insignificant leading zeros (e.g., "09"). - if (digit <= 9) fail(position); - state = NUM_DIGIT; - } - while (state == NUM_DIGIT) { - if (digit > 9) { - if (char == DECIMALPOINT) { - state = NUM_DOT; - } else if ((char | 0x20) == CHAR_e) { - state = NUM_E; - } else { - finishChunkNumber(state, start, position, buffer); - return position; - } - } - position++; - if (position == end) break toBailout; - char = getChar(position); - digit = char ^ CHAR_0; - } - if (state == NUM_DOT) { - if (digit > 9) fail(position); - state = NUM_DOT_DIGIT; - } - while (state == NUM_DOT_DIGIT) { - if (digit > 9) { - if ((char | 0x20) == CHAR_e) { - state = NUM_E; - } else { - finishChunkNumber(state, start, position, buffer); - return position; - } - } - position++; - if (position == end) break toBailout; - char = getChar(position); - digit = char ^ CHAR_0; - } - if (state == NUM_E) { - if (char == PLUS || char == MINUS) { - state = NUM_E_SIGN; - position++; - if (position == end) break toBailout; - char = getChar(position); - digit = char ^ CHAR_0; - } - } - assert(state >= NUM_E); - while (digit <= 9) { - state = NUM_E_DIGIT; - position++; - if (position == end) break toBailout; - char = getChar(position); - digit = char ^ CHAR_0; - } - finishChunkNumber(state, start, position, buffer); - return position; - } - // Bailout code in case the current chunk ends while parsing the numeral. - assert(position == end); - continueChunkNumber(state, start, buffer); - return chunkEnd; - } - - /** - * Continues parsing a partial string literal. - * - * Handles partial escapes and then hands the parsing off to - * [parseStringToBuffer]. - */ - int parsePartialString(int position, int partialState) { - if (partialState == STR_PLAIN) { - return parseStringToBuffer(position); - } - if (partialState == STR_ESCAPE) { - position = parseStringEscape(position); - // parseStringEscape sets partialState if it sees the end. - if (position == chunkEnd) return position; - return parseStringToBuffer(position); - } - assert((partialState & STR_U) != 0); - int value = partialState >> STR_U_VALUE_SHIFT; - int count = (partialState >> STR_U_COUNT_SHIFT) & TWO_BIT_MASK; - for (int i = count; i < 4; i++, position++) { - if (position == chunkEnd) return chunkStringEscapeU(i, value); - int char = getChar(position); - int digit = parseHexDigit(char); - if (digit < 0) fail(position, "Invalid hex digit"); - value = 16 * value + digit; - } - addCharToString(value); - return parseStringToBuffer(position); - } - - /** - * Continues parsing a partial keyword. - */ - int parsePartialKeyword(int position, int partialState) { - int keywordType = partialState & KWD_TYPE_MASK; - int count = partialState >> KWD_COUNT_SHIFT; - int keywordTypeIndex = keywordType >> KWD_TYPE_SHIFT; - String keyword = - const ["null", "true", "false", "\xEF\xBB\xBF"][keywordTypeIndex]; - assert(count < keyword.length); - do { - if (position == chunkEnd) { - this.partialState = - PARTIAL_KEYWORD | keywordType | (count << KWD_COUNT_SHIFT); - return chunkEnd; - } - int expectedChar = keyword.codeUnitAt(count); - if (getChar(position) != expectedChar) { - if (count == 0) { - assert(keywordType == KWD_BOM); - return position; - } - fail(position); - } - position++; - count++; - } while (count < keyword.length); - if (keywordType == KWD_NULL) { - listener.handleNull(); - } else if (keywordType != KWD_BOM) { - listener.handleBool(keywordType == KWD_TRUE); - } - return position; - } - - /** Convert hex-digit to its value. Returns -1 if char is not a hex digit. */ - int parseHexDigit(int char) { - int digit = char ^ 0x30; - if (digit <= 9) return digit; - int letter = (char | 0x20) ^ 0x60; - // values 1 .. 6 are 'a' through 'f' - if (letter <= 6 && letter > 0) return letter + 9; - return -1; - } - - /** - * Parses the current chunk as a chunk of JSON. - * - * Starts parsing at [position] and continues until [chunkEnd]. - * Continues parsing where the previous chunk (if any) ended. - */ - void parse(int position) { - int length = chunkEnd; - if (partialState != NO_PARTIAL) { - position = parsePartial(position); - if (position == length) return; - } - int state = this.state; - while (position < length) { - int char = getChar(position); - switch (char) { - case SPACE: - case CARRIAGE_RETURN: - case NEWLINE: - case TAB: - position++; - break; - case QUOTE: - if ((state & ALLOW_STRING_MASK) != 0) fail(position); - state |= VALUE_READ_BITS; - position = parseString(position + 1); - break; - case LBRACKET: - if ((state & ALLOW_VALUE_MASK) != 0) fail(position); - listener.beginArray(); - saveState(state); - state = STATE_ARRAY_EMPTY; - position++; - break; - case LBRACE: - if ((state & ALLOW_VALUE_MASK) != 0) fail(position); - listener.beginObject(); - saveState(state); - state = STATE_OBJECT_EMPTY; - position++; - break; - case CHAR_n: - if ((state & ALLOW_VALUE_MASK) != 0) fail(position); - state |= VALUE_READ_BITS; - position = parseNull(position); - break; - case CHAR_f: - if ((state & ALLOW_VALUE_MASK) != 0) fail(position); - state |= VALUE_READ_BITS; - position = parseFalse(position); - break; - case CHAR_t: - if ((state & ALLOW_VALUE_MASK) != 0) fail(position); - state |= VALUE_READ_BITS; - position = parseTrue(position); - break; - case COLON: - if (state != STATE_OBJECT_KEY) fail(position); - listener.propertyName(); - state = STATE_OBJECT_COLON; - position++; - break; - case COMMA: - if (state == STATE_OBJECT_VALUE) { - listener.propertyValue(); - state = STATE_OBJECT_COMMA; - position++; - } else if (state == STATE_ARRAY_VALUE) { - listener.arrayElement(); - state = STATE_ARRAY_COMMA; - position++; - } else { - fail(position); - } - break; - case RBRACKET: - if (state == STATE_ARRAY_EMPTY) { - listener.endArray(); - } else if (state == STATE_ARRAY_VALUE) { - listener.arrayElement(); - listener.endArray(); - } else { - fail(position); - } - state = restoreState() | VALUE_READ_BITS; - position++; - break; - case RBRACE: - if (state == STATE_OBJECT_EMPTY) { - listener.endObject(); - } else if (state == STATE_OBJECT_VALUE) { - listener.propertyValue(); - listener.endObject(); - } else { - fail(position); - } - state = restoreState() | VALUE_READ_BITS; - position++; - break; - default: - if ((state & ALLOW_VALUE_MASK) != 0) fail(position); - state |= VALUE_READ_BITS; - position = parseNumber(char, position); - break; - } - } - this.state = state; - } - - /** - * Parses a "true" literal starting at [position]. - * - * The character `source[position]` must be "t". - */ - int parseTrue(int position) { - assert(getChar(position) == CHAR_t); - if (chunkEnd < position + 4) { - return parseKeywordPrefix(position, "true", KWD_TRUE); - } - if (getChar(position + 1) != CHAR_r || - getChar(position + 2) != CHAR_u || - getChar(position + 3) != CHAR_e) { - fail(position); - } - listener.handleBool(true); - return position + 4; - } - - /** - * Parses a "false" literal starting at [position]. - * - * The character `source[position]` must be "f". - */ - int parseFalse(int position) { - assert(getChar(position) == CHAR_f); - if (chunkEnd < position + 5) { - return parseKeywordPrefix(position, "false", KWD_FALSE); - } - if (getChar(position + 1) != CHAR_a || - getChar(position + 2) != CHAR_l || - getChar(position + 3) != CHAR_s || - getChar(position + 4) != CHAR_e) { - fail(position); - } - listener.handleBool(false); - return position + 5; - } - - /** - * Parses a "null" literal starting at [position]. - * - * The character `source[position]` must be "n". - */ - int parseNull(int position) { - assert(getChar(position) == CHAR_n); - if (chunkEnd < position + 4) { - return parseKeywordPrefix(position, "null", KWD_NULL); - } - if (getChar(position + 1) != CHAR_u || - getChar(position + 2) != CHAR_l || - getChar(position + 3) != CHAR_l) { - fail(position); - } - listener.handleNull(); - return position + 4; - } - - int parseKeywordPrefix(int position, String chars, int type) { - assert(getChar(position) == chars.codeUnitAt(0)); - int length = chunkEnd; - int start = position; - int count = 1; - while (++position < length) { - int char = getChar(position); - if (char != chars.codeUnitAt(count)) fail(start); - count++; - } - this.partialState = PARTIAL_KEYWORD | type | (count << KWD_COUNT_SHIFT); - return length; - } - - /** - * Parses a string value. - * - * Initial [position] is right after the initial quote. - * Returned position right after the final quote. - */ - int parseString(int position) { - // Format: '"'([^\x00-\x1f\\\"]|'\\'[bfnrt/\\"])*'"' - // Initial position is right after first '"'. - int start = position; - int end = chunkEnd; - int bits = 0; - while (position < end) { - int char = getChar(position++); - bits |= char; // Includes final '"', but that never matters. - // BACKSLASH is larger than QUOTE and SPACE. - if (char > BACKSLASH) { - continue; - } - if (char == BACKSLASH) { - beginString(); - int sliceEnd = position - 1; - if (start < sliceEnd) addSliceToString(start, sliceEnd); - return parseStringToBuffer(sliceEnd); - } - if (char == QUOTE) { - listener.handleString(getString(start, position - 1, bits)); - return position; - } - if (char < SPACE) { - fail(position - 1, "Control character in string"); - } - } - beginString(); - if (start < end) addSliceToString(start, end); - return chunkString(STR_PLAIN); - } - - /** - * Sets up a partial string state. - * - * The state is either not inside an escape, or right after a backslash. - * For partial strings ending inside a Unicode escape, use - * [chunkStringEscapeU]. - */ - int chunkString(int stringState) { - partialState = PARTIAL_STRING | stringState; - return chunkEnd; - } - - /** - * Sets up a partial string state for a partially parsed Unicode escape. - * - * The partial string state includes the current [buffer] and the - * number of hex digits of the Unicode seen so far (e.g., for `"\u30') - * the state knows that two digits have been seen, and what their value is. - * - * Returns [chunkEnd] so it can be used as part of a return statement. - */ - int chunkStringEscapeU(int count, int value) { - partialState = PARTIAL_STRING | - STR_U | - (count << STR_U_COUNT_SHIFT) | - (value << STR_U_VALUE_SHIFT); - return chunkEnd; - } - - /** - * Parses the remainder of a string literal into a buffer. - * - * The buffer is stored in [buffer] and its underlying format depends on - * the input chunk type. For example UTF-8 decoding happens in the - * buffer, not in the parser, since all significant JSON characters are ASCII. - * - * This function scans through the string literal for escapes, and copies - * slices of non-escape characters using [addSliceToString]. - */ - int parseStringToBuffer(int position) { - int end = chunkEnd; - int start = position; - while (true) { - if (position == end) { - if (position > start) { - addSliceToString(start, position); - } - return chunkString(STR_PLAIN); - } - int char = getChar(position++); - if (char > BACKSLASH) continue; - if (char < SPACE) { - fail(position - 1); // Control character in string. - } - if (char == QUOTE) { - int quotePosition = position - 1; - if (quotePosition > start) { - addSliceToString(start, quotePosition); - } - listener.handleString(endString()); - return position; - } - if (char != BACKSLASH) { - continue; - } - // Handle escape. - if (position - 1 > start) { - addSliceToString(start, position - 1); - } - if (position == end) return chunkString(STR_ESCAPE); - position = parseStringEscape(position); - if (position == end) return position; - start = position; - } - return -1; // UNREACHABLE. - } - - /** - * Parse a string escape. - * - * Position is right after the initial backslash. - * The following escape is parsed into a character code which is added to - * the current string buffer using [addCharToString]. - * - * Returns position after the last character of the escape. - */ - int parseStringEscape(int position) { - int char = getChar(position++); - int length = chunkEnd; - switch (char) { - case CHAR_b: - char = BACKSPACE; - break; - case CHAR_f: - char = FORM_FEED; - break; - case CHAR_n: - char = NEWLINE; - break; - case CHAR_r: - char = CARRIAGE_RETURN; - break; - case CHAR_t: - char = TAB; - break; - case SLASH: - case BACKSLASH: - case QUOTE: - break; - case CHAR_u: - int hexStart = position - 1; - int value = 0; - for (int i = 0; i < 4; i++) { - if (position == length) return chunkStringEscapeU(i, value); - char = getChar(position++); - int digit = char ^ 0x30; - value *= 16; - if (digit <= 9) { - value += digit; - } else { - digit = (char | 0x20) - CHAR_a; - if (digit < 0 || digit > 5) { - fail(hexStart, "Invalid unicode escape"); - } - value += digit + 10; - } - } - char = value; - break; - default: - if (char < SPACE) fail(position, "Control character in string"); - fail(position, "Unrecognized string escape"); - } - addCharToString(char); - if (position == length) return chunkString(STR_PLAIN); - return position; - } - - /// Sets up a partial numeral state. - /// Returns chunkEnd to allow easy one-line bailout tests. - int beginChunkNumber(int state, int start) { - int end = chunkEnd; - int length = end - start; - var buffer = new _NumberBuffer(length); - copyCharsToList(start, end, buffer.list, 0); - buffer.length = length; - this.buffer = buffer; - this.partialState = PARTIAL_NUMERAL | state; - return end; - } - - void addNumberChunk(_NumberBuffer buffer, int start, int end, int overhead) { - int length = end - start; - int count = buffer.length; - int newCount = count + length; - int newCapacity = newCount + overhead; - buffer.ensureCapacity(newCapacity); - copyCharsToList(start, end, buffer.list, count); - buffer.length = newCount; - } - - // Continues an already chunked number across an entire chunk. - int continueChunkNumber(int state, int start, _NumberBuffer buffer) { - int end = chunkEnd; - addNumberChunk(buffer, start, end, _NumberBuffer.kDefaultOverhead); - this.buffer = buffer; - this.partialState = PARTIAL_NUMERAL | state; - return end; - } - - int finishChunkNumber(int state, int start, int end, _NumberBuffer buffer) { - if (state == NUM_ZERO) { - listener.handleNumber(0); - return end; - } - if (end > start) { - addNumberChunk(buffer, start, end, 0); - } - if (state == NUM_DIGIT) { - num value = buffer.parseNum(); - listener.handleNumber(value); - } else if (state == NUM_DOT_DIGIT || state == NUM_E_DIGIT) { - listener.handleNumber(buffer.parseDouble()); - } else { - fail(chunkEnd, "Unterminated number literal"); - } - return end; - } - - int parseNumber(int char, int position) { - // Also called on any unexpected character. - // Format: - // '-'?('0'|[1-9][0-9]*)('.'[0-9]+)?([eE][+-]?[0-9]+)? - int start = position; - int length = chunkEnd; - // Collects an int value while parsing. Used for both an integer literal, - // and the exponent part of a double literal. - // Stored as negative to ensure we can represent -2^63. - int intValue = 0; - double doubleValue = 0.0; // Collect double value while parsing. - // 1 if there is no leading -, -1 if there is. - int sign = 1; - bool isDouble = false; - // Break this block when the end of the number literal is reached. - // At that time, position points to the next character, and isDouble - // is set if the literal contains a decimal point or an exponential. - if (char == MINUS) { - sign = -1; - position++; - if (position == length) return beginChunkNumber(NUM_SIGN, start); - char = getChar(position); - } - int digit = char ^ CHAR_0; - if (digit > 9) { - if (sign < 0) { - fail(position, "Missing expected digit"); - } else { - // If it doesn't even start out as a numeral. - fail(position); - } - } - if (digit == 0) { - position++; - if (position == length) return beginChunkNumber(NUM_ZERO, start); - char = getChar(position); - digit = char ^ CHAR_0; - // If starting with zero, next character must not be digit. - if (digit <= 9) fail(position); - } else { - int digitCount = 0; - do { - if (digitCount >= 18) { - // Check for overflow. - // Is 1 if digit is 8 or 9 and sign == 0, or digit is 9 and sign < 0; - int highDigit = digit >> 3; - if (sign < 0) highDigit &= digit; - if (digitCount == 19 || intValue - highDigit < -922337203685477580) { - isDouble = true; - // Big value that we know is not trusted to be exact later, - // forcing reparsing using `double.parse`. - doubleValue = 9223372036854775808.0; - } - } - intValue = 10 * intValue - digit; - digitCount++; - position++; - if (position == length) return beginChunkNumber(NUM_DIGIT, start); - char = getChar(position); - digit = char ^ CHAR_0; - } while (digit <= 9); - } - if (char == DECIMALPOINT) { - if (!isDouble) { - isDouble = true; - doubleValue = (intValue == 0) ? 0.0 : -intValue.toDouble(); - } - intValue = 0; - position++; - if (position == length) return beginChunkNumber(NUM_DOT, start); - char = getChar(position); - digit = char ^ CHAR_0; - if (digit > 9) fail(position); - do { - doubleValue = 10.0 * doubleValue + digit; - intValue -= 1; - position++; - if (position == length) return beginChunkNumber(NUM_DOT_DIGIT, start); - char = getChar(position); - digit = char ^ CHAR_0; - } while (digit <= 9); - } - if ((char | 0x20) == CHAR_e) { - if (!isDouble) { - isDouble = true; - doubleValue = (intValue == 0) ? 0.0 : -intValue.toDouble(); - intValue = 0; - } - position++; - if (position == length) return beginChunkNumber(NUM_E, start); - char = getChar(position); - int expSign = 1; - int exponent = 0; - if (((char + 1) | 2) == 0x2e /*+ or -*/) { - expSign = 0x2C - char; // -1 for MINUS, +1 for PLUS - position++; - if (position == length) return beginChunkNumber(NUM_E_SIGN, start); - char = getChar(position); - } - digit = char ^ CHAR_0; - if (digit > 9) { - fail(position, "Missing expected digit"); - } - bool exponentOverflow = false; - do { - exponent = 10 * exponent + digit; - if (exponent > 400) exponentOverflow = true; - position++; - if (position == length) return beginChunkNumber(NUM_E_DIGIT, start); - char = getChar(position); - digit = char ^ CHAR_0; - } while (digit <= 9); - if (exponentOverflow) { - if (doubleValue == 0.0 || expSign < 0) { - listener.handleNumber(sign < 0 ? -0.0 : 0.0); - } else { - listener.handleNumber( - sign < 0 ? double.negativeInfinity : double.infinity); - } - return position; - } - intValue += expSign * exponent; - } - if (!isDouble) { - int bitFlag = -(sign + 1) >> 1; // 0 if sign == -1, -1 if sign == 1 - // Negate if bitFlag is -1 by doing ~intValue + 1 - listener.handleNumber((intValue ^ bitFlag) - bitFlag); - return position; - } - // Double values at or above this value (2 ** 53) may have lost precision. - // Only trust results that are below this value. - const double maxExactDouble = 9007199254740992.0; - if (doubleValue < maxExactDouble) { - int exponent = intValue; - double signedMantissa = doubleValue * sign; - if (exponent >= -22) { - if (exponent < 0) { - listener.handleNumber(signedMantissa / POWERS_OF_TEN[-exponent]); - return position; - } - if (exponent == 0) { - listener.handleNumber(signedMantissa); - return position; - } - if (exponent <= 22) { - listener.handleNumber(signedMantissa * POWERS_OF_TEN[exponent]); - return position; - } - } - } - // If the value is outside the range +/-maxExactDouble or - // exponent is outside the range +/-22, then we can't trust simple double - // arithmetic to get the exact result, so we use the system double parsing. - listener.handleNumber(parseDouble(start, position)); - return position; - } - - Never fail(int position, [String? message]) { - if (message == null) { - message = "Unexpected character"; - if (position == chunkEnd) message = "Unexpected end of input"; - } - throw new FormatException(message, chunk, position); - } -} - -/** - * Chunked JSON parser that parses [String] chunks. - */ -class _JsonStringParser extends _ChunkedJsonParser { - String chunk = ''; - int chunkEnd = 0; - - _JsonStringParser(_JsonListener listener) : super(listener); - - int getChar(int position) => chunk.codeUnitAt(position); - - String getString(int start, int end, int bits) { - return chunk.substring(start, end); - } - - void beginString() { - this.buffer = new StringBuffer(); - } - - void addSliceToString(int start, int end) { - StringBuffer buffer = this.buffer; - buffer.write(chunk.substring(start, end)); - } - - void addCharToString(int charCode) { - StringBuffer buffer = this.buffer; - buffer.writeCharCode(charCode); - } - - String endString() { - StringBuffer buffer = this.buffer; - this.buffer = null; - return buffer.toString(); - } - - void copyCharsToList(int start, int end, List target, int offset) { - int length = end - start; - for (int i = 0; i < length; i++) { - target[offset + i] = chunk.codeUnitAt(start + i); - } - } - - double parseDouble(int start, int end) { - return _parseDouble(chunk, start, end); - } -} - -@patch -class JsonDecoder { - @patch - StringConversionSink startChunkedConversion(Sink sink) { - return new _JsonStringDecoderSink(this._reviver, sink); - } -} - -/** - * Implements the chunked conversion from a JSON string to its corresponding - * object. - * - * The sink only creates one object, but its input can be chunked. - */ -class _JsonStringDecoderSink extends StringConversionSinkBase { - _JsonStringParser _parser; - final Object? Function(Object? key, Object? value)? _reviver; - final Sink _sink; - - _JsonStringDecoderSink(this._reviver, this._sink) - : _parser = _createParser(_reviver); - - static _JsonStringParser _createParser( - Object? Function(Object? key, Object? value)? reviver) { - _BuildJsonListener listener; - if (reviver == null) { - listener = new _BuildJsonListener(); - } else { - listener = new _ReviverJsonListener(reviver); - } - return new _JsonStringParser(listener); - } - - void addSlice(String chunk, int start, int end, bool isLast) { - _parser.chunk = chunk; - _parser.chunkEnd = end; - _parser.parse(start); - if (isLast) _parser.close(); - } - - void add(String chunk) { - addSlice(chunk, 0, chunk.length, false); - } - - void close() { - _parser.close(); - var decoded = _parser.result; - _sink.add(decoded); - _sink.close(); - } - - ByteConversionSink asUtf8Sink(bool allowMalformed) { - return new _JsonUtf8DecoderSink(_reviver, _sink, allowMalformed); - } -} - -/** - * Chunked JSON parser that parses UTF-8 chunks. - */ -class _JsonUtf8Parser extends _ChunkedJsonParser> { - static final Uint8List emptyChunk = Uint8List(0); - - final _Utf8Decoder decoder; - List chunk = emptyChunk; - int chunkEnd = 0; - - _JsonUtf8Parser(_JsonListener listener, bool allowMalformed) - : decoder = new _Utf8Decoder(allowMalformed), - super(listener) { - // Starts out checking for an optional BOM (KWD_BOM, count = 0). - partialState = - _ChunkedJsonParser.PARTIAL_KEYWORD | _ChunkedJsonParser.KWD_BOM; - } - - int getChar(int position) => chunk[position]; - - String getString(int start, int end, int bits) { - const int maxAsciiChar = 0x7f; - if (bits <= maxAsciiChar) { - return new String.fromCharCodes(chunk, start, end); - } - beginString(); - if (start < end) addSliceToString(start, end); - String result = endString(); - return result; - } - - void beginString() { - decoder.reset(); - this.buffer = new StringBuffer(); - } - - void addSliceToString(int start, int end) { - final StringBuffer buffer = this.buffer; - buffer.write(decoder.convertChunked(chunk, start, end)); - } - - void addCharToString(int charCode) { - final StringBuffer buffer = this.buffer; - decoder.flush(buffer); - buffer.writeCharCode(charCode); - } - - String endString() { - final StringBuffer buffer = this.buffer; - decoder.flush(buffer); - this.buffer = null; - return buffer.toString(); - } - - void copyCharsToList(int start, int end, List target, int offset) { - int length = end - start; - target.setRange(offset, offset + length, chunk, start); - } - - double parseDouble(int start, int end) { - String string = getString(start, end, 0x7f); - return _parseDouble(string, 0, string.length); - } -} - -double _parseDouble(String source, int start, int end) native "Double_parse"; - -/** - * Implements the chunked conversion from a UTF-8 encoding of JSON - * to its corresponding object. - */ -class _JsonUtf8DecoderSink extends ByteConversionSinkBase { - final _JsonUtf8Parser _parser; - final Sink _sink; - - _JsonUtf8DecoderSink(reviver, this._sink, bool allowMalformed) - : _parser = _createParser(reviver, allowMalformed); - - static _JsonUtf8Parser _createParser( - Object? Function(Object? key, Object? value)? reviver, - bool allowMalformed) { - _BuildJsonListener listener; - if (reviver == null) { - listener = new _BuildJsonListener(); - } else { - listener = new _ReviverJsonListener(reviver); - } - return new _JsonUtf8Parser(listener, allowMalformed); - } - - void addSlice(List chunk, int start, int end, bool isLast) { - _addChunk(chunk, start, end); - if (isLast) close(); - } - - void add(List chunk) { - _addChunk(chunk, 0, chunk.length); - } - - void _addChunk(List chunk, int start, int end) { - _parser.chunk = chunk; - _parser.chunkEnd = end; - _parser.parse(start); - } - - void close() { - _parser.close(); - var decoded = _parser.result; - _sink.add(decoded); - _sink.close(); - } -} - -@patch -class _Utf8Decoder { - /// Flags indicating presence of the various kinds of bytes in the input. - int _scanFlags = 0; - - /// How many bytes of the BOM have been read so far. Set to -1 when the BOM - /// has been skipped (or was not present). - int _bomIndex = 0; - - // Table for the scanning phase, which quickly scans through the input. - // - // Each input byte is looked up in the table, providing a size and some flags. - // The sizes are summed, and the flags are or'ed together. - // - // The resulting size and flags indicate: - // A) How many UTF-16 code units will be emitted by the decoding of this - // input. This can be used to allocate a string of the correct length up - // front. - // B) Which decoder and resulting string representation is appropriate. There - // are three cases: - // 1) Pure ASCII (flags == 0): The input can simply be put into a - // OneByteString without further decoding. - // 2) Latin1 (flags == (flagLatin1 | flagExtension)): The result can be - // represented by a OneByteString, and the decoder can assume that only - // Latin1 characters are present. - // 3) Arbitrary input (otherwise): Needs a full-featured decoder. Output - // can be represented by a TwoByteString. - - static const int sizeMask = 0x03; - static const int flagsMask = 0x3C; - - static const int flagExtension = 1 << 2; - static const int flagLatin1 = 1 << 3; - static const int flagNonLatin1 = 1 << 4; - static const int flagIllegal = 1 << 5; - - // ASCII 'A' = 64 + (1); - // Extension 'D' = 64 + (0 | flagExtension); - // Latin1 'I' = 64 + (1 | flagLatin1); - // BMP 'Q' = 64 + (1 | flagNonLatin1); - // Non-BMP 'R' = 64 + (2 | flagNonLatin1); - // Illegal 'a' = 64 + (1 | flagIllegal); - // Illegal 'b' = 64 + (2 | flagIllegal); - static const String scanTable = "" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 00-1F - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 20-3F - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 40-5F - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 60-7F - "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" // 80-9F - "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" // A0-BF - "aaIIQQQQQQQQQQQQQQQQQQQQQQQQQQQQ" // C0-DF - "QQQQQQQQQQQQQQQQRRRRRbbbbbbbbbbb" // E0-FF - ; - - /// Max chunk to scan at a time. Avoids staying away from safepoints too long. - static const int scanChunkSize = 65536; - - /// Reset the decoder to a state where it is ready to decode a new string but - /// will not skip a leading BOM. Used by the fused UTF-8 / JSON decoder. - void reset() { - _state = initial; - _bomIndex = -1; - } - - @pragma("vm:prefer-inline") - int scan(Uint8List bytes, int start, int end) { - // Assumes 0 <= start <= end <= bytes.length - int size = 0; - _scanFlags = 0; - int localStart = start; - while (end - localStart > scanChunkSize) { - int localEnd = localStart + scanChunkSize; - size += _scan(bytes, localStart, localEnd, scanTable); - localStart = localEnd; - } - size += _scan(bytes, localStart, end, scanTable); - return size; - } - - // This method is recognized by the VM and compiled into specialized code. - @pragma("vm:prefer-inline") - int _scan(Uint8List bytes, int start, int end, String scanTable) { - int size = 0; - int flags = 0; - for (int i = start; i < end; i++) { - int t = scanTable.codeUnitAt(bytes[i]); - size += t & sizeMask; - flags |= t; - } - _scanFlags |= flags & flagsMask; - return size; - } - - @pragma("vm:prefer-inline") - static bool _isNativeUint8List(List array) { - final int cid = ClassID.getID(array); - return cid == ClassID.cidUint8ArrayView || - cid == ClassID.cidUint8Array || - cid == ClassID.cidExternalUint8Array; - } - - // The VM decoder handles BOM explicitly instead of via the state machine. - @patch - _Utf8Decoder(this.allowMalformed) : _state = initial; - - @patch - String convertSingle(List codeUnits, int start, int? maybeEnd) { - int end = RangeError.checkValidRange(start, maybeEnd, codeUnits.length); - - // Have bytes as Uint8List. - Uint8List bytes; - int errorOffset; - if (_isNativeUint8List(codeUnits)) { - bytes = unsafeCast(codeUnits); - errorOffset = 0; - } else { - bytes = _makeUint8List(codeUnits, start, end); - errorOffset = start; - end -= start; - start = 0; - } - - // Skip initial BOM. - start = skipBomSingle(bytes, start, end); - - // Special case empty input. - if (start == end) return ""; - - // Scan input to determine size and appropriate decoder. - int size = scan(bytes, start, end); - int flags = _scanFlags; - - if (flags == 0) { - // Pure ASCII. - assert(size == end - start); - String result = allocateOneByteString(size); - copyRangeFromUint8ListToOneByteString(bytes, result, start, 0, size); - return result; - } - - String result; - if (flags == (flagLatin1 | flagExtension)) { - // Latin1. - result = decode8(bytes, start, end, size); - } else { - // Arbitrary Unicode. - result = decode16(bytes, start, end, size); - } - if (_state == accept) { - return result; - } - - if (!allowMalformed) { - if (!isErrorState(_state)) { - // Unfinished sequence. - _state = errorUnfinished; - _charOrIndex = end; - } - final String message = errorDescription(_state); - throw FormatException(message, codeUnits, errorOffset + _charOrIndex); - } - - // Start over on slow path. - _state = initial; - result = decodeGeneral(bytes, start, end, true); - assert(!isErrorState(_state)); - return result; - } - - @patch - String convertChunked(List codeUnits, int start, int? maybeEnd) { - int end = RangeError.checkValidRange(start, maybeEnd, codeUnits.length); - - // Have bytes as Uint8List. - Uint8List bytes; - int errorOffset; - if (_isNativeUint8List(codeUnits)) { - bytes = unsafeCast(codeUnits); - errorOffset = 0; - } else { - bytes = _makeUint8List(codeUnits, start, end); - errorOffset = start; - end -= start; - start = 0; - } - - // Skip initial BOM. - start = skipBomChunked(bytes, start, end); - - // Special case empty input. - if (start == end) return ""; - - // Scan input to determine size and appropriate decoder. - int size = scan(bytes, start, end); - int flags = _scanFlags; - - // Adjust scan flags and size based on carry-over state. - switch (_state) { - case IA: - break; - case X1: - flags |= _charOrIndex < (0x100 >> 6) ? flagLatin1 : flagNonLatin1; - if (end - start >= 1) { - size += _charOrIndex < (0x10000 >> 6) ? 1 : 2; - } - break; - case X2: - flags |= flagNonLatin1; - if (end - start >= 2) { - size += _charOrIndex < (0x10000 >> 12) ? 1 : 2; - } - break; - case TO: - case TS: - flags |= flagNonLatin1; - if (end - start >= 2) size += 1; - break; - case X3: - case QO: - case QR: - flags |= flagNonLatin1; - if (end - start >= 3) size += 2; - break; - } - - if (flags == 0) { - // Pure ASCII. - assert(_state == accept); - assert(size == end - start); - String result = allocateOneByteString(size); - copyRangeFromUint8ListToOneByteString(bytes, result, start, 0, size); - return result; - } - - // Do not include any final, incomplete character in size. - int extensionCount = 0; - int i = end - 1; - while (i >= start && (bytes[i] & 0xC0) == 0x80) { - extensionCount++; - i--; - } - if (i >= start && bytes[i] >= ((~0x3F >> extensionCount) & 0xFF)) { - size -= bytes[i] >= 0xF0 ? 2 : 1; - } - - final int carryOverState = _state; - final int carryOverChar = _charOrIndex; - String result; - if (flags == (flagLatin1 | flagExtension)) { - // Latin1. - result = decode8(bytes, start, end, size); - } else { - // Arbitrary Unicode. - result = decode16(bytes, start, end, size); - } - if (!isErrorState(_state)) { - return result; - } - assert(_bomIndex == -1); - - if (!allowMalformed) { - final String message = errorDescription(_state); - _state = initial; // Ready for more input. - throw FormatException(message, codeUnits, errorOffset + _charOrIndex); - } - - // Start over on slow path. - _state = carryOverState; - _charOrIndex = carryOverChar; - result = decodeGeneral(bytes, start, end, false); - assert(!isErrorState(_state)); - return result; - } - - @pragma("vm:prefer-inline") - int skipBomSingle(Uint8List bytes, int start, int end) { - if (end - start >= 3 && - bytes[start] == 0xEF && - bytes[start + 1] == 0xBB && - bytes[start + 2] == 0xBF) { - return start + 3; - } - return start; - } - - @pragma("vm:prefer-inline") - int skipBomChunked(Uint8List bytes, int start, int end) { - assert(start <= end); - int bomIndex = _bomIndex; - // Already skipped? - if (bomIndex == -1) return start; - - const bomValues = [0xEF, 0xBB, 0xBF]; - int i = start; - while (bomIndex < 3) { - if (i == end) { - // Unfinished BOM. - _bomIndex = bomIndex; - return start; - } - if (bytes[i++] != bomValues[bomIndex++]) { - // No BOM. - _bomIndex = -1; - return start; - } - } - // Complete BOM. - _bomIndex = -1; - _state = initial; - return i; - } - - String decode8(Uint8List bytes, int start, int end, int size) { - assert(start < end); - String result = allocateOneByteString(size); - int i = start; - int j = 0; - if (_state == X1) { - // Half-way though 2-byte sequence - assert(_charOrIndex == 2 || _charOrIndex == 3); - final int e = bytes[i++] ^ 0x80; - if (e >= 0x40) { - _state = errorMissingExtension; - _charOrIndex = i - 1; - return ""; - } - writeIntoOneByteString(result, j++, (_charOrIndex << 6) | e); - _state = accept; - } - assert(_state == accept); - while (i < end) { - int byte = bytes[i++]; - if (byte >= 0x80) { - if (byte < 0xC0) { - _state = errorUnexpectedExtension; - _charOrIndex = i - 1; - return ""; - } - assert(byte == 0xC2 || byte == 0xC3); - if (i == end) { - _state = X1; - _charOrIndex = byte & 0x1F; - break; - } - final int e = bytes[i++] ^ 0x80; - if (e >= 0x40) { - _state = errorMissingExtension; - _charOrIndex = i - 1; - return ""; - } - byte = (byte << 6) | e; - } - writeIntoOneByteString(result, j++, byte); - } - // Output size must match, unless we are doing single conversion and are - // inside an unfinished sequence (which will trigger an error later). - assert(_bomIndex == 0 && _state != accept - ? (j == size - 1 || j == size - 2) - : (j == size)); - return result; - } - - String decode16(Uint8List bytes, int start, int end, int size) { - assert(start < end); - final String typeTable = _Utf8Decoder.typeTable; - final String transitionTable = _Utf8Decoder.transitionTable; - String result = allocateTwoByteString(size); - int i = start; - int j = 0; - int state = _state; - int char; - - // First byte - assert(!isErrorState(state)); - final int byte = bytes[i++]; - final int type = typeTable.codeUnitAt(byte) & typeMask; - if (state == accept) { - char = byte & (shiftedByteMask >> type); - state = transitionTable.codeUnitAt(type); - } else { - char = (byte & 0x3F) | (_charOrIndex << 6); - state = transitionTable.codeUnitAt(state + type); - } - - while (i < end) { - final int byte = bytes[i++]; - final int type = typeTable.codeUnitAt(byte) & typeMask; - if (state == accept) { - if (char >= 0x10000) { - assert(char < 0x110000); - writeIntoTwoByteString(result, j++, 0xD7C0 + (char >> 10)); - writeIntoTwoByteString(result, j++, 0xDC00 + (char & 0x3FF)); - } else { - writeIntoTwoByteString(result, j++, char); - } - char = byte & (shiftedByteMask >> type); - state = transitionTable.codeUnitAt(type); - } else if (isErrorState(state)) { - _state = state; - _charOrIndex = i - 2; - return ""; - } else { - char = (byte & 0x3F) | (char << 6); - state = transitionTable.codeUnitAt(state + type); - } - } - - // Final write? - if (state == accept) { - if (char >= 0x10000) { - assert(char < 0x110000); - writeIntoTwoByteString(result, j++, 0xD7C0 + (char >> 10)); - writeIntoTwoByteString(result, j++, 0xDC00 + (char & 0x3FF)); - } else { - writeIntoTwoByteString(result, j++, char); - } - } else if (isErrorState(state)) { - _state = state; - _charOrIndex = end - 1; - return ""; - } - - _state = state; - _charOrIndex = char; - // Output size must match, unless we are doing single conversion and are - // inside an unfinished sequence (which will trigger an error later). - assert(_bomIndex == 0 && _state != accept - ? (j == size - 1 || j == size - 2) - : (j == size)); - return result; - } -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/core_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/core_patch.dart deleted file mode 100644 index 21337633c94..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/core_patch.dart +++ /dev/null @@ -1,207 +0,0 @@ -// Copyright (c) 2013, 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. - -/// Note: the VM concatenates all patch files into a single patch file. This -/// file is the first patch in "dart:core" which contains all the imports -/// used by patches of that library. We plan to change this when we have a -/// shared front end and simply use parts. - -import "dart:_internal" as internal show Symbol; - -import "dart:_internal" - show - allocateOneByteString, - allocateTwoByteString, - ClassID, - CodeUnits, - copyRangeFromUint8ListToOneByteString, - EfficientLengthIterable, - FixedLengthListBase, - IterableElementError, - ListIterator, - Lists, - POWERS_OF_TEN, - SubListIterable, - UnmodifiableListBase, - is64Bit, - makeFixedListUnmodifiable, - makeListFixedLength, - patch, - unsafeCast, - writeIntoOneByteString, - writeIntoTwoByteString; - -import "dart:async" show Completer, Future, Timer; - -import "dart:collection" - show - HashMap, - IterableBase, - LinkedHashMap, - LinkedList, - LinkedListEntry, - ListBase, - MapBase, - Maps, - UnmodifiableMapBase, - UnmodifiableMapView; - -import "dart:convert" show ascii, Encoding, json, latin1, utf8; - -import "dart:isolate" show Isolate; - -import "dart:math" show Random; - -import "dart:typed_data" - show Endian, Uint8List, Int64List, Uint16List, Uint32List; - -/// These are the additional parts of this patch library: -// part "array.dart"; -// part "array_patch.dart"; -// part "bigint_patch.dart"; -// part "bool_patch.dart"; -// part "date_patch.dart"; -// part "double.dart"; -// part "double_patch.dart"; -// part "errors_patch.dart"; -// part "expando_patch.dart"; -// part "function.dart"; -// part "function_patch.dart"; -// part "growable_array.dart"; -// part "identical_patch.dart"; -// part "immutable_map.dart"; -// part "integers.dart"; -// part "integers_patch.dart"; -// part "invocation_mirror_patch.dart"; -// part "lib_prefix.dart"; -// part "map_patch.dart"; -// part "null_patch.dart"; -// part "object_patch.dart"; -// part "regexp_patch.dart"; -// part "stacktrace.dart"; -// part "stopwatch_patch.dart"; -// part "string_buffer_patch.dart"; -// part "string_patch.dart"; -// part "type_patch.dart"; -// part "uri_patch.dart"; -// part "weak_property.dart"; - -@patch -class num { - num _addFromInteger(int other); - num _subFromInteger(int other); - num _mulFromInteger(int other); - int _truncDivFromInteger(int other); - num _moduloFromInteger(int other); - num _remainderFromInteger(int other); - bool _greaterThanFromInteger(int other); - bool _equalToInteger(int other); -} - -// _SyncIterable and _syncIterator are used by the compiler to -// implement sync* generator functions. A sync* generator allocates -// and returns a new _SyncIterable object. - -typedef _SyncGeneratorCallback = bool Function(_SyncIterator); -typedef _SyncGeneratorCallbackCallback = _SyncGeneratorCallback - Function(); - -class _SyncIterable extends IterableBase { - // Closure that effectively "clones" the inner _moveNextFn. - // This means a _SyncIterable creates _SyncIterators that do not share state. - final _SyncGeneratorCallbackCallback _moveNextFnMaker; - - const _SyncIterable(this._moveNextFnMaker); - - Iterator get iterator { - return _SyncIterator(_moveNextFnMaker()); - } -} - -class _SyncIterator implements Iterator { - _SyncGeneratorCallback? _moveNextFn; - Iterator? _yieldEachIterator; - - // Stack of suspended _moveNextFn. - List<_SyncGeneratorCallback>? _stack; - - // These two fields are set by generated code for the yield and yield* - // statement. - T? _current; - Iterable? _yieldEachIterable; - - @override - T get current { - final iterator = _yieldEachIterator; - if (iterator != null) { - return iterator.current; - } else { - final cur = _current; - return (cur != null) ? cur : cur as T; - } - } - - _SyncIterator(this._moveNextFn); - - @override - bool moveNext() { - if (_moveNextFn == null) { - return false; - } - - while (true) { - // If the active iterator isn't a nested _SyncIterator, we have to - // delegate downwards from the immediate iterator. - final iterator = _yieldEachIterator; - if (iterator != null) { - if (iterator.moveNext()) { - return true; - } - _yieldEachIterator = null; - } - - final stack = _stack; - if (!_moveNextFn!.call(this)) { - _moveNextFn = null; - _current = null; - // If we have any suspended parent generators, continue next one up: - if (stack != null && stack.isNotEmpty) { - _moveNextFn = stack.removeLast(); - continue; - } - return false; - } - - final iterable = _yieldEachIterable; - if (iterable != null) { - if (iterable is _SyncIterable) { - // We got a recursive yield* of sync* function. Instead of creating - // a new iterator we replace our _moveNextFn (remembering the - // current _moveNextFn for later resumption). - if (stack == null) { - _stack = []; - } - _stack!.add(_moveNextFn!); - final typedIterable = unsafeCast<_SyncIterable>(iterable); - _moveNextFn = typedIterable._moveNextFnMaker(); - } else { - _yieldEachIterator = iterable.iterator; - } - _yieldEachIterable = null; - _current = null; - - // Fetch the next item. - continue; - } - - return true; - } - } -} - -@patch -class StackTrace { - @patch - static StackTrace get current native "StackTrace_current"; -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/date_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/date_patch.dart deleted file mode 100644 index ee3b5a3a78e..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/date_patch.dart +++ /dev/null @@ -1,446 +0,0 @@ -// Copyright (c) 2012, 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. - -// part of "core_patch.dart"; - -// VM implementation of DateTime. -@patch -class DateTime { - // Natives. - // The natives have been moved up here to work around Issue 10401. - static int _getCurrentMicros() native "DateTime_currentTimeMicros"; - - static String _timeZoneNameForClampedSeconds(int secondsSinceEpoch) - native "DateTime_timeZoneName"; - - static int _timeZoneOffsetInSecondsForClampedSeconds(int secondsSinceEpoch) - native "DateTime_timeZoneOffsetInSeconds"; - - static int _localTimeZoneAdjustmentInSeconds() - native "DateTime_localTimeZoneAdjustmentInSeconds"; - - static const _MICROSECOND_INDEX = 0; - static const _MILLISECOND_INDEX = 1; - static const _SECOND_INDEX = 2; - static const _MINUTE_INDEX = 3; - static const _HOUR_INDEX = 4; - static const _DAY_INDEX = 5; - static const _WEEKDAY_INDEX = 6; - static const _MONTH_INDEX = 7; - static const _YEAR_INDEX = 8; - - List? __parts; - - @patch - DateTime.fromMillisecondsSinceEpoch(int millisecondsSinceEpoch, - {bool isUtc: false}) - : this._withValue( - millisecondsSinceEpoch * Duration.microsecondsPerMillisecond, - isUtc: isUtc); - - @patch - DateTime.fromMicrosecondsSinceEpoch(int microsecondsSinceEpoch, - {bool isUtc: false}) - : this._withValue(microsecondsSinceEpoch, isUtc: isUtc); - - @patch - DateTime._internal(int year, int month, int day, int hour, int minute, - int second, int millisecond, int microsecond, bool isUtc) - : this.isUtc = isUtc, - this._value = _brokenDownDateToValue(year, month, day, hour, minute, - second, millisecond, microsecond, isUtc) ?? - -1 { - if (_value == -1) throw new ArgumentError(); - if (isUtc == null) throw new ArgumentError(); - } - - @patch - DateTime._now() - : isUtc = false, - _value = _getCurrentMicros(); - - @patch - String get timeZoneName { - if (isUtc) return "UTC"; - return _timeZoneName(microsecondsSinceEpoch); - } - - @patch - Duration get timeZoneOffset { - if (isUtc) return new Duration(); - int offsetInSeconds = _timeZoneOffsetInSeconds(microsecondsSinceEpoch); - return new Duration(seconds: offsetInSeconds); - } - - @patch - bool operator ==(dynamic other) => - other is DateTime && - _value == other.microsecondsSinceEpoch && - isUtc == other.isUtc; - - @patch - bool isBefore(DateTime other) => _value < other.microsecondsSinceEpoch; - - @patch - bool isAfter(DateTime other) => _value > other.microsecondsSinceEpoch; - - @patch - bool isAtSameMomentAs(DateTime other) => - _value == other.microsecondsSinceEpoch; - - @patch - int compareTo(DateTime other) => - _value.compareTo(other.microsecondsSinceEpoch); - - /** The first list contains the days until each month in non-leap years. The - * second list contains the days in leap years. */ - static const List> _DAYS_UNTIL_MONTH = const [ - const [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334], - const [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335] - ]; - - static List _computeUpperPart(int localMicros) { - const int DAYS_IN_4_YEARS = 4 * 365 + 1; - const int DAYS_IN_100_YEARS = 25 * DAYS_IN_4_YEARS - 1; - const int DAYS_IN_400_YEARS = 4 * DAYS_IN_100_YEARS + 1; - const int DAYS_1970_TO_2000 = 30 * 365 + 7; - const int DAYS_OFFSET = - 1000 * DAYS_IN_400_YEARS + 5 * DAYS_IN_400_YEARS - DAYS_1970_TO_2000; - const int YEARS_OFFSET = 400000; - - int resultYear = 0; - int resultMonth = 0; - int resultDay = 0; - - // Always round down. - final int daysSince1970 = - _flooredDivision(localMicros, Duration.microsecondsPerDay); - int days = daysSince1970; - days += DAYS_OFFSET; - resultYear = 400 * (days ~/ DAYS_IN_400_YEARS) - YEARS_OFFSET; - days = unsafeCast(days.remainder(DAYS_IN_400_YEARS)); - days--; - int yd1 = days ~/ DAYS_IN_100_YEARS; - days = unsafeCast(days.remainder(DAYS_IN_100_YEARS)); - resultYear += 100 * yd1; - days++; - int yd2 = days ~/ DAYS_IN_4_YEARS; - days = unsafeCast(days.remainder(DAYS_IN_4_YEARS)); - resultYear += 4 * yd2; - days--; - int yd3 = days ~/ 365; - days = unsafeCast(days.remainder(365)); - resultYear += yd3; - - bool isLeap = (yd1 == 0 || yd2 != 0) && yd3 == 0; - if (isLeap) days++; - - List daysUntilMonth = _DAYS_UNTIL_MONTH[isLeap ? 1 : 0]; - for (resultMonth = 12; - daysUntilMonth[resultMonth - 1] > days; - resultMonth--) { - // Do nothing. - } - resultDay = days - daysUntilMonth[resultMonth - 1] + 1; - - int resultMicrosecond = localMicros % Duration.microsecondsPerMillisecond; - int resultMillisecond = - _flooredDivision(localMicros, Duration.microsecondsPerMillisecond) % - Duration.millisecondsPerSecond; - int resultSecond = - _flooredDivision(localMicros, Duration.microsecondsPerSecond) % - Duration.secondsPerMinute; - - int resultMinute = - _flooredDivision(localMicros, Duration.microsecondsPerMinute); - resultMinute %= Duration.minutesPerHour; - - int resultHour = - _flooredDivision(localMicros, Duration.microsecondsPerHour); - resultHour %= Duration.hoursPerDay; - - // In accordance with ISO 8601 a week - // starts with Monday. Monday has the value 1 up to Sunday with 7. - // 1970-1-1 was a Thursday. - int resultWeekday = ((daysSince1970 + DateTime.thursday - DateTime.monday) % - DateTime.daysPerWeek) + - DateTime.monday; - - List list = new List.filled(_YEAR_INDEX + 1, 0); - list[_MICROSECOND_INDEX] = resultMicrosecond; - list[_MILLISECOND_INDEX] = resultMillisecond; - list[_SECOND_INDEX] = resultSecond; - list[_MINUTE_INDEX] = resultMinute; - list[_HOUR_INDEX] = resultHour; - list[_DAY_INDEX] = resultDay; - list[_WEEKDAY_INDEX] = resultWeekday; - list[_MONTH_INDEX] = resultMonth; - list[_YEAR_INDEX] = resultYear; - return list; - } - - get _parts { - return __parts ??= _computeUpperPart(_localDateInUtcMicros); - } - - @patch - DateTime add(Duration duration) { - return new DateTime._withValue(_value + duration.inMicroseconds, - isUtc: isUtc); - } - - @patch - DateTime subtract(Duration duration) { - return new DateTime._withValue(_value - duration.inMicroseconds, - isUtc: isUtc); - } - - @patch - Duration difference(DateTime other) { - return new Duration(microseconds: _value - other._value); - } - - @patch - int get millisecondsSinceEpoch => - _value ~/ Duration.microsecondsPerMillisecond; - - @patch - int get microsecondsSinceEpoch => _value; - - @patch - int get microsecond => _parts[_MICROSECOND_INDEX]; - - @patch - int get millisecond => _parts[_MILLISECOND_INDEX]; - - @patch - int get second => _parts[_SECOND_INDEX]; - - @patch - int get minute => _parts[_MINUTE_INDEX]; - - @patch - int get hour => _parts[_HOUR_INDEX]; - - @patch - int get day => _parts[_DAY_INDEX]; - - @patch - int get weekday => _parts[_WEEKDAY_INDEX]; - - @patch - int get month => _parts[_MONTH_INDEX]; - - @patch - int get year => _parts[_YEAR_INDEX]; - - /** - * Returns the amount of microseconds in UTC that represent the same values - * as [this]. - * - * Say `t` is the result of this function, then - * * `this.year == new DateTime.fromMicrosecondsSinceEpoch(t, true).year`, - * * `this.month == new DateTime.fromMicrosecondsSinceEpoch(t, true).month`, - * * `this.day == new DateTime.fromMicrosecondsSinceEpoch(t, true).day`, - * * `this.hour == new DateTime.fromMicrosecondsSinceEpoch(t, true).hour`, - * * ... - * - * Daylight savings is computed as if the date was computed in [1970..2037]. - * If [this] lies outside this range then it is a year with similar - * properties (leap year, weekdays) is used instead. - */ - int get _localDateInUtcMicros { - int micros = _value; - if (isUtc) return micros; - int offset = - _timeZoneOffsetInSeconds(micros) * Duration.microsecondsPerSecond; - return micros + offset; - } - - static int _flooredDivision(int a, int b) { - return (a - (a < 0 ? b - 1 : 0)) ~/ b; - } - - // Returns the days since 1970 for the start of the given [year]. - // [year] may be before epoch. - static int _dayFromYear(int year) { - return 365 * (year - 1970) + - _flooredDivision(year - 1969, 4) - - _flooredDivision(year - 1901, 100) + - _flooredDivision(year - 1601, 400); - } - - static bool _isLeapYear(y) { - // (y % 16 == 0) matches multiples of 400, and is faster than % 400. - return (y % 4 == 0) && ((y % 16 == 0) || (y % 100 != 0)); - } - - /// Converts the given broken down date to microseconds. - @patch - static int? _brokenDownDateToValue(int year, int month, int day, int hour, - int minute, int second, int millisecond, int microsecond, bool isUtc) { - // Simplify calculations by working with zero-based month. - --month; - // Deal with under and overflow. - if (month >= 12) { - year += month ~/ 12; - month = month % 12; - } else if (month < 0) { - int realMonth = month % 12; - year += (month - realMonth) ~/ 12; - month = realMonth; - } - - // First compute the seconds in UTC, independent of the [isUtc] flag. If - // necessary we will add the time-zone offset later on. - int days = day - 1; - days += _DAYS_UNTIL_MONTH[_isLeapYear(year) ? 1 : 0][month]; - days += _dayFromYear(year); - int microsecondsSinceEpoch = days * Duration.microsecondsPerDay + - hour * Duration.microsecondsPerHour + - minute * Duration.microsecondsPerMinute + - second * Duration.microsecondsPerSecond + - millisecond * Duration.microsecondsPerMillisecond + - microsecond; - - // Since [_timeZoneOffsetInSeconds] will crash if the input is far out of - // the valid range we do a preliminary test that weeds out values that can - // not become valid even with timezone adjustments. - // The timezone adjustment is always less than a day, so adding a security - // margin of one day should be enough. - if (microsecondsSinceEpoch.abs() > - _maxMillisecondsSinceEpoch * 1000 + Duration.microsecondsPerDay) { - return null; - } - - if (!isUtc) { - // Note that we can't literally follow the ECMAScript spec (which this - // code is based on), because it leads to incorrect computations at - // the DST transition points. - // - // See V8's comment here: - // https://github.com/v8/v8/blob/089dd7d2447d6eaf57c8ba6d8f37957f3a269777/src/date.h#L118 - - // We need to remove the local timezone adjustment before asking for the - // correct zone offset. - int adjustment = - _localTimeZoneAdjustmentInSeconds() * Duration.microsecondsPerSecond; - // The adjustment is independent of the actual date and of the daylight - // saving time. It is positive east of the Prime Meridian and negative - // west of it, e.g. -28800 sec for America/Los_Angeles timezone. - - // We remove one hour to ensure that we have the correct offset at - // DST transitioning points. This is a temporary solution and only - // correct in timezones that shift for exactly one hour. - adjustment += Duration.microsecondsPerHour; - int zoneOffset = - _timeZoneOffsetInSeconds(microsecondsSinceEpoch - adjustment); - - // The zoneOffset depends on the actual date and reflects any daylight - // saving time and/or historical deviation relative to UTC time. - // It is positive east of the Prime Meridian and negative west of it, - // e.g. -25200 sec for America/Los_Angeles timezone during DST. - microsecondsSinceEpoch -= zoneOffset * Duration.microsecondsPerSecond; - // The resulting microsecondsSinceEpoch value is therefore the calculated - // UTC value decreased by a (positive if east of GMT) timezone adjustment - // and decreased by typically one hour if DST is in effect. - } - if (microsecondsSinceEpoch.abs() > - _maxMillisecondsSinceEpoch * Duration.microsecondsPerMillisecond) { - return null; - } - return microsecondsSinceEpoch; - } - - static int _weekDay(y) { - // 1/1/1970 was a Thursday. - return (_dayFromYear(y) + 4) % 7; - } - - /** - * Returns a year in the range 2008-2035 matching - * * leap year, and - * * week day of first day. - * - * Leap seconds are ignored. - * Adapted from V8's date implementation. See ECMA 262 - 15.9.1.9. - */ - static int _equivalentYear(int year) { - // Returns year y so that _weekDay(y) == _weekDay(year). - // _weekDay returns the week day (in range 0 - 6). - // 1/1/1956 was a Sunday (i.e. weekday 0). 1956 was a leap-year. - // 1/1/1967 was a Sunday (i.e. weekday 0). - // Without leap years a subsequent year has a week day + 1 (for example - // 1/1/1968 was a Monday). With leap-years it jumps over one week day - // (e.g. 1/1/1957 was a Tuesday). - // After 12 years the weekdays have advanced by 12 days + 3 leap days = - // 15 days. 15 % 7 = 1. So after 12 years the week day has always - // (now independently of leap-years) advanced by one. - // weekDay * 12 gives thus a year starting with the wanted weekDay. - int recentYear = (_isLeapYear(year) ? 1956 : 1967) + (_weekDay(year) * 12); - // Close to the year 2008 the calendar cycles every 4 * 7 years (4 for the - // leap years, 7 for the weekdays). - // Find the year in the range 2008..2037 that is equivalent mod 28. - return 2008 + (recentYear - 2008) % 28; - } - - /** - * Returns the UTC year for the corresponding [secondsSinceEpoch]. - * It is relatively fast for values in the range 0 to year 2098. - * - * Code is adapted from V8. - */ - static int _yearsFromSecondsSinceEpoch(int secondsSinceEpoch) { - const int DAYS_IN_4_YEARS = 4 * 365 + 1; - const int DAYS_IN_100_YEARS = 25 * DAYS_IN_4_YEARS - 1; - const int DAYS_YEAR_2098 = DAYS_IN_100_YEARS + 6 * DAYS_IN_4_YEARS; - - int days = secondsSinceEpoch ~/ Duration.secondsPerDay; - if (days > 0 && days < DAYS_YEAR_2098) { - // According to V8 this fast case works for dates from 1970 to 2099. - return 1970 + (4 * days + 2) ~/ DAYS_IN_4_YEARS; - } - int micros = secondsSinceEpoch * Duration.microsecondsPerSecond; - return _computeUpperPart(micros)[_YEAR_INDEX]; - } - - /** - * Returns a date in seconds that is equivalent to the given - * date in microseconds [microsecondsSinceEpoch]. An equivalent - * date has the same fields (`month`, `day`, etc.) as the given - * date, but the `year` is in the range [1901..2038]. - * - * * The time since the beginning of the year is the same. - * * If the given date is in a leap year then the returned - * seconds are in a leap year, too. - * * The week day of given date is the same as the one for the - * returned date. - */ - static int _equivalentSeconds(int microsecondsSinceEpoch) { - const int CUT_OFF_SECONDS = 0x7FFFFFFF; - - int secondsSinceEpoch = _flooredDivision( - microsecondsSinceEpoch, Duration.microsecondsPerSecond); - - if (secondsSinceEpoch.abs() > CUT_OFF_SECONDS) { - int year = _yearsFromSecondsSinceEpoch(secondsSinceEpoch); - int days = _dayFromYear(year); - int equivalentYear = _equivalentYear(year); - int equivalentDays = _dayFromYear(equivalentYear); - int diffDays = equivalentDays - days; - secondsSinceEpoch += diffDays * Duration.secondsPerDay; - } - return secondsSinceEpoch; - } - - static int _timeZoneOffsetInSeconds(int microsecondsSinceEpoch) { - int equivalentSeconds = _equivalentSeconds(microsecondsSinceEpoch); - return _timeZoneOffsetInSecondsForClampedSeconds(equivalentSeconds); - } - - static String _timeZoneName(int microsecondsSinceEpoch) { - int equivalentSeconds = _equivalentSeconds(microsecondsSinceEpoch); - return _timeZoneNameForClampedSeconds(equivalentSeconds); - } -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/deferred_load_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/deferred_load_patch.dart deleted file mode 100644 index 3f3cf12cea8..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/deferred_load_patch.dart +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) 2013, 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. - -// part of "async_patch.dart"; - -final Set _loadedLibraries = new Set(); - -@patch -class DeferredLibrary { - @patch - Future load() { - // Dummy implementation that should eventually be replaced by real - // implementation. - Future future = new Future.value(null); - _loadedLibraries.add(libraryName); - return future; - } -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/developer.dart b/sdk_nnbd/lib/_internal/vm/lib/developer.dart deleted file mode 100644 index d9c87a87f58..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/developer.dart +++ /dev/null @@ -1,169 +0,0 @@ -// 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. - -/// Note: the VM concatenates all patch files into a single patch file. This -/// file is the first patch in "dart:developer" which contains all the imports -/// used by patches of that library. We plan to change this when we have a -/// shared front end and simply use parts. - -import "dart:_internal" show patch; - -import "dart:async" show Future, Zone; - -import "dart:isolate" show SendPort; - -/// These are the additional parts of this patch library: -// part "profiler.dart" -// part "timeline.dart" - -@patch -bool debugger({bool when: true, String? message}) native "Developer_debugger"; - -@patch -Object inspect(Object object) native "Developer_inspect"; - -@patch -void log(String message, - {DateTime? time, - int? sequenceNumber, - int level: 0, - String name: '', - Zone? zone, - Object? error, - StackTrace? stackTrace}) { - if (message is! String) { - throw new ArgumentError.value(message, "message", "Must be a String"); - } - time ??= new DateTime.now(); - if (time is! DateTime) { - throw new ArgumentError.value(time, "time", "Must be a DateTime"); - } - if (sequenceNumber == null) { - sequenceNumber = _nextSequenceNumber++; - } else { - _nextSequenceNumber = sequenceNumber + 1; - } - _log(message, time.millisecondsSinceEpoch, sequenceNumber, level, name, zone, - error, stackTrace); -} - -int _nextSequenceNumber = 0; - -_log(String message, int timestamp, int sequenceNumber, int level, String name, - Zone? zone, Object? error, StackTrace? stackTrace) native "Developer_log"; - -@patch -void _postEvent(String eventKind, String eventData) - native "Developer_postEvent"; - -@patch -ServiceExtensionHandler? _lookupExtension(String method) - native "Developer_lookupExtension"; - -@patch -_registerExtension(String method, ServiceExtensionHandler handler) - native "Developer_registerExtension"; - -// This code is only invoked when there is no other Dart code on the stack. -@pragma("vm:entry-point", !const bool.fromEnvironment("dart.vm.product")) -_runExtension( - ServiceExtensionHandler handler, - String method, - List parameterKeys, - List parameterValues, - SendPort replyPort, - Object id, - bool trace_service) { - var parameters = {}; - for (var i = 0; i < parameterKeys.length; i++) { - parameters[parameterKeys[i]] = parameterValues[i]; - } - var response; - try { - response = handler(method, parameters); - } catch (e, st) { - var errorDetails = (st == null) ? '$e' : '$e\n$st'; - response = new ServiceExtensionResponse.error( - ServiceExtensionResponse.kExtensionError, errorDetails); - _postResponse(replyPort, id, response, trace_service); - return; - } - if (response is! Future) { - response = new ServiceExtensionResponse.error( - ServiceExtensionResponse.kExtensionError, - "Extension handler must return a Future"); - _postResponse(replyPort, id, response, trace_service); - return; - } - response.catchError((e, st) { - // Catch any errors eagerly and wrap them in a ServiceExtensionResponse. - var errorDetails = (st == null) ? '$e' : '$e\n$st'; - return new ServiceExtensionResponse.error( - ServiceExtensionResponse.kExtensionError, errorDetails); - }).then((response) { - // Post the valid response or the wrapped error after verifying that - // the response is a ServiceExtensionResponse. - if (response is! ServiceExtensionResponse) { - response = new ServiceExtensionResponse.error( - ServiceExtensionResponse.kExtensionError, - "Extension handler must complete to a ServiceExtensionResponse"); - } - _postResponse(replyPort, id, response, trace_service); - }).catchError((e, st) { - // We do not expect any errors to occur in the .then or .catchError blocks - // but, suppress them just in case. - }); -} - -// This code is only invoked by _runExtension. -_postResponse(SendPort replyPort, Object id, ServiceExtensionResponse response, - bool trace_service) { - assert(replyPort != null); - if (id == null) { - if (trace_service) { - print("vm-service: posting no response for request"); - } - // No id -> no response. - replyPort.send(null); - return; - } - assert(id != null); - StringBuffer sb = new StringBuffer(); - sb.write('{"jsonrpc":"2.0",'); - if (response.isError()) { - if (trace_service) { - print("vm-service: posting error response for request $id"); - } - sb.write('"error":'); - } else { - if (trace_service) { - print("vm-service: posting response for request $id"); - } - sb.write('"result":'); - } - sb.write('${response._toString()},'); - if (id is String) { - sb.write('"id":"$id"}'); - } else { - sb.write('"id":$id}'); - } - replyPort.send(sb.toString()); -} - -@patch -int _getServiceMajorVersion() native "Developer_getServiceMajorVersion"; - -@patch -int _getServiceMinorVersion() native "Developer_getServiceMinorVersion"; - -@patch -void _getServerInfo(SendPort sendPort) native "Developer_getServerInfo"; - -@patch -void _webServerControl(SendPort sendPort, bool enable) - native "Developer_webServerControl"; - -@patch -String _getIsolateIDFromSendPort(SendPort sendPort) - native "Developer_getIsolateIDFromSendPort"; diff --git a/sdk_nnbd/lib/_internal/vm/lib/double.dart b/sdk_nnbd/lib/_internal/vm/lib/double.dart deleted file mode 100644 index 83b32623c45..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/double.dart +++ /dev/null @@ -1,360 +0,0 @@ -// Copyright (c) 2012, 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. - -// part of "core_patch.dart"; - -@pragma("vm:entry-point") -class _Double implements double { - @pragma("vm:exact-result-type", _Double) - factory _Double.fromInteger(int value) native "Double_doubleFromInteger"; - - int get hashCode native "Double_hashCode"; - int get _identityHashCode native "Double_hashCode"; - - @pragma("vm:exact-result-type", _Double) - @pragma("vm:never-inline") - double operator +(num other) { - return _add(other.toDouble()); - } - - @pragma("vm:exact-result-type", _Double) - double _add(double other) native "Double_add"; - - @pragma("vm:exact-result-type", _Double) - @pragma("vm:never-inline") - double operator -(num other) { - return _sub(other.toDouble()); - } - - @pragma("vm:exact-result-type", _Double) - double _sub(double other) native "Double_sub"; - - @pragma("vm:exact-result-type", _Double) - @pragma("vm:never-inline") - double operator *(num other) { - return _mul(other.toDouble()); - } - - @pragma("vm:exact-result-type", _Double) - double _mul(double other) native "Double_mul"; - - int operator ~/(num other) { - return _trunc_div(other.toDouble()); - } - - @pragma("vm:non-nullable-result-type") - int _trunc_div(double other) native "Double_trunc_div"; - - @pragma("vm:exact-result-type", _Double) - @pragma("vm:never-inline") - double operator /(num other) { - return _div(other.toDouble()); - } - - @pragma("vm:exact-result-type", _Double) - double _div(double other) native "Double_div"; - - double operator %(num other) { - return _modulo(other.toDouble()); - } - - @pragma("vm:exact-result-type", _Double) - double _modulo(double other) native "Double_modulo"; - - double remainder(num other) { - return _remainder(other.toDouble()); - } - - double _remainder(double other) native "Double_remainder"; - - @pragma("vm:exact-result-type", _Double) - double operator -() native "Double_flipSignBit"; - - @pragma("vm:exact-result-type", bool) - @pragma("vm:never-inline") - bool operator ==(Object other) { - return (other is num) && _equal(other.toDouble()); - } - - @pragma("vm:exact-result-type", bool) - bool _equal(double other) native "Double_equal"; - @pragma("vm:exact-result-type", bool) - bool _equalToInteger(int other) native "Double_equalToInteger"; - - @pragma("vm:exact-result-type", bool) - @pragma("vm:never-inline") - bool operator <(num other) { - return other > this; - } - - @pragma("vm:exact-result-type", bool) - @pragma("vm:never-inline") - bool operator >(num other) { - return _greaterThan(other.toDouble()); - } - - @pragma("vm:exact-result-type", bool) - bool _greaterThan(double other) native "Double_greaterThan"; - - @pragma("vm:exact-result-type", bool) - @pragma("vm:never-inline") - bool operator >=(num other) { - return (this == other) || (this > other); - } - - @pragma("vm:exact-result-type", bool) - @pragma("vm:never-inline") - bool operator <=(num other) { - return (this == other) || (this < other); - } - - double _addFromInteger(int other) { - return new _Double.fromInteger(other)._add(this); - } - - double _subFromInteger(int other) { - return new _Double.fromInteger(other)._sub(this); - } - - @pragma("vm:exact-result-type", "dart:core#_Double") - double _mulFromInteger(int other) { - return new _Double.fromInteger(other)._mul(this); - } - - int _truncDivFromInteger(int other) { - return new _Double.fromInteger(other)._trunc_div(this); - } - - double _moduloFromInteger(int other) { - return new _Double.fromInteger(other)._modulo(this); - } - - double _remainderFromInteger(int other) { - return new _Double.fromInteger(other)._remainder(this); - } - - bool _greaterThanFromInteger(int other) - native "Double_greaterThanFromInteger"; - - @pragma("vm:exact-result-type", bool) - bool get isNegative native "Double_getIsNegative"; - @pragma("vm:exact-result-type", bool) - bool get isInfinite native "Double_getIsInfinite"; - @pragma("vm:exact-result-type", bool) - bool get isNaN native "Double_getIsNaN"; - bool get isFinite => !isInfinite && !isNaN; // Can be optimized. - - double abs() { - // Handle negative 0.0. - if (this == 0.0) return 0.0; - return this < 0.0 ? -this : this; - } - - double get sign { - if (this > 0.0) return 1.0; - if (this < 0.0) return -1.0; - return this; // +/-0.0 or NaN. - } - - int round() => roundToDouble().toInt(); - int floor() => floorToDouble().toInt(); - int ceil() => ceilToDouble().toInt(); - int truncate() => truncateToDouble().toInt(); - - @pragma("vm:exact-result-type", _Double) - double roundToDouble() native "Double_round"; - @pragma("vm:exact-result-type", _Double) - double floorToDouble() native "Double_floor"; - @pragma("vm:exact-result-type", _Double) - double ceilToDouble() native "Double_ceil"; - @pragma("vm:exact-result-type", _Double) - double truncateToDouble() native "Double_truncate"; - - num clamp(num lowerLimit, num upperLimit) { - // TODO: Remove these null checks once all code is opted into strong nonnullable mode. - if (lowerLimit == null) { - throw new ArgumentError.notNull("lowerLimit"); - } - if (upperLimit == null) { - throw new ArgumentError.notNull("upperLimit"); - } - if (lowerLimit.compareTo(upperLimit) > 0) { - throw new ArgumentError(lowerLimit); - } - if (lowerLimit.isNaN) return lowerLimit; - if (this.compareTo(lowerLimit) < 0) return lowerLimit; - if (this.compareTo(upperLimit) > 0) return upperLimit; - return this; - } - - @pragma("vm:non-nullable-result-type") - int toInt() native "Double_toInt"; - - double toDouble() { - return this; - } - - static const int CACHE_SIZE_LOG2 = 3; - static const int CACHE_LENGTH = 1 << (CACHE_SIZE_LOG2 + 1); - static const int CACHE_MASK = CACHE_LENGTH - 1; - // Each key (double) followed by its toString result. - static final List _cache = new List.filled(CACHE_LENGTH, null); - static int _cacheEvictIndex = 0; - - String _toString() native "Double_toString"; - - String toString() { - // TODO(koda): Consider starting at most recently inserted. - for (int i = 0; i < CACHE_LENGTH; i += 2) { - // Need 'identical' to handle negative zero, etc. - if (identical(_cache[i], this)) { - return _cache[i + 1]; - } - } - // TODO(koda): Consider optimizing all small integral values. - if (identical(0.0, this)) { - return "0.0"; - } - String result = _toString(); - // Replace the least recently inserted entry. - _cache[_cacheEvictIndex] = this; - _cache[_cacheEvictIndex + 1] = result; - _cacheEvictIndex = (_cacheEvictIndex + 2) & CACHE_MASK; - return result; - } - - String toStringAsFixed(int fractionDigits) { - // See ECMAScript-262, 15.7.4.5 for details. - - // TODO: Remove these null checks once all code is opted into strong nonnullable mode. - if (fractionDigits == null) { - throw new ArgumentError.notNull("fractionDigits"); - } - - // Step 2. - if (fractionDigits < 0 || fractionDigits > 20) { - throw new RangeError.range(fractionDigits, 0, 20, "fractionDigits"); - } - - // Step 3. - double x = this; - - // Step 4. - if (isNaN) return "NaN"; - - // Step 5 and 6 skipped. Will be dealt with by native function. - - // Step 7. - if (x >= 1e21 || x <= -1e21) { - return x.toString(); - } - - return _toStringAsFixed(fractionDigits); - } - - String _toStringAsFixed(int fractionDigits) native "Double_toStringAsFixed"; - - String toStringAsExponential([int? fractionDigits]) { - // See ECMAScript-262, 15.7.4.6 for details. - - // The EcmaScript specification checks for NaN and Infinity before looking - // at the fractionDigits. In Dart we are consistent with toStringAsFixed and - // look at the fractionDigits first. - - // Step 7. - if (fractionDigits != null) { - if (fractionDigits < 0 || fractionDigits > 20) { - throw new RangeError.range(fractionDigits, 0, 20, "fractionDigits"); - } - } - - if (isNaN) return "NaN"; - if (this == double.infinity) return "Infinity"; - if (this == -double.infinity) return "-Infinity"; - - // The dart function prints the shortest representation when fractionDigits - // equals null. The native function wants -1 instead. - fractionDigits = (fractionDigits == null) ? -1 : fractionDigits; - - return _toStringAsExponential(fractionDigits); - } - - String _toStringAsExponential(int fractionDigits) - native "Double_toStringAsExponential"; - - String toStringAsPrecision(int precision) { - // See ECMAScript-262, 15.7.4.7 for details. - - if (precision == null) { - throw new ArgumentError.notNull("precision"); - } - // The EcmaScript specification checks for NaN and Infinity before looking - // at the fractionDigits. In Dart we are consistent with toStringAsFixed and - // look at the fractionDigits first. - - // Step 8. - if (precision < 1 || precision > 21) { - throw new RangeError.range(precision, 1, 21, "precision"); - } - - if (isNaN) return "NaN"; - if (this == double.infinity) return "Infinity"; - if (this == -double.infinity) return "-Infinity"; - - return _toStringAsPrecision(precision); - } - - String _toStringAsPrecision(int fractionDigits) - native "Double_toStringAsPrecision"; - - // Order is: NaN > Infinity > ... > 0.0 > -0.0 > ... > -Infinity. - int compareTo(num other) { - const int EQUAL = 0, LESS = -1, GREATER = 1; - if (this < other) { - return LESS; - } else if (this > other) { - return GREATER; - } else if (this == other) { - if (this == 0.0) { - bool thisIsNegative = isNegative; - bool otherIsNegative = other.isNegative; - if (thisIsNegative == otherIsNegative) { - return EQUAL; - } - return thisIsNegative ? LESS : GREATER; - } else if (other is int) { - // Compare as integers as it is more precise if the integer value is - // outside of MIN_EXACT_INT_TO_DOUBLE..MAX_EXACT_INT_TO_DOUBLE range. - const int MAX_EXACT_INT_TO_DOUBLE = 9007199254740992; // 2^53. - const int MIN_EXACT_INT_TO_DOUBLE = -MAX_EXACT_INT_TO_DOUBLE; - if ((MIN_EXACT_INT_TO_DOUBLE <= other) && - (other <= MAX_EXACT_INT_TO_DOUBLE)) { - return EQUAL; - } - const bool limitIntsTo64Bits = ((1 << 64) == 0); - if (limitIntsTo64Bits) { - // With integers limited to 64 bits, double.toInt() clamps - // double value to fit into the MIN_INT64..MAX_INT64 range. - // MAX_INT64 is not precisely representable as double, so - // integers near MAX_INT64 compare as equal to (MAX_INT64 + 1) when - // represented as doubles. - // There is no similar problem with MIN_INT64 as it is precisely - // representable as double. - const double maxInt64Plus1AsDouble = 9223372036854775808.0; - if (this >= maxInt64Plus1AsDouble) { - return GREATER; - } - } - return toInt().compareTo(other); - } else { - return EQUAL; - } - } else if (isNaN) { - return other.isNaN ? EQUAL : GREATER; - } else { - // Other is NaN. - return LESS; - } - } -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/double_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/double_patch.dart deleted file mode 100644 index e6ccf5ca4c4..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/double_patch.dart +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (c) 2012, 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. - -// part of "core_patch.dart"; - -// VM implementation of double. - -@patch -class double { - static double? _nativeParse(String str, int start, int end) - native "Double_parse"; - - static double? _tryParseDouble(String str, int start, int end) { - assert(start < end); - const int _DOT = 0x2e; // '.' - const int _ZERO = 0x30; // '0' - const int _MINUS = 0x2d; // '-' - const int _N = 0x4e; // 'N' - const int _a = 0x61; // 'a' - const int _I = 0x49; // 'I' - const int _e = 0x65; // 'e' - int exponent = 0; - // Set to non-zero if a digit is seen. Avoids accepting ".". - bool digitsSeen = false; - // Added to exponent for each digit. Set to -1 when seeing '.'. - int exponentDelta = 0; - double doubleValue = 0.0; - double sign = 1.0; - int firstChar = str.codeUnitAt(start); - if (firstChar == _MINUS) { - sign = -1.0; - start++; - if (start == end) return null; - firstChar = str.codeUnitAt(start); - } - if (firstChar == _I) { - if (end == start + 8 && str.startsWith("nfinity", start + 1)) { - return sign * double.infinity; - } - return null; - } - if (firstChar == _N) { - if (end == start + 3 && - str.codeUnitAt(start + 1) == _a && - str.codeUnitAt(start + 2) == _N) { - return double.nan; - } - return null; - } - - int firstDigit = firstChar ^ _ZERO; - if (firstDigit <= 9) { - start++; - doubleValue = firstDigit.toDouble(); - digitsSeen = true; - } - for (int i = start; i < end; i++) { - int c = str.codeUnitAt(i); - int digit = c ^ _ZERO; // '0'-'9' characters are now 0-9 integers. - if (digit <= 9) { - doubleValue = 10.0 * doubleValue + digit; - // Doubles at or above this value (2**53) might have lost precission. - const double MAX_EXACT_DOUBLE = 9007199254740992.0; - if (doubleValue >= MAX_EXACT_DOUBLE) return null; - exponent += exponentDelta; - digitsSeen = true; - } else if (c == _DOT && exponentDelta == 0) { - exponentDelta = -1; - } else if ((c | 0x20) == _e) { - i++; - if (i == end) return null; - // int._tryParseSmi treats its end argument as inclusive. - final int? expPart = int._tryParseSmi(str, i, end - 1); - if (expPart == null) return null; - exponent += expPart; - break; - } else { - return null; - } - } - if (!digitsSeen) return null; // No digits. - if (exponent == 0) return sign * doubleValue; - const P10 = POWERS_OF_TEN; // From shared library - if (exponent < 0) { - int negExponent = -exponent; - if (negExponent >= P10.length) return null; - return sign * (doubleValue / P10[negExponent]); - } - if (exponent >= P10.length) return null; - return sign * (doubleValue * P10[exponent]); - } - - static double? _parse(String str) { - int len = str.length; - final strbase = str as _StringBase; - int start = strbase._firstNonWhitespace(); - if (start == len) return null; // All whitespace. - int end = strbase._lastNonWhitespace() + 1; - assert(start < end); - var result = _tryParseDouble(str, start, end); - if (result != null) return result; - return _nativeParse(str, start, end); - } - - @patch - static double parse(String source, - [@deprecated double onError(String source)?]) { - var result = _parse(source); - if (result == null) { - if (onError == null) throw new FormatException("Invalid double", source); - return onError(source); - } - return result; - } - - @patch - static double? tryParse(String source) => _parse(source); -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/empty_source.dart b/sdk_nnbd/lib/_internal/vm/lib/empty_source.dart deleted file mode 100644 index 95e028f13ca..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/empty_source.dart +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright (c) 2012, 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. - -// THIS FILE INTENTIONALLY LEFT BLANK. diff --git a/sdk_nnbd/lib/_internal/vm/lib/errors_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/errors_patch.dart deleted file mode 100644 index c4b91f205e3..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/errors_patch.dart +++ /dev/null @@ -1,503 +0,0 @@ -// Copyright (c) 2012, 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. - -// part of "core_patch.dart"; - -@patch -class Error { - @patch - static String _objectToString(Object object) { - return Object._toString(object); - } - - @patch - static String _stringToSafeString(String string) { - return json.encode(string); - } - - @patch - StackTrace? get stackTrace => _stackTrace; - - @pragma("vm:entry-point") - StackTrace? _stackTrace; -} - -class _AssertionError extends Error implements AssertionError { - @pragma("vm:entry-point") - _AssertionError._create( - this._failedAssertion, this._url, this._line, this._column, this.message); - - // AssertionError_throwNew in errors.cc fishes the assertion source code - // out of the script. It expects a Dart stack frame from class - // _AssertionError. Thus we need a Dart stub that calls the native code. - @pragma("vm:entry-point", "call") - static _throwNew(int assertionStart, int assertionEnd, Object? message) { - _doThrowNew(assertionStart, assertionEnd, message); - } - - static _doThrowNew(int assertionStart, int assertionEnd, Object? message) - native "AssertionError_throwNew"; - - @pragma("vm:entry-point", "call") - static _evaluateAssertion(condition) { - if (identical(condition, true) || identical(condition, false)) { - return condition; - } - if (condition is _Closure) { - return (condition as dynamic)(); - } - if (condition is Function) { - condition = condition(); - } - return condition; - } - - String get _messageString { - final msg = message; - if (msg == null) return "is not true."; - if (msg is String) return msg; - return Error.safeToString(msg); - } - - String toString() { - if (_url == null) { - if (message == null) return _failedAssertion.trim(); - return "'${_failedAssertion.trim()}': $_messageString"; - } - var columnInfo = ""; - if (_column > 0) { - // Only add column information if it is valid. - columnInfo = " pos $_column"; - } - return "'$_url': Failed assertion: line $_line$columnInfo: " - "'$_failedAssertion': $_messageString"; - } - - final String _failedAssertion; - final String _url; - final int _line; - final int _column; - final Object? message; -} - -class _TypeError extends Error implements TypeError, CastError { - @pragma("vm:entry-point") - _TypeError._create(this._url, this._line, this._column, this._message); - - @pragma("vm:entry-point", "call") - static _throwNew(int location, Object srcValue, _Type dstType, String dstName) - native "TypeError_throwNew"; - - String toString() => _message; - - final String _url; - final int _line; - final int _column; - final String _message; -} - -class _CastError extends Error implements CastError, TypeError { - @pragma("vm:entry-point") - _CastError._create(this._url, this._line, this._column, this._errorMsg); - - // A CastError is allocated by TypeError._throwNew() when dstName equals - // Symbols::InTypeCast(). - - String toString() => _errorMsg; - - // Fields _url, _line, and _column are only used for debugging purposes. - final String _url; - final int _line; - final int _column; - final String _errorMsg; -} - -@patch -class FallThroughError { - @patch - @pragma("vm:entry-point") - FallThroughError._create(this._url, this._line); - - static _throwNew(int caseClausePos) native "FallThroughError_throwNew"; - - @patch - String toString() { - return "'$_url': Switch case fall-through at line $_line."; - } - - // These new fields cannot be declared final, because a constructor exists - // in the original version of this patched class. - String? _url; - int _line = 0; -} - -class _InternalError { - @pragma("vm:entry-point") - const _InternalError(this._msg); - String toString() => "InternalError: '${_msg}'"; - final String _msg; -} - -@patch -@pragma("vm:entry-point") -class UnsupportedError { - static _throwNew(String msg) { - throw new UnsupportedError(msg); - } -} - -@patch -class CyclicInitializationError { - static _throwNew(String variableName) { - throw new CyclicInitializationError(variableName); - } -} - -@patch -class AbstractClassInstantiationError { - @pragma("vm:entry-point") - AbstractClassInstantiationError._create( - this._className, this._url, this._line); - - static _throwNew(int caseClausePos, String className) - native "AbstractClassInstantiationError_throwNew"; - - @patch - String toString() { - return "Cannot instantiate abstract class $_className: " - "_url '$_url' line $_line"; - } - - // These new fields cannot be declared final, because a constructor exists - // in the original version of this patched class. - String? _url; - int _line = 0; -} - -@patch -class NoSuchMethodError { - final Object? _receiver; - final Invocation _invocation; - - @patch - NoSuchMethodError.withInvocation(Object? receiver, Invocation invocation) - : _receiver = receiver, - _invocation = invocation; - - static void _throwNewInvocation(Object? receiver, Invocation invocation) { - throw new NoSuchMethodError.withInvocation(receiver, invocation); - } - - // The compiler emits a call to _throwNew when it cannot resolve a static - // method at compile time. The receiver is actually the literal class of the - // unresolved method. - @pragma("vm:entry-point", "call") - static void _throwNew( - Object receiver, - String memberName, - int invocationType, - int typeArgumentsLength, - Object? typeArguments, - List? arguments, - List? argumentNames) { - throw new NoSuchMethodError._withType(receiver, memberName, invocationType, - typeArgumentsLength, typeArguments, arguments, argumentNames); - } - - // Deprecated constructor. - @patch - NoSuchMethodError(this._receiver, Symbol memberName, - List? positionalArguments, Map? namedArguments, - [List? existingArgumentNames = null]) // existingArgumentNames ignored. - : this._invocation = new _InvocationMirror._withType( - memberName, - _InvocationMirror._UNINITIALIZED, - null, // Type arguments not supported in deprecated constructor. - positionalArguments, - namedArguments); - - // Helper to build a map of named arguments. - static Map _NamedArgumentsMap( - List arguments, List argumentNames) { - Map namedArguments = new Map(); - int numPositionalArguments = arguments.length - argumentNames.length; - for (int i = 0; i < argumentNames.length; i++) { - final argValue = arguments[numPositionalArguments + i]; - namedArguments[new Symbol(argumentNames[i])] = argValue; - } - return namedArguments; - } - - // Constructor called from Exceptions::ThrowByType(kNoSuchMethod) and from - // _throwNew above, taking a TypeArguments object rather than an unpacked list - // of types, as well as a list of all arguments and a list of names, rather - // than a separate list of positional arguments and a map of named arguments. - @pragma("vm:entry-point") - NoSuchMethodError._withType( - this._receiver, - String memberName, - int invocationType, - int typeArgumentsLength, // Needed with all-dynamic (null) typeArguments. - Object? typeArguments, - List? arguments, - List? argumentNames) - : this._invocation = new _InvocationMirror._withType( - new Symbol(memberName), - invocationType, - _InvocationMirror._unpackTypeArguments( - typeArguments, typeArgumentsLength), - argumentNames != null - ? arguments!.sublist(0, arguments.length - argumentNames.length) - : arguments, - argumentNames != null - ? _NamedArgumentsMap(arguments!, argumentNames) - : null); - - static String? _existingMethodSignature(Object? receiver, String methodName, - int invocationType) native "NoSuchMethodError_existingMethodSignature"; - - @patch - String toString() { - final localInvocation = _invocation; - if (localInvocation is _InvocationMirror) { - var internalName = localInvocation.memberName as internal.Symbol; - String memberName = internal.Symbol.computeUnmangledName(internalName); - - var level = (localInvocation._type >> _InvocationMirror._LEVEL_SHIFT) & - _InvocationMirror._LEVEL_MASK; - var kind = localInvocation._type & _InvocationMirror._KIND_MASK; - if (kind == _InvocationMirror._LOCAL_VAR) { - return "NoSuchMethodError: Cannot assign to final variable '$memberName'"; - } - - StringBuffer? typeArgumentsBuf = null; - final typeArguments = localInvocation.typeArguments; - if ((typeArguments != null) && (typeArguments.length > 0)) { - final argsBuf = new StringBuffer(); - argsBuf.write("<"); - for (int i = 0; i < typeArguments.length; i++) { - if (i > 0) { - argsBuf.write(", "); - } - argsBuf.write(Error.safeToString(typeArguments[i])); - } - argsBuf.write(">"); - typeArgumentsBuf = argsBuf; - } - StringBuffer argumentsBuf = new StringBuffer(); - var positionalArguments = localInvocation.positionalArguments; - int argumentCount = 0; - if (positionalArguments != null) { - for (; argumentCount < positionalArguments.length; argumentCount++) { - if (argumentCount > 0) { - argumentsBuf.write(", "); - } - argumentsBuf - .write(Error.safeToString(positionalArguments[argumentCount])); - } - } - var namedArguments = localInvocation.namedArguments; - if (namedArguments != null) { - namedArguments.forEach((Symbol key, var value) { - if (argumentCount > 0) { - argumentsBuf.write(", "); - } - var internalName = key as internal.Symbol; - argumentsBuf - .write(internal.Symbol.computeUnmangledName(internalName)); - argumentsBuf.write(": "); - argumentsBuf.write(Error.safeToString(value)); - argumentCount++; - }); - } - String? existingSig = _existingMethodSignature( - _receiver, memberName, localInvocation._type); - String argsMsg = existingSig != null ? " with matching arguments" : ""; - - String kindBuf = "function"; - if (kind >= 0 && kind < 5) { - kindBuf = (const [ - "method", - "getter", - "setter", - "getter or setter", - "variable" - ])[kind]; - } - - StringBuffer msgBuf = new StringBuffer("NoSuchMethodError: "); - bool isTypeCall = false; - switch (level) { - case _InvocationMirror._DYNAMIC: - { - if (_receiver == null) { - if (existingSig != null) { - msgBuf.writeln("The null object does not have a $kindBuf " - "'$memberName'$argsMsg."); - } else { - msgBuf - .writeln("The $kindBuf '$memberName' was called on null."); - } - } else { - if (_receiver is _Closure) { - msgBuf.writeln("Closure call with mismatched arguments: " - "function '$memberName'"); - } else if (_receiver is _Type && memberName == "call") { - isTypeCall = true; - String name = _receiver.toString(); - msgBuf.writeln("Attempted to use type '$name' as a function. " - "Since types do not define a method 'call', this is not " - "possible. Did you intend to call the $name constructor and " - "forget the 'new' operator?"); - } else { - msgBuf - .writeln("Class '${_receiver.runtimeType}' has no instance " - "$kindBuf '$memberName'$argsMsg."); - } - } - break; - } - case _InvocationMirror._SUPER: - { - msgBuf - .writeln("Super class of class '${_receiver.runtimeType}' has " - "no instance $kindBuf '$memberName'$argsMsg."); - memberName = "super.$memberName"; - break; - } - case _InvocationMirror._STATIC: - { - msgBuf.writeln("No static $kindBuf '$memberName'$argsMsg " - "declared in class '$_receiver'."); - break; - } - case _InvocationMirror._CONSTRUCTOR: - { - msgBuf.writeln("No constructor '$memberName'$argsMsg declared " - "in class '$_receiver'."); - memberName = "new $memberName"; - break; - } - case _InvocationMirror._TOP_LEVEL: - { - msgBuf.writeln("No top-level $kindBuf '$memberName'$argsMsg " - "declared."); - break; - } - } - - if (level == _InvocationMirror._TOP_LEVEL) { - msgBuf.writeln("Receiver: top-level"); - } else { - msgBuf.writeln("Receiver: ${Error.safeToString(_receiver)}"); - } - - if (kind == _InvocationMirror._METHOD) { - String m = isTypeCall ? "$_receiver" : "$memberName"; - msgBuf.write("Tried calling: $m"); - if (typeArgumentsBuf != null) { - msgBuf.write(typeArgumentsBuf); - } - msgBuf.write("($argumentsBuf)"); - } else if (argumentCount == 0) { - msgBuf.write("Tried calling: $memberName"); - } else if (kind == _InvocationMirror._SETTER) { - msgBuf.write("Tried calling: $memberName$argumentsBuf"); - } else { - msgBuf.write("Tried calling: $memberName = $argumentsBuf"); - } - - if (existingSig != null) { - msgBuf.write("\nFound: $memberName$existingSig"); - } - - return msgBuf.toString(); - } - return _toStringPlain(_receiver, localInvocation); - } - - /// Creates a string representation of an invocation. - /// - /// Used for situations where there is no extra information available - /// about the failed invocation than the [Invocation] object and receiver, - /// which includes errors created using [NoSuchMethodError.withInvocation]. - static String _toStringPlain(Object? receiver, Invocation invocation) { - var name = _symbolToString(invocation.memberName); - var receiverType = "${receiver.runtimeType}"; - if (invocation.isAccessor) { - return "NoSuchMethodError: $receiverType has no $name " - "${invocation.isGetter ? "getter" : "setter"}"; - } - var buffer = StringBuffer("NoSuchMethodError")..write(": "); - buffer.write("$receiverType has no $name method accepting arguments "); - var separator = ""; - if (invocation.typeArguments.isNotEmpty) { - buffer.write("<"); - for (var type in invocation.typeArguments) { - buffer..write(separator)..write("_"); - separator = ", "; - } - buffer.write(">"); - separator = ""; - } - buffer.write("("); - for (var argument in invocation.positionalArguments) { - buffer..write(separator)..write("_"); - separator = ", "; - } - if (invocation.namedArguments.isNotEmpty) { - buffer..write(separator)..write("{"); - separator = ""; - for (var name in invocation.namedArguments.keys) { - buffer..write(separator)..write(_symbolToString(name))..write(": _"); - separator = ","; - } - buffer.write("}"); - } - buffer.write(")"); - return buffer.toString(); - } - - static String _symbolToString(Symbol symbol) { - if (symbol is internal.Symbol) { - return internal.Symbol.computeUnmangledName(symbol); - } - return "$symbol"; - } -} - -@pragma("vm:entry-point") -class _CompileTimeError extends Error { - final String _errorMsg; - _CompileTimeError(this._errorMsg); - String toString() => _errorMsg; -} - -/// Used by Fasta to report a runtime error when a final field with an -/// initializer is also initialized in a generative constructor. -/// -/// Note: in strong mode, this is a compile-time error and this class becomes -/// obsolete. -class _DuplicatedFieldInitializerError extends Error { - final String _name; - - _DuplicatedFieldInitializerError(this._name); - - toString() => "Error: field '$_name' is already initialized."; -} - -class _LateInitializationError extends Error - implements LateInitializationError { - @pragma("vm:entry-point") - _LateInitializationError(this._name); - - @pragma("vm:entry-point") - static void _throwNew(String name) { - throw _LateInitializationError(name); - } - - String toString() => "LateInitializationError: $_name"; - - final String _name; -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/expando_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/expando_patch.dart deleted file mode 100644 index 1d99cab6cad..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/expando_patch.dart +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright (c) 2012, 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. - -// part of "core_patch.dart"; - -@patch -class Expando { - @patch - Expando([String? name]) - : name = name, - _data = new List.filled(_minSize, null), - _used = 0; - - static const _minSize = 8; - static final _deletedEntry = new _WeakProperty(null, null); - - @patch - T? operator [](Object object) { - _checkType(object); - - var mask = _size - 1; - var idx = object._identityHashCode & mask; - var wp = _data[idx]; - - while (wp != null) { - if (identical(wp.key, object)) { - return wp.value; - } else if (wp.key == null) { - // This entry has been cleared by the GC. - _data[idx] = _deletedEntry; - } - idx = (idx + 1) & mask; - wp = _data[idx]; - } - - return null; - } - - @patch - void operator []=(Object object, T? value) { - _checkType(object); - - var mask = _size - 1; - var idx = object._identityHashCode & mask; - var empty_idx = -1; - var wp = _data[idx]; - - while (wp != null) { - if (identical(wp.key, object)) { - if (value != null) { - // Update the associated value. - wp.value = value; - } else { - // Mark the entry as deleted. - _data[idx] = _deletedEntry; - } - return; - } else if ((empty_idx < 0) && identical(wp, _deletedEntry)) { - empty_idx = idx; // Insert at this location if not found. - } else if (wp.key == null) { - // This entry has been cleared by the GC. - _data[idx] = _deletedEntry; - if (empty_idx < 0) { - empty_idx = idx; // Insert at this location if not found. - } - } - idx = (idx + 1) & mask; - wp = _data[idx]; - } - - if (value == null) { - // Not entering a null value. We just needed to make sure to clear an - // existing value if it existed. - return; - } - - if (empty_idx >= 0) { - // We will be reusing the empty slot below. - _used--; - idx = empty_idx; - } - - if (_used < _limit) { - _data[idx] = new _WeakProperty(object, value); - _used++; - return; - } - - // Grow/reallocate if too many slots have been used. - _rehash(); - this[object] = value; // Recursively add the value. - } - - _rehash() { - // Determine the population count of the map to allocate an appropriately - // sized map below. - var count = 0; - var old_data = _data; - var len = old_data.length; - for (var i = 0; i < len; i++) { - var entry = old_data[i]; - if ((entry != null) && (entry.key != null)) { - // Only count non-cleared entries. - count++; - } - } - - var new_size = _size; - if (count <= (new_size >> 2)) { - new_size = new_size >> 1; - } else if (count > (new_size >> 1)) { - new_size = new_size << 1; - } - new_size = (new_size < _minSize) ? _minSize : new_size; - - // Reset the mappings to empty so that we can just add the existing - // valid entries. - _data = new List.filled(new_size, null); - _used = 0; - - for (var i = 0; i < old_data.length; i++) { - var entry = old_data[i]; - if (entry != null) { - // Ensure that the entry.key is not cleared between checking for it and - // inserting it into the new table. - var val = entry.value; - var key = entry.key; - if (key != null) { - this[key] = val; - } - } - } - } - - static _checkType(object) { - if ((object == null) || - (object is bool) || - (object is num) || - (object is String)) { - throw new ArgumentError.value(object, - "Expandos are not allowed on strings, numbers, booleans or null"); - } - } - - get _size => _data.length; - get _limit => (3 * (_size ~/ 4)); - - List _data; - int _used; // Number of used (active and deleted) slots. -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart deleted file mode 100644 index 303c5a4d385..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) 2019, 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. - -// All imports must be in all FFI patch files to not depend on the order -// the patches are applied. -import "dart:_internal" show patch; -import 'dart:typed_data'; -import 'dart:isolate'; - -DynamicLibrary _open(String name) native "Ffi_dl_open"; -DynamicLibrary _processLibrary() native "Ffi_dl_processLibrary"; -DynamicLibrary _executableLibrary() native "Ffi_dl_executableLibrary"; - -@patch -@pragma("vm:entry-point") -class DynamicLibrary { - @patch - factory DynamicLibrary.open(String name) { - return _open(name); - } - - @patch - factory DynamicLibrary.process() => _processLibrary(); - - @patch - factory DynamicLibrary.executable() => _executableLibrary(); - - @patch - Pointer lookup(String symbolName) - native "Ffi_dl_lookup"; - - // TODO(dacoharkes): Expose this to users, or extend Pointer? - // https://github.com/dart-lang/sdk/issues/35881 - int getHandle() native "Ffi_dl_getHandle"; - - @patch - bool operator ==(Object other) { - if (other is! DynamicLibrary) return false; - DynamicLibrary otherLib = other; - return getHandle() == otherLib.getHandle(); - } - - @patch - int get hashCode { - return getHandle().hashCode; - } - - @patch - Pointer get handle => Pointer.fromAddress(getHandle()); -} - -extension DynamicLibraryExtension on DynamicLibrary { - @patch - DS lookupFunction( - String symbolName) => - throw UnsupportedError("The body is inlined in the frontend."); -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/ffi_native_type_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/ffi_native_type_patch.dart deleted file mode 100644 index cc7831b26c6..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/ffi_native_type_patch.dart +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (c) 2019, 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. - -// All imports must be in all FFI patch files to not depend on the order -// the patches are applied. -import "dart:_internal" show patch; -import 'dart:typed_data'; -import 'dart:isolate'; - -// NativeType is not private, because it is used in type arguments. -// NativeType is abstract because it not used with const constructors in -// annotations directly, so it should never be instantiated at runtime. -@patch -@pragma("vm:entry-point") -abstract class NativeType {} - -@patch -@pragma("vm:entry-point") -class _NativeInteger extends NativeType {} - -@patch -@pragma("vm:entry-point") -class _NativeDouble extends NativeType {} - -@patch -@pragma("vm:entry-point") -class Int8 extends _NativeInteger {} - -@patch -@pragma("vm:entry-point") -class Int16 extends _NativeInteger {} - -@patch -@pragma("vm:entry-point") -class Int32 extends _NativeInteger {} - -@patch -@pragma("vm:entry-point") -class Int64 extends _NativeInteger {} - -@patch -@pragma("vm:entry-point") -class Uint8 extends _NativeInteger {} - -@patch -@pragma("vm:entry-point") -class Uint16 extends _NativeInteger {} - -@patch -@pragma("vm:entry-point") -class Uint32 extends _NativeInteger {} - -@patch -@pragma("vm:entry-point") -class Uint64 extends _NativeInteger {} - -@patch -@pragma("vm:entry-point") -class IntPtr extends _NativeInteger {} - -@patch -@pragma("vm:entry-point") -class Float extends _NativeDouble {} - -@patch -@pragma("vm:entry-point") -class Double extends _NativeDouble {} - -@patch -@pragma("vm:entry-point") -abstract class Void extends NativeType {} - -@patch -@pragma("vm:entry-point") -abstract class Handle extends NativeType {} - -@patch -@pragma("vm:entry-point") -abstract class NativeFunction extends NativeType {} diff --git a/sdk_nnbd/lib/_internal/vm/lib/ffi_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/ffi_patch.dart deleted file mode 100644 index d42689ce0d3..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/ffi_patch.dart +++ /dev/null @@ -1,478 +0,0 @@ -// Copyright (c) 2019, 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. - -// All imports must be in all FFI patch files to not depend on the order -// the patches are applied. -import "dart:_internal" show patch; -import 'dart:typed_data'; -import 'dart:isolate'; - -const Map _knownSizes = { - Int8: 1, - Uint8: 1, - Int16: 2, - Uint16: 2, - Int32: 4, - Uint32: 4, - Int64: 8, - Uint64: 8, - Float: 4, - Double: 8, -}; - -@pragma("vm:prefer-inline") -int get _intPtrSize => (const [8, 4, 4])[_abi()]; - -@patch -int sizeOf() { - // This is not super fast, but it is faster than a runtime entry. - // Hot loops with elementAt().load() do not use this sizeOf, elementAt is - // optimized per NativeType statically to prevent use of sizeOf at runtime. - final int? knownSize = _knownSizes[T]; - if (knownSize != null) return knownSize; - if (T == IntPtr) return _intPtrSize; - if (T == Pointer) return _intPtrSize; - // For structs we fall back to a runtime entry. - return _sizeOf(); -} - -int _sizeOf() native "Ffi_sizeOf"; - -// Implemented in the method recognizer, bytecode interpreter uses runtime. -Pointer _fromAddress(int ptr) native "Ffi_fromAddress"; - -// The real implementation of this function (for interface calls) lives in -// BuildFfiAsFunctionCall in the Kernel frontend. No calls can actually reach -// this function. -DS _asFunctionInternal( - Pointer> ptr) native "Ffi_asFunctionInternal"; - -dynamic _asExternalTypedData(Pointer ptr, int count) - native "Ffi_asExternalTypedData"; - -// Returns a Function object for a native callback. -// -// Calls to [Pointer.fromFunction] are re-written by the FE into calls to this -// method + _pointerFromFunction. All three arguments must be constants. -// -// In AOT we evaluate calls to this function during precompilation and replace -// them with Constant instruction referencing the callback trampoline, to ensure -// that it will be precompiled. -// -// In all JIT modes we call a native runtime entry. We *cannot* use the IL -// implementation, since that would pull the callback trampoline into JIT -// snapshots. The callback trampolines can only be serialized into AOT snapshots -// because they embed the addresses of runtime routines in JIT mode. -// -// Function objects returned by this native method are not Dart instances, -// so we need to use top type as a return type to avoid type check. -dynamic _nativeCallbackFunction(Function target, - Object exceptionalReturn) native "Ffi_nativeCallbackFunction"; - -Pointer _pointerFromFunction(dynamic function) - native "Ffi_pointerFromFunction"; - -@patch -@pragma("vm:entry-point") -class Pointer { - @patch - factory Pointer.fromAddress(int ptr) => _fromAddress(ptr); - - // All static calls to this method are replaced by the FE into - // _nativeCallbackFunction + _pointerFromFunction. - // - // We still need to throw an error on a dynamic invocations, invocations - // through tearoffs or reflective calls. - @patch - static Pointer> fromFunction( - @DartRepresentationOf("T") Function f, - [Object? exceptionalReturn]) { - throw UnsupportedError( - "Pointer.fromFunction cannot be called dynamically."); - } - - // Implemented in the method recognizer, bytecode interpreter uses runtime. - @patch - int get address native "Ffi_address"; - - // For statically known types, this is rewired. - // (Method sizeOf is slow, see notes above.) - @patch - Pointer elementAt(int index) => - Pointer.fromAddress(address + sizeOf() * index); - - @patch - Pointer _offsetBy(int offsetInBytes) => - Pointer.fromAddress(address + offsetInBytes); - - @patch - Pointer cast() => Pointer.fromAddress(address); -} - -/// Returns an integer encoding the ABI used for size and alignment -/// calculations. See pkg/vm/lib/transformations/ffi.dart. -@pragma('vm:prefer-inline') -int _abi() - native "Recognized method: method is directly interpreted by the bytecode interpreter or IR graph is built in the flow graph builder."; - -// The following functions are implemented in the method recognizer, but the -// bytecode interpreter uses native entries. -// -// TODO(38172): Since these are not inlined (force optimize), they force -// allocating a Pointer with in elementAt/offsetBy. Allocating these pointers -// and GCing new spaces takes a lot of the benchmark time. The next speedup is -// getting rid of these allocations by inlining these functions. -int _loadInt8(Pointer pointer, int offsetInBytes) native "Ffi_loadInt8"; - -int _loadInt16(Pointer pointer, int offsetInBytes) native "Ffi_loadInt16"; - -int _loadInt32(Pointer pointer, int offsetInBytes) native "Ffi_loadInt32"; - -int _loadInt64(Pointer pointer, int offsetInBytes) native "Ffi_loadInt64"; - -int _loadUint8(Pointer pointer, int offsetInBytes) native "Ffi_loadUint8"; - -int _loadUint16(Pointer pointer, int offsetInBytes) native "Ffi_loadUint16"; - -int _loadUint32(Pointer pointer, int offsetInBytes) native "Ffi_loadUint32"; - -int _loadUint64(Pointer pointer, int offsetInBytes) native "Ffi_loadUint64"; - -int _loadIntPtr(Pointer pointer, int offsetInBytes) native "Ffi_loadIntPtr"; - -double _loadFloat(Pointer pointer, int offsetInBytes) native "Ffi_loadFloat"; - -double _loadDouble(Pointer pointer, int offsetInBytes) native "Ffi_loadDouble"; - -Pointer _loadPointer( - Pointer pointer, int offsetInBytes) native "Ffi_loadPointer"; - -S _loadStruct(Pointer pointer, int index) - native "Ffi_loadStruct"; - -void _storeInt8(Pointer pointer, int offsetInBytes, int value) - native "Ffi_storeInt8"; - -void _storeInt16(Pointer pointer, int offsetInBytes, int value) - native "Ffi_storeInt16"; - -void _storeInt32(Pointer pointer, int offsetInBytes, int value) - native "Ffi_storeInt32"; - -void _storeInt64(Pointer pointer, int offsetInBytes, int value) - native "Ffi_storeInt64"; - -void _storeUint8(Pointer pointer, int offsetInBytes, int value) - native "Ffi_storeUint8"; - -void _storeUint16(Pointer pointer, int offsetInBytes, int value) - native "Ffi_storeUint16"; - -void _storeUint32(Pointer pointer, int offsetInBytes, int value) - native "Ffi_storeUint32"; - -void _storeUint64(Pointer pointer, int offsetInBytes, int value) - native "Ffi_storeUint64"; - -void _storeIntPtr(Pointer pointer, int offsetInBytes, int value) - native "Ffi_storeIntPtr"; - -void _storeFloat(Pointer pointer, int offsetInBytes, double value) - native "Ffi_storeFloat"; - -void _storeDouble(Pointer pointer, int offsetInBytes, double value) - native "Ffi_storeDouble"; - -void _storePointer(Pointer pointer, int offsetInBytes, - Pointer value) native "Ffi_storePointer"; - -Pointer _elementAtInt8(Pointer pointer, int index) => - Pointer.fromAddress(pointer.address + 1 * index); - -Pointer _elementAtInt16(Pointer pointer, int index) => - Pointer.fromAddress(pointer.address + 2 * index); - -Pointer _elementAtInt32(Pointer pointer, int index) => - Pointer.fromAddress(pointer.address + 4 * index); - -Pointer _elementAtInt64(Pointer pointer, int index) => - Pointer.fromAddress(pointer.address + 8 * index); - -Pointer _elementAtUint8(Pointer pointer, int index) => - Pointer.fromAddress(pointer.address + 1 * index); - -Pointer _elementAtUint16(Pointer pointer, int index) => - Pointer.fromAddress(pointer.address + 2 * index); - -Pointer _elementAtUint32(Pointer pointer, int index) => - Pointer.fromAddress(pointer.address + 4 * index); - -Pointer _elementAtUint64(Pointer pointer, int index) => - Pointer.fromAddress(pointer.address + 8 * index); - -Pointer _elementAtIntPtr(Pointer pointer, int index) => - Pointer.fromAddress(pointer.address + _intPtrSize * index); - -Pointer _elementAtFloat(Pointer pointer, int index) => - Pointer.fromAddress(pointer.address + 4 * index); - -Pointer _elementAtDouble(Pointer pointer, int index) => - Pointer.fromAddress(pointer.address + 8 * index); - -Pointer> _elementAtPointer( - Pointer> pointer, int index) => - Pointer.fromAddress(pointer.address + _intPtrSize * index); - -extension NativeFunctionPointer - on Pointer> { - @patch - DF asFunction() => - throw UnsupportedError("The body is inlined in the frontend."); -} - -// -// The following code is generated, do not edit by hand. -// -// Code generated by `runtime/tools/ffi/sdk_lib_ffi_generator.dart`. -// - -extension Int8Pointer on Pointer { - @patch - int get value => _loadInt8(this, 0); - - @patch - set value(int value) => _storeInt8(this, 0, value); - - @patch - int operator [](int index) => _loadInt8(this, index); - - @patch - operator []=(int index, int value) => _storeInt8(this, index, value); - - @patch - Int8List asTypedList(int elements) => _asExternalTypedData(this, elements); -} - -extension Int16Pointer on Pointer { - @patch - int get value => _loadInt16(this, 0); - - @patch - set value(int value) => _storeInt16(this, 0, value); - - @patch - int operator [](int index) => _loadInt16(this, 2 * index); - - @patch - operator []=(int index, int value) => _storeInt16(this, 2 * index, value); - - @patch - Int16List asTypedList(int elements) => _asExternalTypedData(this, elements); -} - -extension Int32Pointer on Pointer { - @patch - int get value => _loadInt32(this, 0); - - @patch - set value(int value) => _storeInt32(this, 0, value); - - @patch - int operator [](int index) => _loadInt32(this, 4 * index); - - @patch - operator []=(int index, int value) => _storeInt32(this, 4 * index, value); - - @patch - Int32List asTypedList(int elements) => _asExternalTypedData(this, elements); -} - -extension Int64Pointer on Pointer { - @patch - int get value => _loadInt64(this, 0); - - @patch - set value(int value) => _storeInt64(this, 0, value); - - @patch - int operator [](int index) => _loadInt64(this, 8 * index); - - @patch - operator []=(int index, int value) => _storeInt64(this, 8 * index, value); - - @patch - Int64List asTypedList(int elements) => _asExternalTypedData(this, elements); -} - -extension Uint8Pointer on Pointer { - @patch - int get value => _loadUint8(this, 0); - - @patch - set value(int value) => _storeUint8(this, 0, value); - - @patch - int operator [](int index) => _loadUint8(this, index); - - @patch - operator []=(int index, int value) => _storeUint8(this, index, value); - - @patch - Uint8List asTypedList(int elements) => _asExternalTypedData(this, elements); -} - -extension Uint16Pointer on Pointer { - @patch - int get value => _loadUint16(this, 0); - - @patch - set value(int value) => _storeUint16(this, 0, value); - - @patch - int operator [](int index) => _loadUint16(this, 2 * index); - - @patch - operator []=(int index, int value) => _storeUint16(this, 2 * index, value); - - @patch - Uint16List asTypedList(int elements) => _asExternalTypedData(this, elements); -} - -extension Uint32Pointer on Pointer { - @patch - int get value => _loadUint32(this, 0); - - @patch - set value(int value) => _storeUint32(this, 0, value); - - @patch - int operator [](int index) => _loadUint32(this, 4 * index); - - @patch - operator []=(int index, int value) => _storeUint32(this, 4 * index, value); - - @patch - Uint32List asTypedList(int elements) => _asExternalTypedData(this, elements); -} - -extension Uint64Pointer on Pointer { - @patch - int get value => _loadUint64(this, 0); - - @patch - set value(int value) => _storeUint64(this, 0, value); - - @patch - int operator [](int index) => _loadUint64(this, 8 * index); - - @patch - operator []=(int index, int value) => _storeUint64(this, 8 * index, value); - - @patch - Uint64List asTypedList(int elements) => _asExternalTypedData(this, elements); -} - -extension IntPtrPointer on Pointer { - @patch - int get value => _loadIntPtr(this, 0); - - @patch - set value(int value) => _storeIntPtr(this, 0, value); - - @patch - int operator [](int index) => _loadIntPtr(this, _intPtrSize * index); - - @patch - operator []=(int index, int value) => - _storeIntPtr(this, _intPtrSize * index, value); -} - -extension FloatPointer on Pointer { - @patch - double get value => _loadFloat(this, 0); - - @patch - set value(double value) => _storeFloat(this, 0, value); - - @patch - double operator [](int index) => _loadFloat(this, 4 * index); - - @patch - operator []=(int index, double value) => _storeFloat(this, 4 * index, value); - - @patch - Float32List asTypedList(int elements) => _asExternalTypedData(this, elements); -} - -extension DoublePointer on Pointer { - @patch - double get value => _loadDouble(this, 0); - - @patch - set value(double value) => _storeDouble(this, 0, value); - - @patch - double operator [](int index) => _loadDouble(this, 8 * index); - - @patch - operator []=(int index, double value) => _storeDouble(this, 8 * index, value); - - @patch - Float64List asTypedList(int elements) => _asExternalTypedData(this, elements); -} - -// -// End of generated code. -// - -extension PointerPointer on Pointer> { - @patch - Pointer get value => _loadPointer(this, 0); - - @patch - set value(Pointer value) => _storePointer(this, 0, value); - - @patch - Pointer operator [](int index) => _loadPointer(this, _intPtrSize * index); - - @patch - operator []=(int index, Pointer value) => - _storePointer(this, _intPtrSize * index, value); -} - -extension StructPointer on Pointer { - @patch - T get ref => _loadStruct(this, 0); - - @patch - T operator [](int index) => _loadStruct(this, index); -} - -extension NativePort on SendPort { - @patch - int get nativePort native "SendPortImpl_get_id"; -} - -int _nativeApiFunctionPointer(String symbol) native "NativeApiFunctionPointer"; - -@patch -abstract class NativeApi { - @patch - static Pointer)>> - get postCObject => - Pointer.fromAddress(_nativeApiFunctionPointer("Dart_PostCObject")); - - @patch - static Pointer< - NativeFunction< - Int64 Function( - Pointer, - Pointer>, - Int8)>> get newNativePort => - Pointer.fromAddress(_nativeApiFunctionPointer("Dart_NewNativePort")); - - @patch - static Pointer> get closeNativePort => - Pointer.fromAddress(_nativeApiFunctionPointer("Dart_CloseNativePort")); -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/ffi_struct_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/ffi_struct_patch.dart deleted file mode 100644 index 8fad96754e1..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/ffi_struct_patch.dart +++ /dev/null @@ -1,12 +0,0 @@ -// 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. - -// All imports must be in all FFI patch files to not depend on the order -// the patches are applied. -import "dart:_internal" show patch; -import 'dart:typed_data'; -import 'dart:isolate'; - -@pragma("vm:entry-point") -abstract class Struct extends NativeType {} diff --git a/sdk_nnbd/lib/_internal/vm/lib/function.dart b/sdk_nnbd/lib/_internal/vm/lib/function.dart deleted file mode 100644 index 1c99ca26e5f..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/function.dart +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) 2013, 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. - -// part of "core_patch.dart"; - -@pragma("vm:entry-point") -class _Closure implements Function { - factory _Closure._uninstantiable() { - throw "Unreachable"; - } - - bool operator ==(Object other) native "Closure_equals"; - - int get hashCode { - _hash ??= _computeHash(); - return _hash; - } - - _Closure get call => this; - - _Closure _clone() native "Closure_clone"; - - int _computeHash() native "Closure_computeHash"; - - // No instance fields should be declared before the following fields whose - // offsets must be identical in Dart and C++. - - // The following fields are declared both in raw_object.h (for direct access - // from C++ code) and also here so that the offset-to-field map used by - // deferred objects is properly initialized. - // Caution: These fields are not Dart instances, but VM objects. Their Dart - // names do not need to match the C++ names, but they must be private. - @pragma("vm:entry-point") - var _instantiator_type_arguments; - @pragma("vm:entry-point") - var _function_type_arguments; - @pragma("vm:entry-point") - var _delayed_type_arguments; - @pragma("vm:entry-point") - var _function; - @pragma("vm:entry-point") - var _context; - - // Note: _Closure objects are created by VM "magically", without invoking - // constructor. So, _Closure default constructor is never compiled and - // detection of default-initialized fields is not performed. - // As a consequence, VM incorrectly assumes that _hash field is not - // nullable and may incorrectly remove 'if (_hash == null)' in get:hashCode. - // This initializer makes _hash field nullable even without constructor - // compilation. - @pragma("vm:entry-point") - var _hash = null; -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/function_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/function_patch.dart deleted file mode 100644 index b4d3daa75e2..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/function_patch.dart +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) 2012, 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. - -// part of "core_patch.dart"; - -@patch -class Function { - // TODO(regis): Pass type arguments to generic functions. Wait for API spec. - static _apply(List? arguments, List? names) - native "Function_apply"; - - @patch - static apply(Function function, List? positionalArguments, - [Map? namedArguments]) { - int numPositionalArguments = 1 + // Function is first implicit argument. - (positionalArguments != null ? positionalArguments.length : 0); - int numNamedArguments = namedArguments != null ? namedArguments.length : 0; - int numArguments = numPositionalArguments + numNamedArguments; - List arguments = new List.filled(numArguments, null); - arguments[0] = function; - if (positionalArguments != null) { - arguments.setRange(1, numPositionalArguments, positionalArguments); - } - List names = new List.filled(numNamedArguments, null); - int argumentIndex = numPositionalArguments; - int nameIndex = 0; - if (numNamedArguments > 0) { - namedArguments?.forEach((name, value) { - arguments[argumentIndex++] = value; - names[nameIndex++] = internal.Symbol.getName(name as internal.Symbol); - }); - } - return _apply(arguments, names); - } -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/growable_array.dart b/sdk_nnbd/lib/_internal/vm/lib/growable_array.dart deleted file mode 100644 index bca95abd0f4..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/growable_array.dart +++ /dev/null @@ -1,410 +0,0 @@ -// Copyright (c) 2012, 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. - -// part of "core_patch.dart"; - -@pragma("vm:entry-point") -class _GrowableList extends ListBase { - void insert(int index, T element) { - if ((index < 0) || (index > length)) { - throw new RangeError.range(index, 0, length); - } - int oldLength = this.length; - add(element); - if (index == oldLength) { - return; - } - Lists.copy(this, index, this, index + 1, oldLength - index); - this[index] = element; - } - - T removeAt(int index) { - var result = this[index]; - int newLength = this.length - 1; - if (index < newLength) { - Lists.copy(this, index + 1, this, index, newLength - index); - } - this.length = newLength; - return result; - } - - bool remove(Object? element) { - for (int i = 0; i < this.length; i++) { - if (this[i] == element) { - removeAt(i); - return true; - } - } - return false; - } - - void insertAll(int index, Iterable iterable) { - if (index < 0 || index > length) { - throw new RangeError.range(index, 0, length); - } - // TODO(floitsch): we can probably detect more cases. - if (iterable is! List && iterable is! Set && iterable is! SubListIterable) { - iterable = iterable.toList(); - } - int insertionLength = iterable.length; - // There might be errors after the length change, in which case the list - // will end up being modified but the operation not complete. Unless we - // always go through a "toList" we can't really avoid that. - int capacity = _capacity; - int newLength = length + insertionLength; - if (newLength > capacity) { - do { - capacity = _nextCapacity(capacity); - } while (newLength > capacity); - _grow(capacity); - } - _setLength(newLength); - setRange(index + insertionLength, this.length, this, index); - setAll(index, iterable); - } - - void setAll(int index, Iterable iterable) { - if (iterable is List) { - setRange(index, index + iterable.length, iterable); - } else { - for (T element in iterable) { - this[index++] = element; - } - } - } - - void removeRange(int start, int end) { - RangeError.checkValidRange(start, end, this.length); - Lists.copy(this, end, this, start, this.length - end); - this.length = this.length - (end - start); - } - - List sublist(int start, [int? end]) { - final int actualEnd = RangeError.checkValidRange(start, end, this.length); - int length = actualEnd - start; - if (length == 0) return []; - final list = new _List(length); - for (int i = 0; i < length; i++) { - list[i] = this[start + i]; - } - final result = new _GrowableList._withData(list); - result._setLength(length); - return result; - } - - factory _GrowableList(int length) { - var data = _allocateData(length); - var result = new _GrowableList._withData(data); - if (length > 0) { - result._setLength(length); - } - return result; - } - - factory _GrowableList.withCapacity(int capacity) { - var data = _allocateData(capacity); - return new _GrowableList._withData(data); - } - - @pragma("vm:exact-result-type", - [_GrowableList, "result-type-uses-passed-type-arguments"]) - factory _GrowableList._withData(_List data) native "GrowableList_allocate"; - - @pragma("vm:exact-result-type", "dart:core#_Smi") - @pragma("vm:prefer-inline") - int get _capacity native "GrowableList_getCapacity"; - - @pragma("vm:exact-result-type", "dart:core#_Smi") - @pragma("vm:prefer-inline") - int get length native "GrowableList_getLength"; - - void set length(int new_length) { - int old_capacity = _capacity; - int new_capacity = new_length; - if (new_capacity > old_capacity) { - // Verify that element type is nullable. - null as T; - _grow(new_capacity); - _setLength(new_length); - return; - } - // We are shrinking. Pick the method which has fewer writes. - // In the shrink-to-fit path, we write |new_capacity + new_length| words - // (null init + copy). - // In the non-shrink-to-fit path, we write |length - new_length| words - // (null overwrite). - final bool shouldShrinkToFit = - (new_capacity + new_length) < (length - new_length); - if (shouldShrinkToFit) { - _shrink(new_capacity, new_length); - } else { - for (int i = new_length; i < length; i++) { - _setIndexed(i, null); - } - } - _setLength(new_length); - } - - void _setLength(int new_length) native "GrowableList_setLength"; - - void _setData(_List array) native "GrowableList_setData"; - - T operator [](int index) native "GrowableList_getIndexed"; - - void operator []=(int index, T value) { - _setIndexed(index, value); - } - - void _setIndexed(int index, T? value) native "GrowableList_setIndexed"; - - @pragma("vm:entry-point", "call") - @pragma("vm:prefer-inline") - void add(T value) { - var len = length; - if (len == _capacity) { - _grow(_nextCapacity(len)); - } - _setLength(len + 1); - this[len] = value; - } - - void addAll(Iterable iterable) { - var len = length; - final cid = ClassID.getID(iterable); - final isVMList = (cid == ClassID.cidArray) || - (cid == ClassID.cidGrowableObjectArray) || - (cid == ClassID.cidImmutableArray); - if (isVMList || (iterable is EfficientLengthIterable)) { - var cap = _capacity; - // Pregrow if we know iterable.length. - var iterLen = iterable.length; - var newLen = len + iterLen; - if (newLen > cap) { - do { - cap = _nextCapacity(cap); - } while (newLen > cap); - _grow(cap); - } - if (isVMList) { - if (identical(iterable, this)) { - throw new ConcurrentModificationError(this); - } - this._setLength(newLen); - final ListBase iterableAsList = iterable as ListBase; - for (int i = 0; i < iterLen; i++) { - this[len++] = iterableAsList[i]; - } - return; - } - } - Iterator it = iterable.iterator; - if (!it.moveNext()) return; - do { - while (len < _capacity) { - int newLen = len + 1; - this._setLength(newLen); - this[len] = it.current; - if (!it.moveNext()) return; - if (this.length != newLen) throw new ConcurrentModificationError(this); - len = newLen; - } - _grow(_nextCapacity(_capacity)); - } while (true); - } - - @pragma("vm:prefer-inline") - T removeLast() { - var len = length - 1; - var elem = this[len]; - this.length = len; - return elem; - } - - T get first { - if (length > 0) return this[0]; - throw IterableElementError.noElement(); - } - - T get last { - if (length > 0) return this[length - 1]; - throw IterableElementError.noElement(); - } - - T get single { - if (length == 1) return this[0]; - if (length == 0) throw IterableElementError.noElement(); - throw IterableElementError.tooMany(); - } - - // Shared array used as backing for new empty growable arrays. - static final _List _emptyList = new _List(0); - - static _List _allocateData(int capacity) { - if (capacity == 0) { - // Use shared empty list as backing. - return _emptyList; - } - // Round up size to the next odd number, since this is free - // because of alignment requirements of the GC. - return new _List(capacity | 1); - } - - // Grow from 0 to 3, and then double + 1. - int _nextCapacity(int old_capacity) => (old_capacity * 2) | 3; - - void _grow(int new_capacity) { - var newData = _allocateData(new_capacity); - // This is a work-around for dartbug.com/30090: array-bound-check - // generalization causes excessive deoptimizations because it - // hoists CheckArrayBound(i, ...) out of the loop below and turns it - // into CheckArrayBound(length - 1, ...). Which deoptimizes - // if length == 0. However the loop itself does not execute - // if length == 0. - if (length > 0) { - for (int i = 0; i < length; i++) { - newData[i] = this[i]; - } - } - _setData(newData); - } - - void _shrink(int new_capacity, int new_length) { - var newData = _allocateData(new_capacity); - // This is a work-around for dartbug.com/30090. See the comment in _grow. - if (new_length > 0) { - for (int i = 0; i < new_length; i++) { - newData[i] = this[i]; - } - } - _setData(newData); - } - - // Iterable interface. - - @pragma("vm:prefer-inline") - void forEach(f(T element)) { - int initialLength = length; - for (int i = 0; i < length; i++) { - f(this[i]); - if (length != initialLength) throw new ConcurrentModificationError(this); - } - } - - String join([String separator = ""]) { - final int length = this.length; - if (length == 0) return ""; - if (length == 1) return "${this[0]}"; - if (separator.isNotEmpty) return _joinWithSeparator(separator); - var i = 0; - var codeUnitCount = 0; - while (i < length) { - final element = this[i]; - // While list contains one-byte strings. - if (element is _OneByteString) { - codeUnitCount += element.length; - i++; - // Loop back while strings are one-byte strings. - continue; - } - // Otherwise, never loop back to the outer loop, and - // handle the remaining strings below. - - // Loop while elements are strings, - final int firstNonOneByteStringLimit = i; - var nextElement = element; - while (nextElement is String) { - i++; - if (i == length) { - return _StringBase._concatRangeNative(this, 0, length); - } - nextElement = this[i]; - } - - // Not all elements are strings, so allocate a new backing array. - final list = new _List(length); - for (int copyIndex = 0; copyIndex < i; copyIndex++) { - list[copyIndex] = this[copyIndex]; - } - // Is non-zero if list contains a non-onebyte string. - var onebyteCanary = i - firstNonOneByteStringLimit; - while (true) { - final String elementString = "$nextElement"; - onebyteCanary |= - (ClassID.getID(elementString) ^ ClassID.cidOneByteString); - list[i] = elementString; - codeUnitCount += elementString.length; - i++; - if (i == length) break; - nextElement = this[i]; - } - if (onebyteCanary == 0) { - // All elements returned a one-byte string from toString. - return _OneByteString._concatAll(list, codeUnitCount); - } - return _StringBase._concatRangeNative(list, 0, length); - } - // All elements were one-byte strings. - return _OneByteString._concatAll(this, codeUnitCount); - } - - String _joinWithSeparator(String separator) { - StringBuffer buffer = new StringBuffer(); - buffer.write(this[0]); - for (int i = 1; i < this.length; i++) { - buffer.write(separator); - buffer.write(this[i]); - } - return buffer.toString(); - } - - T elementAt(int index) { - return this[index]; - } - - bool get isEmpty { - return this.length == 0; - } - - bool get isNotEmpty => !isEmpty; - - void clear() { - this.length = 0; - } - - String toString() => ListBase.listToString(this); - - @pragma("vm:prefer-inline") - Iterator get iterator { - return new ListIterator(this); - } - - List toList({bool growable: true}) { - final length = this.length; - if (growable) { - if (length > 0) { - final list = new _List(length); - for (int i = 0; i < length; i++) { - list[i] = this[i]; - } - final result = new _GrowableList._withData(list); - result._setLength(length); - return result; - } - return []; - } else { - if (length > 0) { - final list = new _List(length); - for (int i = 0; i < length; i++) { - list[i] = this[i]; - } - return list; - } - return List.empty(growable: false); - } - } - - Set toSet() { - return new Set.of(this); - } -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/identical_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/identical_patch.dart deleted file mode 100644 index 4b5743084c7..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/identical_patch.dart +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) 2012, 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. - -// part of "core_patch.dart"; - -@patch -@pragma("vm:exact-result-type", bool) -bool identical(Object? a, Object? b) native "Identical_comparison"; - -@patch -@pragma("vm:entry-point", "call") -int identityHashCode(Object? object) => object._identityHashCode; diff --git a/sdk_nnbd/lib/_internal/vm/lib/immutable_map.dart b/sdk_nnbd/lib/_internal/vm/lib/immutable_map.dart deleted file mode 100644 index 7be9890c2be..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/immutable_map.dart +++ /dev/null @@ -1,229 +0,0 @@ -// Copyright (c) 2012, 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. - -// part of "core_patch.dart"; - -/// Immutable map class for compiler generated map literals. -// TODO(lrn): Extend MapBase with UnmodifiableMapMixin when mixins -// support forwarding const constructors. -@pragma("vm:entry-point") -class _ImmutableMap implements Map { - final _ImmutableList _kvPairs; - - @pragma("vm:entry-point") - const _ImmutableMap._create(_ImmutableList keyValuePairs) - : _kvPairs = keyValuePairs; - - Map cast() => Map.castFrom(this); - V? operator [](Object? key) { - // To preserve the key-value order of the map literal, the keys are - // not sorted. Need to do linear search or implement an additional - // lookup table. - for (int i = 0; i < _kvPairs.length - 1; i += 2) { - if (key == _kvPairs[i]) { - return _kvPairs[i + 1]; - } - } - return null; - } - - bool get isEmpty { - return _kvPairs.length == 0; - } - - bool get isNotEmpty => !isEmpty; - - int get length { - return _kvPairs.length ~/ 2; - } - - void forEach(void f(K key, V value)) { - for (int i = 0; i < _kvPairs.length; i += 2) { - f(_kvPairs[i], _kvPairs[i + 1]); - } - } - - Iterable get keys { - return new _ImmutableMapKeyIterable(this); - } - - Iterable get values { - return new _ImmutableMapValueIterable(this); - } - - bool containsKey(Object? key) { - for (int i = 0; i < _kvPairs.length; i += 2) { - if (key == _kvPairs[i]) { - return true; - } - } - return false; - } - - bool containsValue(Object? value) { - for (int i = 1; i < _kvPairs.length; i += 2) { - if (value == _kvPairs[i]) { - return true; - } - } - return false; - } - - void operator []=(K key, V value) { - throw new UnsupportedError("Cannot set value in unmodifiable Map"); - } - - void addAll(Map other) { - throw new UnsupportedError("Cannot set value in unmodifiable Map"); - } - - V putIfAbsent(K key, V ifAbsent()) { - throw new UnsupportedError("Cannot set value in unmodifiable Map"); - } - - void clear() { - throw new UnsupportedError("Cannot clear unmodifiable Map"); - } - - V? remove(Object? key) { - throw new UnsupportedError("Cannot remove from unmodifiable Map"); - } - - Iterable> get entries => - new _ImmutableMapEntryIterable(this); - - Map map(MapEntry f(K key, V value)) { - var result = {}; - for (int i = 0; i < _kvPairs.length; i += 2) { - var entry = f(_kvPairs[i], _kvPairs[i + 1]); - result[entry.key] = entry.value; - } - return result; - } - - void addEntries(Iterable> newEntries) { - throw new UnsupportedError("Cannot modify an unmodifiable Map"); - } - - V update(K key, V update(V value), {V ifAbsent()?}) { - throw new UnsupportedError("Cannot modify an unmodifiable Map"); - } - - void updateAll(V update(K key, V value)) { - throw new UnsupportedError("Cannot modify an unmodifiable Map"); - } - - void removeWhere(bool predicate(K key, V value)) { - throw new UnsupportedError("Cannot modify an unmodifiable Map"); - } - - String toString() => MapBase.mapToString(this); -} - -class _ImmutableMapKeyIterable extends EfficientLengthIterable { - final _ImmutableMap _map; - _ImmutableMapKeyIterable(this._map); - - Iterator get iterator { - return new _ImmutableMapKeyIterator(_map); - } - - int get length => _map.length; -} - -class _ImmutableMapValueIterable extends EfficientLengthIterable { - final _ImmutableMap _map; - _ImmutableMapValueIterable(this._map); - - Iterator get iterator { - return new _ImmutableMapValueIterator(_map); - } - - int get length => _map.length; -} - -class _ImmutableMapEntryIterable - extends EfficientLengthIterable> { - final _ImmutableMap _map; - _ImmutableMapEntryIterable(this._map); - - Iterator> get iterator { - return new _ImmutableMapEntryIterator(_map); - } - - int get length => _map.length; -} - -class _ImmutableMapKeyIterator implements Iterator { - _ImmutableMap _map; - int _nextIndex = 0; - E? _current; - - _ImmutableMapKeyIterator(this._map); - - bool moveNext() { - int newIndex = _nextIndex; - if (newIndex < _map.length) { - _nextIndex = newIndex + 1; - _current = _map._kvPairs[newIndex * 2]; - return true; - } - _current = null; - return false; - } - - E get current { - final cur = _current; - return (cur != null) ? cur : cur as E; - } -} - -class _ImmutableMapValueIterator implements Iterator { - _ImmutableMap _map; - int _nextIndex = 0; - E? _current; - - _ImmutableMapValueIterator(this._map); - - bool moveNext() { - int newIndex = _nextIndex; - if (newIndex < _map.length) { - _nextIndex = newIndex + 1; - _current = _map._kvPairs[newIndex * 2 + 1]; - return true; - } - _current = null; - return false; - } - - E get current { - final cur = _current; - return (cur != null) ? cur : cur as E; - } -} - -class _ImmutableMapEntryIterator implements Iterator> { - _ImmutableMap _map; - int _nextIndex = 0; - MapEntry? _current; - - _ImmutableMapEntryIterator(this._map); - - bool moveNext() { - int newIndex = _nextIndex; - if (newIndex < _map.length) { - _nextIndex = newIndex + 1; - _current = new MapEntry( - _map._kvPairs[newIndex * 2], _map._kvPairs[newIndex * 2 + 1]); - return true; - } - _current = null; - return false; - } - - MapEntry get current { - final cur = _current; - return (cur != null) ? cur : cur as MapEntry; - } -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/integers.dart b/sdk_nnbd/lib/_internal/vm/lib/integers.dart deleted file mode 100644 index 9fd3a76d013..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/integers.dart +++ /dev/null @@ -1,735 +0,0 @@ -// Copyright (c) 2012, 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. - -// part of "core_patch.dart"; - -abstract class _IntegerImplementation implements int { - @pragma("vm:non-nullable-result-type") - @pragma("vm:never-inline") - num operator +(num other) => other._addFromInteger(this); - @pragma("vm:non-nullable-result-type") - @pragma("vm:never-inline") - num operator -(num other) => other._subFromInteger(this); - @pragma("vm:non-nullable-result-type") - @pragma("vm:never-inline") - num operator *(num other) => other._mulFromInteger(this); - - @pragma("vm:non-nullable-result-type") - @pragma("vm:never-inline") - int operator ~/(num other) { - if ((other is int) && (other == 0)) { - throw const IntegerDivisionByZeroException(); - } - return other._truncDivFromInteger(this); - } - - double operator /(num other) { - return this.toDouble() / other.toDouble(); - } - - @pragma("vm:non-nullable-result-type") - num operator %(num other) { - if ((other is int) && (other == 0)) { - throw const IntegerDivisionByZeroException(); - } - return other._moduloFromInteger(this); - } - - @pragma("vm:non-nullable-result-type") - @pragma("vm:never-inline") - int operator -() { - // Issue(https://dartbug.com/39639): The analyzer incorrectly reports the - // result type as `num`. - return unsafeCast(0 - this); - } - - @pragma("vm:non-nullable-result-type") - @pragma("vm:never-inline") - int operator &(int other) => other._bitAndFromInteger(this); - @pragma("vm:non-nullable-result-type") - @pragma("vm:never-inline") - int operator |(int other) => other._bitOrFromInteger(this); - @pragma("vm:non-nullable-result-type") - @pragma("vm:never-inline") - int operator ^(int other) => other._bitXorFromInteger(this); - - num remainder(num other) { - return other._remainderFromInteger(this); - } - - @pragma("vm:non-nullable-result-type") - int _bitAndFromSmi(_Smi other) native "Integer_bitAndFromInteger"; - @pragma("vm:non-nullable-result-type") - int _bitAndFromInteger(int other) native "Integer_bitAndFromInteger"; - @pragma("vm:non-nullable-result-type") - int _bitOrFromInteger(int other) native "Integer_bitOrFromInteger"; - @pragma("vm:non-nullable-result-type") - int _bitXorFromInteger(int other) native "Integer_bitXorFromInteger"; - @pragma("vm:non-nullable-result-type") - int _shrFromInteger(int other) native "Integer_shrFromInteger"; - @pragma("vm:non-nullable-result-type") - int _shlFromInteger(int other) native "Integer_shlFromInteger"; - @pragma("vm:non-nullable-result-type") - int _addFromInteger(int other) native "Integer_addFromInteger"; - @pragma("vm:non-nullable-result-type") - int _subFromInteger(int other) native "Integer_subFromInteger"; - @pragma("vm:non-nullable-result-type") - int _mulFromInteger(int other) native "Integer_mulFromInteger"; - @pragma("vm:non-nullable-result-type") - int _truncDivFromInteger(int other) native "Integer_truncDivFromInteger"; - @pragma("vm:non-nullable-result-type") - int _moduloFromInteger(int other) native "Integer_moduloFromInteger"; - int _remainderFromInteger(int other) { - // Issue(https://dartbug.com/39639): The analyzer incorrectly reports the - // result type as `num`. - return unsafeCast(other - (other ~/ this) * this); - } - - @pragma("vm:non-nullable-result-type") - @pragma("vm:never-inline") - int operator >>(int other) => other._shrFromInteger(this); - @pragma("vm:non-nullable-result-type") - @pragma("vm:never-inline") - int operator <<(int other) => other._shlFromInteger(this); - - @pragma("vm:exact-result-type", bool) - @pragma("vm:never-inline") - bool operator <(num other) { - return other > this; - } - - @pragma("vm:exact-result-type", bool) - @pragma("vm:never-inline") - bool operator >(num other) { - return other._greaterThanFromInteger(this); - } - - @pragma("vm:exact-result-type", bool) - @pragma("vm:never-inline") - bool operator >=(num other) { - return (this == other) || (this > other); - } - - @pragma("vm:exact-result-type", bool) - @pragma("vm:never-inline") - bool operator <=(num other) { - return (this == other) || (this < other); - } - - @pragma("vm:exact-result-type", bool) - bool _greaterThanFromInteger(int other) - native "Integer_greaterThanFromInteger"; - - @pragma("vm:exact-result-type", bool) - @pragma("vm:never-inline") - bool operator ==(Object other) { - if (other is num) { - return other._equalToInteger(this); - } - return false; - } - - @pragma("vm:exact-result-type", bool) - bool _equalToInteger(int other) native "Integer_equalToInteger"; - int abs() { - return this < 0 ? -this : this; - } - - int get sign { - return (this > 0) ? 1 : (this < 0) ? -1 : 0; - } - - bool get isEven => ((this & 1) == 0); - bool get isOdd => !isEven; - bool get isNaN => false; - bool get isNegative => this < 0; - bool get isInfinite => false; - bool get isFinite => true; - - int toUnsigned(int width) { - return this & ((1 << width) - 1); - } - - int toSigned(int width) { - // The value of binary number weights each bit by a power of two. The - // twos-complement value weights the sign bit negatively. We compute the - // value of the negative weighting by isolating the sign bit with the - // correct power of two weighting and subtracting it from the value of the - // lower bits. - int signMask = 1 << (width - 1); - return (this & (signMask - 1)) - (this & signMask); - } - - int compareTo(num other) { - const int EQUAL = 0, LESS = -1, GREATER = 1; - if (other is double) { - const int MAX_EXACT_INT_TO_DOUBLE = 9007199254740992; // 2^53. - const int MIN_EXACT_INT_TO_DOUBLE = -MAX_EXACT_INT_TO_DOUBLE; - const bool limitIntsTo64Bits = ((1 << 64) == 0); - if (limitIntsTo64Bits) { - // With integers limited to 64 bits, double.toInt() clamps - // double value to fit into the MIN_INT64..MAX_INT64 range. - // Check if the double value is outside of this range. - // This check handles +/-infinity as well. - const double minInt64AsDouble = -9223372036854775808.0; - // MAX_INT64 is not precisely representable in doubles, so - // check against (MAX_INT64 + 1). - const double maxInt64Plus1AsDouble = 9223372036854775808.0; - if (other < minInt64AsDouble) { - return GREATER; - } else if (other >= maxInt64Plus1AsDouble) { - return LESS; - } - } else { - if (other.isInfinite) { - return other.isNegative ? GREATER : LESS; - } - } - if (other.isNaN) { - return LESS; - } - if (MIN_EXACT_INT_TO_DOUBLE <= this && this <= MAX_EXACT_INT_TO_DOUBLE) { - // Let the double implementation deal with -0.0. - return -(other.compareTo(this.toDouble())); - } else { - // If abs(other) > MAX_EXACT_INT_TO_DOUBLE, then other has an integer - // value (no bits below the decimal point). - other = other.toInt(); - } - } - if (this < other) { - return LESS; - } else if (this > other) { - return GREATER; - } else { - return EQUAL; - } - } - - int round() { - return this; - } - - int floor() { - return this; - } - - int ceil() { - return this; - } - - int truncate() { - return this; - } - - double roundToDouble() { - return this.toDouble(); - } - - double floorToDouble() { - return this.toDouble(); - } - - double ceilToDouble() { - return this.toDouble(); - } - - double truncateToDouble() { - return this.toDouble(); - } - - num clamp(num lowerLimit, num upperLimit) { - // TODO: Remove these null checks once all code is opted into strong nonnullable mode. - if (lowerLimit == null) { - throw new ArgumentError.notNull("lowerLimit"); - } - if (upperLimit == null) { - throw new ArgumentError.notNull("upperLimit"); - } - // Special case for integers. - if (lowerLimit is int && upperLimit is int && lowerLimit <= upperLimit) { - if (this < lowerLimit) return lowerLimit; - if (this > upperLimit) return upperLimit; - return this; - } - // Generic case involving doubles, and invalid integer ranges. - if (lowerLimit.compareTo(upperLimit) > 0) { - throw new ArgumentError(lowerLimit); - } - if (lowerLimit.isNaN) return lowerLimit; - // Note that we don't need to care for -0.0 for the lower limit. - if (this < lowerLimit) return lowerLimit; - if (this.compareTo(upperLimit) > 0) return upperLimit; - return this; - } - - int toInt() { - return this; - } - - @pragma("vm:exact-result-type", _Double) - double toDouble() { - return new _Double.fromInteger(this); - } - - String toStringAsFixed(int fractionDigits) { - return this.toDouble().toStringAsFixed(fractionDigits); - } - - String toStringAsExponential([int? fractionDigits]) { - return this.toDouble().toStringAsExponential(fractionDigits); - } - - String toStringAsPrecision(int precision) { - return this.toDouble().toStringAsPrecision(precision); - } - - static const _digits = "0123456789abcdefghijklmnopqrstuvwxyz"; - - String toRadixString(int radix) { - if (radix < 2 || 36 < radix) { - throw new RangeError.range(radix, 2, 36, "radix"); - } - if (radix & (radix - 1) == 0) { - return _toPow2String(radix); - } - if (radix == 10) return this.toString(); - final bool isNegative = this < 0; - int value = isNegative ? -this : this; - if (value < 0) { - // With integers limited to 64 bits, the value - // MIN_INT64 = -0x8000000000000000 overflows at negation: - // -MIN_INT64 == MIN_INT64, so it requires special handling. - return _minInt64ToRadixString(radix); - } - var temp = []; - do { - int digit = value % radix; - value ~/= radix; - temp.add(_digits.codeUnitAt(digit)); - } while (value > 0); - if (isNegative) temp.add(0x2d); // '-'. - - _OneByteString string = _OneByteString._allocate(temp.length); - for (int i = 0, j = temp.length; j > 0; i++) { - string._setAt(i, temp[--j]); - } - return string; - } - - String _toPow2String(int radix) { - int value = this; - if (value == 0) return "0"; - assert(radix & (radix - 1) == 0); - var negative = value < 0; - var bitsPerDigit = radix.bitLength - 1; - var length = 0; - if (negative) { - value = -value; - length = 1; - if (value < 0) { - // With integers limited to 64 bits, the value - // MIN_INT64 = -0x8000000000000000 overflows at negation: - // -MIN_INT64 == MIN_INT64, so it requires special handling. - return _minInt64ToRadixString(radix); - } - } - // Integer division, rounding up, to find number of _digits. - length += (value.bitLength + bitsPerDigit - 1) ~/ bitsPerDigit; - _OneByteString string = _OneByteString._allocate(length); - string._setAt(0, 0x2d); // '-'. Is overwritten if not negative. - var mask = radix - 1; - do { - string._setAt(--length, _digits.codeUnitAt(value & mask)); - value >>= bitsPerDigit; - } while (value > 0); - return string; - } - - /// Converts negative value to radix string. - /// This method is only used to handle corner case of - /// MIN_INT64 = -0x8000000000000000. - String _minInt64ToRadixString(int radix) { - var temp = []; - int value = this; - assert(value < 0); - do { - int digit = -unsafeCast(value.remainder(radix)); - value ~/= radix; - temp.add(_digits.codeUnitAt(digit)); - } while (value != 0); - temp.add(0x2d); // '-'. - - _OneByteString string = _OneByteString._allocate(temp.length); - for (int i = 0, j = temp.length; j > 0; i++) { - string._setAt(i, temp[--j]); - } - return string; - } - - // Returns pow(this, e) % m. - int modPow(int e, int m) { - // TODO: Remove these null checks once all code is opted into strong nonnullable mode. - if (e == null) { - throw new ArgumentError.notNull("exponent"); - } - if (m == null) { - throw new ArgumentError.notNull("modulus"); - } - if (e < 0) throw new RangeError.range(e, 0, null, "exponent"); - if (m <= 0) throw new RangeError.range(m, 1, null, "modulus"); - if (e == 0) return 1; - - // This is floor(sqrt(2^63)). - const int maxValueThatCanBeSquaredWithoutTruncation = 3037000499; - if (m > maxValueThatCanBeSquaredWithoutTruncation) { - // Use BigInt version to avoid truncation in multiplications below. - return BigInt.from(this).modPow(BigInt.from(e), BigInt.from(m)).toInt(); - } - - int b = this; - if (b < 0 || b > m) { - b %= m; - } - int r = 1; - while (e > 0) { - if (e.isOdd) { - r = (r * b) % m; - } - e >>= 1; - b = (b * b) % m; - } - return r; - } - - // If inv is false, returns gcd(x, y). - // If inv is true and gcd(x, y) = 1, returns d, so that c*x + d*y = 1. - // If inv is true and gcd(x, y) != 1, throws Exception("Not coprime"). - static int _binaryGcd(int x, int y, bool inv) { - int s = 0; - if (!inv) { - while (x.isEven && y.isEven) { - x >>= 1; - y >>= 1; - s++; - } - if (y.isOdd) { - var t = x; - x = y; - y = t; - } - } - final bool ac = x.isEven; - int u = x; - int v = y; - int a = 1, b = 0, c = 0, d = 1; - do { - while (u.isEven) { - u >>= 1; - if (ac) { - if (!a.isEven || !b.isEven) { - a += y; - b -= x; - } - a >>= 1; - } else if (!b.isEven) { - b -= x; - } - b >>= 1; - } - while (v.isEven) { - v >>= 1; - if (ac) { - if (!c.isEven || !d.isEven) { - c += y; - d -= x; - } - c >>= 1; - } else if (!d.isEven) { - d -= x; - } - d >>= 1; - } - if (u >= v) { - u -= v; - if (ac) a -= c; - b -= d; - } else { - v -= u; - if (ac) c -= a; - d -= b; - } - } while (u != 0); - if (!inv) return v << s; - if (v != 1) { - throw new Exception("Not coprime"); - } - if (d < 0) { - d += x; - if (d < 0) d += x; - } else if (d > x) { - d -= x; - if (d > x) d -= x; - } - return d; - } - - // Returns 1/this % m, with m > 0. - int modInverse(int m) { - // TODO: Remove these null checks once all code is opted into strong nonnullable mode. - if (m == null) { - throw new ArgumentError.notNull("modulus"); - } - if (m <= 0) throw new RangeError.range(m, 1, null, "modulus"); - if (m == 1) return 0; - int t = this; - if ((t < 0) || (t >= m)) t %= m; - if (t == 1) return 1; - if ((t == 0) || (t.isEven && m.isEven)) { - throw new Exception("Not coprime"); - } - return _binaryGcd(m, t, true); - } - - // Returns gcd of abs(this) and abs(other). - int gcd(int other) { - // TODO: Remove these null checks once all code is opted into strong nonnullable mode. - if (other == null) { - throw new ArgumentError.notNull("other"); - } - int x = this.abs(); - int y = other.abs(); - if (x == 0) return y; - if (y == 0) return x; - if ((x == 1) || (y == 1)) return 1; - return _binaryGcd(x, y, false); - } -} - -@pragma("vm:entry-point") -class _Smi extends _IntegerImplementation { - factory _Smi._uninstantiable() { - throw "Unreachable"; - } - - int get hashCode => this; - int get _identityHashCode => this; - @pragma("vm:exact-result-type", "dart:core#_Smi") - int operator ~() native "Smi_bitNegate"; - @pragma("vm:exact-result-type", "dart:core#_Smi") - int get bitLength native "Smi_bitLength"; - - int operator &(int other) => other._bitAndFromSmi(this); - - @pragma("vm:exact-result-type", "dart:core#_Smi") - int _bitAndFromSmi(_Smi other) native "Smi_bitAndFromSmi"; - - /** - * The digits of '00', '01', ... '99' as a single array. - * - * Get the digits of `n`, with `0 <= n < 100`, as - * `_digitTable[n * 2]` and `_digitTable[n * 2 + 1]`. - */ - static const _digitTable = const [ - 0x30, 0x30, 0x30, 0x31, 0x30, 0x32, 0x30, 0x33, // - 0x30, 0x34, 0x30, 0x35, 0x30, 0x36, 0x30, 0x37, // - 0x30, 0x38, 0x30, 0x39, 0x31, 0x30, 0x31, 0x31, // - 0x31, 0x32, 0x31, 0x33, 0x31, 0x34, 0x31, 0x35, // - 0x31, 0x36, 0x31, 0x37, 0x31, 0x38, 0x31, 0x39, // - 0x32, 0x30, 0x32, 0x31, 0x32, 0x32, 0x32, 0x33, // - 0x32, 0x34, 0x32, 0x35, 0x32, 0x36, 0x32, 0x37, // - 0x32, 0x38, 0x32, 0x39, 0x33, 0x30, 0x33, 0x31, // - 0x33, 0x32, 0x33, 0x33, 0x33, 0x34, 0x33, 0x35, // - 0x33, 0x36, 0x33, 0x37, 0x33, 0x38, 0x33, 0x39, // - 0x34, 0x30, 0x34, 0x31, 0x34, 0x32, 0x34, 0x33, // - 0x34, 0x34, 0x34, 0x35, 0x34, 0x36, 0x34, 0x37, // - 0x34, 0x38, 0x34, 0x39, 0x35, 0x30, 0x35, 0x31, // - 0x35, 0x32, 0x35, 0x33, 0x35, 0x34, 0x35, 0x35, // - 0x35, 0x36, 0x35, 0x37, 0x35, 0x38, 0x35, 0x39, // - 0x36, 0x30, 0x36, 0x31, 0x36, 0x32, 0x36, 0x33, // - 0x36, 0x34, 0x36, 0x35, 0x36, 0x36, 0x36, 0x37, // - 0x36, 0x38, 0x36, 0x39, 0x37, 0x30, 0x37, 0x31, // - 0x37, 0x32, 0x37, 0x33, 0x37, 0x34, 0x37, 0x35, // - 0x37, 0x36, 0x37, 0x37, 0x37, 0x38, 0x37, 0x39, // - 0x38, 0x30, 0x38, 0x31, 0x38, 0x32, 0x38, 0x33, // - 0x38, 0x34, 0x38, 0x35, 0x38, 0x36, 0x38, 0x37, // - 0x38, 0x38, 0x38, 0x39, 0x39, 0x30, 0x39, 0x31, // - 0x39, 0x32, 0x39, 0x33, 0x39, 0x34, 0x39, 0x35, // - 0x39, 0x36, 0x39, 0x37, 0x39, 0x38, 0x39, 0x39, // - ]; - - /** - * Result of int.toString for -99, -98, ..., 98, 99. - */ - static const _smallLookupTable = const [ - "-99", "-98", "-97", "-96", "-95", "-94", "-93", "-92", "-91", "-90", // - "-89", "-88", "-87", "-86", "-85", "-84", "-83", "-82", "-81", "-80", // - "-79", "-78", "-77", "-76", "-75", "-74", "-73", "-72", "-71", "-70", // - "-69", "-68", "-67", "-66", "-65", "-64", "-63", "-62", "-61", "-60", // - "-59", "-58", "-57", "-56", "-55", "-54", "-53", "-52", "-51", "-50", // - "-49", "-48", "-47", "-46", "-45", "-44", "-43", "-42", "-41", "-40", // - "-39", "-38", "-37", "-36", "-35", "-34", "-33", "-32", "-31", "-30", // - "-29", "-28", "-27", "-26", "-25", "-24", "-23", "-22", "-21", "-20", // - "-19", "-18", "-17", "-16", "-15", "-14", "-13", "-12", "-11", "-10", // - "-9", "-8", "-7", "-6", "-5", "-4", "-3", "-2", "-1", "0", // - "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", // - "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", // - "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", // - "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", // - "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", // - "51", "52", "53", "54", "55", "56", "57", "58", "59", "60", // - "61", "62", "63", "64", "65", "66", "67", "68", "69", "70", // - "71", "72", "73", "74", "75", "76", "77", "78", "79", "80", // - "81", "82", "83", "84", "85", "86", "87", "88", "89", "90", // - "91", "92", "93", "94", "95", "96", "97", "98", "99" // - ]; - - // Powers of 10 above 1000000 are indistinguishable by eye. - static const int _POW_10_7 = 10000000; - static const int _POW_10_8 = 100000000; - static const int _POW_10_9 = 1000000000; - - // Find the number of decimal digits in a positive smi. - // Never called with numbers < 100. These are handled before calling. - static int _positiveBase10Length(var smi) { - // A positive smi has length <= 19 if 63-bit, <=10 if 31-bit. - // Avoid comparing a 31-bit smi to a non-smi. - if (smi < 1000) return 3; - if (smi < 10000) return 4; - if (smi < _POW_10_7) { - if (smi < 100000) return 5; - if (smi < 1000000) return 6; - return 7; - } - if (smi < _POW_10_8) return 8; - if (smi < _POW_10_9) return 9; - smi = smi ~/ _POW_10_9; - // Handle numbers < 100 before calling recursively. - if (smi < 10) return 10; - if (smi < 100) return 11; - return 9 + _positiveBase10Length(smi); - } - - String toString() { - if (this < 100 && this > -100) { - // Issue(https://dartbug.com/39639): The analyzer incorrectly reports the - // result type as `num`. - return _smallLookupTable[unsafeCast(this + 99)]; - } - if (this < 0) return _negativeToString(this); - // Inspired by Andrei Alexandrescu: "Three Optimization Tips for C++" - // Avoid expensive remainder operation by doing it on more than - // one digit at a time. - const int DIGIT_ZERO = 0x30; - int length = _positiveBase10Length(this); - _OneByteString result = _OneByteString._allocate(length); - int index = length - 1; - _Smi smi = this; - do { - // Two digits at a time. - final int twoDigits = unsafeCast(smi.remainder(100)); - smi = unsafeCast<_Smi>(smi ~/ 100); - int digitIndex = twoDigits * 2; - result._setAt(index, _digitTable[digitIndex + 1]); - result._setAt(index - 1, _digitTable[digitIndex]); - index -= 2; - } while (smi >= 100); - if (smi < 10) { - // Character code for '0'. - // Issue(https://dartbug.com/39639): The analyzer incorrectly reports the - // result type as `num`. - result._setAt(index, unsafeCast(DIGIT_ZERO + smi)); - } else { - // No remainder for this case. - // Issue(https://dartbug.com/39639): The analyzer incorrectly reports the - // result type as `num`. - int digitIndex = unsafeCast(smi * 2); - result._setAt(index, _digitTable[digitIndex + 1]); - result._setAt(index - 1, _digitTable[digitIndex]); - } - return result; - } - - // Find the number of decimal digits in a negative smi. - // Never called with numbers > -100. These are handled before calling. - static int _negativeBase10Length(var negSmi) { - // A negative smi has length <= 19 if 63-bit, <=10 if 31-bit. - // Avoid comparing a 31-bit smi to a non-smi. - if (negSmi > -1000) return 3; - if (negSmi > -10000) return 4; - if (negSmi > -_POW_10_7) { - if (negSmi > -100000) return 5; - if (negSmi > -1000000) return 6; - return 7; - } - if (negSmi > -_POW_10_8) return 8; - if (negSmi > -_POW_10_9) return 9; - negSmi = negSmi ~/ _POW_10_9; - // Handle numbers > -100 before calling recursively. - if (negSmi > -10) return 10; - if (negSmi > -100) return 11; - return 9 + _negativeBase10Length(negSmi); - } - - // Convert a negative smi to a string. - // Doesn't negate the smi to avoid negating the most negative smi, which - // would become a non-smi. - static String _negativeToString(int negSmi) { - // Character code for '-' - const int MINUS_SIGN = 0x2d; - // Character code for '0'. - const int DIGIT_ZERO = 0x30; - if (negSmi > -10) { - return _OneByteString._allocate(2) - .._setAt(0, MINUS_SIGN) - .._setAt(1, DIGIT_ZERO - negSmi); - } - if (negSmi > -100) { - int digitIndex = 2 * -negSmi; - return _OneByteString._allocate(3) - .._setAt(0, MINUS_SIGN) - .._setAt(1, _digitTable[digitIndex]) - .._setAt(2, _digitTable[digitIndex + 1]); - } - // Number of digits, not including minus. - int digitCount = _negativeBase10Length(negSmi); - _OneByteString result = _OneByteString._allocate(digitCount + 1); - result._setAt(0, MINUS_SIGN); // '-'. - int index = digitCount; - do { - int twoDigits = unsafeCast(negSmi.remainder(100)); - negSmi = negSmi ~/ 100; - int digitIndex = -twoDigits * 2; - result._setAt(index, _digitTable[digitIndex + 1]); - result._setAt(index - 1, _digitTable[digitIndex]); - index -= 2; - } while (negSmi <= -100); - if (negSmi > -10) { - result._setAt(index, DIGIT_ZERO - negSmi); - } else { - // No remainder necessary for this case. - int digitIndex = -negSmi * 2; - result._setAt(index, _digitTable[digitIndex + 1]); - result._setAt(index - 1, _digitTable[digitIndex]); - } - return result; - } -} - -// Represents integers that cannot be represented by Smi but fit into 64bits. -@pragma("vm:entry-point") -class _Mint extends _IntegerImplementation { - factory _Mint._uninstantiable() { - throw "Unreachable"; - } - - int get hashCode => this; - int get _identityHashCode => this; - @pragma("vm:non-nullable-result-type") - int operator ~() native "Mint_bitNegate"; - @pragma("vm:exact-result-type", "dart:core#_Smi") - int get bitLength native "Mint_bitLength"; - - int _bitAndFromSmi(_Smi other) => _bitAndFromInteger(other); -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/integers_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/integers_patch.dart deleted file mode 100644 index 48313538f64..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/integers_patch.dart +++ /dev/null @@ -1,308 +0,0 @@ -// Copyright (c) 2012, 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. - -// part of "core_patch.dart"; - -/// VM implementation of int. -@patch -class int { - @patch - const factory int.fromEnvironment(String name, {int defaultValue = 0}) - native "Integer_fromEnvironment"; - - int _bitAndFromSmi(_Smi other); - int _bitAndFromInteger(int other); - int _bitOrFromInteger(int other); - int _bitXorFromInteger(int other); - int _shrFromInteger(int other); - int _shlFromInteger(int other); - - static int? _tryParseSmi(String str, int first, int last) { - assert(first <= last); - var ix = first; - var sign = 1; - var c = str.codeUnitAt(ix); - // Check for leading '+' or '-'. - if ((c == 0x2b) || (c == 0x2d)) { - ix++; - sign = 0x2c - c; // -1 for '-', +1 for '+'. - if (ix > last) { - return null; // Empty. - } - } - var smiLimit = is64Bit ? 18 : 9; - if ((last - ix) >= smiLimit) { - return null; // May not fit into a Smi. - } - var result = 0; - for (int i = ix; i <= last; i++) { - var c = 0x30 ^ str.codeUnitAt(i); - if (9 < c) { - return null; - } - result = 10 * result + c; - } - return sign * result; - } - - @patch - static int parse(String source, {int? radix, int onError(String source)?}) { - if (source == null) throw new ArgumentError("The source must not be null"); - if (source.isEmpty) { - return _throwFormatException(onError, source, 0, radix, null); - } - if (radix == null || radix == 10) { - // Try parsing immediately, without trimming whitespace. - int? result = _tryParseSmi(source, 0, source.length - 1); - if (result != null) return result; - } else if (radix < 2 || radix > 36) { - throw new RangeError("Radix $radix not in range 2..36"); - } - // Split here so improve odds of parse being inlined and the checks omitted. - return _parse(unsafeCast<_StringBase>(source), radix, onError); - } - - static int _parse(_StringBase source, int? radix, onError) { - int end = source._lastNonWhitespace() + 1; - if (end == 0) { - return _throwFormatException(onError, source, source.length, radix, null); - } - int start = source._firstNonWhitespace(); - - int first = source.codeUnitAt(start); - int sign = 1; - if (first == 0x2b /* + */ || first == 0x2d /* - */) { - sign = 0x2c - first; // -1 if '-', +1 if '+'. - start++; - if (start == end) { - return _throwFormatException(onError, source, end, radix, null); - } - first = source.codeUnitAt(start); - } - if (radix == null) { - // check for 0x prefix. - int index = start; - if (first == 0x30 /* 0 */) { - index++; - if (index == end) return 0; - first = source.codeUnitAt(index); - if ((first | 0x20) == 0x78 /* x */) { - index++; - if (index == end) { - return _throwFormatException(onError, source, index, null, null); - } - return _parseRadix(source, 16, index, end, sign, sign > 0, onError); - } - } - radix = 10; - } - return _parseRadix(source, radix, start, end, sign, false, onError); - } - - @patch - static int? tryParse(String source, {int? radix}) { - if (source == null) throw new ArgumentError("The source must not be null"); - if (source.isEmpty) return null; - if (radix == null || radix == 10) { - // Try parsing immediately, without trimming whitespace. - int? result = _tryParseSmi(source, 0, source.length - 1); - if (result != null) return result; - } else if (radix < 2 || radix > 36) { - throw new RangeError("Radix $radix not in range 2..36"); - } - try { - return _parse(unsafeCast<_StringBase>(source), radix, _kNull); - } catch (e) { - return null; - } - } - - static Null _kNull(_) => null; - - static int _throwFormatException(onError, source, index, radix, message) { - if (onError != null) return onError(source); - if (message != null) { - throw new FormatException(message, source, index); - } - if (radix == null) { - throw new FormatException("Invalid number", source, index); - } - throw new FormatException("Invalid radix-$radix number", source, index); - } - - static int _parseRadix(String source, int radix, int start, int end, int sign, - bool allowU64, onError) { - int tableIndex = (radix - 2) * 4 + (is64Bit ? 2 : 0); - int blockSize = _PARSE_LIMITS[tableIndex]; - int length = end - start; - if (length <= blockSize) { - int? smi = _parseBlock(source, radix, start, end); - if (smi == null) { - return _throwFormatException(onError, source, start, radix, null); - } - return sign * smi; - } - - // Often cheaper than: int smallBlockSize = length % blockSize; - // because digit count generally tends towards smaller. rather - // than larger. - int smallBlockSize = length; - while (smallBlockSize >= blockSize) smallBlockSize -= blockSize; - int result = 0; - if (smallBlockSize > 0) { - int blockEnd = start + smallBlockSize; - int? smi = _parseBlock(source, radix, start, blockEnd); - if (smi == null) { - return _throwFormatException(onError, source, start, radix, null); - } - result = sign * smi; - start = blockEnd; - } - int multiplier = _PARSE_LIMITS[tableIndex + 1]; - int positiveOverflowLimit = 0; - int negativeOverflowLimit = 0; - tableIndex = tableIndex << 1; // pre-multiply by 2 for simpler indexing - positiveOverflowLimit = _int64OverflowLimits[tableIndex]; - if (positiveOverflowLimit == 0) { - positiveOverflowLimit = _initInt64OverflowLimits(tableIndex, multiplier); - } - negativeOverflowLimit = _int64OverflowLimits[tableIndex + 1]; - int blockEnd = start + blockSize; - do { - int? smi = _parseBlock(source, radix, start, blockEnd); - if (smi == null) { - return _throwFormatException(onError, source, start, radix, null); - } - if (result >= positiveOverflowLimit) { - if ((result > positiveOverflowLimit) || - (smi > _int64OverflowLimits[tableIndex + 2])) { - // Although the unsigned overflow limits do not depend on the - // platform, the multiplier and block size, which are used to - // compute it, do. - int X = is64Bit ? 1 : 0; - if (allowU64 && - !(result >= _int64UnsignedOverflowLimits[X] && - (result > _int64UnsignedOverflowLimits[X] || - smi > _int64UnsignedSmiOverflowLimits[X])) && - blockEnd + blockSize > end) { - return (result * multiplier) + smi; - } - return _throwFormatException(onError, source, null, radix, - "Positive input exceeds the limit of integer"); - } - } else if (result <= negativeOverflowLimit) { - if ((result < negativeOverflowLimit) || - (smi > _int64OverflowLimits[tableIndex + 3])) { - return _throwFormatException(onError, source, null, radix, - "Negative input exceeds the limit of integer"); - } - } - result = (result * multiplier) + (sign * smi); - start = blockEnd; - blockEnd = start + blockSize; - } while (blockEnd <= end); - return result; - } - - // Parse block of digits into a Smi. - static _Smi? _parseBlock(String source, int radix, int start, int end) { - _Smi result = unsafeCast<_Smi>(0); - if (radix <= 10) { - for (int i = start; i < end; i++) { - int digit = source.codeUnitAt(i) ^ 0x30; - if (digit >= radix) return null; - result = (radix * result + digit) as _Smi; - } - } else { - for (int i = start; i < end; i++) { - int char = source.codeUnitAt(i); - int digit = char ^ 0x30; - if (digit > 9) { - digit = (char | 0x20) - (0x61 - 10); - if (digit < 10 || digit >= radix) return null; - } - result = (radix * result + digit) as _Smi; - } - } - return result; - } - - // For each radix, 2-36, how many digits are guaranteed to fit in a smi, - // and magnitude of such a block (radix ** digit-count). - // 32-bit limit/multiplier at (radix - 2)*4, 64-bit limit at (radix-2)*4+2 - static const _PARSE_LIMITS = const [ - 30, 1073741824, 62, 4611686018427387904, // radix: 2 - 18, 387420489, 39, 4052555153018976267, - 15, 1073741824, 30, 1152921504606846976, - 12, 244140625, 26, 1490116119384765625, // radix: 5 - 11, 362797056, 23, 789730223053602816, - 10, 282475249, 22, 3909821048582988049, - 10, 1073741824, 20, 1152921504606846976, - 9, 387420489, 19, 1350851717672992089, - 9, 1000000000, 18, 1000000000000000000, // radix: 10 - 8, 214358881, 17, 505447028499293771, - 8, 429981696, 17, 2218611106740436992, - 8, 815730721, 16, 665416609183179841, - 7, 105413504, 16, 2177953337809371136, - 7, 170859375, 15, 437893890380859375, // radix: 15 - 7, 268435456, 15, 1152921504606846976, - 7, 410338673, 15, 2862423051509815793, - 7, 612220032, 14, 374813367582081024, - 7, 893871739, 14, 799006685782884121, - 6, 64000000, 14, 1638400000000000000, // radix: 20 - 6, 85766121, 14, 3243919932521508681, - 6, 113379904, 13, 282810057883082752, - 6, 148035889, 13, 504036361936467383, - 6, 191102976, 13, 876488338465357824, - 6, 244140625, 13, 1490116119384765625, // radix: 25 - 6, 308915776, 13, 2481152873203736576, - 6, 387420489, 13, 4052555153018976267, - 6, 481890304, 12, 232218265089212416, - 6, 594823321, 12, 353814783205469041, - 6, 729000000, 12, 531441000000000000, // radix: 30 - 6, 887503681, 12, 787662783788549761, - 6, 1073741824, 12, 1152921504606846976, - 5, 39135393, 12, 1667889514952984961, - 5, 45435424, 12, 2386420683693101056, - 5, 52521875, 12, 3379220508056640625, // radix: 35 - 5, 60466176, 11, 131621703842267136, - ]; - - static const _maxInt64 = 0x7fffffffffffffff; - static const _minInt64 = -0x8000000000000000; - - static const _int64UnsignedOverflowLimits = const [0xfffffffff, 0xf]; - static const _int64UnsignedSmiOverflowLimits = const [ - 0xfffffff, - 0xfffffffffffffff - ]; - - /// Calculation of the expression - /// - /// result = (result * multiplier) + (sign * smi) - /// - /// in `_parseRadix()` may overflow 64-bit integers. In such case, - /// `int.parse()` should stop with an error. - /// - /// This table is lazily filled with int64 overflow limits for result and smi. - /// For each multiplier from `_PARSE_LIMITS[tableIndex + 1]` this table - /// contains - /// - /// * `[tableIndex*2]` = positive limit for result - /// * `[tableIndex*2 + 1]` = negative limit for result - /// * `[tableIndex*2 + 2]` = limit for smi if result is exactly at positive limit - /// * `[tableIndex*2 + 3]` = limit for smi if result is exactly at negative limit - static final Int64List _int64OverflowLimits = - new Int64List(_PARSE_LIMITS.length * 2); - - static int _initInt64OverflowLimits(int tableIndex, int multiplier) { - _int64OverflowLimits[tableIndex] = _maxInt64 ~/ multiplier; - _int64OverflowLimits[tableIndex + 1] = _minInt64 ~/ multiplier; - _int64OverflowLimits[tableIndex + 2] = - unsafeCast(_maxInt64.remainder(multiplier)); - _int64OverflowLimits[tableIndex + 3] = - -unsafeCast(_minInt64.remainder(multiplier)); - return _int64OverflowLimits[tableIndex]; - } -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/internal_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/internal_patch.dart deleted file mode 100644 index b904f9eb3f1..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/internal_patch.dart +++ /dev/null @@ -1,190 +0,0 @@ -// Copyright (c) 2013, 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. - -/// Note: the VM concatenates all patch files into a single patch file. This -/// file is the first patch in "dart:_internal" which contains all the imports -/// used by patches of that library. We plan to change this when we have a -/// shared front end and simply use parts. - -import "dart:core" hide Symbol; - -import "dart:isolate" show SendPort; -import "dart:typed_data" show Int32List, Uint8List; - -/// These are the additional parts of this patch library: -// part "class_id_fasta.dart"; -// part "print_patch.dart"; -// part "symbol_patch.dart"; - -// On the VM, we don't make the entire legacy weak mode check -// const to avoid having a constant in the platform libraries -// which evaluates differently in weak vs strong mode. -@patch -bool typeAcceptsNull() => (const []) is List || null is T; - -@patch -List makeListFixedLength(List growableList) - native "Internal_makeListFixedLength"; - -@patch -List makeFixedListUnmodifiable(List fixedLengthList) - native "Internal_makeFixedListUnmodifiable"; - -@patch -Object extractTypeArguments(T instance, Function extract) - native "Internal_extractTypeArguments"; - -/// The returned string is a [_OneByteString] with uninitialized content. -@pragma("vm:entry-point", "call") -String allocateOneByteString(int length) - native "Internal_allocateOneByteString"; - -/// The [string] must be a [_OneByteString]. The [index] must be valid. -@pragma("vm:entry-point", "call") -void writeIntoOneByteString(String string, int index, int codePoint) - native "Internal_writeIntoOneByteString"; - -/// This function is recognized by the VM and compiled into specialized code. -/// It is assumed that [from] is a native [Uint8List] class and [to] is a -/// [_OneByteString]. The [fromStart] and [toStart] indices together with the -/// [length] must specify ranges within the bounds of the list / string. -@pragma("vm:prefer-inline") -void copyRangeFromUint8ListToOneByteString( - Uint8List from, String to, int fromStart, int toStart, int length) { - for (int i = 0; i < length; i++) { - writeIntoOneByteString(to, toStart + i, from[fromStart + i]); - } -} - -/// The returned string is a [_TwoByteString] with uninitialized content. -@pragma("vm:entry-point", "call") -String allocateTwoByteString(int length) - native "Internal_allocateTwoByteString"; - -/// The [string] must be a [_TwoByteString]. The [index] must be valid. -@pragma("vm:entry-point", "call") -void writeIntoTwoByteString(String string, int index, int codePoint) - native "Internal_writeIntoTwoByteString"; - -class VMLibraryHooks { - // Example: "dart:isolate _Timer._factory" - static var timerFactory; - - // Example: "dart:io _EventHandler._sendData" - static var eventHandlerSendData; - - // A nullary closure that answers the current clock value in milliseconds. - // Example: "dart:io _EventHandler._timerMillisecondClock" - static var timerMillisecondClock; - - // Implementation of Resource.readAsBytes. - static var resourceReadAsBytes; - - // Implementation of package root/map provision. - static var packageRootString; - static var packageConfigString; - static var packageConfigUriFuture; - static var resolvePackageUriFuture; - - static var _computeScriptUri; - static var _cachedScript; - static set platformScript(var f) { - _computeScriptUri = f; - _cachedScript = null; - } - - static get platformScript { - if (_cachedScript == null && _computeScriptUri != null) { - _cachedScript = _computeScriptUri(); - } - return _cachedScript; - } -} - -final bool is64Bit = _inquireIs64Bit(); - -bool _inquireIs64Bit() native "Internal_inquireIs64Bit"; - -@pragma("vm:entry-point", "call") -@pragma("vm:exact-result-type", bool) -@pragma("vm:prefer-inline") -bool _classRangeCheck(int cid, int lowerLimit, int upperLimit) { - return cid >= lowerLimit && cid <= upperLimit; -} - -// Utility class now only used by the VM. -class Lists { - @pragma("vm:prefer-inline") - static void copy(List src, int srcStart, List dst, int dstStart, int count) { - if (srcStart < dstStart) { - for (int i = srcStart + count - 1, j = dstStart + count - 1; - i >= srcStart; - i--, j--) { - dst[j] = src[i]; - } - } else { - for (int i = srcStart, j = dstStart; i < srcStart + count; i++, j++) { - dst[j] = src[i]; - } - } - } -} - -// Prepend the parent type arguments (maybe null) of length 'parentLen' to the -// function type arguments (may be null). The result is null if both input -// vectors are null or is a newly allocated and canonicalized vector of length -// 'totalLen'. -@pragma("vm:entry-point", "call") -_prependTypeArguments(functionTypeArguments, parentTypeArguments, parentLen, - totalLen) native "Internal_prependTypeArguments"; - -// Check that a set of type arguments satisfy the type parameter bounds on a -// closure. -@pragma("vm:entry-point", "call") -_boundsCheckForPartialInstantiation(closure, typeArgs) - native "Internal_boundsCheckForPartialInstantiation"; - -// Called by IRRegExpMacroAssembler::GrowStack. -Int32List _growRegExpStack(Int32List stack) { - final newStack = new Int32List(stack.length * 2); - for (int i = 0; i < stack.length; i++) { - newStack[i] = stack[i]; - } - return newStack; -} - -// This function can be used to skip implicit or explicit checked down casts in -// the parts of the core library implementation where we know by construction the -// type of a value. -// -// Important: this is unsafe and must be used with care. -T unsafeCast(Object? v) native "Internal_unsafeCast"; - -// This function can be used to keep an object alive til that point. -// -// This is implemented by a recognized method, but in bytecode through a native. -@pragma('vm:prefer-inline') -void reachabilityFence(Object object) native "Internal_reachabilityFence"; - -void sendAndExit(SendPort sendPort, var message) - native "SendPortImpl_sendAndExitInternal_"; - -void spawnFunction( - SendPort readyPort, - String uri, - Function topLevelFunction, - var message, - bool paused, - bool errorsAreFatal, - SendPort? onExit, - SendPort? onError, - String? packageConfig, - bool newIsolateGroup, - String? debugName) native "Isolate_spawnFunction"; - -// Collection of functions which should only be used for testing purposes. -abstract class VMInternalsForTesting { - // This function can be used by tests to enforce garbage collection. - static void collectAllGarbage() native "Internal_collectAllGarbage"; -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/invocation_mirror_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/invocation_mirror_patch.dart deleted file mode 100644 index 075e001b14d..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/invocation_mirror_patch.dart +++ /dev/null @@ -1,210 +0,0 @@ -// Copyright (c) 2012, 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. - -// part of "core_patch.dart"; - -// NOTE: When making changes to this class, please also update -// `VmTarget.instantiateInvocation` and `VmTarget._invocationType` in -// `pkg/kernel/lib/target/vm.dart`. -class _InvocationMirror implements Invocation { - // Constants describing the invocation kind. - // _FIELD cannot be generated by regular invocation mirrors. - static const int _UNINITIALIZED = -1; - static const int _METHOD = 0; - static const int _GETTER = 1; - static const int _SETTER = 2; - static const int _FIELD = 3; - static const int _LOCAL_VAR = 4; - static const int _KIND_SHIFT = 0; - static const int _KIND_BITS = 3; - static const int _KIND_MASK = (1 << _KIND_BITS) - 1; - - // These values, except _DYNAMIC and _SUPER, are only used when throwing - // NoSuchMethodError for compile-time resolution failures. - static const int _DYNAMIC = 0; - static const int _SUPER = 1; - static const int _STATIC = 2; - static const int _CONSTRUCTOR = 3; - static const int _TOP_LEVEL = 4; - static const int _LEVEL_SHIFT = _KIND_BITS; - static const int _LEVEL_BITS = 3; - static const int _LEVEL_MASK = (1 << _LEVEL_BITS) - 1; - - // ArgumentsDescriptor layout. Keep in sync with enum in dart_entry.h. - static const int _TYPE_ARGS_LEN = 0; - static const int _COUNT = 1; - static const int _SIZE = 2; - static const int _POSITIONAL_COUNT = 3; - static const int _FIRST_NAMED_ENTRY = 4; - - // Internal representation of the invocation mirror. - String? _functionName; - List? _argumentsDescriptor; - List? _arguments; - bool _isSuperInvocation = false; - int _delayedTypeArgumentsLen = 0; - - // External representation of the invocation mirror; populated on demand. - Symbol? _memberName; - int _type = _UNINITIALIZED; - List? _typeArguments; - List? _positionalArguments; - Map? _namedArguments; - - _InvocationMirror._withType(this._memberName, int? type, this._typeArguments, - this._positionalArguments, this._namedArguments) - : _type = type ?? _UNINITIALIZED { - _typeArguments ??= const []; - _positionalArguments ??= const []; - _namedArguments ??= const {}; - } - - void _setMemberNameAndType() { - final funcName = _functionName!; - if (_type == _UNINITIALIZED) { - _type = 0; - } - if (funcName.startsWith("get:")) { - _type |= _GETTER; - _memberName = new internal.Symbol.unvalidated(funcName.substring(4)); - } else if (funcName.startsWith("set:")) { - _type |= _SETTER; - _memberName = - new internal.Symbol.unvalidated(funcName.substring(4) + "="); - } else { - _type |= - _isSuperInvocation ? (_SUPER << _LEVEL_SHIFT) | _METHOD : _METHOD; - _memberName = new internal.Symbol.unvalidated(funcName); - } - } - - Symbol get memberName { - if (_memberName == null) { - _setMemberNameAndType(); - } - return _memberName!; - } - - int get _typeArgsLen { - int typeArgsLen = _argumentsDescriptor![_TYPE_ARGS_LEN]; - return typeArgsLen == 0 ? _delayedTypeArgumentsLen : typeArgsLen; - } - - List get typeArguments { - if (_typeArguments == null) { - if (_typeArgsLen == 0) { - return _typeArguments = const []; - } - // A TypeArguments object does not have a corresponding Dart class and - // cannot be accessed as an array in Dart. Therefore, we need a native - // call to unpack the individual types into a list. - _typeArguments = _unpackTypeArguments(_arguments![0], _typeArgsLen); - } - return _typeArguments!; - } - - // Unpack the given TypeArguments object into a new list of individual types. - static List _unpackTypeArguments(typeArguments, int numTypeArguments) - native "InvocationMirror_unpackTypeArguments"; - - List get positionalArguments { - if (_positionalArguments == null) { - // The argument descriptor counts the receiver, but not the type arguments - // as positional arguments. - int numPositionalArguments = _argumentsDescriptor![_POSITIONAL_COUNT] - 1; - if (numPositionalArguments == 0) { - return _positionalArguments = const []; - } - // Exclude receiver and type args in the returned list. - int receiverIndex = _typeArgsLen > 0 ? 1 : 0; - var args = _arguments!; - _positionalArguments = new _ImmutableList._from( - args, receiverIndex + 1, numPositionalArguments); - } - return _positionalArguments!; - } - - Map get namedArguments { - if (_namedArguments == null) { - final argsDescriptor = _argumentsDescriptor!; - int numArguments = argsDescriptor[_COUNT] - 1; // Exclude receiver. - int numPositionalArguments = argsDescriptor[_POSITIONAL_COUNT] - 1; - int numNamedArguments = numArguments - numPositionalArguments; - if (numNamedArguments == 0) { - return _namedArguments = const {}; - } - int receiverIndex = _typeArgsLen > 0 ? 1 : 0; - final namedArguments = new Map(); - for (int i = 0; i < numNamedArguments; i++) { - int namedEntryIndex = _FIRST_NAMED_ENTRY + 2 * i; - int pos = argsDescriptor[namedEntryIndex + 1]; - String arg_name = argsDescriptor[namedEntryIndex]; - var arg_value = _arguments![receiverIndex + pos]; - namedArguments[new internal.Symbol.unvalidated(arg_name)] = arg_value; - } - _namedArguments = new Map.unmodifiable(namedArguments); - } - return _namedArguments!; - } - - bool get isMethod { - if (_type == _UNINITIALIZED) { - _setMemberNameAndType(); - } - return (_type & _KIND_MASK) == _METHOD; - } - - bool get isAccessor { - if (_type == _UNINITIALIZED) { - _setMemberNameAndType(); - } - return (_type & _KIND_MASK) != _METHOD; - } - - bool get isGetter { - if (_type == _UNINITIALIZED) { - _setMemberNameAndType(); - } - return (_type & _KIND_MASK) == _GETTER; - } - - bool get isSetter { - if (_type == _UNINITIALIZED) { - _setMemberNameAndType(); - } - return (_type & _KIND_MASK) == _SETTER; - } - - _InvocationMirror(this._functionName, this._argumentsDescriptor, - this._arguments, this._isSuperInvocation, this._type, - [this._delayedTypeArgumentsLen = 0]); - - _InvocationMirror._withoutType(this._functionName, this._typeArguments, - this._positionalArguments, this._namedArguments, this._isSuperInvocation, - [this._delayedTypeArgumentsLen = 0]); - - @pragma("vm:entry-point", "call") - static _allocateInvocationMirror(String functionName, - List argumentsDescriptor, List arguments, bool isSuperInvocation, - [int type = _UNINITIALIZED]) { - return new _InvocationMirror( - functionName, argumentsDescriptor, arguments, isSuperInvocation, type); - } - - // This factory is used when creating an `Invocation` for a closure call which - // may have delayed type arguments. In that case, the arguments descriptor will - // indicate 0 type arguments, but the actual number of type arguments are - // passed in `delayedTypeArgumentsLen`. If any type arguments are available, - // the type arguments vector will be the first entry in `arguments`. - @pragma("vm:entry-point", "call") - static _allocateInvocationMirrorForClosure( - String functionName, - List argumentsDescriptor, - List arguments, - int? type, - int delayedTypeArgumentsLen) { - return new _InvocationMirror(functionName, argumentsDescriptor, arguments, - false, type ?? _UNINITIALIZED, delayedTypeArgumentsLen); - } -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/isolate_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/isolate_patch.dart deleted file mode 100644 index da2ed6829ba..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/isolate_patch.dart +++ /dev/null @@ -1,676 +0,0 @@ -// Copyright (c) 2012, 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. - -/// Note: the VM concatenates all patch files into a single patch file. This -/// file is the first patch in "dart:isolate" which contains all the imports -/// used by patches of that library. We plan to change this when we have a -/// shared front end and simply use parts. - -import "dart:_internal" show ClassID, VMLibraryHooks, patch; - -import "dart:async" - show Completer, Future, Stream, StreamController, StreamSubscription, Timer; - -import "dart:collection" show HashMap; -import "dart:typed_data" show ByteBuffer, TypedData, Uint8List; -import "dart:_internal" show spawnFunction; - -/// These are the additional parts of this patch library: -// part "timer_impl.dart"; - -@patch -class ReceivePort { - @patch - factory ReceivePort() => new _ReceivePortImpl(); - - @patch - factory ReceivePort.fromRawReceivePort(RawReceivePort rawPort) { - return new _ReceivePortImpl.fromRawReceivePort(rawPort); - } -} - -@patch -class Capability { - @patch - factory Capability() => new _CapabilityImpl(); -} - -@pragma("vm:entry-point") -class _CapabilityImpl implements Capability { - factory _CapabilityImpl() native "CapabilityImpl_factory"; - - bool operator ==(var other) { - return (other is _CapabilityImpl) && _equals(other); - } - - int get hashCode { - return _get_hashcode(); - } - - _equals(other) native "CapabilityImpl_equals"; - _get_hashcode() native "CapabilityImpl_get_hashcode"; -} - -@patch -class RawReceivePort { - /** - * Opens a long-lived port for receiving messages. - * - * A [RawReceivePort] is low level and does not work with [Zone]s. It - * can not be paused. The data-handler must be set before the first - * event is received. - */ - @patch - factory RawReceivePort([Function? handler]) { - _RawReceivePortImpl result = new _RawReceivePortImpl(); - result.handler = handler; - return result; - } -} - -class _ReceivePortImpl extends Stream implements ReceivePort { - _ReceivePortImpl() : this.fromRawReceivePort(new RawReceivePort()); - - _ReceivePortImpl.fromRawReceivePort(this._rawPort) - : _controller = new StreamController(sync: true) { - _controller.onCancel = close; - _rawPort.handler = _controller.add; - } - - SendPort get sendPort { - return _rawPort.sendPort; - } - - StreamSubscription listen(void onData(var message)?, - {Function? onError, void onDone()?, bool? cancelOnError}) { - return _controller.stream.listen(onData, - onError: onError, onDone: onDone, cancelOnError: cancelOnError); - } - - close() { - _rawPort.close(); - _controller.close(); - } - - final RawReceivePort _rawPort; - final StreamController _controller; -} - -typedef void _ImmediateCallback(); - -/// The callback that has been registered through `scheduleImmediate`. -_ImmediateCallback? _pendingImmediateCallback; - -/// The closure that should be used as scheduleImmediateClosure, when the VM -/// is responsible for the event loop. -void _isolateScheduleImmediate(void callback()) { - assert((_pendingImmediateCallback == null) || - (_pendingImmediateCallback == callback)); - _pendingImmediateCallback = callback; -} - -@pragma("vm:entry-point", "call") -void _runPendingImmediateCallback() { - final callback = _pendingImmediateCallback; - if (callback != null) { - _pendingImmediateCallback = null; - callback(); - } -} - -/// The embedder can execute this function to get hold of -/// [_isolateScheduleImmediate] above. -@pragma("vm:entry-point", "call") -Function _getIsolateScheduleImmediateClosure() { - return _isolateScheduleImmediate; -} - -@pragma("vm:entry-point") -class _RawReceivePortImpl implements RawReceivePort { - factory _RawReceivePortImpl() native "RawReceivePortImpl_factory"; - - close() { - // Close the port and remove it from the handler map. - _handlerMap.remove(this._closeInternal()); - } - - SendPort get sendPort { - return _get_sendport(); - } - - bool operator ==(var other) { - return (other is _RawReceivePortImpl) && - (this._get_id() == other._get_id()); - } - - int get hashCode { - return sendPort.hashCode; - } - - /**** Internal implementation details ****/ - _get_id() native "RawReceivePortImpl_get_id"; - _get_sendport() native "RawReceivePortImpl_get_sendport"; - - // Called from the VM to retrieve the handler for a message. - @pragma("vm:entry-point", "call") - static _lookupHandler(int id) { - var result = _handlerMap[id]; - return result; - } - - // Called from the VM to dispatch to the handler. - @pragma("vm:entry-point", "call") - static void _handleMessage(Function handler, var message) { - // TODO(floitsch): this relies on the fact that any exception aborts the - // VM. Once we have non-fatal global exceptions we need to catch errors - // so that we can run the immediate callbacks. - handler(message); - _runPendingImmediateCallback(); - } - - // Call into the VM to close the VM maintained mappings. - _closeInternal() native "RawReceivePortImpl_closeInternal"; - - void set handler(Function? value) { - _handlerMap[this._get_id()] = value; - } - - // TODO(iposva): Ideally keep this map in the VM. - // id to handler mapping. - static _initHandlerMap() { - // TODO(18511): Workaround bad CheckSmi hoisting. - var tempMap = new HashMap(); - // Collect feedback that not all keys are Smis. - tempMap["."] = 1; - tempMap["."] = 2; - - return new HashMap(); - } - - static final Map _handlerMap = _initHandlerMap(); -} - -@pragma("vm:entry-point") -class _SendPortImpl implements SendPort { - factory _SendPortImpl._uninstantiable() { - throw "Unreachable"; - } - - /*--- public interface ---*/ - @pragma("vm:entry-point", "call") - void send(var message) { - _sendInternal(message); - } - - bool operator ==(var other) { - return (other is _SendPortImpl) && (this._get_id() == other._get_id()); - } - - int get hashCode { - return _get_hashcode(); - } - - /*--- private implementation ---*/ - _get_id() native "SendPortImpl_get_id"; - _get_hashcode() native "SendPortImpl_get_hashcode"; - - // Forward the implementation of sending messages to the VM. - void _sendInternal(var message) native "SendPortImpl_sendInternal_"; -} - -typedef _NullaryFunction(); -typedef _UnaryFunction(Never args); -typedef _BinaryFunction(Never args, Never message); - -/** - * Takes the real entry point as argument and invokes it with the - * initial message. Defers execution of the entry point until the - * isolate is in the message loop. - */ -@pragma("vm:entry-point", "call") -void _startMainIsolate(Function entryPoint, List args) { - _startIsolate( - null, // no parent port - entryPoint, - args, - null, // no message - true, // isSpawnUri - null, // no control port - null); // no capabilities -} - -/** - * Returns the _startMainIsolate function. This closurization allows embedders - * to setup trampolines to the main function. This workaround can be removed - * once support for @pragma("vm:entry_point", "get") as documented in - * https://github.com/dart-lang/sdk/issues/35720 lands. - */ -@pragma("vm:entry-point", "call") -Function _getStartMainIsolateFunction() { - return _startMainIsolate; -} - -/** - * Takes the real entry point as argument and invokes it with the initial - * message. - */ -@pragma("vm:entry-point", "call") -void _startIsolate( - SendPort? parentPort, - Function entryPoint, - List? args, - Object? message, - bool isSpawnUri, - RawReceivePort? controlPort, - List? capabilities) { - // The control port (aka the main isolate port) does not handle any messages. - if (controlPort != null) { - controlPort.handler = (_) {}; // Nobody home on the control port. - - if (parentPort != null) { - // Build a message to our parent isolate providing access to the - // current isolate's control port and capabilities. - // - // TODO(floitsch): Send an error message if we can't find the entry point. - final readyMessage = List.filled(2, null); - readyMessage[0] = controlPort.sendPort; - readyMessage[1] = capabilities; - - // Out of an excess of paranoia we clear the capabilities from the - // stack. Not really necessary. - capabilities = null; - parentPort.send(readyMessage); - } - } - assert(capabilities == null); - - // Delay all user code handling to the next run of the message loop. This - // allows us to intercept certain conditions in the event dispatch, such as - // starting in paused state. - RawReceivePort port = new RawReceivePort(); - port.handler = (_) { - port.close(); - - if (isSpawnUri) { - if (entryPoint is _BinaryFunction) { - (entryPoint as dynamic)(args, message); - } else if (entryPoint is _UnaryFunction) { - (entryPoint as dynamic)(args); - } else { - entryPoint(); - } - } else { - entryPoint(message); - } - }; - // Make sure the message handler is triggered. - port.sendPort.send(null); -} - -@patch -class Isolate { - static final _currentIsolate = _getCurrentIsolate(); - static final _rootUri = _getCurrentRootUri(); - - @patch - static Isolate get current => _currentIsolate; - - @patch - String get debugName => _getDebugName(controlPort); - - @patch - static Future get packageRoot { - return Future.value(null); - } - - @patch - static Future get packageConfig { - var hook = VMLibraryHooks.packageConfigUriFuture; - if (hook == null) { - throw new UnsupportedError("Isolate.packageConfig"); - } - return hook(); - } - - @patch - static Future resolvePackageUri(Uri packageUri) { - var hook = VMLibraryHooks.resolvePackageUriFuture; - if (hook == null) { - throw new UnsupportedError("Isolate.resolvePackageUri"); - } - return hook(packageUri); - } - - static bool _packageSupported() => - (VMLibraryHooks.packageConfigUriFuture != null) && - (VMLibraryHooks.resolvePackageUriFuture != null); - - @patch - static Future spawn(void entryPoint(T message), T message, - {bool paused = false, - bool errorsAreFatal = true, - SendPort? onExit, - SendPort? onError, - String? debugName}) async { - // `paused` isn't handled yet. - // Check for the type of `entryPoint` on the spawning isolate to make - // error-handling easier. - if (entryPoint is! _UnaryFunction) { - throw new ArgumentError(entryPoint); - } - // The VM will invoke [_startIsolate] with entryPoint as argument. - - // We do not inherit the package config settings from the parent isolate, - // instead we use the values that were set on the command line. - var packageConfig = VMLibraryHooks.packageConfigString; - var script = VMLibraryHooks.platformScript; - if (script == null) { - // We do not have enough information to support spawning the new - // isolate. - throw new UnsupportedError("Isolate.spawn"); - } - if (script.isScheme("package")) { - script = await Isolate.resolvePackageUri(script); - } - - const bool newIsolateGroup = false; - final RawReceivePort readyPort = new RawReceivePort(); - try { - spawnFunction( - readyPort.sendPort, - script.toString(), - entryPoint, - message, - paused, - errorsAreFatal, - onExit, - onError, - packageConfig, - newIsolateGroup, - debugName); - return await _spawnCommon(readyPort); - } catch (e, st) { - readyPort.close(); - return await new Future.error(e, st); - } - } - - @patch - static Future spawnUri(Uri uri, List args, var message, - {bool paused = false, - SendPort? onExit, - SendPort? onError, - bool errorsAreFatal = true, - bool? checked, - Map? environment, - Uri? packageRoot, - Uri? packageConfig, - bool automaticPackageResolution = false, - String? debugName}) async { - if (environment != null) { - throw new UnimplementedError("environment"); - } - - // Verify that no mutually exclusive arguments have been passed. - if (automaticPackageResolution) { - if (packageRoot != null) { - throw new ArgumentError("Cannot simultaneously request " - "automaticPackageResolution and specify a" - "packageRoot."); - } - if (packageConfig != null) { - throw new ArgumentError("Cannot simultaneously request " - "automaticPackageResolution and specify a" - "packageConfig."); - } - } else { - if ((packageRoot != null) && (packageConfig != null)) { - throw new ArgumentError("Cannot simultaneously specify a " - "packageRoot and a packageConfig."); - } - } - // Resolve the uri against the current isolate's root Uri first. - final Uri spawnedUri = _rootUri!.resolveUri(uri); - - // Inherit this isolate's package resolution setup if not overridden. - if (!automaticPackageResolution && packageConfig == null) { - if (Isolate._packageSupported()) { - packageConfig = await Isolate.packageConfig; - } - } - - // Ensure to resolve package: URIs being handed in as parameters. - if (packageConfig != null) { - // Avoid calling resolvePackageUri if not strictly necessary in case - // the API is not supported. - if (packageConfig.isScheme("package")) { - packageConfig = await Isolate.resolvePackageUri(packageConfig); - } - } - - // The VM will invoke [_startIsolate] and not `main`. - final packageConfigString = packageConfig?.toString(); - - final RawReceivePort readyPort = new RawReceivePort(); - try { - _spawnUri( - readyPort.sendPort, - spawnedUri.toString(), - args, - message, - paused, - onExit, - onError, - errorsAreFatal, - checked, - null, - /* environment */ - packageConfigString, - debugName); - return await _spawnCommon(readyPort); - } catch (e) { - readyPort.close(); - rethrow; - } - } - - static Future _spawnCommon(RawReceivePort readyPort) { - final completer = new Completer.sync(); - readyPort.handler = (readyMessage) { - readyPort.close(); - if (readyMessage is List && readyMessage.length == 2) { - SendPort controlPort = readyMessage[0]; - List capabilities = readyMessage[1]; - completer.complete(new Isolate(controlPort, - pauseCapability: capabilities[0], - terminateCapability: capabilities[1])); - } else if (readyMessage is String) { - // We encountered an error while starting the new isolate. - completer.completeError(new IsolateSpawnException( - 'Unable to spawn isolate: ${readyMessage}')); - } else { - // This shouldn't happen. - completer.completeError(new IsolateSpawnException( - "Internal error: unexpected format for ready message: " - "'${readyMessage}'")); - } - }; - return completer.future; - } - - // TODO(iposva): Cleanup to have only one definition. - // These values need to be kept in sync with the class IsolateMessageHandler - // in vm/isolate.cc. - static const _PAUSE = 1; - static const _RESUME = 2; - static const _PING = 3; - static const _KILL = 4; - static const _ADD_EXIT = 5; - static const _DEL_EXIT = 6; - static const _ADD_ERROR = 7; - static const _DEL_ERROR = 8; - static const _ERROR_FATAL = 9; - - // For 'spawnFunction' see internal_patch.dart. - - static void _spawnUri( - SendPort readyPort, - String uri, - List args, - var message, - bool paused, - SendPort? onExit, - SendPort? onError, - bool errorsAreFatal, - bool? checked, - List? environment, - String? packageConfig, - String? debugName) native "Isolate_spawnUri"; - - static void _sendOOB(port, msg) native "Isolate_sendOOB"; - - static String _getDebugName(SendPort controlPort) - native "Isolate_getDebugName"; - - @patch - void _pause(Capability resumeCapability) { - // _sendOOB expects a fixed length array and hence we create a fixed - // length array and assign values to it instead of using [ ... ]. - var msg = new List.filled(4, null) - ..[0] = 0 // Make room for OOB message type. - ..[1] = _PAUSE - ..[2] = pauseCapability - ..[3] = resumeCapability; - _sendOOB(controlPort, msg); - } - - @patch - void resume(Capability resumeCapability) { - var msg = new List.filled(4, null) - ..[0] = 0 // Make room for OOB message type. - ..[1] = _RESUME - ..[2] = pauseCapability - ..[3] = resumeCapability; - _sendOOB(controlPort, msg); - } - - @patch - void addOnExitListener(SendPort responsePort, {Object? response}) { - var msg = new List.filled(4, null) - ..[0] = 0 // Make room for OOB message type. - ..[1] = _ADD_EXIT - ..[2] = responsePort - ..[3] = response; - _sendOOB(controlPort, msg); - } - - @patch - void removeOnExitListener(SendPort responsePort) { - var msg = new List.filled(3, null) - ..[0] = 0 // Make room for OOB message type. - ..[1] = _DEL_EXIT - ..[2] = responsePort; - _sendOOB(controlPort, msg); - } - - @patch - void setErrorsFatal(bool errorsAreFatal) { - var msg = new List.filled(4, null) - ..[0] = 0 // Make room for OOB message type. - ..[1] = _ERROR_FATAL - ..[2] = terminateCapability - ..[3] = errorsAreFatal; - _sendOOB(controlPort, msg); - } - - @patch - void kill({int priority: beforeNextEvent}) { - var msg = new List.filled(4, null) - ..[0] = 0 // Make room for OOB message type. - ..[1] = _KILL - ..[2] = terminateCapability - ..[3] = priority; - _sendOOB(controlPort, msg); - } - - @patch - void ping(SendPort responsePort, - {Object? response, int priority: immediate}) { - var msg = new List.filled(5, null) - ..[0] = 0 // Make room for OOM message type. - ..[1] = _PING - ..[2] = responsePort - ..[3] = priority - ..[4] = response; - _sendOOB(controlPort, msg); - } - - @patch - void addErrorListener(SendPort port) { - var msg = new List.filled(3, null) - ..[0] = 0 // Make room for OOB message type. - ..[1] = _ADD_ERROR - ..[2] = port; - _sendOOB(controlPort, msg); - } - - @patch - void removeErrorListener(SendPort port) { - var msg = new List.filled(3, null) - ..[0] = 0 // Make room for OOB message type. - ..[1] = _DEL_ERROR - ..[2] = port; - _sendOOB(controlPort, msg); - } - - static Isolate _getCurrentIsolate() { - List portAndCapabilities = _getPortAndCapabilitiesOfCurrentIsolate(); - return new Isolate(portAndCapabilities[0], - pauseCapability: portAndCapabilities[1], - terminateCapability: portAndCapabilities[2]); - } - - static List _getPortAndCapabilitiesOfCurrentIsolate() - native "Isolate_getPortAndCapabilitiesOfCurrentIsolate"; - - static Uri? _getCurrentRootUri() { - try { - return Uri.parse(_getCurrentRootUriStr()); - } catch (e) { - return null; - } - } - - static String _getCurrentRootUriStr() native "Isolate_getCurrentRootUriStr"; -} - -@patch -abstract class TransferableTypedData { - @patch - factory TransferableTypedData.fromList(List chunks) { - if (chunks == null) { - throw ArgumentError(chunks); - } - final int cid = ClassID.getID(chunks); - if (cid != ClassID.cidArray && - cid != ClassID.cidGrowableObjectArray && - cid != ClassID.cidImmutableArray) { - chunks = List.unmodifiable(chunks); - } - return _TransferableTypedDataImpl(chunks); - } -} - -@pragma("vm:entry-point") -class _TransferableTypedDataImpl implements TransferableTypedData { - factory _TransferableTypedDataImpl(List list) - native "TransferableTypedData_factory"; - - ByteBuffer materialize() { - return _materializeIntoUint8List().buffer; - } - - Uint8List _materializeIntoUint8List() - native "TransferableTypedData_materialize"; -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/lib_prefix.dart b/sdk_nnbd/lib/_internal/vm/lib/lib_prefix.dart deleted file mode 100644 index d8e52fdb3e0..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/lib_prefix.dart +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) 2014, 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. - -// part of "core_patch.dart"; - -// This type corresponds to the VM-internal class LibraryPrefix. -@pragma("vm:entry-point") -class _LibraryPrefix { - factory _LibraryPrefix._uninstantiable() { - throw "Unreachable"; - } - - bool _isLoaded() native "LibraryPrefix_isLoaded"; - void _setLoaded() native "LibraryPrefix_setLoaded"; -} - -class _DeferredNotLoadedError extends Error implements NoSuchMethodError { - final _LibraryPrefix prefix; - - _DeferredNotLoadedError(this.prefix); - - String toString() { - return "Deferred library $prefix was not loaded."; - } -} - -@pragma("vm:entry-point") -@pragma("vm:never-inline") // Don't duplicate prefix checking code. -Future _loadLibrary(_LibraryPrefix prefix) { - return new Future(() { - prefix._setLoaded(); - }); -} - -@pragma("vm:entry-point") -@pragma("vm:never-inline") // Don't duplicate prefix checking code. -void _checkLoaded(_LibraryPrefix prefix) { - if (!prefix._isLoaded()) { - throw new _DeferredNotLoadedError(prefix); - } -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/map_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/map_patch.dart deleted file mode 100644 index 07dbc690b57..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/map_patch.dart +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) 2012, 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. - -// part of "core_patch.dart"; - -@patch -class Map { - // Factory constructing a Map from a parser generated Map literal. - // [elements] contains n key-value pairs. - // The keys are at position 2*n and are already type checked by the parser - // in checked mode. - // The values are at position 2*n+1 and are not yet type checked. - @pragma("vm:entry-point", "call") - factory Map._fromLiteral(List elements) { - var map = new LinkedHashMap(); - var len = elements.length; - for (int i = 1; i < len; i += 2) { - map[elements[i - 1]] = elements[i]; - } - return map; - } - - @patch - factory Map.unmodifiable(Map other) { - return new UnmodifiableMapView(new Map.from(other)); - } - - @patch - factory Map() => new LinkedHashMap(); -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/math_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/math_patch.dart deleted file mode 100644 index b41daad7009..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/math_patch.dart +++ /dev/null @@ -1,301 +0,0 @@ -// Copyright (c) 2012, 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. - -/// Note: the VM concatenates all patch files into a single patch file. This -/// file is the first patch in "dart:math" which contains all the imports used -/// by patches of that library. We plan to change this when we have a shared -/// front end and simply use parts. - -import "dart:_internal" show patch; - -import "dart:typed_data" show Uint32List; - -/// There are no parts of this patch library. - -@patch -@pragma("vm:prefer-inline") -T min(T a, T b) { - if (a > b) return b; - if (a < b) return a; - if (b is double) { - // Special case for NaN and -0.0. If one argument is NaN return NaN. - // [min] must also distinguish between -0.0 and 0.0. - if (a is double) { - if (a == 0.0) { - // a is either 0.0 or -0.0. b is either 0.0, -0.0 or NaN. - // The following returns -0.0 if either a or b is -0.0, and it - // returns NaN if b is NaN. - num n = (a + b) * a * b; - return n as T; - } - } - // Check for NaN and b == -0.0. - if (a == 0 && b.isNegative || b.isNaN) return b; - return a; - } - return a; -} - -@patch -@pragma("vm:prefer-inline") -T max(T a, T b) { - if (a > b) return a; - if (a < b) return b; - if (b is double) { - // Special case for NaN and -0.0. If one argument is NaN return NaN. - // [max] must also distinguish between -0.0 and 0.0. - if (a is double) { - if (a == 0.0) { - // a is either 0.0 or -0.0. b is either 0.0, -0.0, or NaN. - // The following returns 0.0 if either a or b is 0.0, and it - // returns NaN if b is NaN. - num n = a + b; - return n as T; - } - } - // Check for NaN. - if (b.isNaN) return b; - return a; - } - // max(-0.0, 0) must return 0. - if (b == 0 && a.isNegative) return b; - return a; -} - -// If [x] is an [int] and [exponent] is a non-negative [int], the result is -// an [int], otherwise the result is a [double]. -@patch -@pragma("vm:prefer-inline") -num pow(num x, num exponent) { - if ((x is int) && (exponent is int) && (exponent >= 0)) { - return _intPow(x, exponent); - } - return _doublePow(x.toDouble(), exponent.toDouble()); -} - -@pragma("vm:exact-result-type", "dart:core#_Double") -double _doublePow(double base, double exponent) { - if (exponent == 0.0) { - return 1.0; // ECMA-262 15.8.2.13 - } - // Speed up simple cases. - if (exponent == 1.0) return base; - if (exponent == 2.0) return base * base; - if (exponent == 3.0) return base * base * base; - - if (base == 1.0) return 1.0; - - if (base.isNaN || exponent.isNaN) { - return double.nan; - } - if ((base != -double.infinity) && (exponent == 0.5)) { - if (base == 0.0) { - return 0.0; - } - return sqrt(base); - } - return _pow(base.toDouble(), exponent.toDouble()); -} - -double _pow(double base, double exponent) native "Math_doublePow"; - -int _intPow(int base, int exponent) { - // Exponentiation by squaring. - int result = 1; - while (exponent != 0) { - if ((exponent & 1) == 1) { - result *= base; - } - exponent >>= 1; - // Skip unnecessary operation (can overflow to Mint). - if (exponent != 0) { - base *= base; - } - } - return result; -} - -@patch -@pragma("vm:exact-result-type", "dart:core#_Double") -@pragma("vm:never-inline") -double atan2(num a, num b) => _atan2(a.toDouble(), b.toDouble()); -@patch -@pragma("vm:exact-result-type", "dart:core#_Double") -@pragma("vm:never-inline") -double sin(num radians) => _sin(radians.toDouble()); -@patch -@pragma("vm:exact-result-type", "dart:core#_Double") -@pragma("vm:never-inline") -double cos(num radians) => _cos(radians.toDouble()); -@patch -@pragma("vm:exact-result-type", "dart:core#_Double") -@pragma("vm:never-inline") -double tan(num radians) => _tan(radians.toDouble()); -@patch -@pragma("vm:exact-result-type", "dart:core#_Double") -@pragma("vm:never-inline") -double acos(num x) => _acos(x.toDouble()); -@patch -@pragma("vm:exact-result-type", "dart:core#_Double") -@pragma("vm:never-inline") -double asin(num x) => _asin(x.toDouble()); -@patch -@pragma("vm:exact-result-type", "dart:core#_Double") -@pragma("vm:never-inline") -double atan(num x) => _atan(x.toDouble()); -@patch -@pragma("vm:exact-result-type", "dart:core#_Double") -@pragma("vm:never-inline") -double sqrt(num x) => _sqrt(x.toDouble()); -@patch -@pragma("vm:prefer-inline") -double exp(num x) => _exp(x.toDouble()); -@patch -@pragma("vm:prefer-inline") -double log(num x) => _log(x.toDouble()); - -double _atan2(double a, double b) native "Math_atan2"; -double _sin(double x) native "Math_sin"; -double _cos(double x) native "Math_cos"; -double _tan(double x) native "Math_tan"; -double _acos(double x) native "Math_acos"; -double _asin(double x) native "Math_asin"; -double _atan(double x) native "Math_atan"; -double _sqrt(double x) native "Math_sqrt"; -double _exp(double x) native "Math_exp"; -double _log(double x) native "Math_log"; - -// TODO(iposva): Handle patch methods within a patch class correctly. -@patch -class Random { - @patch - factory Random([int? seed]) { - var state = _Random._setupSeed((seed == null) ? _Random._nextSeed() : seed); - // Crank a couple of times to distribute the seed bits a bit further. - return new _Random._withState(state) - .._nextState() - .._nextState() - .._nextState() - .._nextState(); - } - - @patch - factory Random.secure() { - return new _SecureRandom(); - } -} - -class _Random implements Random { - // Internal state of the random number generator. - @pragma("vm:entry-point") - final Uint32List _state; - static const _kSTATE_LO = 0; - static const _kSTATE_HI = 1; // Unused in Dart code. - - _Random._withState(this._state); - - // The algorithm used here is Multiply with Carry (MWC) with a Base b = 2^32. - // http://en.wikipedia.org/wiki/Multiply-with-carry - // The constant A is selected from "Numerical Recipes 3rd Edition" p.348 B1. - - // Implements: - // const _A = 0xffffda61; - // var state = - // ((_A * (_state[_kSTATE_LO])) + _state[_kSTATE_HI]) & ((1 << 64) - 1); - // _state[_kSTATE_LO] = state & ((1 << 32) - 1); - // _state[_kSTATE_HI] = state >> 32; - // This is a native to prevent 64-bit operations in Dart, which - // fail with --throw_on_javascript_int_overflow. - // TODO(regis): Implement in Dart and remove Random_nextState in math.cc. - void _nextState() native "Random_nextState"; - - int nextInt(int max) { - const limit = 0x3FFFFFFF; - if ((max <= 0) || ((max > limit) && (max > _POW2_32))) { - throw new RangeError.range( - max, 1, _POW2_32, "max", "Must be positive and <= 2^32"); - } - if ((max & -max) == max) { - // Fast case for powers of two. - _nextState(); - return _state[_kSTATE_LO] & (max - 1); - } - - var rnd32; - var result; - do { - _nextState(); - rnd32 = _state[_kSTATE_LO]; - result = rnd32 % max; - } while ((rnd32 - result + max) > _POW2_32); - return result; - } - - double nextDouble() { - return ((nextInt(1 << 26) * _POW2_27_D) + nextInt(1 << 27)) / _POW2_53_D; - } - - bool nextBool() { - return nextInt(2) == 0; - } - - // Constants used by the algorithm. - static const _POW2_32 = 1 << 32; - static const _POW2_53_D = 1.0 * (1 << 53); - static const _POW2_27_D = 1.0 * (1 << 27); - - // Use a singleton Random object to get a new seed if no seed was passed. - static final _prng = new _Random._withState(_initialSeed()); - - // This is a native to prevent 64-bit operations in Dart, which - // fail with --throw_on_javascript_int_overflow. - // TODO(regis): Implement here in Dart and remove native in math.cc. - static Uint32List _setupSeed(int seed) native "Random_setupSeed"; - // Get a seed from the VM's random number provider. - static Uint32List _initialSeed() native "Random_initialSeed"; - - static int _nextSeed() { - // Trigger the PRNG once to change the internal state. - _prng._nextState(); - return _prng._state[_kSTATE_LO]; - } -} - -class _SecureRandom implements Random { - _SecureRandom() { - // Throw early in constructor if entropy source is not hooked up. - _getBytes(1); - } - - // Return count bytes of entropy as a positive integer; count <= 8. - static int _getBytes(int count) native "SecureRandom_getBytes"; - - int nextInt(int max) { - RangeError.checkValueInInterval( - max, 1, _POW2_32, "max", "Must be positive and <= 2^32"); - final byteCount = ((max - 1).bitLength + 7) >> 3; - if (byteCount == 0) { - return 0; // Not random if max == 1. - } - var rnd; - var result; - do { - rnd = _getBytes(byteCount); - result = rnd % max; - } while ((rnd - result + max) > (1 << (byteCount << 3))); - return result; - } - - double nextDouble() { - return (_getBytes(7) >> 3) / _POW2_53_D; - } - - bool nextBool() { - return _getBytes(1).isEven; - } - - // Constants used by the algorithm. - static const _POW2_32 = 1 << 32; - static const _POW2_53_D = 1.0 * (1 << 53); -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/mirror_reference.dart b/sdk_nnbd/lib/_internal/vm/lib/mirror_reference.dart deleted file mode 100644 index 0cb1e377661..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/mirror_reference.dart +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) 2013, 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. - -// part of "mirrors_patch.dart"; - -@pragma("vm:entry-point") -class _MirrorReference { - factory _MirrorReference._uninstantiable() { - throw "Unreachable"; - } - - bool operator ==(Object other) native "MirrorReference_equals"; -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/mirrors_impl.dart b/sdk_nnbd/lib/_internal/vm/lib/mirrors_impl.dart deleted file mode 100644 index a7f1f136814..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/mirrors_impl.dart +++ /dev/null @@ -1,1499 +0,0 @@ -// Copyright (c) 2012, 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. - -// part of "mirrors_patch.dart"; - -var _dirty = false; // Set to true by the VM when more libraries are loaded. - -class _InternalMirrorError extends Error { - final String _msg; - _InternalMirrorError(this._msg); - String toString() => _msg; -} - -String _n(Symbol symbol) => internal.Symbol.getName(symbol as internal.Symbol); - -Symbol _s(String name) { - return new internal.Symbol.unvalidated(name); -} - -Symbol? _sOpt(String? name) { - if (name == null) return null; - return new internal.Symbol.unvalidated(name); -} - -Symbol _computeQualifiedName(DeclarationMirror? owner, Symbol simpleName) { - if (owner == null) return simpleName; - return _s('${_n(owner.qualifiedName)}.${_n(simpleName)}'); -} - -String _makeSignatureString( - TypeMirror returnType, List parameters) { - StringBuffer buf = new StringBuffer(); - buf.write('('); - bool found_optional_positional = false; - bool found_optional_named = false; - - for (int i = 0; i < parameters.length; i++) { - var param = parameters[i]; - if (param.isOptional && param.isNamed && !found_optional_named) { - buf.write('{'); - found_optional_named = true; - } - if (param.isOptional && !param.isNamed && !found_optional_positional) { - buf.write('['); - found_optional_positional = true; - } - if (param.isNamed) { - buf.write(_n(param.simpleName)); - buf.write(': '); - } - buf.write(_n(param.type.qualifiedName)); - if (i < (parameters.length - 1)) { - buf.write(', '); - } - } - if (found_optional_named) { - buf.write('}'); - } - if (found_optional_positional) { - buf.write(']'); - } - buf.write(') -> '); - buf.write(_n(returnType.qualifiedName)); - return buf.toString(); -} - -SourceLocation? _location(reflectee) native "DeclarationMirror_location"; - -List _metadata(reflectee) native 'DeclarationMirror_metadata'; - -List _wrapMetadata(List reflectees) { - var mirrors = []; - for (var reflectee in reflectees) { - mirrors.add(reflect(reflectee)); - } - return new UnmodifiableListView(mirrors); -} - -bool _subtypeTest(Type a, Type b) native 'TypeMirror_subtypeTest'; - -class _MirrorSystem extends MirrorSystem { - final TypeMirror dynamicType = new _SpecialTypeMirror._('dynamic'); - final TypeMirror voidType = new _SpecialTypeMirror._('void'); - final TypeMirror neverType = new _SpecialTypeMirror._('Never'); - - var _libraries; - Map get libraries { - if ((_libraries == null) || _dirty) { - _libraries = new Map(); - for (LibraryMirror lib in _computeLibraries()) { - _libraries[lib.uri] = lib; - } - _libraries = new UnmodifiableMapView(_libraries); - _dirty = false; - } - return _libraries; - } - - static List _computeLibraries() native "MirrorSystem_libraries"; - - IsolateMirror? _isolate; - IsolateMirror get isolate { - var i = _isolate; - if (i != null) return i; - return _isolate = _computeIsolate(); - } - - static IsolateMirror _computeIsolate() native "MirrorSystem_isolate"; - - String toString() => "MirrorSystem for isolate '${isolate.debugName}'"; -} - -class _SourceLocation implements SourceLocation { - _SourceLocation._(uriString, this.line, this.column) - : this.sourceUri = Uri.parse(uriString); - - // Line and column positions are 1-origin, or 0 if unknown. - final int line; - final int column; - - final Uri sourceUri; - - String toString() { - return column == 0 ? "$sourceUri:$line" : "$sourceUri:$line:$column"; - } -} - -class _IsolateMirror extends Mirror implements IsolateMirror { - final String debugName; - final LibraryMirror rootLibrary; - - _IsolateMirror._(this.debugName, this.rootLibrary); - - bool get isCurrent => true; - - String toString() => "IsolateMirror on '$debugName'"; - - Future loadUri(Uri uri) async { - var result = _loadUri(uri.toString()); - if (result == null) { - // Censored library. - throw new Exception("Cannot load $uri"); - } - return result; - } - - static LibraryMirror? _loadUri(String uri) native "IsolateMirror_loadUri"; -} - -class _SyntheticAccessor implements MethodMirror { - final DeclarationMirror owner; - final Symbol simpleName; - final bool isGetter; - final bool isStatic; - final bool isTopLevel; - final _target; - - _SyntheticAccessor(this.owner, this.simpleName, this.isGetter, this.isStatic, - this.isTopLevel, this._target); - - bool get isSynthetic => true; - bool get isRegularMethod => false; - bool get isOperator => false; - bool get isConstructor => false; - bool get isConstConstructor => false; - bool get isGenerativeConstructor => false; - bool get isFactoryConstructor => false; - bool get isExternal => false; - bool get isRedirectingConstructor => false; - bool get isAbstract => false; - bool get isExtensionMember => false; - - bool get isSetter => !isGetter; - bool get isPrivate => _n(simpleName).startsWith('_'); - - Symbol get qualifiedName => _computeQualifiedName(owner, simpleName); - Symbol get constructorName => Symbol.empty; - - TypeMirror get returnType => _target.type; - List get parameters { - if (isGetter) return const []; - return new UnmodifiableListView( - [new _SyntheticSetterParameter(this, this._target)]); - } - - SourceLocation? get location => null; - List get metadata => const []; - String? get source => null; -} - -class _SyntheticSetterParameter implements ParameterMirror { - final DeclarationMirror owner; - final VariableMirror _target; - - _SyntheticSetterParameter(this.owner, this._target); - - Symbol get simpleName => _target.simpleName; - Symbol get qualifiedName => _computeQualifiedName(owner, simpleName); - TypeMirror get type => _target.type; - - bool get isOptional => false; - bool get isNamed => false; - bool get isStatic => false; - bool get isTopLevel => false; - bool get isConst => false; - bool get isFinal => true; - bool get isPrivate => false; - bool get isExtensionMember => false; - bool get hasDefaultValue => false; - InstanceMirror? get defaultValue => null; - SourceLocation? get location => null; - List get metadata => const []; -} - -abstract class _ObjectMirror extends Mirror implements ObjectMirror { - _invoke(reflectee, functionName, arguments, argumentNames); - _invokeGetter(reflectee, getterName); - _invokeSetter(reflectee, setterName, value); - - final _reflectee; // May be a MirrorReference or an ordinary object. - - _ObjectMirror._(this._reflectee); - - InstanceMirror invoke(Symbol memberName, List positionalArguments, - [Map namedArguments = const {}]) { - int numPositionalArguments = positionalArguments.length; - int numNamedArguments = namedArguments.length; - int numArguments = numPositionalArguments + numNamedArguments; - List arguments = new List.filled(numArguments, null); - arguments.setRange(0, numPositionalArguments, positionalArguments); - List names = new List.filled(numNamedArguments, null); - int argumentIndex = numPositionalArguments; - int nameIndex = 0; - if (numNamedArguments > 0) { - namedArguments.forEach((name, value) { - arguments[argumentIndex++] = value; - names[nameIndex++] = _n(name); - }); - } - - return reflect(this._invoke(_reflectee, _n(memberName), arguments, names)); - } - - InstanceMirror getField(Symbol memberName) { - return reflect(this._invokeGetter(_reflectee, _n(memberName))); - } - - InstanceMirror setField(Symbol memberName, dynamic value) { - this._invokeSetter(_reflectee, _n(memberName), value); - return reflect(value); - } - - delegate(Invocation invocation) { - if (invocation.isMethod) { - return this - .invoke(invocation.memberName, invocation.positionalArguments, - invocation.namedArguments) - .reflectee; - } - if (invocation.isGetter) { - return this.getField(invocation.memberName).reflectee; - } - if (invocation.isSetter) { - var unwrapped = _n(invocation.memberName); - var withoutEqual = _s(unwrapped.substring(0, unwrapped.length - 1)); - var arg = invocation.positionalArguments[0]; - this.setField(withoutEqual, arg).reflectee; - return arg; - } - throw "UNREACHABLE"; - } -} - -class _InstanceMirror extends _ObjectMirror implements InstanceMirror { - _InstanceMirror._(reflectee) : super._(reflectee); - - ClassMirror? _type; - ClassMirror get type { - var t = _type; - if (t != null) return t; - - // Note it not safe to use reflectee.runtimeType because runtimeType may - // be overridden. - return _type = reflectType(_computeType(reflectee)) as ClassMirror; - } - - // LocalInstanceMirrors always reflect local instances - bool get hasReflectee => true; - - get reflectee => _reflectee; - - String toString() => 'InstanceMirror on ${Error.safeToString(_reflectee)}'; - - bool operator ==(Object other) { - return other is _InstanceMirror && identical(_reflectee, other._reflectee); - } - - int get hashCode { - // Avoid hash collisions with the reflectee. This constant is in Smi range - // and happens to be the inner padding from RFC 2104. - return identityHashCode(_reflectee) ^ 0x36363636; - } - - InstanceMirror getField(Symbol memberName) { - return reflect(_invokeGetter(_reflectee, _n(memberName))); - } - - InstanceMirror setField(Symbol memberName, dynamic arg) { - _invokeSetter(_reflectee, _n(memberName), arg); - return reflect(arg); - } - - // Override to include the receiver in the arguments. - InstanceMirror invoke(Symbol memberName, List positionalArguments, - [Map namedArguments = const {}]) { - int numPositionalArguments = positionalArguments.length + 1; // Receiver. - int numNamedArguments = namedArguments.length; - int numArguments = numPositionalArguments + numNamedArguments; - List arguments = new List.filled(numArguments, null); - arguments[0] = _reflectee; // Receiver. - arguments.setRange(1, numPositionalArguments, positionalArguments); - List names = new List.filled(numNamedArguments, null); - int argumentIndex = numPositionalArguments; - int nameIndex = 0; - if (numNamedArguments > 0) { - namedArguments.forEach((name, value) { - arguments[argumentIndex++] = value; - names[nameIndex++] = _n(name); - }); - } - - return reflect(this._invoke(_reflectee, _n(memberName), arguments, names)); - } - - _invoke(reflectee, functionName, arguments, argumentNames) - native 'InstanceMirror_invoke'; - - _invokeGetter(reflectee, getterName) native 'InstanceMirror_invokeGetter'; - - _invokeSetter(reflectee, setterName, value) - native 'InstanceMirror_invokeSetter'; - - static _computeType(reflectee) native 'InstanceMirror_computeType'; -} - -class _ClosureMirror extends _InstanceMirror implements ClosureMirror { - _ClosureMirror._(reflectee) : super._(reflectee); - - MethodMirror? _function; - MethodMirror get function { - var f = _function; - if (f != null) return f; - return _function = _computeFunction(reflectee); - } - - InstanceMirror apply(List positionalArguments, - [Map namedArguments = const {}]) { - return this.invoke(#call, positionalArguments, namedArguments); - } - - String toString() => "ClosureMirror on '${Error.safeToString(_reflectee)}'"; - - static _computeFunction(reflectee) native 'ClosureMirror_function'; -} - -abstract class _TypeMirror { - Type get _reflectedType; -} - -class _ClassMirror extends _ObjectMirror implements ClassMirror, _TypeMirror { - final Type _reflectedType; - Symbol? _simpleName; - DeclarationMirror? _owner; - final bool isAbstract; - final bool _isGeneric; - - // Since Dart 2, mixins are erased by kernel transformation. - // Resulting classes have this flag set, and mixed-in type is pulled into - // the end of interfaces list. - final bool _isTransformedMixinApplication; - - final bool _isGenericDeclaration; - final bool isEnum; - Type _instantiator; - - _ClassMirror._( - reflectee, - reflectedType, - String? simpleName, - this._owner, - this.isAbstract, - this._isGeneric, - this._isTransformedMixinApplication, - this._isGenericDeclaration, - this.isEnum) - : this._simpleName = _sOpt(simpleName), - this._reflectedType = reflectedType, - this._instantiator = reflectedType, - super._(reflectee); - - bool get hasReflectedType => !_isGenericDeclaration; - Type get reflectedType { - if (!hasReflectedType) { - throw new UnsupportedError( - "Declarations of generics have no reflected type"); - } - return _reflectedType; - } - - Symbol get simpleName { - // All but anonymous mixin applications have their name set at construction. - var n = _simpleName; - if (n != null) return n; - - return _simpleName = this._mixinApplicationName; - } - - Symbol? _qualifiedName; - Symbol get qualifiedName { - var n = _qualifiedName; - if (n != null) return n; - - return _qualifiedName = _computeQualifiedName(owner, simpleName); - } - - DeclarationMirror? get owner { - var o = _owner; - if (o != null) return o; - - var uri = _ClassMirror._libraryUri(_reflectee); - return _owner = currentMirrorSystem().libraries[Uri.parse(uri)]; - } - - bool get isPrivate => _n(simpleName).startsWith('_'); - - bool get isTopLevel => true; - - SourceLocation? get location { - return _location(_reflectee); - } - - _ClassMirror? _trueSuperclassField; - _ClassMirror? get _trueSuperclass { - if (_trueSuperclassField == null) { - Type? supertype = isOriginalDeclaration - ? _supertype(_reflectedType) - : _supertypeInstantiated(_reflectedType); - if (supertype == null) { - // Object has no superclass. - return null; - } - var supertypeMirror = reflectType(supertype) as _ClassMirror; - supertypeMirror._instantiator = _instantiator; - _trueSuperclassField = supertypeMirror; - } - return _trueSuperclassField; - } - - ClassMirror? get superclass { - return _trueSuperclass; - } - - var _superinterfaces; - List get superinterfaces { - var i = _superinterfaces; - if (i != null) return i; - - var interfaceTypes = isOriginalDeclaration - ? _nativeInterfaces(_reflectedType) - : _nativeInterfacesInstantiated(_reflectedType); - if (_isTransformedMixinApplication) { - interfaceTypes = interfaceTypes.sublist(0, interfaceTypes.length - 1); - } - var interfaceMirrors = []; - for (var interfaceType in interfaceTypes) { - interfaceMirrors.add(reflectType(interfaceType) as ClassMirror); - } - return _superinterfaces = - new UnmodifiableListView(interfaceMirrors); - } - - Symbol get _mixinApplicationName { - var mixins = []; - var klass = this; - while (_nativeMixin(klass._reflectedType) != null) { - mixins.add(klass.mixin); - klass = klass.superclass as _ClassMirror; - } - return _s(_n(klass.qualifiedName) + - ' with ' + - mixins.reversed.map((ClassMirror m) => _n(m.qualifiedName)).join(', ')); - } - - ClassMirror? _mixin; - ClassMirror get mixin { - var m = _mixin; - if (m != null) return m; - - Type? mixinType = _nativeMixinInstantiated(_reflectedType, _instantiator); - if (mixinType == null) { - // The reflectee is not a mixin application. - return _mixin = this; - } else { - return _mixin = reflectType(mixinType) as ClassMirror; - } - } - - var _cachedStaticMembers; - Map get staticMembers { - var m = _cachedStaticMembers; - if (m != null) m; - - var result = new Map(); - var library = this.owner as LibraryMirror; - declarations.values.forEach((decl) { - if (decl is MethodMirror && decl.isStatic && !decl.isConstructor) { - result[decl.simpleName] = decl; - } - if (decl is VariableMirror && decl.isStatic) { - var getterName = decl.simpleName; - result[getterName] = - new _SyntheticAccessor(this, getterName, true, true, false, decl); - if (!decl.isFinal) { - var setterName = _asSetter(decl.simpleName, library); - result[setterName] = new _SyntheticAccessor( - this, setterName, false, true, false, decl); - } - } - }); - return _cachedStaticMembers = - new UnmodifiableMapView(result); - } - - var _cachedInstanceMembers; - Map get instanceMembers { - var m = _cachedInstanceMembers; - if (m != null) return m; - - var result = new Map(); - var library = this.owner as LibraryMirror; - var sup = superclass; - if (sup != null) { - result.addAll(sup.instanceMembers); - } - declarations.values.forEach((decl) { - if (decl is MethodMirror && - !decl.isStatic && - !decl.isConstructor && - !decl.isAbstract) { - result[decl.simpleName] = decl; - } - if (decl is VariableMirror && !decl.isStatic) { - var getterName = decl.simpleName; - result[getterName] = - new _SyntheticAccessor(this, getterName, true, false, false, decl); - if (!decl.isFinal) { - var setterName = _asSetter(decl.simpleName, library); - result[setterName] = new _SyntheticAccessor( - this, setterName, false, false, false, decl); - } - } - }); - return _cachedInstanceMembers = - new UnmodifiableMapView(result); - } - - Map? _declarations; - Map get declarations { - var d = _declarations; - if (d != null) return d; - - var decls = new Map(); - - var members = _computeMembers(mixin, _instantiator, _reflectee); - for (var member in members) { - decls[member.simpleName] = member; - } - - var constructors = _computeConstructors(_instantiator, _reflectee); - var stringName = _n(simpleName); - for (var constructor in constructors) { - constructor._patchConstructorName(stringName); - decls[constructor.simpleName] = constructor; - } - - for (var typeVariable in typeVariables) { - decls[typeVariable.simpleName] = typeVariable; - } - - return _declarations = - new UnmodifiableMapView(decls); - } - - // Note: returns correct result only for Dart 1 anonymous mixin applications. - bool get _isAnonymousMixinApplication { - if (mixin == this) return false; // Not a mixin application. - return true; - } - - List? _typeVariables; - List get typeVariables { - var v = _typeVariables; - if (v != null) return v; - - if (!_isTransformedMixinApplication && _isAnonymousMixinApplication) { - return _typeVariables = const []; - } - var result = []; - - List params = _ClassMirror_type_variables(_reflectee); - ClassMirror owner = originalDeclaration; - var mirror; - for (var i = 0; i < params.length; i += 2) { - mirror = new _TypeVariableMirror._(params[i + 1], params[i], owner); - result.add(mirror); - } - return _typeVariables = - new UnmodifiableListView(result); - } - - List? _typeArguments; - List get typeArguments { - var a = _typeArguments; - if (a != null) return a; - - if (_isGenericDeclaration || - (!_isTransformedMixinApplication && _isAnonymousMixinApplication)) { - return _typeArguments = const []; - } else { - return _typeArguments = new UnmodifiableListView( - _computeTypeArguments(_reflectedType).cast()); - } - } - - bool get isOriginalDeclaration => !_isGeneric || _isGenericDeclaration; - - ClassMirror get originalDeclaration { - if (isOriginalDeclaration) { - return this; - } else { - return reflectClass(_reflectedType); - } - } - - String toString() => "ClassMirror on '${MirrorSystem.getName(simpleName)}'"; - - InstanceMirror newInstance(Symbol constructorName, List positionalArguments, - [Map namedArguments = const {}]) { - // Native code will add the 1 or 2 implicit arguments depending on whether - // we end up invoking a factory or constructor respectively. - int numPositionalArguments = positionalArguments.length; - int numNamedArguments = namedArguments.length; - int numArguments = numPositionalArguments + numNamedArguments; - List arguments = new List.filled(numArguments, null); - arguments.setRange(0, numPositionalArguments, positionalArguments); - List names = new List.filled(numNamedArguments, null); - int argumentIndex = numPositionalArguments; - int nameIndex = 0; - if (numNamedArguments > 0) { - namedArguments.forEach((name, value) { - arguments[argumentIndex++] = value; - names[nameIndex++] = _n(name); - }); - } - - return reflect(_invokeConstructor( - _reflectee, _reflectedType, _n(constructorName), arguments, names)); - } - - List get metadata { - return _wrapMetadata(_metadata(_reflectee)); - } - - bool operator ==(Object other) { - return other is _ClassMirror && - this._reflectee == other._reflectee && - this._reflectedType == other._reflectedType && - this._isGenericDeclaration == other._isGenericDeclaration; - } - - int get hashCode => simpleName.hashCode; - - bool isSubtypeOf(TypeMirror other) { - if (other == currentMirrorSystem().dynamicType) return true; - if (other == currentMirrorSystem().voidType) return true; - if (other == currentMirrorSystem().neverType) return false; - return _subtypeTest(_reflectedType, (other as _TypeMirror)._reflectedType); - } - - bool isAssignableTo(TypeMirror other) { - if (other == currentMirrorSystem().dynamicType) return true; - if (other == currentMirrorSystem().voidType) return true; - if (other == currentMirrorSystem().neverType) return false; - final otherReflectedType = (other as _TypeMirror)._reflectedType; - return _subtypeTest(_reflectedType, otherReflectedType) || - _subtypeTest(otherReflectedType, _reflectedType); - } - - bool isSubclassOf(ClassMirror other) { - // TODO: Remove these null checks once all code is opted into strong nonnullable mode. - if (other == null) { - throw new ArgumentError.notNull('other'); - } - ClassMirror otherDeclaration = other.originalDeclaration as ClassMirror; - ClassMirror c = this; - while (c != null) { - c = c.originalDeclaration as ClassMirror; - if (c == otherDeclaration) return true; - c = c.superclass as ClassMirror; - } - return false; - } - - static String _libraryUri(reflectee) native "ClassMirror_libraryUri"; - - static Type? _supertype(reflectedType) native "ClassMirror_supertype"; - - static Type? _supertypeInstantiated(reflectedType) - native "ClassMirror_supertype_instantiated"; - - static List _nativeInterfaces(reflectedType) - native "ClassMirror_interfaces"; - - static List _nativeInterfacesInstantiated(reflectedType) - native "ClassMirror_interfaces_instantiated"; - - static Type? _nativeMixin(reflectedType) native "ClassMirror_mixin"; - - static Type? _nativeMixinInstantiated(reflectedType, instantiator) - native "ClassMirror_mixin_instantiated"; - - static List _computeMembers(owner, reflectee, instantiator) - native "ClassMirror_members"; - - List _computeConstructors(reflectee, instantiator) - native "ClassMirror_constructors"; - - _invoke(reflectee, memberName, arguments, argumentNames) - native 'ClassMirror_invoke'; - - _invokeGetter(reflectee, getterName) native 'ClassMirror_invokeGetter'; - - _invokeSetter(reflectee, setterName, value) native 'ClassMirror_invokeSetter'; - - static _invokeConstructor(reflectee, type, constructorName, arguments, - argumentNames) native 'ClassMirror_invokeConstructor'; - - static List _ClassMirror_type_variables(reflectee) - native "ClassMirror_type_variables"; - - static List _computeTypeArguments(reflectee) - native "ClassMirror_type_arguments"; -} - -class _FunctionTypeMirror extends _ClassMirror implements FunctionTypeMirror { - final _functionReflectee; - _FunctionTypeMirror._(reflectee, this._functionReflectee, reflectedType) - : super._(reflectee, reflectedType, null, null, false, false, false, - false, false); - - bool get _isAnonymousMixinApplication => false; - - // FunctionTypeMirrors have a simpleName generated from their signature. - Symbol? _simpleName; - Symbol get simpleName { - var n = _simpleName; - if (n != null) return n; - return _simpleName = _s(_makeSignatureString(returnType, parameters)); - } - - MethodMirror? _callMethod; - MethodMirror get callMethod { - var m = _callMethod; - if (m != null) return m; - return _callMethod = _FunctionTypeMirror_call_method(_functionReflectee); - } - - TypeMirror? _returnType; - TypeMirror get returnType { - var t = _returnType; - if (t != null) return t; - return _returnType = - reflectType(_FunctionTypeMirror_return_type(_functionReflectee)); - } - - List? _parameters; - List get parameters { - var p = _parameters; - if (p != null) return p; - return _parameters = new UnmodifiableListView( - _FunctionTypeMirror_parameters(_functionReflectee) - .cast()); - } - - bool get isOriginalDeclaration => true; - ClassMirror get originalDeclaration => this; - List get typeVariables => const []; - List get typeArguments => const []; - List get metadata => const []; - SourceLocation? get location => null; - - String toString() => "FunctionTypeMirror on '${_n(simpleName)}'"; - - MethodMirror _FunctionTypeMirror_call_method(functionReflectee) - native "FunctionTypeMirror_call_method"; - - static Type _FunctionTypeMirror_return_type(functionReflectee) - native "FunctionTypeMirror_return_type"; - - List _FunctionTypeMirror_parameters(functionReflectee) - native "FunctionTypeMirror_parameters"; -} - -abstract class _DeclarationMirror extends Mirror implements DeclarationMirror { - final _reflectee; - Symbol _simpleName; - - _DeclarationMirror._(this._reflectee, this._simpleName); - - Symbol get simpleName => _simpleName; - - Symbol? _qualifiedName; - Symbol get qualifiedName { - var n = _qualifiedName; - if (n != null) return n; - return _qualifiedName = _computeQualifiedName(owner, simpleName); - } - - bool get isPrivate => _n(simpleName).startsWith('_'); - - SourceLocation? get location { - return _location(_reflectee); - } - - List get metadata { - return _wrapMetadata(_metadata(_reflectee)); - } - - bool operator ==(Object other) { - return other is _DeclarationMirror && this._reflectee == other._reflectee; - } - - int get hashCode => simpleName.hashCode; -} - -class _TypeVariableMirror extends _DeclarationMirror - implements TypeVariableMirror, _TypeMirror { - _TypeVariableMirror._(reflectee, String simpleName, this._owner) - : super._(reflectee, _s(simpleName)); - - DeclarationMirror? _owner; - DeclarationMirror get owner { - var o = _owner; - if (o != null) return o; - return _owner = (_TypeVariableMirror_owner(_reflectee) as TypeMirror) - .originalDeclaration; - } - - bool get isStatic => false; - bool get isTopLevel => false; - - TypeMirror? _upperBound; - TypeMirror get upperBound { - var b = _upperBound; - if (b != null) return b; - return _upperBound = - reflectType(_TypeVariableMirror_upper_bound(_reflectee)); - } - - bool get hasReflectedType => false; - Type get reflectedType { - throw new UnsupportedError('Type variables have no reflected type'); - } - - Type get _reflectedType => _reflectee; - - List get typeVariables => const []; - List get typeArguments => const []; - - bool get isOriginalDeclaration => true; - TypeMirror get originalDeclaration => this; - - String toString() => "TypeVariableMirror on '${_n(simpleName)}'"; - - bool operator ==(Object other) { - return other is TypeVariableMirror && - simpleName == other.simpleName && - owner == other.owner; - } - - int get hashCode => simpleName.hashCode; - - bool isSubtypeOf(TypeMirror other) { - if (other == currentMirrorSystem().dynamicType) return true; - if (other == currentMirrorSystem().voidType) return true; - if (other == currentMirrorSystem().neverType) return false; - return _subtypeTest(_reflectedType, (other as _TypeMirror)._reflectedType); - } - - bool isAssignableTo(TypeMirror other) { - if (other == currentMirrorSystem().dynamicType) return true; - if (other == currentMirrorSystem().voidType) return true; - if (other == currentMirrorSystem().neverType) return false; - final otherReflectedType = (other as _TypeMirror)._reflectedType; - return _subtypeTest(_reflectedType, otherReflectedType) || - _subtypeTest(otherReflectedType, _reflectedType); - } - - static DeclarationMirror _TypeVariableMirror_owner(reflectee) - native "TypeVariableMirror_owner"; - - static Type _TypeVariableMirror_upper_bound(reflectee) - native "TypeVariableMirror_upper_bound"; -} - -class _TypedefMirror extends _DeclarationMirror - implements TypedefMirror, _TypeMirror { - final Type _reflectedType; - final bool _isGeneric; - final bool _isGenericDeclaration; - - _TypedefMirror(reflectee, this._reflectedType, String simpleName, - this._isGeneric, this._isGenericDeclaration, this._owner) - : super._(reflectee, _s(simpleName)); - - bool get isTopLevel => true; - - DeclarationMirror? _owner; - DeclarationMirror? get owner { - var o = _owner; - if (o != null) return o; - var uri = _ClassMirror._libraryUri(_reflectee); - return _owner = currentMirrorSystem().libraries[Uri.parse(uri)]; - } - - _FunctionTypeMirror? _referent; - FunctionTypeMirror get referent { - var r = _referent; - if (r != null) return r; - var result = _nativeReferent(_reflectedType) as _FunctionTypeMirror; - result._instantiator = _reflectedType; - return _referent = result; - } - - bool get hasReflectedType => !_isGenericDeclaration; - Type get reflectedType { - if (!hasReflectedType) { - throw new UnsupportedError( - "Declarations of generics have no reflected type"); - } - return _reflectedType; - } - - bool get isOriginalDeclaration => !_isGeneric || _isGenericDeclaration; - - TypedefMirror get originalDeclaration { - if (isOriginalDeclaration) { - return this; - } else { - return _nativeDeclaration(_reflectedType); - } - } - - List? _typeVariables; - List get typeVariables { - var v = _typeVariables; - if (v != null) return v; - - var result = []; - List params = _ClassMirror._ClassMirror_type_variables(_reflectee); - TypedefMirror owner = originalDeclaration; - var mirror; - for (var i = 0; i < params.length; i += 2) { - mirror = new _TypeVariableMirror._(params[i + 1], params[i], owner); - result.add(mirror); - } - return _typeVariables = - new UnmodifiableListView(result); - } - - List? _typeArguments; - List get typeArguments { - var a = _typeArguments; - if (a != null) return a; - - if (_isGenericDeclaration) { - return _typeArguments = const []; - } else { - return _typeArguments = new UnmodifiableListView( - _ClassMirror._computeTypeArguments(_reflectedType) - .cast()); - } - } - - String toString() => "TypedefMirror on '${_n(simpleName)}'"; - - bool isSubtypeOf(TypeMirror other) { - if (other == currentMirrorSystem().dynamicType) return true; - if (other == currentMirrorSystem().voidType) return true; - if (other == currentMirrorSystem().neverType) return false; - return _subtypeTest(_reflectedType, (other as _TypeMirror)._reflectedType); - } - - bool isAssignableTo(TypeMirror other) { - if (other == currentMirrorSystem().dynamicType) return true; - if (other == currentMirrorSystem().voidType) return true; - if (other == currentMirrorSystem().neverType) return false; - final otherReflectedType = (other as _TypeMirror)._reflectedType; - return _subtypeTest(_reflectedType, otherReflectedType) || - _subtypeTest(otherReflectedType, _reflectedType); - } - - static FunctionTypeMirror _nativeReferent(reflectedType) - native "TypedefMirror_referent"; - - static TypedefMirror _nativeDeclaration(reflectedType) - native "TypedefMirror_declaration"; -} - -Symbol _asSetter(Symbol getter, LibraryMirror library) { - var unwrapped = MirrorSystem.getName(getter); - return MirrorSystem.getSymbol('${unwrapped}=', library); -} - -class _LibraryMirror extends _ObjectMirror implements LibraryMirror { - final Symbol simpleName; - final Uri uri; - - _LibraryMirror._(reflectee, String simpleName, String url) - : this.simpleName = _s(simpleName), - this.uri = Uri.parse(url), - super._(reflectee); - - // The simple name and the qualified name are the same for a library. - Symbol get qualifiedName => simpleName; - - DeclarationMirror? get owner => null; - - bool get isPrivate => false; - bool get isTopLevel => false; - - Type? get _instantiator => null; - - Map? _declarations; - Map get declarations { - var d = _declarations; - if (d != null) return d; - - var decls = new Map(); - var members = _computeMembers(_reflectee); - for (var member in members) { - decls[member.simpleName] = member; - } - - return _declarations = - new UnmodifiableMapView(decls); - } - - SourceLocation? get location { - return _location(_reflectee); - } - - List get metadata { - return _wrapMetadata(_metadata(_reflectee)); - } - - bool operator ==(Object other) { - return other is _LibraryMirror && this._reflectee == other._reflectee; - } - - int get hashCode => simpleName.hashCode; - - String toString() => "LibraryMirror on '${_n(simpleName)}'"; - - var _cachedLibraryDependencies; - get libraryDependencies { - var d = _cachedLibraryDependencies; - if (d != null) return d; - return _cachedLibraryDependencies = - new UnmodifiableListView( - _libraryDependencies(_reflectee).cast()); - } - - List _libraryDependencies(reflectee) - native 'LibraryMirror_libraryDependencies'; - - _invoke(reflectee, memberName, arguments, argumentNames) - native 'LibraryMirror_invoke'; - - _invokeGetter(reflectee, getterName) native 'LibraryMirror_invokeGetter'; - - _invokeSetter(reflectee, setterName, value) - native 'LibraryMirror_invokeSetter'; - - List _computeMembers(reflectee) native "LibraryMirror_members"; -} - -class _LibraryDependencyMirror extends Mirror - implements LibraryDependencyMirror { - final LibraryMirror sourceLibrary; - var _targetMirrorOrPrefix; - final List combinators; - final Symbol? prefix; - final bool isImport; - final bool isDeferred; - final List metadata; - - _LibraryDependencyMirror._( - this.sourceLibrary, - this._targetMirrorOrPrefix, - List mutableCombinators, - prefixString, - this.isImport, - this.isDeferred, - List unwrappedMetadata) - : prefix = _sOpt(prefixString), - combinators = new UnmodifiableListView( - mutableCombinators.cast()), - metadata = _wrapMetadata(unwrappedMetadata); - - bool get isExport => !isImport; - - LibraryMirror? get targetLibrary { - if (_targetMirrorOrPrefix is _LibraryMirror) { - return _targetMirrorOrPrefix; - } - var mirrorOrNull = _tryUpgradePrefix(_targetMirrorOrPrefix); - if (mirrorOrNull != null) { - _targetMirrorOrPrefix = mirrorOrNull; - } - return mirrorOrNull; - } - - Future loadLibrary() { - if (_targetMirrorOrPrefix is _LibraryMirror) { - return new Future.value(_targetMirrorOrPrefix); - } - var savedPrefix = _targetMirrorOrPrefix; - return savedPrefix.loadLibrary().then((_) { - return _tryUpgradePrefix(savedPrefix); - }); - } - - static LibraryMirror _tryUpgradePrefix(libraryPrefix) - native "LibraryMirror_fromPrefix"; - - SourceLocation? get location => null; -} - -class _CombinatorMirror extends Mirror implements CombinatorMirror { - final List identifiers; - final bool isShow; - - _CombinatorMirror._(identifierString, this.isShow) - : this.identifiers = - new UnmodifiableListView([_s(identifierString)]); - - bool get isHide => !isShow; -} - -class _MethodMirror extends _DeclarationMirror implements MethodMirror { - final Type _instantiator; - final bool isStatic; - final int _kindFlags; - - _MethodMirror._(reflectee, String simpleName, this._owner, this._instantiator, - this.isStatic, this._kindFlags) - : super._(reflectee, _s(simpleName)); - - static const kAbstract = 0; - static const kGetter = 1; - static const kSetter = 2; - static const kConstructor = 3; - static const kConstCtor = 4; - static const kGenerativeCtor = 5; - static const kRedirectingCtor = 6; - static const kFactoryCtor = 7; - static const kExternal = 8; - static const kSynthetic = 9; - static const kExtensionMember = 10; - - // These offsets much be kept in sync with those in mirrors.h. - bool get isAbstract => 0 != (_kindFlags & (1 << kAbstract)); - bool get isGetter => 0 != (_kindFlags & (1 << kGetter)); - bool get isSetter => 0 != (_kindFlags & (1 << kSetter)); - bool get isConstructor => 0 != (_kindFlags & (1 << kConstructor)); - bool get isConstConstructor => 0 != (_kindFlags & (1 << kConstCtor)); - bool get isGenerativeConstructor => - 0 != (_kindFlags & (1 << kGenerativeCtor)); - bool get isRedirectingConstructor => - 0 != (_kindFlags & (1 << kRedirectingCtor)); - bool get isFactoryConstructor => 0 != (_kindFlags & (1 << kFactoryCtor)); - bool get isExternal => 0 != (_kindFlags & (1 << kExternal)); - bool get isSynthetic => 0 != (_kindFlags & (1 << kSynthetic)); - bool get isExtensionMember => 0 != (_kindFlags & (1 << kExtensionMember)); - - static const _operators = const [ - "%", "&", "*", "+", "-", "/", "<", "<<", // - "<=", "==", ">", ">=", ">>", "[]", "[]=", - "^", "|", "~", "unary-", "~/", - ]; - bool get isOperator => _operators.contains(_n(simpleName)); - - DeclarationMirror? _owner; - DeclarationMirror get owner { - // For nested closures it is possible, that the mirror for the owner has not - // been created yet. - var o = _owner; - if (o != null) return o; - return _owner = _MethodMirror_owner(_reflectee, _instantiator); - } - - bool get isPrivate => - _n(simpleName).startsWith('_') || _n(constructorName).startsWith('_'); - - bool get isTopLevel => owner is LibraryMirror; - - TypeMirror? _returnType; - TypeMirror get returnType { - var t = _returnType; - if (t != null) return t; - if (isConstructor) { - return _returnType = owner as _ClassMirror; - } else { - return _returnType = - reflectType(_MethodMirror_return_type(_reflectee, _instantiator)); - } - } - - List? _parameters; - List get parameters { - var p = _parameters; - if (p != null) return p; - return _parameters = new UnmodifiableListView( - _MethodMirror_parameters(_reflectee).cast()); - } - - bool get isRegularMethod => !isGetter && !isSetter && !isConstructor; - - Symbol? _constructorName; - Symbol get constructorName { - var n = _constructorName; - if (n != null) return n; - - if (!isConstructor) { - return _constructorName = _s(''); - } else { - var parts = MirrorSystem.getName(simpleName).split('.'); - if (parts.length > 2) { - throw new _InternalMirrorError( - 'Internal error in MethodMirror.constructorName: ' - 'malformed name <$simpleName>'); - } else if (parts.length == 2) { - LibraryMirror definingLibrary = owner.owner as _LibraryMirror; - return _constructorName = - MirrorSystem.getSymbol(parts[1], definingLibrary); - } else { - return _constructorName = _s(''); - } - } - } - - String? get source => _MethodMirror_source(_reflectee); - - void _patchConstructorName(ownerName) { - var cn = _n(constructorName); - if (cn == '') { - _simpleName = _s(ownerName); - } else { - _simpleName = _s(ownerName + "." + cn); - } - } - - String toString() => "MethodMirror on '${MirrorSystem.getName(simpleName)}'"; - - static dynamic _MethodMirror_owner(reflectee, instantiator) - native "MethodMirror_owner"; - - static dynamic _MethodMirror_return_type(reflectee, instantiator) - native "MethodMirror_return_type"; - - List _MethodMirror_parameters(reflectee) - native "MethodMirror_parameters"; - - static String? _MethodMirror_source(reflectee) native "MethodMirror_source"; -} - -class _VariableMirror extends _DeclarationMirror implements VariableMirror { - final DeclarationMirror owner; - final bool isStatic; - final bool isFinal; - final bool isConst; - final bool isExtensionMember; - - _VariableMirror._(reflectee, String simpleName, this.owner, this._type, - this.isStatic, this.isFinal, this.isConst, this.isExtensionMember) - : super._(reflectee, _s(simpleName)); - - bool get isTopLevel => owner is LibraryMirror; - - Type? get _instantiator { - final o = owner; // Note: need local variable for promotion to happen. - if (o is _ClassMirror) { - return o._instantiator; - } else if (o is _MethodMirror) { - return o._instantiator; - } else if (o is _LibraryMirror) { - return o._instantiator; - } else { - throw new UnsupportedError("unexpected owner ${owner}"); - } - } - - TypeMirror? _type; - TypeMirror get type { - var t = _type; - if (t != null) return t; - return _type = reflectType(_VariableMirror_type(_reflectee, _instantiator)); - } - - String toString() => - "VariableMirror on '${MirrorSystem.getName(simpleName)}'"; - - static _VariableMirror_type(reflectee, instantiator) - native "VariableMirror_type"; -} - -class _ParameterMirror extends _VariableMirror implements ParameterMirror { - final int _position; - final bool isOptional; - final bool isNamed; - final List? _unmirroredMetadata; - - _ParameterMirror._( - reflectee, - String simpleName, - DeclarationMirror owner, - this._position, - this.isOptional, - this.isNamed, - bool isFinal, - this._defaultValueReflectee, - this._unmirroredMetadata) - : super._( - reflectee, - simpleName, - owner, - null, // We override the type. - false, // isStatic does not apply. - isFinal, - false, // Not const. - false // Not extension member. - ); - - Object _defaultValueReflectee; - InstanceMirror? _defaultValue; - InstanceMirror? get defaultValue { - if (!isOptional) { - return null; - } - if (_defaultValue == null) { - _defaultValue = reflect(_defaultValueReflectee); - } - return _defaultValue; - } - - bool get hasDefaultValue => _defaultValueReflectee != null; - - SourceLocation? get location { - throw new UnsupportedError("ParameterMirror.location unimplemented"); - } - - List get metadata { - var m = _unmirroredMetadata; - if (m == null) return const []; - return _wrapMetadata(m); - } - - TypeMirror? _type; - TypeMirror get type { - var t = _type; - if (t != null) return t; - return _type = reflectType( - _ParameterMirror_type(_reflectee, _position, _instantiator)); - } - - String toString() => "ParameterMirror on '${_n(simpleName)}'"; - - static Type _ParameterMirror_type(_reflectee, _position, instantiator) - native "ParameterMirror_type"; -} - -class _SpecialTypeMirror extends Mirror - implements TypeMirror, DeclarationMirror { - final Symbol simpleName; - - _SpecialTypeMirror._(String name) : simpleName = _s(name); - - bool get isPrivate => false; - bool get isTopLevel => true; - - DeclarationMirror? get owner => null; - - SourceLocation? get location => null; - List get metadata => const []; - - bool get hasReflectedType => simpleName == #dynamic; - Type get reflectedType { - if (simpleName == #dynamic) return dynamic; - throw new UnsupportedError("void has no reflected type"); - } - - List get typeVariables => const []; - List get typeArguments => const []; - - bool get isOriginalDeclaration => true; - TypeMirror get originalDeclaration => this; - - Symbol get qualifiedName => simpleName; - - bool operator ==(Object other) { - if (other is! _SpecialTypeMirror) { - return false; - } - return this.simpleName == other.simpleName; - } - - int get hashCode => simpleName.hashCode; - - String toString() => "TypeMirror on '${_n(simpleName)}'"; - - bool isSubtypeOf(TypeMirror other) { - return simpleName == #dynamic || other is _SpecialTypeMirror; - } - - bool isAssignableTo(TypeMirror other) { - return simpleName == #dynamic || other is _SpecialTypeMirror; - } -} - -class _Mirrors { - static MirrorSystem _currentMirrorSystem = new _MirrorSystem(); - static MirrorSystem currentMirrorSystem() { - return _currentMirrorSystem; - } - - // Creates a new local mirror for some Object. - static InstanceMirror reflect(dynamic reflectee) { - return reflectee is Function - ? new _ClosureMirror._(reflectee) - : new _InstanceMirror._(reflectee); - } - - static _ClassMirror _makeLocalClassMirror(Type key) - native "Mirrors_makeLocalClassMirror"; - static TypeMirror _makeLocalTypeMirror(Type key) - native "Mirrors_makeLocalTypeMirror"; - static Type _instantiateGenericType(Type key, typeArguments) - native "Mirrors_instantiateGenericType"; - - static Expando<_ClassMirror> _declarationCache = new Expando("ClassMirror"); - static Expando _instantiationCache = new Expando("TypeMirror"); - - static ClassMirror reflectClass(Type key) { - var classMirror = _declarationCache[key]; - if (classMirror == null) { - classMirror = _makeLocalClassMirror(key); - _declarationCache[key] = classMirror; - if (!classMirror._isGeneric) { - _instantiationCache[key] = classMirror; - } - } - return classMirror; - } - - static TypeMirror reflectType(Type key, [List? typeArguments]) { - if (typeArguments != null) { - key = _instantiateType(key, typeArguments); - } - var typeMirror = _instantiationCache[key]; - if (typeMirror == null) { - typeMirror = _makeLocalTypeMirror(key); - _instantiationCache[key] = typeMirror; - if (typeMirror is _ClassMirror && !typeMirror._isGeneric) { - _declarationCache[key] = typeMirror; - } - } - return typeMirror; - } - - static Type _instantiateType(Type key, List typeArguments) { - if (typeArguments.isEmpty) { - throw new ArgumentError.value(typeArguments, 'typeArguments', - 'Type arguments list cannot be empty.'); - } - return _instantiateGenericType(key, typeArguments.toList(growable: false)); - } -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/mirrors_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/mirrors_patch.dart deleted file mode 100644 index a06d5464580..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/mirrors_patch.dart +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright (c) 2012, 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. - -/// Note: the VM concatenates all patch files into a single patch file. This -/// file is the first patch in "dart:_internal" which contains all the imports -/// used by patches of that library. We plan to change this when we have a -/// shared front end and simply use parts. - -import "dart:_internal" as internal; - -import "dart:_internal" show patch; - -import "dart:async" show Future; - -import "dart:collection" show UnmodifiableListView, UnmodifiableMapView; - -/// These are the additional parts of this patch library: -// part "mirrors_impl.dart"; -// part "mirror_reference.dart"; - -/** - * Returns a [MirrorSystem] for the current isolate. - */ -@patch -MirrorSystem currentMirrorSystem() { - return _Mirrors.currentMirrorSystem(); -} - -/** - * Returns an [InstanceMirror] for some Dart language object. - * - * This only works if this mirror system is associated with the - * current running isolate. - */ -@patch -InstanceMirror reflect(dynamic reflectee) { - return _Mirrors.reflect(reflectee); -} - -/** - * Returns a [ClassMirror] for the class represented by a Dart - * Type object. - * - * This only works with objects local to the current isolate. - */ -@patch -ClassMirror reflectClass(Type key) { - return _Mirrors.reflectClass(key); -} - -@patch -TypeMirror reflectType(Type key, [List? typeArguments]) { - return _Mirrors.reflectType(key, typeArguments); -} - -@patch -class MirrorSystem { - @patch - LibraryMirror findLibrary(Symbol libraryName) { - var candidates = - libraries.values.where((lib) => lib.simpleName == libraryName); - if (candidates.length == 1) { - return candidates.single; - } - if (candidates.length > 1) { - var uris = candidates.map((lib) => lib.uri.toString()).toList(); - throw new Exception("There are multiple libraries named " - "'${getName(libraryName)}': $uris"); - } - throw new Exception("There is no library named '${getName(libraryName)}'"); - } - - @patch - static String getName(Symbol symbol) { - return internal.Symbol.computeUnmangledName(symbol as internal.Symbol); - } - - @patch - static Symbol getSymbol(String name, [LibraryMirror? library]) { - if ((library != null && library is! _LibraryMirror) || - ((name.length > 0) && (name[0] == '_') && (library == null))) { - throw new ArgumentError(library); - } - if (library != null) { - name = _mangleName(name, (library as _LibraryMirror)._reflectee); - } - return new internal.Symbol.unvalidated(name); - } - - static _mangleName(String name, _MirrorReference lib) - native "Mirrors_mangleName"; -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/null_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/null_patch.dart deleted file mode 100644 index 01bb5aa8829..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/null_patch.dart +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) 2013, 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. - -// part of "core_patch.dart"; - -@patch -@pragma("vm:entry-point") -class Null { - static const _HASH_CODE = 2011; // The year Dart was announced and a prime. - - @patch - int get hashCode => _HASH_CODE; - - int get _identityHashCode => _HASH_CODE; -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/object_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/object_patch.dart deleted file mode 100644 index e862e5cd1a5..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/object_patch.dart +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) 2012, 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. - -// part of "core_patch.dart"; - -@pragma("vm:exact-result-type", "dart:core#_Smi") -int _getHash(obj) native "Object_getHash"; -void _setHash(obj, hash) native "Object_setHash"; - -@patch -@pragma("vm:entry-point") -class Object { - // The VM has its own implementation of equals. - @patch - @pragma("vm:exact-result-type", bool) - @pragma("vm:prefer-inline") - bool operator ==(Object other) native "Object_equals"; - - // Helpers used to implement hashCode. If a hashCode is used, we remember it - // in a weak table in the VM (32 bit) or in the header of the object (64 - // bit). A new hashCode value is calculated using a random number generator. - static final _hashCodeRnd = new Random(); - - static int _objectHashCode(obj) { - var result = _getHash(obj); - if (result == 0) { - // We want the hash to be a Smi value greater than 0. - result = _hashCodeRnd.nextInt(0x40000000); - do { - result = _hashCodeRnd.nextInt(0x40000000); - } while (result == 0); - _setHash(obj, result); - } - return result; - } - - @patch - int get hashCode => _objectHashCode(this); - int get _identityHashCode => _objectHashCode(this); - - @patch - String toString() native "Object_toString"; - // A statically dispatched version of Object.toString. - static String _toString(obj) native "Object_toString"; - - @patch - @pragma("vm:entry-point", "call") - dynamic noSuchMethod(Invocation invocation) { - // TODO(regis): Remove temp constructor identifier 'withInvocation'. - throw new NoSuchMethodError.withInvocation(this, invocation); - } - - @patch - @pragma("vm:exact-result-type", "dart:core#_Type") - Type get runtimeType native "Object_runtimeType"; - - @pragma("vm:entry-point", "call") - @pragma("vm:exact-result-type", bool) - static bool _haveSameRuntimeType(a, b) native "Object_haveSameRuntimeType"; - - // Call this function instead of inlining instanceof, thus collecting - // type feedback and reducing code size of unoptimized code. - @pragma("vm:entry-point", "call") - bool _instanceOf(instantiatorTypeArguments, functionTypeArguments, type) - native "Object_instanceOf"; - - // Group of functions for implementing fast simple instance of. - @pragma("vm:entry-point", "call") - bool _simpleInstanceOf(type) native "Object_simpleInstanceOf"; - @pragma("vm:entry-point", "call") - bool _simpleInstanceOfTrue(type) => true; - @pragma("vm:entry-point", "call") - bool _simpleInstanceOfFalse(type) => false; -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/print_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/print_patch.dart deleted file mode 100644 index f0e7d916dc4..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/print_patch.dart +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) 2012, 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. - -// part of "internal_patch.dart"; - -// A print-closure gets a String that should be printed. In general the -// string is a line, but it may contain "\n" characters. -typedef void _PrintClosure(String line); - -@patch -void printToConsole(String line) { - _printClosure(line); -} - -void _unsupportedPrint(String line) { - throw new UnsupportedError("'print' is not supported"); -} - -// _printClosure can be overwritten by the embedder to supply a different -// print implementation. -@pragma("vm:entry-point") -_PrintClosure _printClosure = _unsupportedPrint; diff --git a/sdk_nnbd/lib/_internal/vm/lib/profiler.dart b/sdk_nnbd/lib/_internal/vm/lib/profiler.dart deleted file mode 100644 index 745eaa5f175..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/profiler.dart +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2014, 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. - -// part of "developer.dart"; - -@patch -class UserTag { - @patch - factory UserTag(String label) { - return new _UserTag(label); - } - @patch - static UserTag get defaultTag => _getDefaultTag(); -} - -@pragma("vm:entry-point") -class _UserTag implements UserTag { - factory _UserTag(String label) native "UserTag_new"; - String get label native "UserTag_label"; - UserTag makeCurrent() native "UserTag_makeCurrent"; -} - -@patch -UserTag getCurrentTag() => _getCurrentTag(); -UserTag _getCurrentTag() native "Profiler_getCurrentTag"; - -UserTag _getDefaultTag() native "UserTag_defaultTag"; diff --git a/sdk_nnbd/lib/_internal/vm/lib/regexp_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/regexp_patch.dart deleted file mode 100644 index 7a575836a37..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/regexp_patch.dart +++ /dev/null @@ -1,417 +0,0 @@ -// Copyright (c) 2012, 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. - -// part of "core_patch.dart"; - -@patch -class RegExp { - @patch - factory RegExp(String source, - {bool multiLine: false, - bool caseSensitive: true, - bool unicode: false, - bool dotAll: false}) { - _RegExpHashKey key = - new _RegExpHashKey(source, multiLine, caseSensitive, unicode, dotAll); - _RegExpHashValue? value = _cache[key]; - - if (value == null) { - if (_cache.length > _MAX_CACHE_SIZE) { - _RegExpHashKey lastKey = _recentlyUsed.last; - _recentlyUsed.remove(lastKey); - _cache.remove(lastKey); - } - - value = new _RegExpHashValue( - new _RegExp(source, - multiLine: multiLine, - caseSensitive: caseSensitive, - unicode: unicode, - dotAll: dotAll), - key); - _cache[key] = value; - } else { - value.key.unlink(); - } - - assert(value != null); - - _recentlyUsed.addFirst(value.key); - assert(_recentlyUsed.length == _cache.length); - - // TODO(zerny): We might not want to canonicalize regexp objects. - return value.regexp; - } - - /** - * Finds the index of the first RegExp-significant char in [text]. - * - * Starts looking from [start]. Returns `text.length` if no character - * is found that has special meaning in RegExp syntax. - */ - static int _findEscapeChar(String text, int start) { - // Table where each character in the range U+0000 to U+007f is represented - // by whether it needs to be escaped in a regexp. - // The \x00 characters means escacped, and \x01 means non-escaped. - const escapes = - "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01" - "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01" - // $ ( ) * + . - "\x01\x01\x01\x01\x00\x01\x01\x01\x00\x00\x00\x00\x01\x01\x00\x01" - // ? - "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00" - "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01" - // [ \ ] ^ - "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x01" - "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01" - // { | } - "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x01\x01"; - for (int i = start; i < text.length; i++) { - int char = text.codeUnitAt(i); - if (char <= 0x7f && escapes.codeUnitAt(char) == 0) return i; - } - return text.length; - } - - @patch - static String escape(String text) { - int escapeCharIndex = _findEscapeChar(text, 0); - // If the text contains no characters needing escape, return it directly. - if (escapeCharIndex == text.length) return text; - - var buffer = new StringBuffer(); - int previousSliceEndIndex = 0; - do { - // Copy characters from previous escape to current escape into result. - // This includes the previously escaped character. - buffer.write(text.substring(previousSliceEndIndex, escapeCharIndex)); - // Prepare the current character to be escaped by prefixing it with a '\'. - buffer.write(r"\"); - previousSliceEndIndex = escapeCharIndex; - escapeCharIndex = _findEscapeChar(text, escapeCharIndex + 1); - } while (escapeCharIndex < text.length); - // Copy tail of string into result. - buffer.write(text.substring(previousSliceEndIndex, escapeCharIndex)); - return buffer.toString(); - } - - // Regular expression objects are stored in a cache of up to _MAX_CACHE_SIZE - // elements using an LRU eviction strategy. - // TODO(zerny): Do not impose a fixed limit on the number of cached objects. - // Other possibilities could be limiting by the size of the regexp objects, - // or imposing a lower time bound for the most recent use under which a regexp - // may not be removed from the cache. - // TODO(zerny): Use self-sizing cache similar to _AccessorCache in - // mirrors_impl.dart. - static const int _MAX_CACHE_SIZE = 256; - static final Map<_RegExpHashKey, _RegExpHashValue> _cache = - new HashMap<_RegExpHashKey, _RegExpHashValue>(); - static final LinkedList<_RegExpHashKey> _recentlyUsed = - new LinkedList<_RegExpHashKey>(); - - int get _groupCount; - Iterable get _groupNames; - int _groupNameIndex(String name); -} - -// Represents both a key in the regular expression cache as well as its -// corresponding entry in the LRU list. -class _RegExpHashKey extends LinkedListEntry<_RegExpHashKey> { - final String pattern; - final bool multiLine; - final bool caseSensitive; - final bool unicode; - final bool dotAll; - - _RegExpHashKey(this.pattern, this.multiLine, this.caseSensitive, this.unicode, - this.dotAll); - - int get hashCode => pattern.hashCode; - bool operator ==(that) { - return (that is _RegExpHashKey) && - (this.pattern == that.pattern) && - (this.multiLine == that.multiLine) && - (this.caseSensitive == that.caseSensitive) && - (this.unicode == that.unicode) && - (this.dotAll == that.dotAll); - } -} - -// Represents a value in the regular expression cache. Contains a pointer -// back to the key in order to access the corresponding LRU entry. -class _RegExpHashValue { - final _RegExp regexp; - final _RegExpHashKey key; - - _RegExpHashValue(this.regexp, this.key); -} - -class _RegExpMatch implements RegExpMatch { - _RegExpMatch._(this._regexp, this.input, this._match); - - int get start => _start(0); - int get end => _end(0); - - int _start(int groupIdx) { - return _match[(groupIdx * _MATCH_PAIR)]; - } - - int _end(int groupIdx) { - return _match[(groupIdx * _MATCH_PAIR) + 1]; - } - - String? group(int groupIdx) { - if (groupIdx < 0 || groupIdx > _regexp._groupCount) { - throw new RangeError.value(groupIdx); - } - int startIndex = _start(groupIdx); - int endIndex = _end(groupIdx); - if (startIndex == -1) { - assert(endIndex == -1); - return null; - } - return input._substringUnchecked(startIndex, endIndex); - } - - String? operator [](int groupIdx) { - return this.group(groupIdx); - } - - List groups(List groupsSpec) { - var groupsList = new List.filled(groupsSpec.length, null); - for (int i = 0; i < groupsSpec.length; i++) { - groupsList[i] = group(groupsSpec[i]); - } - return groupsList; - } - - int get groupCount => _regexp._groupCount; - - Pattern get pattern => _regexp; - - String? namedGroup(String name) { - var idx = _regexp._groupNameIndex(name); - if (idx < 0) { - throw ArgumentError("Not a capture group name: ${name}"); - } - return group(idx); - } - - Iterable get groupNames { - return _regexp._groupNames; - } - - final RegExp _regexp; - final String input; - final List _match; - static const int _MATCH_PAIR = 2; -} - -@pragma("vm:entry-point") -class _RegExp implements RegExp { - factory _RegExp(String pattern, - {bool multiLine: false, - bool caseSensitive: true, - bool unicode: false, - bool dotAll: false}) native "RegExp_factory"; - - RegExpMatch? firstMatch(String input) { - // TODO: Remove these null checks once all code is opted into strong nonnullable mode. - if (input == null) throw new ArgumentError.notNull('input'); - final match = _ExecuteMatch(input, 0); - if (match == null) { - return null; - } - return new _RegExpMatch._(this, input, match); - } - - Iterable allMatches(String string, [int start = 0]) { - // TODO: Remove these null checks once all code is opted into strong nonnullable mode. - if (string == null) throw new ArgumentError.notNull('string'); - if (start == null) throw new ArgumentError.notNull('start'); - if (0 > start || start > string.length) { - throw new RangeError.range(start, 0, string.length); - } - return new _AllMatchesIterable(this, string, start); - } - - RegExpMatch? matchAsPrefix(String string, [int start = 0]) { - // TODO: Remove these null checks once all code is opted into strong nonnullable mode. - if (string == null) throw new ArgumentError.notNull('string'); - if (start == null) throw new ArgumentError.notNull('start'); - if (start < 0 || start > string.length) { - throw new RangeError.range(start, 0, string.length); - } - final list = _ExecuteMatchSticky(string, start); - if (list == null) return null; - return new _RegExpMatch._(this, string, list); - } - - bool hasMatch(String input) { - // TODO: Remove these null checks once all code is opted into strong nonnullable mode. - if (input == null) throw new ArgumentError.notNull('input'); - List? match = _ExecuteMatch(input, 0); - return (match == null) ? false : true; - } - - String? stringMatch(String input) { - // TODO: Remove these null checks once all code is opted into strong nonnullable mode. - if (input == null) throw new ArgumentError.notNull('input'); - List? match = _ExecuteMatch(input, 0); - if (match == null) { - return null; - } - return input._substringUnchecked(match[0], match[1]); - } - - String get pattern native "RegExp_getPattern"; - - bool get isMultiLine native "RegExp_getIsMultiLine"; - - bool get isCaseSensitive native "RegExp_getIsCaseSensitive"; - - bool get isUnicode native "RegExp_getIsUnicode"; - - bool get isDotAll native "RegExp_getIsDotAll"; - - int get _groupCount native "RegExp_getGroupCount"; - - /// The names and indices of named capture group. - /// - /// Returns a [List] of alternating strings and integers, - /// `[String, int, String, int, ...]` where each - /// [String] is the name of a capture group and the following - /// [int] is that capture group's index. - /// Returns `null` if there are no group names. - List? get _groupNameList native "RegExp_getGroupNameMap"; - - Iterable get _groupNames sync* { - final nameList = _groupNameList; - if (nameList == null) return; - for (var i = 0; i < nameList.length; i += 2) { - yield nameList[i] as String; - } - } - - int _groupNameIndex(String name) { - var nameList = _groupNameList; - if (nameList == null) return -1; - for (var i = 0; i < nameList.length; i += 2) { - if (name == nameList[i]) { - return nameList[i + 1] as int; - } - } - return -1; - } - - // Byte map of one byte characters with a 0xff if the character is a word - // character (digit, letter or underscore) and 0x00 otherwise. - // Used by generated RegExp code. - static const List _wordCharacterMap = const [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // '0' - '7' - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // '8' - '9' - - 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 'A' - 'G' - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 'H' - 'O' - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 'P' - 'W' - 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, // 'X' - 'Z', '_' - - 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 'a' - 'g' - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 'h' - 'o' - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 'p' - 'w' - 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, // 'x' - 'z' - // Latin-1 range - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - ]; - - List? _ExecuteMatch(String str, int start_index) - native "RegExp_ExecuteMatch"; - - List? _ExecuteMatchSticky(String str, int start_index) - native "RegExp_ExecuteMatchSticky"; -} - -class _AllMatchesIterable extends IterableBase { - final _RegExp _re; - final String _str; - final int _start; - - _AllMatchesIterable(this._re, this._str, this._start); - - Iterator get iterator => - new _AllMatchesIterator(_re, _str, _start); -} - -class _AllMatchesIterator implements Iterator { - final String _str; - int _nextIndex; - _RegExp? _re; - RegExpMatch? _current; - - _AllMatchesIterator(this._re, this._str, this._nextIndex); - - RegExpMatch get current => _current!; - - static bool _isLeadSurrogate(int c) { - return c >= 0xd800 && c <= 0xdbff; - } - - static bool _isTrailSurrogate(int c) { - return c >= 0xdc00 && c <= 0xdfff; - } - - bool moveNext() { - final re = _re; - if (re == null) return false; // Cleared after a failed match. - if (_nextIndex <= _str.length) { - final match = re._ExecuteMatch(_str, _nextIndex); - if (match != null) { - var current = new _RegExpMatch._(re, _str, match); - _current = current; - _nextIndex = current.end; - if (_nextIndex == current.start) { - // Zero-width match. Advance by one more, unless the regexp - // is in unicode mode and it would put us within a surrogate - // pair. In that case, advance past the code point as a whole. - if (re.isUnicode && - _nextIndex + 1 < _str.length && - _isLeadSurrogate(_str.codeUnitAt(_nextIndex)) && - _isTrailSurrogate(_str.codeUnitAt(_nextIndex + 1))) { - _nextIndex++; - } - _nextIndex++; - } - return true; - } - } - _current = null; - _re = null; - return false; - } -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/schedule_microtask_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/schedule_microtask_patch.dart deleted file mode 100644 index 3abbcb593f9..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/schedule_microtask_patch.dart +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) 2013, 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. - -// part of "async_patch.dart"; - -@patch -class _AsyncRun { - @patch - static void _scheduleImmediate(void callback()) { - final closure = _ScheduleImmediate._closure; - if (closure == null) { - throw new UnsupportedError("Microtasks are not supported"); - } - closure(callback); - } -} - -typedef void _ScheduleImmediateClosure(void callback()); - -class _ScheduleImmediate { - static _ScheduleImmediateClosure? _closure; -} - -@pragma("vm:entry-point", "call") -void _setScheduleImmediateClosure(_ScheduleImmediateClosure closure) { - _ScheduleImmediate._closure = closure; -} - -@pragma("vm:entry-point", "call") -void _ensureScheduleImmediate() { - _AsyncRun._scheduleImmediate(_startMicrotaskLoop); -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/stacktrace.dart b/sdk_nnbd/lib/_internal/vm/lib/stacktrace.dart deleted file mode 100644 index 719d55a8162..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/stacktrace.dart +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) 2013, 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. - -// part of "core_patch.dart"; - -/// VM internal StackTrace implementation. -@pragma("vm:entry-point") -class _StackTrace implements StackTrace { - // toString() is overridden on the C++ side. -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/stopwatch_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/stopwatch_patch.dart deleted file mode 100644 index df29ecaf7cd..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/stopwatch_patch.dart +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 2012, 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. - -// part of "core_patch.dart"; - -@patch -class Stopwatch { - static const _maxInt = 0x7FFFFFFFFFFFFFFF; - - @patch - static int _initTicker() => _computeFrequency(); - - // Returns the current clock tick. - @patch - static int _now() native "Stopwatch_now"; - - // Returns the frequency of clock ticks in Hz. - static int _computeFrequency() native "Stopwatch_frequency"; - - @patch - int get elapsedMicroseconds { - int ticks = elapsedTicks; - // Special case the more likely frequencies to avoid division, - // or divide by a known value. - if (_frequency == 1000000000) return ticks ~/ 1000; - if (_frequency == 1000000) return ticks; - if (_frequency == 1000) return ticks * 1000; - if (ticks <= (_maxInt ~/ 1000000)) { - return (ticks * 1000000) ~/ _frequency; - } - // Multiplication would have overflowed. - int ticksPerSecond = ticks ~/ _frequency; - int remainingTicks = unsafeCast(ticks.remainder(_frequency)); - return ticksPerSecond * 1000000 + (remainingTicks * 1000000) ~/ _frequency; - } - - @patch - int get elapsedMilliseconds { - int ticks = elapsedTicks; - if (_frequency == 1000000000) return ticks ~/ 1000000; - if (_frequency == 1000000) return ticks ~/ 1000; - if (_frequency == 1000) return ticks; - if (ticks <= (_maxInt ~/ 1000)) { - return (ticks * 1000) ~/ _frequency; - } - // Multiplication would have overflowed. - int ticksPerSecond = ticks ~/ _frequency; - int remainingTicks = unsafeCast(ticks.remainder(_frequency)); - return ticksPerSecond * 1000 + (remainingTicks * 1000) ~/ _frequency; - } -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/string_buffer_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/string_buffer_patch.dart deleted file mode 100644 index 0a1b06d8046..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/string_buffer_patch.dart +++ /dev/null @@ -1,202 +0,0 @@ -// Copyright (c) 2012, 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. - -// part of "core_patch.dart"; - -@patch -class StringBuffer { - static const int _BUFFER_SIZE = 64; - static const int _PARTS_TO_COMPACT = 128; - static const int _PARTS_TO_COMPACT_SIZE_LIMIT = _PARTS_TO_COMPACT * 8; - - /** - * When strings are written to the string buffer, we add them to a - * list of string parts. - */ - List? _parts; - - /** - * Total number of code units in the string parts. Does not include - * the code units added to the buffer. - */ - int _partsCodeUnits = 0; - - /** - * To preserve memory, we sometimes compact the parts. This combines - * several smaller parts into a single larger part to cut down on the - * cost that comes from the per-object memory overhead. We keep track - * of the last index where we ended our compaction and the number of - * code units added since the last compaction. - */ - int _partsCompactionIndex = 0; - int _partsCodeUnitsSinceCompaction = 0; - - /** - * The buffer is used to build up a string from code units. It is - * used when writing short strings or individual char codes to the - * buffer. The buffer is allocated on demand. - */ - Uint16List? _buffer; - int _bufferPosition = 0; - - /** - * Collects the approximate maximal magnitude of the code units added - * to the buffer. - * - * The value of each added code unit is or'ed with this variable, so the - * most significant bit set in any code unit is also set in this value. - * If below 256, the string in the buffer is a Latin-1 string. - */ - int _bufferCodeUnitMagnitude = 0; - - /// Creates the string buffer with an initial content. - @patch - StringBuffer([Object content = ""]) { - write(content); - } - - @patch - int get length => _partsCodeUnits + _bufferPosition; - - @patch - void write(Object? obj) { - String str = obj.toString(); - if (str.isEmpty) return; - _consumeBuffer(); - _addPart(str); - } - - @patch - void writeCharCode(int charCode) { - if (charCode <= 0xFFFF) { - if (charCode < 0) { - throw new RangeError.range(charCode, 0, 0x10FFFF); - } - _ensureCapacity(1); - final localBuffer = _buffer!; - localBuffer[_bufferPosition++] = charCode; - _bufferCodeUnitMagnitude |= charCode; - } else { - if (charCode > 0x10FFFF) { - throw new RangeError.range(charCode, 0, 0x10FFFF); - } - _ensureCapacity(2); - int bits = charCode - 0x10000; - final localBuffer = _buffer!; - localBuffer[_bufferPosition++] = 0xD800 | (bits >> 10); - localBuffer[_bufferPosition++] = 0xDC00 | (bits & 0x3FF); - _bufferCodeUnitMagnitude |= 0xFFFF; - } - } - - @patch - void writeAll(Iterable objects, [String separator = ""]) { - Iterator iterator = objects.iterator; - if (!iterator.moveNext()) return; - if (separator.isEmpty) { - do { - write(iterator.current); - } while (iterator.moveNext()); - } else { - write(iterator.current); - while (iterator.moveNext()) { - write(separator); - write(iterator.current); - } - } - } - - @patch - void writeln([Object? obj = ""]) { - write(obj); - write("\n"); - } - - /** Makes the buffer empty. */ - @patch - void clear() { - _parts = null; - _partsCodeUnits = _bufferPosition = _bufferCodeUnitMagnitude = 0; - } - - /** Returns the contents of buffer as a string. */ - @patch - String toString() { - _consumeBuffer(); - final localParts = _parts; - return (_partsCodeUnits == 0 || localParts == null) - ? "" - : _StringBase._concatRange(localParts, 0, localParts.length); - } - - /** Ensures that the buffer has enough capacity to add n code units. */ - void _ensureCapacity(int n) { - final localBuffer = _buffer; - if (localBuffer == null) { - _buffer = new Uint16List(_BUFFER_SIZE); - } else if (_bufferPosition + n > localBuffer.length) { - _consumeBuffer(); - } - } - - /** - * Consumes the content of the buffer by turning it into a string - * and adding it as a part. After calling this the buffer position - * will be reset to zero. - */ - void _consumeBuffer() { - if (_bufferPosition == 0) return; - bool isLatin1 = _bufferCodeUnitMagnitude <= 0xFF; - String str = _create(_buffer!, _bufferPosition, isLatin1); - _bufferPosition = _bufferCodeUnitMagnitude = 0; - _addPart(str); - } - - /** - * Adds a new part to this string buffer and keeps track of how - * many code units are contained in the parts. - */ - void _addPart(String str) { - final localParts = _parts; - int length = str.length; - _partsCodeUnits += length; - _partsCodeUnitsSinceCompaction += length; - - if (localParts == null) { - // Empirically this is a good capacity to minimize total bytes allocated. - _parts = new _GrowableList.withCapacity(10)..add(str); - } else { - localParts.add(str); - int partsSinceCompaction = localParts.length - _partsCompactionIndex; - if (partsSinceCompaction == _PARTS_TO_COMPACT) { - _compact(); - } - } - } - - /** - * Compacts the last N parts if their average size allows us to save a - * lot of memory by turning them all into a single part. - */ - void _compact() { - final localParts = _parts!; - if (_partsCodeUnitsSinceCompaction < _PARTS_TO_COMPACT_SIZE_LIMIT) { - String compacted = _StringBase._concatRange( - localParts, - _partsCompactionIndex, // Start - _partsCompactionIndex + _PARTS_TO_COMPACT // End - ); - localParts.length = localParts.length - _PARTS_TO_COMPACT; - localParts.add(compacted); - } - _partsCodeUnitsSinceCompaction = 0; - _partsCompactionIndex = localParts.length; - } - - /** - * Create a [String] from the UFT-16 code units in buffer. - */ - static String _create(Uint16List buffer, int length, bool isLatin1) - native "StringBuffer_createStringFromUint16Array"; -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/string_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/string_patch.dart deleted file mode 100644 index 55fc053fbe3..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/string_patch.dart +++ /dev/null @@ -1,1416 +0,0 @@ -// Copyright (c) 2012, 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. - -// part of "core_patch.dart"; - -const int _maxAscii = 0x7f; -const int _maxLatin1 = 0xff; -const int _maxUtf16 = 0xffff; -const int _maxUnicode = 0x10ffff; - -@patch -class String { - @patch - factory String.fromCharCodes(Iterable charCodes, - [int start = 0, int? end]) { - // TODO: Remove these null checks once all code is opted into strong nonnullable mode. - if (charCodes == null) throw new ArgumentError.notNull("charCodes"); - if (start == null) throw new ArgumentError.notNull("start"); - return _StringBase.createFromCharCodes(charCodes, start, end, null); - } - - @patch - factory String.fromCharCode(int charCode) { - if (charCode >= 0) { - if (charCode <= 0xff) { - return _OneByteString._allocate(1).._setAt(0, charCode); - } - if (charCode <= 0xffff) { - return _StringBase._createFromCodePoints( - new _List(1)..[0] = charCode, 0, 1); - } - if (charCode <= 0x10ffff) { - var low = 0xDC00 | (charCode & 0x3ff); - int bits = charCode - 0x10000; - var high = 0xD800 | (bits >> 10); - return _StringBase._createFromCodePoints( - new _List(2) - ..[0] = high - ..[1] = low, - 0, - 2); - } - } - throw new RangeError.range(charCode, 0, 0x10ffff); - } - - @patch - const factory String.fromEnvironment(String name, {String defaultValue = ""}) - native "String_fromEnvironment"; - - bool get _isOneByte; - String _substringUnchecked(int startIndex, int endIndex); -} - -/** - * [_StringBase] contains common methods used by concrete String - * implementations, e.g., _OneByteString. - */ -abstract class _StringBase implements String { - bool _isWhitespace(int codeUnit); - - // Constants used by replaceAll encoding of string slices between matches. - // A string slice (start+length) is encoded in a single Smi to save memory - // overhead in the common case. - // We use fewer bits for length (11 bits) than for the start index (19+ bits). - // For long strings, it's possible to have many large indices, - // but it's unlikely to have many long lengths since slices don't overlap. - // If there are few matches in a long string, then there are few long slices, - // and if there are many matches, there'll likely be many short slices. - // - // Encoding is: 0((start << _lengthBits) | length) - - // Number of bits used by length. - // This is the shift used to encode and decode the start index. - static const int _lengthBits = 11; - // The maximal allowed length value in an encoded slice. - static const int _maxLengthValue = (1 << _lengthBits) - 1; - // Mask of length in encoded smi value. - static const int _lengthMask = _maxLengthValue; - static const int _startBits = _maxUnsignedSmiBits - _lengthBits; - // Maximal allowed start index value in an encoded slice. - static const int _maxStartValue = (1 << _startBits) - 1; - // We pick 30 as a safe lower bound on available bits in a negative smi. - // TODO(lrn): Consider allowing more bits for start on 64-bit systems. - static const int _maxUnsignedSmiBits = 30; - - // For longer strings, calling into C++ to create the result of a - // [replaceAll] is faster than [_joinReplaceAllOneByteResult]. - // TODO(lrn): See if this limit can be tweaked. - static const int _maxJoinReplaceOneByteStringLength = 500; - - factory _StringBase._uninstantiable() { - throw new UnsupportedError("_StringBase can't be instaniated"); - } - - @pragma("vm:exact-result-type", "dart:core#_Smi") - int get hashCode native "String_getHashCode"; - - @pragma("vm:exact-result-type", "dart:core#_Smi") - int get _identityHashCode native "String_getHashCode"; - - bool get _isOneByte { - // Alternatively return false and override it on one-byte string classes. - int id = ClassID.getID(this); - return id == ClassID.cidOneByteString || - id == ClassID.cidExternalOneByteString; - } - - /** - * Create the most efficient string representation for specified - * [charCodes]. - * - * Only uses the character codes between index [start] and index [end] of - * `charCodes`. They must satisfy `0 <= start <= end <= charCodes.length`. - * - * The [limit] is an upper limit on the character codes in the iterable. - * It's `null` if unknown. - */ - static String createFromCharCodes( - Iterable charCodes, int start, int? end, int? limit) { - // TODO(srdjan): Also skip copying of wide typed arrays. - final ccid = ClassID.getID(charCodes); - if ((ccid != ClassID.cidArray) && - (ccid != ClassID.cidGrowableObjectArray) && - (ccid != ClassID.cidImmutableArray)) { - if (charCodes is Uint8List) { - final actualEnd = - RangeError.checkValidRange(start, end, charCodes.length); - return _createOneByteString(charCodes, start, actualEnd - start); - } else if (charCodes is! Uint16List) { - return _createStringFromIterable(charCodes, start, end); - } - } - final int codeCount = charCodes.length; - final actualEnd = RangeError.checkValidRange(start, end, codeCount); - final len = actualEnd - start; - if (len == 0) return ""; - - final typedCharCodes = unsafeCast>(charCodes); - - final int actualLimit = - limit ?? _scanCodeUnits(typedCharCodes, start, actualEnd); - if (actualLimit < 0) { - throw new ArgumentError(typedCharCodes); - } - if (actualLimit <= _maxLatin1) { - return _createOneByteString(typedCharCodes, start, len); - } - if (actualLimit <= _maxUtf16) { - return _TwoByteString._allocateFromTwoByteList( - typedCharCodes, start, actualEnd); - } - // TODO(lrn): Consider passing limit to _createFromCodePoints, because - // the function is currently fully generic and doesn't know that its - // charCodes are not all Latin-1 or Utf-16. - return _createFromCodePoints(typedCharCodes, start, actualEnd); - } - - static int _scanCodeUnits(List charCodes, int start, int end) { - int bits = 0; - for (int i = start; i < end; i++) { - int code = charCodes[i]; - if (code is! _Smi) throw new ArgumentError(charCodes); - bits |= code; - } - return bits; - } - - static String _createStringFromIterable( - Iterable charCodes, int start, int? end) { - // Treat charCodes as Iterable. - if (charCodes is EfficientLengthIterable) { - int length = charCodes.length; - final endVal = RangeError.checkValidRange(start, end, length); - final charCodeList = new List.from( - charCodes.take(endVal).skip(start), - growable: false); - return createFromCharCodes(charCodeList, 0, charCodeList.length, null); - } - // Don't know length of iterable, so iterate and see if all the values - // are there. - if (start < 0) throw new RangeError.range(start, 0, charCodes.length); - var it = charCodes.iterator; - for (int i = 0; i < start; i++) { - if (!it.moveNext()) { - throw new RangeError.range(start, 0, i); - } - } - List charCodeList; - int bits = 0; // Bitwise-or of all char codes in list. - final endVal = end; - if (endVal == null) { - var list = []; - while (it.moveNext()) { - int code = it.current; - bits |= code; - list.add(code); - } - charCodeList = makeListFixedLength(list); - } else { - if (endVal < start) { - throw new RangeError.range(endVal, start, charCodes.length); - } - int len = endVal - start; - charCodeList = new List.generate(len, (int i) { - if (!it.moveNext()) { - throw new RangeError.range(endVal, start, start + i); - } - int code = it.current; - bits |= code; - return code; - }); - } - int length = charCodeList.length; - if (bits < 0) { - throw new ArgumentError(charCodes); - } - bool isOneByteString = (bits <= _maxLatin1); - if (isOneByteString) { - return _createOneByteString(charCodeList, 0, length); - } - return createFromCharCodes(charCodeList, 0, length, bits); - } - - // Inlining is disabled as a workaround to http://dartbug.com/37800. - @pragma("vm:never-inline") - static String _createOneByteString(List charCodes, int start, int len) { - // It's always faster to do this in Dart than to call into the runtime. - var s = _OneByteString._allocate(len); - - // Special case for native Uint8 typed arrays. - final int cid = ClassID.getID(charCodes); - if (cid == ClassID.cidUint8ArrayView || - cid == ClassID.cidUint8Array || - cid == ClassID.cidExternalUint8Array) { - Uint8List bytes = unsafeCast(charCodes); - copyRangeFromUint8ListToOneByteString(bytes, s, start, 0, len); - return s; - } - - // Fall through to normal case. - for (int i = 0; i < len; i++) { - s._setAt(i, charCodes[start + i]); - } - return s; - } - - static String _createFromCodePoints(List codePoints, int start, int end) - native "StringBase_createFromCodePoints"; - - String operator [](int index) native "String_charAt"; - - int codeUnitAt(int index); // Implemented in the subclasses. - - @pragma("vm:exact-result-type", "dart:core#_Smi") - @pragma("vm:prefer-inline") - int get length native "String_getLength"; - - @pragma("vm:exact-result-type", bool) - bool get isEmpty { - return this.length == 0; - } - - bool get isNotEmpty => !isEmpty; - - String operator +(String other) native "String_concat"; - - String toString() { - return this; - } - - @pragma("vm:exact-result-type", bool) - bool operator ==(Object other) { - if (identical(this, other)) { - return true; - } - if (other is String && this.length == other.length) { - final len = this.length; - for (int i = 0; i < len; i++) { - if (this.codeUnitAt(i) != other.codeUnitAt(i)) { - return false; - } - } - return true; - } - return false; - } - - int compareTo(String other) { - int thisLength = this.length; - int otherLength = other.length; - int len = (thisLength < otherLength) ? thisLength : otherLength; - for (int i = 0; i < len; i++) { - int thisCodeUnit = this.codeUnitAt(i); - int otherCodeUnit = other.codeUnitAt(i); - if (thisCodeUnit < otherCodeUnit) { - return -1; - } - if (thisCodeUnit > otherCodeUnit) { - return 1; - } - } - if (thisLength < otherLength) return -1; - if (thisLength > otherLength) return 1; - return 0; - } - - @pragma("vm:exact-result-type", bool) - bool _substringMatches(int start, String other) { - if (other.isEmpty) return true; - final len = other.length; - if ((start < 0) || (start + len > this.length)) { - return false; - } - for (int i = 0; i < len; i++) { - if (this.codeUnitAt(i + start) != other.codeUnitAt(i)) { - return false; - } - } - return true; - } - - bool endsWith(String other) { - return _substringMatches(this.length - other.length, other); - } - - bool startsWith(Pattern pattern, [int index = 0]) { - if ((index < 0) || (index > this.length)) { - throw new RangeError.range(index, 0, this.length); - } - if (pattern is String) { - return _substringMatches(index, pattern); - } - return pattern.matchAsPrefix(this, index) != null; - } - - int indexOf(Pattern pattern, [int start = 0]) { - if ((start < 0) || (start > this.length)) { - throw new RangeError.range(start, 0, this.length, "start"); - } - if (pattern is String) { - String other = pattern; - int maxIndex = this.length - other.length; - // TODO: Use an efficient string search (e.g. BMH). - for (int index = start; index <= maxIndex; index++) { - if (_substringMatches(index, other)) { - return index; - } - } - return -1; - } - for (int i = start; i <= this.length; i++) { - // TODO(11276); This has quadratic behavior because matchAsPrefix tries - // to find a later match too. Optimize matchAsPrefix to avoid this. - if (pattern.matchAsPrefix(this, i) != null) return i; - } - return -1; - } - - int lastIndexOf(Pattern pattern, [int? start]) { - if (start == null) { - start = this.length; - } else if (start < 0 || start > this.length) { - throw new RangeError.range(start, 0, this.length); - } - if (pattern is String) { - String other = pattern; - int maxIndex = this.length - other.length; - if (maxIndex < start) start = maxIndex; - for (int index = start; index >= 0; index--) { - if (_substringMatches(index, other)) { - return index; - } - } - return -1; - } - for (int i = start; i >= 0; i--) { - // TODO(11276); This has quadratic behavior because matchAsPrefix tries - // to find a later match too. Optimize matchAsPrefix to avoid this. - if (pattern.matchAsPrefix(this, i) != null) return i; - } - return -1; - } - - String substring(int startIndex, [int? endIndex]) { - endIndex ??= this.length; - - if ((startIndex < 0) || (startIndex > this.length)) { - throw new RangeError.value(startIndex); - } - if ((endIndex < 0) || (endIndex > this.length)) { - throw new RangeError.value(endIndex); - } - if (startIndex > endIndex) { - throw new RangeError.value(startIndex); - } - return _substringUnchecked(startIndex, endIndex); - } - - String _substringUnchecked(int startIndex, int endIndex) { - assert(endIndex != null); - assert((startIndex >= 0) && (startIndex <= this.length)); - assert((endIndex >= 0) && (endIndex <= this.length)); - assert(startIndex <= endIndex); - - if (startIndex == endIndex) { - return ""; - } - if ((startIndex == 0) && (endIndex == this.length)) { - return this; - } - if ((startIndex + 1) == endIndex) { - return this[startIndex]; - } - return _substringUncheckedNative(startIndex, endIndex); - } - - String _substringUncheckedNative(int startIndex, int endIndex) - native "StringBase_substringUnchecked"; - - // Checks for one-byte whitespaces only. - static bool _isOneByteWhitespace(int codeUnit) { - if (codeUnit <= 32) { - return ((codeUnit == 32) || // Space. - ((codeUnit <= 13) && (codeUnit >= 9))); // CR, LF, TAB, etc. - } - return (codeUnit == 0x85) || (codeUnit == 0xA0); // NEL, NBSP. - } - - // Characters with Whitespace property (Unicode 6.3). - // 0009..000D ; White_Space # Cc .. - // 0020 ; White_Space # Zs SPACE - // 0085 ; White_Space # Cc - // 00A0 ; White_Space # Zs NO-BREAK SPACE - // 1680 ; White_Space # Zs OGHAM SPACE MARK - // 2000..200A ; White_Space # Zs EN QUAD..HAIR SPACE - // 2028 ; White_Space # Zl LINE SEPARATOR - // 2029 ; White_Space # Zp PARAGRAPH SEPARATOR - // 202F ; White_Space # Zs NARROW NO-BREAK SPACE - // 205F ; White_Space # Zs MEDIUM MATHEMATICAL SPACE - // 3000 ; White_Space # Zs IDEOGRAPHIC SPACE - // - // BOM: 0xFEFF - static bool _isTwoByteWhitespace(int codeUnit) { - if (codeUnit <= 32) { - return (codeUnit == 32) || ((codeUnit <= 13) && (codeUnit >= 9)); - } - if (codeUnit < 0x85) return false; - if ((codeUnit == 0x85) || (codeUnit == 0xA0)) return true; - return (codeUnit <= 0x200A) - ? ((codeUnit == 0x1680) || (0x2000 <= codeUnit)) - : ((codeUnit == 0x2028) || - (codeUnit == 0x2029) || - (codeUnit == 0x202F) || - (codeUnit == 0x205F) || - (codeUnit == 0x3000) || - (codeUnit == 0xFEFF)); - } - - int _firstNonWhitespace() { - final len = this.length; - int first = 0; - for (; first < len; first++) { - if (!_isWhitespace(this.codeUnitAt(first))) { - break; - } - } - return first; - } - - int _lastNonWhitespace() { - int last = this.length - 1; - for (; last >= 0; last--) { - if (!_isWhitespace(this.codeUnitAt(last))) { - break; - } - } - return last; - } - - String trim() { - final len = this.length; - int first = _firstNonWhitespace(); - if (len == first) { - // String contains only whitespaces. - return ""; - } - int last = _lastNonWhitespace() + 1; - if ((first == 0) && (last == len)) { - // Returns this string since it does not have leading or trailing - // whitespaces. - return this; - } - return _substringUnchecked(first, last); - } - - String trimLeft() { - final len = this.length; - int first = 0; - for (; first < len; first++) { - if (!_isWhitespace(this.codeUnitAt(first))) { - break; - } - } - if (len == first) { - // String contains only whitespaces. - return ""; - } - if (first == 0) { - // Returns this string since it does not have leading or trailing - // whitespaces. - return this; - } - return _substringUnchecked(first, len); - } - - String trimRight() { - final len = this.length; - int last = len - 1; - for (; last >= 0; last--) { - if (!_isWhitespace(this.codeUnitAt(last))) { - break; - } - } - if (last == -1) { - // String contains only whitespaces. - return ""; - } - if (last == (len - 1)) { - // Returns this string since it does not have trailing whitespaces. - return this; - } - return _substringUnchecked(0, last + 1); - } - - String operator *(int times) { - if (times <= 0) return ""; - if (times == 1) return this; - StringBuffer buffer = new StringBuffer(this); - for (int i = 1; i < times; i++) { - buffer.write(this); - } - return buffer.toString(); - } - - String padLeft(int width, [String padding = ' ']) { - int delta = width - this.length; - if (delta <= 0) return this; - StringBuffer buffer = new StringBuffer(); - for (int i = 0; i < delta; i++) { - buffer.write(padding); - } - buffer.write(this); - return buffer.toString(); - } - - String padRight(int width, [String padding = ' ']) { - int delta = width - this.length; - if (delta <= 0) return this; - StringBuffer buffer = new StringBuffer(this); - for (int i = 0; i < delta; i++) { - buffer.write(padding); - } - return buffer.toString(); - } - - bool contains(Pattern pattern, [int startIndex = 0]) { - if (pattern is String) { - if (startIndex < 0 || startIndex > this.length) { - throw new RangeError.range(startIndex, 0, this.length); - } - return indexOf(pattern, startIndex) >= 0; - } - return pattern.allMatches(this.substring(startIndex)).isNotEmpty; - } - - String replaceFirst(Pattern pattern, String replacement, - [int startIndex = 0]) { - // TODO: Remove these null checks once all code is opted into strong nonnullable mode. - if (pattern == null) { - throw new ArgumentError.notNull("pattern"); - } - if (replacement == null) { - throw new ArgumentError.notNull("replacement"); - } - if (startIndex == null) { - throw new ArgumentError.notNull("startIndex"); - } - RangeError.checkValueInInterval(startIndex, 0, this.length, "startIndex"); - Iterator iterator = startIndex == 0 - ? pattern.allMatches(this).iterator - : pattern.allMatches(this, startIndex).iterator; - if (!iterator.moveNext()) return this; - Match match = iterator.current; - return replaceRange(match.start, match.end, replacement); - } - - String replaceRange(int start, int? end, String replacement) { - final length = this.length; - final localEnd = RangeError.checkValidRange(start, end, length); - bool replacementIsOneByte = replacement._isOneByte; - if (start == 0 && localEnd == length) return replacement; - int replacementLength = replacement.length; - int totalLength = start + (length - localEnd) + replacementLength; - if (replacementIsOneByte && this._isOneByte) { - var result = _OneByteString._allocate(totalLength); - int index = 0; - index = result._setRange(index, this, 0, start); - index = result._setRange(start, replacement, 0, replacementLength); - result._setRange(index, this, localEnd, length); - return result; - } - List slices = []; - _addReplaceSlice(slices, 0, start); - if (replacement.length > 0) slices.add(replacement); - _addReplaceSlice(slices, localEnd, length); - return _joinReplaceAllResult( - this, slices, totalLength, replacementIsOneByte); - } - - static int _addReplaceSlice(List matches, int start, int end) { - int length = end - start; - if (length > 0) { - if (length <= _maxLengthValue && start <= _maxStartValue) { - matches.add(-((start << _lengthBits) | length)); - } else { - matches.add(start); - matches.add(end); - } - } - return length; - } - - String replaceAll(Pattern pattern, String replacement) { - if (pattern == null) throw new ArgumentError.notNull("pattern"); - if (replacement == null) throw new ArgumentError.notNull("replacement"); - - int startIndex = 0; - // String fragments that replace the the prefix [this] up to [startIndex]. - List matches = []; - int length = 0; // Length of all fragments. - int replacementLength = replacement.length; - - if (replacementLength == 0) { - for (Match match in pattern.allMatches(this)) { - length += _addReplaceSlice(matches, startIndex, match.start); - startIndex = match.end; - } - } else { - for (Match match in pattern.allMatches(this)) { - length += _addReplaceSlice(matches, startIndex, match.start); - matches.add(replacement); - length += replacementLength; - startIndex = match.end; - } - } - // No match, or a zero-length match at start with zero-length replacement. - if (startIndex == 0 && length == 0) return this; - length += _addReplaceSlice(matches, startIndex, this.length); - bool replacementIsOneByte = replacement._isOneByte; - if (replacementIsOneByte && - length < _maxJoinReplaceOneByteStringLength && - this._isOneByte) { - // TODO(lrn): Is there a cut-off point, or is runtime always faster? - return _joinReplaceAllOneByteResult(this, matches, length); - } - return _joinReplaceAllResult(this, matches, length, replacementIsOneByte); - } - - /** - * As [_joinReplaceAllResult], but knowing that the result - * is always a [_OneByteString]. - */ - static String _joinReplaceAllOneByteResult( - String base, List matches, int length) { - _OneByteString result = _OneByteString._allocate(length); - int writeIndex = 0; - for (int i = 0; i < matches.length; i++) { - var entry = matches[i]; - if (entry is _Smi) { - int sliceStart = entry; - int sliceEnd; - if (sliceStart < 0) { - int bits = -sliceStart; - int sliceLength = bits & _lengthMask; - sliceStart = bits >> _lengthBits; - sliceEnd = sliceStart + sliceLength; - } else { - i++; - // This function should only be called with valid matches lists. - // If the list is short, or sliceEnd is not an integer, one of - // the next few lines will throw anyway. - assert(i < matches.length); - sliceEnd = matches[i]; - } - for (int j = sliceStart; j < sliceEnd; j++) { - result._setAt(writeIndex++, base.codeUnitAt(j)); - } - } else { - // Replacement is a one-byte string. - String replacement = entry; - for (int j = 0; j < replacement.length; j++) { - result._setAt(writeIndex++, replacement.codeUnitAt(j)); - } - } - } - assert(writeIndex == length); - return result; - } - - /** - * Combine the results of a [replaceAll] match into a new string. - * - * The [matches] lists contains Smi index pairs representing slices of - * [base] and [String]s to be put in between the slices. - * - * The total [length] of the resulting string is known, as is - * whether the replacement strings are one-byte strings. - * If they are, then we have to check the base string slices to know - * whether the result must be a one-byte string. - */ - static String - _joinReplaceAllResult(String base, List matches, int length, - bool replacementStringsAreOneByte) - native "StringBase_joinReplaceAllResult"; - - String replaceAllMapped(Pattern pattern, String replace(Match match)) { - if (pattern == null) throw new ArgumentError.notNull("pattern"); - if (replace == null) throw new ArgumentError.notNull("replace"); - List matches = []; - int length = 0; - int startIndex = 0; - bool replacementStringsAreOneByte = true; - for (Match match in pattern.allMatches(this)) { - length += _addReplaceSlice(matches, startIndex, match.start); - var replacement = "${replace(match)}"; - matches.add(replacement); - length += replacement.length; - replacementStringsAreOneByte = - replacementStringsAreOneByte && replacement._isOneByte; - startIndex = match.end; - } - if (matches.isEmpty) return this; - length += _addReplaceSlice(matches, startIndex, this.length); - if (replacementStringsAreOneByte && - length < _maxJoinReplaceOneByteStringLength && - this._isOneByte) { - return _joinReplaceAllOneByteResult(this, matches, length); - } - return _joinReplaceAllResult( - this, matches, length, replacementStringsAreOneByte); - } - - String replaceFirstMapped(Pattern pattern, String replace(Match match), - [int startIndex = 0]) { - if (pattern == null) throw new ArgumentError.notNull("pattern"); - if (replace == null) throw new ArgumentError.notNull("replace"); - if (startIndex == null) throw new ArgumentError.notNull("startIndex"); - RangeError.checkValueInInterval(startIndex, 0, this.length, "startIndex"); - - var matches = pattern.allMatches(this, startIndex).iterator; - if (!matches.moveNext()) return this; - var match = matches.current; - var replacement = "${replace(match)}"; - return replaceRange(match.start, match.end, replacement); - } - - static String _matchString(Match match) => match[0]!; - static String _stringIdentity(String string) => string; - - String _splitMapJoinEmptyString( - String onMatch(Match match), String onNonMatch(String nonMatch)) { - // Pattern is the empty string. - StringBuffer buffer = new StringBuffer(); - int length = this.length; - int i = 0; - buffer.write(onNonMatch("")); - while (i < length) { - buffer.write(onMatch(new _StringMatch(i, this, ""))); - // Special case to avoid splitting a surrogate pair. - int code = this.codeUnitAt(i); - if ((code & ~0x3FF) == 0xD800 && length > i + 1) { - // Leading surrogate; - code = this.codeUnitAt(i + 1); - if ((code & ~0x3FF) == 0xDC00) { - // Matching trailing surrogate. - buffer.write(onNonMatch(this.substring(i, i + 2))); - i += 2; - continue; - } - } - buffer.write(onNonMatch(this[i])); - i++; - } - buffer.write(onMatch(new _StringMatch(i, this, ""))); - buffer.write(onNonMatch("")); - return buffer.toString(); - } - - String splitMapJoin(Pattern pattern, - {String onMatch(Match match)?, String onNonMatch(String nonMatch)?}) { - if (pattern == null) { - throw new ArgumentError.notNull("pattern"); - } - onMatch ??= _matchString; - onNonMatch ??= _stringIdentity; - if (pattern is String) { - String stringPattern = pattern; - if (stringPattern.isEmpty) { - return _splitMapJoinEmptyString(onMatch, onNonMatch); - } - } - StringBuffer buffer = new StringBuffer(); - int startIndex = 0; - for (Match match in pattern.allMatches(this)) { - buffer.write(onNonMatch(this.substring(startIndex, match.start))); - buffer.write(onMatch(match).toString()); - startIndex = match.end; - } - buffer.write(onNonMatch(this.substring(startIndex))); - return buffer.toString(); - } - - // Convert single object to string. - @pragma("vm:entry-point", "call") - static String _interpolateSingle(Object o) { - if (o is String) return o; - final s = o.toString(); - if (s is! String) { - throw new ArgumentError(s); - } - return s; - } - - /** - * Convert all objects in [values] to strings and concat them - * into a result string. - * Modifies the input list if it contains non-`String` values. - */ - @pragma("vm:entry-point", "call") - static String _interpolate(final List values) { - final numValues = values.length; - int totalLength = 0; - int i = 0; - while (i < numValues) { - final e = values[i]; - final s = e.toString(); - values[i] = s; - if (ClassID.getID(s) == ClassID.cidOneByteString) { - totalLength += s.length; - i++; - } else if (s is! String) { - throw new ArgumentError(s); - } else { - // Handle remaining elements without checking for one-byte-ness. - while (++i < numValues) { - final e = values[i]; - final s = e.toString(); - values[i] = s; - if (s is! String) { - throw new ArgumentError(s); - } - } - return _concatRangeNative(values, 0, numValues); - } - } - // All strings were one-byte strings. - return _OneByteString._concatAll(values, totalLength); - } - - Iterable allMatches(String string, [int start = 0]) { - if (start < 0 || start > string.length) { - throw new RangeError.range(start, 0, string.length, "start"); - } - return new _StringAllMatchesIterable(string, this, start); - } - - Match? matchAsPrefix(String string, [int start = 0]) { - if (start < 0 || start > string.length) { - throw new RangeError.range(start, 0, string.length); - } - if (start + this.length > string.length) return null; - for (int i = 0; i < this.length; i++) { - if (string.codeUnitAt(start + i) != this.codeUnitAt(i)) { - return null; - } - } - return new _StringMatch(start, string, this); - } - - List split(Pattern pattern) { - if ((pattern is String) && pattern.isEmpty) { - List result = - new List.generate(this.length, (int i) => this[i]); - return result; - } - int length = this.length; - Iterator iterator = pattern.allMatches(this).iterator; - if (length == 0 && iterator.moveNext()) { - // A matched empty string input returns the empty list. - return []; - } - List result = []; - int startIndex = 0; - int previousIndex = 0; - // 'pattern' may not be implemented correctly and therefore we cannot - // call _substringUnhchecked unless it is a trustworthy type (e.g. String). - while (true) { - if (startIndex == length || !iterator.moveNext()) { - result.add(this.substring(previousIndex, length)); - break; - } - Match match = iterator.current; - if (match.start == length) { - result.add(this.substring(previousIndex, length)); - break; - } - int endIndex = match.end; - if (startIndex == endIndex && endIndex == previousIndex) { - ++startIndex; // empty match, advance and restart - continue; - } - result.add(this.substring(previousIndex, match.start)); - startIndex = previousIndex = endIndex; - } - return result; - } - - List get codeUnits => new CodeUnits(this); - - Runes get runes => new Runes(this); - - String toUpperCase() native "String_toUpperCase"; - - String toLowerCase() native "String_toLowerCase"; - - // Concatenate ['start', 'end'[ elements of 'strings'. - static String _concatRange(List strings, int start, int end) { - if ((end - start) == 1) { - return strings[start]; - } - return _concatRangeNative(strings, start, end); - } - - // Call this method if all elements of [strings] are known to be strings - // but not all are known to be OneByteString(s). - static String _concatRangeNative(List strings, int start, int end) - native "String_concatRange"; -} - -@pragma("vm:entry-point") -class _OneByteString extends _StringBase { - factory _OneByteString._uninstantiable() { - throw "Unreachable"; - } - - @pragma("vm:exact-result-type", "dart:core#_Smi") - int get hashCode native "String_getHashCode"; - - @pragma("vm:exact-result-type", "dart:core#_Smi") - int codeUnitAt(int index) native "String_codeUnitAt"; - - bool _isWhitespace(int codeUnit) { - return _StringBase._isOneByteWhitespace(codeUnit); - } - - @pragma("vm:exact-result-type", bool) - bool operator ==(Object other) { - return super == other; - } - - @pragma("vm:exact-result-type", _OneByteString) - String _substringUncheckedNative(int startIndex, int endIndex) - native "OneByteString_substringUnchecked"; - - List _splitWithCharCode(int charCode) - native "OneByteString_splitWithCharCode"; - - List split(Pattern pattern) { - // TODO(vegorov) investigate if this can be rewritten as `is _OneByteString` - // check without performance penalty. Front-end would then promote - // pattern variable to _OneByteString. - if (ClassID.getID(pattern) == ClassID.cidOneByteString) { - final String patternAsString = unsafeCast(pattern); - if (patternAsString.length == 1) { - return _splitWithCharCode(patternAsString.codeUnitAt(0)); - } - } - return super.split(pattern); - } - - // All element of 'strings' must be OneByteStrings. - static _concatAll(List strings, int totalLength) { - if (totalLength > 128) { - // Native is quicker. - return _StringBase._concatRangeNative(strings, 0, strings.length); - } - final res = _OneByteString._allocate(totalLength); - final stringsLength = strings.length; - int rIx = 0; - for (int i = 0; i < stringsLength; i++) { - final _OneByteString e = strings[i]; - final eLength = e.length; - for (int s = 0; s < eLength; s++) { - res._setAt(rIx++, e.codeUnitAt(s)); - } - } - return res; - } - - int indexOf(Pattern pattern, [int start = 0]) { - // Specialize for single character pattern. - final pCid = ClassID.getID(pattern); - if ((pCid == ClassID.cidOneByteString) || - (pCid == ClassID.cidTwoByteString) || - (pCid == ClassID.cidExternalOneByteString)) { - final String patternAsString = unsafeCast(pattern); - final len = this.length; - if ((patternAsString.length == 1) && (start >= 0) && (start < len)) { - final patternCu0 = patternAsString.codeUnitAt(0); - if (patternCu0 > 0xFF) { - return -1; - } - for (int i = start; i < len; i++) { - if (this.codeUnitAt(i) == patternCu0) { - return i; - } - } - return -1; - } - } - return super.indexOf(pattern, start); - } - - bool contains(Pattern pattern, [int start = 0]) { - final pCid = ClassID.getID(pattern); - if ((pCid == ClassID.cidOneByteString) || - (pCid == ClassID.cidTwoByteString) || - (pCid == ClassID.cidExternalOneByteString)) { - final String patternAsString = unsafeCast(pattern); - final len = this.length; - if ((patternAsString.length == 1) && (start >= 0) && (start < len)) { - final patternCu0 = patternAsString.codeUnitAt(0); - if (patternCu0 > 0xFF) { - return false; - } - for (int i = start; i < len; i++) { - if (this.codeUnitAt(i) == patternCu0) { - return true; - } - } - return false; - } - } - return super.contains(pattern, start); - } - - String operator *(int times) { - if (times <= 0) return ""; - if (times == 1) return this; - int length = this.length; - if (this.isEmpty) return this; // Don't clone empty string. - _OneByteString result = _OneByteString._allocate(length * times); - int index = 0; - for (int i = 0; i < times; i++) { - for (int j = 0; j < length; j++) { - result._setAt(index++, this.codeUnitAt(j)); - } - } - return result; - } - - String padLeft(int width, [String padding = ' ']) { - int padCid = ClassID.getID(padding); - if ((padCid != ClassID.cidOneByteString) && - (padCid != ClassID.cidExternalOneByteString)) { - return super.padLeft(width, padding); - } - int length = this.length; - int delta = width - length; - if (delta <= 0) return this; - int padLength = padding.length; - int resultLength = padLength * delta + length; - _OneByteString result = _OneByteString._allocate(resultLength); - int index = 0; - if (padLength == 1) { - int padChar = padding.codeUnitAt(0); - for (int i = 0; i < delta; i++) { - result._setAt(index++, padChar); - } - } else { - for (int i = 0; i < delta; i++) { - for (int j = 0; j < padLength; j++) { - result._setAt(index++, padding.codeUnitAt(j)); - } - } - } - for (int i = 0; i < length; i++) { - result._setAt(index++, this.codeUnitAt(i)); - } - return result; - } - - String padRight(int width, [String padding = ' ']) { - int padCid = ClassID.getID(padding); - if ((padCid != ClassID.cidOneByteString) && - (padCid != ClassID.cidExternalOneByteString)) { - return super.padRight(width, padding); - } - int length = this.length; - int delta = width - length; - if (delta <= 0) return this; - int padLength = padding.length; - int resultLength = length + padLength * delta; - _OneByteString result = _OneByteString._allocate(resultLength); - int index = 0; - for (int i = 0; i < length; i++) { - result._setAt(index++, this.codeUnitAt(i)); - } - if (padLength == 1) { - int padChar = padding.codeUnitAt(0); - for (int i = 0; i < delta; i++) { - result._setAt(index++, padChar); - } - } else { - for (int i = 0; i < delta; i++) { - for (int j = 0; j < padLength; j++) { - result._setAt(index++, padding.codeUnitAt(j)); - } - } - } - return result; - } - - // Lower-case conversion table for Latin-1 as string. - // Upper-case ranges: 0x41-0x5a ('A' - 'Z'), 0xc0-0xd6, 0xd8-0xde. - // Conversion to lower case performed by adding 0x20. - static const _LC_TABLE = - "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" - "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" - "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f" - "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f" - "\x40\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f" - "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x5b\x5c\x5d\x5e\x5f" - "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f" - "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f" - "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f" - "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f" - "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf" - "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf" - "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef" - "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xd7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xdf" - "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef" - "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"; - - // Upper-case conversion table for Latin-1 as string. - // Lower-case ranges: 0x61-0x7a ('a' - 'z'), 0xe0-0xff. - // The characters 0xb5 (µ) and 0xff (ÿ) have upper case variants - // that are not Latin-1. These are both marked as 0x00 in the table. - // The German "sharp s" \xdf (ß) should be converted into two characters (SS), - // and is also marked with 0x00. - // Conversion to lower case performed by subtracting 0x20. - static const _UC_TABLE = - "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" - "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" - "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f" - "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f" - "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f" - "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f" - "\x60\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f" - "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x7b\x7c\x7d\x7e\x7f" - "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f" - "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f" - "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf" - "\xb0\xb1\xb2\xb3\xb4\x00\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf" - "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf" - "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\x00" - "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf" - "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xf7\xd8\xd9\xda\xdb\xdc\xdd\xde\x00"; - - String toLowerCase() { - for (int i = 0; i < this.length; i++) { - final c = this.codeUnitAt(i); - if (c == _LC_TABLE.codeUnitAt(c)) continue; - // Upper-case character found. - final result = _allocate(this.length); - for (int j = 0; j < i; j++) { - result._setAt(j, this.codeUnitAt(j)); - } - for (int j = i; j < this.length; j++) { - result._setAt(j, _LC_TABLE.codeUnitAt(this.codeUnitAt(j))); - } - return result; - } - return this; - } - - String toUpperCase() { - for (int i = 0; i < this.length; i++) { - final c = this.codeUnitAt(i); - // Continue loop if character is unchanged by upper-case conversion. - if (c == _UC_TABLE.codeUnitAt(c)) continue; - - // Check rest of string for characters that do not convert to - // single-characters in the Latin-1 range. - for (int j = i; j < this.length; j++) { - final c = this.codeUnitAt(j); - if ((_UC_TABLE.codeUnitAt(c) == 0x00) && (c != 0x00)) { - // We use the 0x00 value for characters other than the null character, - // that don't convert to a single Latin-1 character when upper-cased. - // In that case, call the generic super-class method. - return super.toUpperCase(); - } - } - // Some lower-case characters found, but all upper-case to single Latin-1 - // characters. - final result = _allocate(this.length); - for (int j = 0; j < i; j++) { - result._setAt(j, this.codeUnitAt(j)); - } - for (int j = i; j < this.length; j++) { - result._setAt(j, _UC_TABLE.codeUnitAt(this.codeUnitAt(j))); - } - return result; - } - return this; - } - - // Allocates a string of given length, expecting its content to be - // set using _setAt. - @pragma("vm:exact-result-type", _OneByteString) - @pragma("vm:prefer-inline") - static _OneByteString _allocate(int length) { - return unsafeCast<_OneByteString>(allocateOneByteString(length)); - } - - static _OneByteString _allocateFromOneByteList(List list, int start, - int end) native "OneByteString_allocateFromOneByteList"; - - // This is internal helper method. Code point value must be a valid - // Latin1 value (0..0xFF), index must be valid. - @pragma("vm:prefer-inline") - void _setAt(int index, int codePoint) { - writeIntoOneByteString(this, index, codePoint); - } - - // Should be optimizable to a memory move. - // Accepts both _OneByteString and _ExternalOneByteString as argument. - // Returns index after last character written. - int _setRange(int index, String oneByteString, int start, int end) { - assert(oneByteString._isOneByte); - assert(0 <= start); - assert(start <= end); - assert(end <= oneByteString.length); - assert(0 <= index); - assert(index + (end - start) <= length); - for (int i = start; i < end; i++) { - _setAt(index, oneByteString.codeUnitAt(i)); - index += 1; - } - return index; - } -} - -@pragma("vm:entry-point") -class _TwoByteString extends _StringBase { - factory _TwoByteString._uninstantiable() { - throw "Unreachable"; - } - - // Allocates a string of given length, expecting its content to be - // set using _setAt. - @pragma("vm:exact-result-type", _TwoByteString) - @pragma("vm:prefer-inline") - static _TwoByteString _allocate(int length) { - return unsafeCast<_TwoByteString>(allocateTwoByteString(length)); - } - - static String _allocateFromTwoByteList(List list, int start, int end) - native "TwoByteString_allocateFromTwoByteList"; - - // This is internal helper method. Code point value must be a valid - // UTF-16 value (0..0xFFFF), index must be valid. - @pragma("vm:prefer-inline") - void _setAt(int index, int codePoint) { - writeIntoTwoByteString(this, index, codePoint); - } - - bool _isWhitespace(int codeUnit) { - return _StringBase._isTwoByteWhitespace(codeUnit); - } - - @pragma("vm:exact-result-type", "dart:core#_Smi") - int codeUnitAt(int index) native "String_codeUnitAt"; - - @pragma("vm:exact-result-type", bool) - bool operator ==(Object other) { - return super == other; - } -} - -@pragma("vm:entry-point") -class _ExternalOneByteString extends _StringBase { - factory _ExternalOneByteString._uninstantiable() { - throw "Unreachable"; - } - - bool _isWhitespace(int codeUnit) { - return _StringBase._isOneByteWhitespace(codeUnit); - } - - @pragma("vm:exact-result-type", "dart:core#_Smi") - int codeUnitAt(int index) native "String_codeUnitAt"; - - bool operator ==(Object other) { - return super == other; - } -} - -@pragma("vm:entry-point") -class _ExternalTwoByteString extends _StringBase { - factory _ExternalTwoByteString._uninstantiable() { - throw "Unreachable"; - } - - bool _isWhitespace(int codeUnit) { - return _StringBase._isTwoByteWhitespace(codeUnit); - } - - @pragma("vm:exact-result-type", "dart:core#_Smi") - int codeUnitAt(int index) native "String_codeUnitAt"; - - bool operator ==(Object other) { - return super == other; - } -} - -class _StringMatch implements Match { - const _StringMatch(this.start, this.input, this.pattern); - - int get end => start + pattern.length; - String operator [](int g) => group(g); - int get groupCount => 0; - - String group(int group) { - if (group != 0) { - throw new RangeError.value(group); - } - return pattern; - } - - List groups(List groups) { - List result = []; - for (int g in groups) { - result.add(group(g)); - } - return result; - } - - final int start; - final String input; - final String pattern; -} - -class _StringAllMatchesIterable extends Iterable { - final String _input; - final String _pattern; - final int _index; - - _StringAllMatchesIterable(this._input, this._pattern, this._index); - - Iterator get iterator => - new _StringAllMatchesIterator(_input, _pattern, _index); - - Match get first { - int index = _input.indexOf(_pattern, _index); - if (index >= 0) { - return new _StringMatch(index, _input, _pattern); - } - throw IterableElementError.noElement(); - } -} - -class _StringAllMatchesIterator implements Iterator { - final String _input; - final String _pattern; - int _index; - Match? _current; - - _StringAllMatchesIterator(this._input, this._pattern, this._index); - - bool moveNext() { - if (_index + _pattern.length > _input.length) { - _current = null; - return false; - } - var index = _input.indexOf(_pattern, _index); - if (index < 0) { - _index = _input.length + 1; - _current = null; - return false; - } - int end = index + _pattern.length; - _current = new _StringMatch(index, _input, _pattern); - // Empty match, don't start at same location again. - if (end == _index) end++; - _index = end; - return true; - } - - Match get current { - final cur = _current; - return (cur != null) ? cur : cur as Match; - } -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/symbol_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/symbol_patch.dart deleted file mode 100644 index 06eb58833a8..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/symbol_patch.dart +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) 2013, 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. - -// part of "internal_patch.dart"; - -@patch -class Symbol { - @patch - const Symbol(String name) : this._name = name; - - @patch - String toString() => 'Symbol("${computeUnmangledName(this)}")'; - - @patch - static String computeUnmangledName(Symbol symbol) { - String string = Symbol.getName(symbol); - - // get:foo -> foo - // set:foo -> foo= - // get:_foo@xxx -> _foo - // set:_foo@xxx -> _foo= - // Class._constructor@xxx -> Class._constructor - // _Class@xxx._constructor@xxx -> _Class._constructor - // lib._S@xxx with lib._M1@xxx, lib._M2@xxx -> lib._S with lib._M1, lib._M2 - StringBuffer result = new StringBuffer(); - bool add_setter_suffix = false; - var pos = 0; - if (string.length >= 4 && string[3] == ':') { - // Drop 'get:' or 'set:' prefix. - pos = 4; - if (string[0] == 's') { - add_setter_suffix = true; - } - } - // Skip everything between AT and PERIOD, SPACE, COMMA or END - bool skip = false; - for (; pos < string.length; pos++) { - var char = string[pos]; - if (char == '@') { - skip = true; - } else if (char == '.' || char == ' ' || char == ',') { - skip = false; - } - if (!skip) { - result.write(char); - } - } - if (add_setter_suffix) { - result.write('='); - } - return result.toString(); - } - - @patch - int get hashCode { - const arbitraryPrime = 664597; - return 0x1fffffff & (arbitraryPrime * _name.hashCode); - } -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/timeline.dart b/sdk_nnbd/lib/_internal/vm/lib/timeline.dart deleted file mode 100644 index 5e8066b8c04..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/timeline.dart +++ /dev/null @@ -1,26 +0,0 @@ -// 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. - -// part of "developer.dart"; - -@patch -bool _isDartStreamEnabled() native "Timeline_isDartStreamEnabled"; - -@patch -int _getTraceClock() native "Timeline_getTraceClock"; - -@patch -int _getNextAsyncId() native "Timeline_getNextAsyncId"; - -@patch -void _reportTaskEvent(int taskId, String phase, String category, String name, - String argumentsAsJson) native "Timeline_reportTaskEvent"; - -@patch -void _reportFlowEvent(String category, String name, int type, int id, - String argumentsAsJson) native "Timeline_reportFlowEvent"; - -@patch -void _reportInstantEvent(String category, String name, String argumentsAsJson) - native "Timeline_reportInstantEvent"; diff --git a/sdk_nnbd/lib/_internal/vm/lib/timer_impl.dart b/sdk_nnbd/lib/_internal/vm/lib/timer_impl.dart deleted file mode 100644 index db626c2a39d..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/timer_impl.dart +++ /dev/null @@ -1,486 +0,0 @@ -// Copyright (c) 2013, 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. - -// part of "isolate_patch.dart"; - -// Timer heap implemented as a array-based binary heap[0]. -// This allows for O(1) `first`, O(log(n)) `remove`/`removeFirst` and O(log(n)) -// `add`. -// -// To ensure the timers are ordered by insertion time, the _Timer class has a -// `_id` field set when added to the heap. -// -// [0] http://en.wikipedia.org/wiki/Binary_heap -class _TimerHeap { - List<_Timer> _list; - int _used = 0; - - _TimerHeap([int initSize = 7]) - : _list = List<_Timer>.filled(initSize, _Timer._sentinelTimer); - - bool get isEmpty => _used == 0; - - _Timer get first => _list[0]; - - bool isFirst(_Timer timer) => timer._indexOrNext == 0; - - void add(_Timer timer) { - if (_used == _list.length) { - _resize(); - } - timer._indexOrNext = _used++; - _list[timer._indexOrNext] = timer; - _bubbleUp(timer); - } - - _Timer removeFirst() { - var f = first; - remove(f); - return f; - } - - void remove(_Timer timer) { - _used--; - if (isEmpty) { - _list[0] = _Timer._sentinelTimer; - timer._indexOrNext = null; - return; - } - var last = _list[_used]; - if (!identical(last, timer)) { - last._indexOrNext = timer._indexOrNext; - _list[last._indexOrNext] = last; - if (last._compareTo(timer) < 0) { - _bubbleUp(last); - } else { - _bubbleDown(last); - } - } - _list[_used] = _Timer._sentinelTimer; - timer._indexOrNext = null; - } - - void _resize() { - var newList = - List<_Timer>.filled(_list.length * 2 + 1, _Timer._sentinelTimer); - newList.setRange(0, _used, _list); - _list = newList; - } - - void _bubbleUp(_Timer timer) { - while (!isFirst(timer)) { - _Timer parent = _parent(timer); - if (timer._compareTo(parent) < 0) { - _swap(timer, parent); - } else { - break; - } - } - } - - void _bubbleDown(_Timer timer) { - while (true) { - int leftIndex = _leftChildIndex(timer._indexOrNext); - int rightIndex = _rightChildIndex(timer._indexOrNext); - _Timer newest = timer; - if (leftIndex < _used && _list[leftIndex]._compareTo(newest) < 0) { - newest = _list[leftIndex]; - } - if (rightIndex < _used && _list[rightIndex]._compareTo(newest) < 0) { - newest = _list[rightIndex]; - } - if (identical(newest, timer)) { - // We are where we should be, break. - break; - } - _swap(newest, timer); - } - } - - void _swap(_Timer first, _Timer second) { - int tmp = first._indexOrNext; - first._indexOrNext = second._indexOrNext; - second._indexOrNext = tmp; - _list[first._indexOrNext] = first; - _list[second._indexOrNext] = second; - } - - _Timer _parent(_Timer timer) => _list[_parentIndex(timer._indexOrNext)]; - - static int _parentIndex(int index) => (index - 1) ~/ 2; - static int _leftChildIndex(int index) => 2 * index + 1; - static int _rightChildIndex(int index) => 2 * index + 2; -} - -class _Timer implements Timer { - // Cancels the timer in the event handler. - static const _NO_TIMER = -1; - - // A generic null timer object that is used to populate unused slots - // in TimerHeap. - static final _sentinelTimer = _Timer._sentinel(); - - // We distinguish what kind of message arrived based on the value being sent. - static const _ZERO_EVENT = 1; - static const _TIMEOUT_EVENT = null; - - // Timers are ordered by wakeup time. Timers with a timeout value of > 0 do - // end up on the TimerHeap. Timers with a timeout of 0 are queued in a list. - static final _heap = new _TimerHeap(); - static _Timer? _firstZeroTimer; - static _Timer _lastZeroTimer = _sentinelTimer; - - // We use an id to be able to sort timers with the same expiration time. - // ids are recycled after ID_MASK enqueues or when the timer queue is empty. - static const _ID_MASK = 0x1fffffff; - static int _idCount = 0; - - static RawReceivePort? _receivePort; - static SendPort? _sendPort; - static int _scheduledWakeupTime = 0; - - static bool _handlingCallbacks = false; - - Function? _callback; // Closure to call when timer fires. null if canceled. - int _wakeupTime; // Expiration time. - final int _milliSeconds; // Duration specified at creation. - final bool _repeating; // Indicates periodic timers. - var _indexOrNext; // Index if part of the TimerHeap, link otherwise. - int _id; // Incrementing id to enable sorting of timers with same expiry. - - int _tick = 0; // Backing for [tick], - - // Get the next available id. We accept collisions and reordering when the - // _idCount overflows and the timers expire at the same millisecond. - static int _nextId() { - var result = _idCount; - _idCount = (_idCount + 1) & _ID_MASK; - return result; - } - - _Timer._sentinel() - : _callback = null, - _wakeupTime = 0, - _milliSeconds = 0, - _repeating = false, - _indexOrNext = null, - _id = -1; - - _Timer._internal( - this._callback, this._wakeupTime, this._milliSeconds, this._repeating) - : _id = _nextId(); - - static _Timer _createTimer( - void callback(Timer timer), int milliSeconds, bool repeating) { - // Negative timeouts are treated as if 0 timeout. - if (milliSeconds < 0) { - milliSeconds = 0; - } - // Add one because DateTime.now() is assumed to round down - // to nearest millisecond, not up, so that time + duration is before - // duration milliseconds from now. Using microsecond timers like - // Stopwatch allows detecting that the timer fires early. - int now = VMLibraryHooks.timerMillisecondClock(); - int wakeupTime = (milliSeconds == 0) ? now : (now + 1 + milliSeconds); - - _Timer timer = - new _Timer._internal(callback, wakeupTime, milliSeconds, repeating); - // Enqueue this newly created timer in the appropriate structure and - // notify if necessary. - timer._enqueue(); - return timer; - } - - factory _Timer(int milliSeconds, void callback(Timer timer)) { - return _createTimer(callback, milliSeconds, false); - } - - factory _Timer.periodic(int milliSeconds, void callback(Timer timer)) { - return _createTimer(callback, milliSeconds, true); - } - - bool get _isInHeap => _indexOrNext is int; - - int _compareTo(_Timer other) { - int c = _wakeupTime - other._wakeupTime; - if (c != 0) return c; - return _id - other._id; - } - - bool get isActive => _callback != null; - - int get tick => _tick; - - // Cancels a set timer. The timer is removed from the timer heap if it is a - // non-zero timer. Zero timers are kept in the list as they need to consume - // the corresponding pending message. - void cancel() { - _callback = null; - // Only heap timers are really removed. Zero timers need to consume their - // corresponding wakeup message so they are left in the queue. - if (!_isInHeap) return; - bool update = _heap.isFirst(this); - _heap.remove(this); - if (update) { - _notifyEventHandler(); - } - } - - void _advanceWakeupTime() { - // Recalculate the next wakeup time. For repeating timers with a 0 timeout - // the next wakeup time is now. - _id = _nextId(); - if (_milliSeconds > 0) { - _wakeupTime += _milliSeconds; - } else { - _wakeupTime = VMLibraryHooks.timerMillisecondClock(); - } - } - - // Adds a timer to the heap or timer list. Timers with the same wakeup time - // are enqueued in order and notified in FIFO order. - void _enqueue() { - if (_milliSeconds == 0) { - if (_firstZeroTimer == null) { - _lastZeroTimer = this; - _firstZeroTimer = this; - } else { - _lastZeroTimer._indexOrNext = this; - _lastZeroTimer = this; - } - // Every zero timer gets its own event. - _notifyZeroHandler(); - } else { - _heap.add(this); - if (_heap.isFirst(this)) { - _notifyEventHandler(); - } - } - } - - // Enqueue one message for each zero timer. To be able to distinguish from - // EventHandler messages we send a _ZERO_EVENT instead of a _TIMEOUT_EVENT. - static void _notifyZeroHandler() { - var port = _sendPort; - if (port == null) { - port = _createTimerHandler(); - _sendPort = port; - } - port.send(_ZERO_EVENT); - } - - // Handle the notification of a zero timer. Make sure to also execute non-zero - // timers with a lower expiration time. - static List _queueFromZeroEvent() { - var pendingTimers = []; - final firstTimer = _firstZeroTimer; - if (firstTimer != null) { - // Collect pending timers from the timer heap that have an expiration prior - // to the currently notified zero timer. - var timer; - while (!_heap.isEmpty && (_heap.first._compareTo(firstTimer) < 0)) { - timer = _heap.removeFirst(); - pendingTimers.add(timer); - } - // Append the first zero timer to the pending timers. - timer = _firstZeroTimer; - _firstZeroTimer = timer._indexOrNext; - timer._indexOrNext = null; - pendingTimers.add(timer); - } - return pendingTimers; - } - - static void _notifyEventHandler() { - if (_handlingCallbacks) { - // While we are already handling callbacks we will not notify the event - // handler. _handleTimeout will call _notifyEventHandler once all pending - // timers are processed. - return; - } - - // If there are no pending timers. Close down the receive port. - if ((_firstZeroTimer == null) && _heap.isEmpty) { - // No pending timers: Close the receive port and let the event handler - // know. - if (_sendPort != null) { - _cancelWakeup(); - _shutdownTimerHandler(); - } - return; - } else if (_heap.isEmpty) { - // Only zero timers are left. Cancel any scheduled wakeups. - _cancelWakeup(); - return; - } - - // Only send a message if the requested wakeup time differs from the - // already scheduled wakeup time. - var wakeupTime = _heap.first._wakeupTime; - if ((_scheduledWakeupTime == 0) || (wakeupTime != _scheduledWakeupTime)) { - _scheduleWakeup(wakeupTime); - } - } - - static List _queueFromTimeoutEvent() { - var pendingTimers = []; - final firstTimer = _firstZeroTimer; - if (firstTimer != null) { - // Collect pending timers from the timer heap that have an expiration - // prior to the next zero timer. - // By definition the first zero timer has been scheduled before the - // current time, meaning all timers which are "less than" the first zero - // timer are expired. The first zero timer will be dispatched when its - // corresponding message is delivered. - var timer; - while (!_heap.isEmpty && (_heap.first._compareTo(firstTimer) < 0)) { - timer = _heap.removeFirst(); - pendingTimers.add(timer); - } - } else { - // Collect pending timers from the timer heap which have expired at this - // time. - var currentTime = VMLibraryHooks.timerMillisecondClock(); - var timer; - while (!_heap.isEmpty && (_heap.first._wakeupTime <= currentTime)) { - timer = _heap.removeFirst(); - pendingTimers.add(timer); - } - } - return pendingTimers; - } - - static void _runTimers(List pendingTimers) { - // If there are no pending timers currently reset the id space before we - // have a chance to enqueue new timers. - if (_heap.isEmpty && (_firstZeroTimer == null)) { - _idCount = 0; - } - - // Fast exit if no pending timers. - if (pendingTimers.length == 0) { - return; - } - - // Trigger all of the pending timers. New timers added as part of the - // callbacks will be enqueued now and notified in the next spin at the - // earliest. - _handlingCallbacks = true; - var i = 0; - try { - for (; i < pendingTimers.length; i++) { - // Next pending timer. - var timer = pendingTimers[i]; - timer._indexOrNext = null; - - // One of the timers in the pending_timers list can cancel - // one of the later timers which will set the callback to - // null. Or the pending zero timer has been canceled earlier. - if (timer._callback != null) { - var callback = timer._callback; - if (!timer._repeating) { - // Mark timer as inactive. - timer._callback = null; - } else if (timer._milliSeconds > 0) { - var ms = timer._milliSeconds; - int overdue = - VMLibraryHooks.timerMillisecondClock() - timer._wakeupTime; - if (overdue > ms) { - int missedTicks = overdue ~/ ms; - timer._wakeupTime += missedTicks * ms; - timer._tick += missedTicks; - } - } - timer._tick += 1; - - callback(timer); - // Re-insert repeating timer if not canceled. - if (timer._repeating && (timer._callback != null)) { - timer._advanceWakeupTime(); - timer._enqueue(); - } - // Execute pending micro tasks. - _runPendingImmediateCallback(); - } - } - } finally { - _handlingCallbacks = false; - // Re-queue timers we didn't get to. - for (i++; i < pendingTimers.length; i++) { - var timer = pendingTimers[i]; - timer._enqueue(); - } - _notifyEventHandler(); - } - } - - static void _handleMessage(msg) { - var pendingTimers; - if (msg == _ZERO_EVENT) { - pendingTimers = _queueFromZeroEvent(); - assert(pendingTimers.length > 0); - } else { - assert(msg == _TIMEOUT_EVENT); - _scheduledWakeupTime = 0; // Consumed the last scheduled wakeup now. - pendingTimers = _queueFromTimeoutEvent(); - } - _runTimers(pendingTimers); - // Notify the event handler or shutdown the port if no more pending - // timers are present. - _notifyEventHandler(); - } - - // Tell the event handler to wake this isolate at a specific time. - static void _scheduleWakeup(int wakeupTime) { - var port = _sendPort; - if (port == null) { - port = _createTimerHandler(); - _sendPort = port; - } - VMLibraryHooks.eventHandlerSendData(null, port, wakeupTime); - _scheduledWakeupTime = wakeupTime; - } - - // Cancel pending wakeups in the event handler. - static void _cancelWakeup() { - if (_sendPort != null) { - VMLibraryHooks.eventHandlerSendData(null, _sendPort, _NO_TIMER); - _scheduledWakeupTime = 0; - } - } - - // Create a receive port and register a message handler for the timer - // events. - static SendPort _createTimerHandler() { - assert(_receivePort == null); - assert(_sendPort == null); - final port = new RawReceivePort(_handleMessage); - final sendPort = port.sendPort; - _receivePort = port; - _sendPort = sendPort; - _scheduledWakeupTime = 0; - return sendPort; - } - - static void _shutdownTimerHandler() { - _sendPort = null; - _scheduledWakeupTime = 0; - _receivePort!.close(); - _receivePort = null; - } - - // The Timer factory registered with the dart:async library by the embedder. - static Timer _factory( - int milliSeconds, void callback(Timer timer), bool repeating) { - if (repeating) { - return new _Timer.periodic(milliSeconds, callback); - } - return new _Timer(milliSeconds, callback); - } -} - -@pragma("vm:entry-point", "call") -_setupHooks() { - VMLibraryHooks.timerFactory = _Timer._factory; -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/timer_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/timer_patch.dart deleted file mode 100644 index 5e8b987fbd4..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/timer_patch.dart +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) 2012, 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. - -// part of "async_patch.dart"; - -@patch -class Timer { - @patch - static Timer _createTimer(Duration duration, void callback()) { - final factory = VMLibraryHooks.timerFactory; - if (factory == null) { - throw new UnsupportedError("Timer interface not supported."); - } - int milliseconds = duration.inMilliseconds; - if (milliseconds < 0) milliseconds = 0; - return factory(milliseconds, (_) { - callback(); - }, false); - } - - @patch - static Timer _createPeriodicTimer( - Duration duration, void callback(Timer timer)) { - final factory = VMLibraryHooks.timerFactory; - if (factory == null) { - throw new UnsupportedError("Timer interface not supported."); - } - int milliseconds = duration.inMilliseconds; - if (milliseconds < 0) milliseconds = 0; - return factory(milliseconds, callback, true); - } -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/type_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/type_patch.dart deleted file mode 100644 index 1b8f3c1cab9..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/type_patch.dart +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) 2012, 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. - -// part of "core_patch.dart"; - -// These Dart classes correspond to the VM internal implementation classes. - -// Equivalent of RawAbstractType. -abstract class _AbstractType implements Type { - String toString() native "AbstractType_toString"; -} - -// Equivalent of RawType. -@pragma("vm:entry-point") -class _Type extends _AbstractType { - factory _Type._uninstantiable() { - throw "Unreachable"; - } - - @pragma("vm:exact-result-type", "dart:core#_Smi") - int get hashCode native "Type_getHashCode"; - - @pragma("vm:exact-result-type", bool) - bool operator ==(other) native "Type_equality"; -} - -// Equivalent of RawTypeRef. -@pragma("vm:entry-point") -class _TypeRef extends _AbstractType { - factory _TypeRef._uninstantiable() { - throw "Unreachable"; - } -} - -// Equivalent of RawTypeParameter. -@pragma("vm:entry-point") -class _TypeParameter extends _AbstractType { - factory _TypeParameter._uninstantiable() { - throw "Unreachable"; - } -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/typed_data_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/typed_data_patch.dart deleted file mode 100644 index 6d0cc5a8933..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/typed_data_patch.dart +++ /dev/null @@ -1,4816 +0,0 @@ -// Copyright (c) 2013, 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. - -/// Note: the VM concatenates all patch files into a single patch file. This -/// file is the first patch in "dart:typed_data" which contains all the imports -/// used by patches of that library. We plan to change this when we have a -/// shared front end and simply use parts. - -import "dart:_internal" - show - ClassID, - CodeUnits, - ExpandIterable, - FollowedByIterable, - IterableElementError, - ListMapView, - Lists, - MappedIterable, - MappedIterable, - ReversedListIterable, - SkipWhileIterable, - Sort, - SubListIterable, - TakeWhileIterable, - WhereIterable, - WhereTypeIterable, - patch; - -import "dart:collection" show ListBase; - -import 'dart:math' show Random; - -/// There are no parts in patch library: - -@patch -class ByteData implements TypedData { - @patch - @pragma("vm:entry-point") - factory ByteData(int length) { - final list = new Uint8List(length) as _TypedList; - _rangeCheck(list.lengthInBytes, 0, length); - return new _ByteDataView._(list, 0, length); - } - - // Called directly from C code. - @pragma("vm:entry-point") - factory ByteData._view(_TypedList typedData, int offsetInBytes, int length) { - _rangeCheck(typedData.lengthInBytes, offsetInBytes, length); - return new _ByteDataView._(typedData, offsetInBytes, length); - } -} - -// Based class for _TypedList that provides common methods for implementing -// the collection and list interfaces. -// This class does not extend ListBase since that would add type arguments -// to instances of _TypeListBase. Instead the subclasses use type specific -// mixins (like _IntListMixin, _DoubleListMixin) to implement ListBase. -abstract class _TypedListBase { - int get length; - int get elementSizeInBytes; - int get offsetInBytes; - _ByteBuffer get buffer; - - // Method(s) implementing the Collection interface. - String join([String separator = ""]) { - StringBuffer buffer = new StringBuffer(); - buffer.writeAll(this as Iterable, separator); - return buffer.toString(); - } - - bool get isEmpty { - return this.length == 0; - } - - bool get isNotEmpty => !isEmpty; - - // Method(s) implementing the List interface. - - set length(newLength) { - throw new UnsupportedError("Cannot resize a fixed-length list"); - } - - void clear() { - throw new UnsupportedError("Cannot remove from a fixed-length list"); - } - - bool remove(Object? element) { - throw new UnsupportedError("Cannot remove from a fixed-length list"); - } - - void removeRange(int start, int end) { - throw new UnsupportedError("Cannot remove from a fixed-length list"); - } - - void replaceRange(int start, int end, Iterable iterable) { - throw new UnsupportedError("Cannot remove from a fixed-length list"); - } - - // Method(s) implementing Object interface. - String toString() => ListBase.listToString(this as List); - - // Internal utility methods. - - // Returns true if operation succeeds. - // 'fromCid' and 'toCid' may be cid-s of the views and therefore may not - // match the cids of 'this' and 'from'. - // Uses toCid and fromCid to decide if clamping is necessary. - // Element size of toCid and fromCid must match (test at caller). - bool _setRange(int startInBytes, int lengthInBytes, _TypedListBase from, - int startFromInBytes, int toCid, int fromCid) native "TypedData_setRange"; -} - -mixin _IntListMixin implements List { - int get elementSizeInBytes; - int get offsetInBytes; - _ByteBuffer get buffer; - - Iterable whereType() => new WhereTypeIterable(this); - - Iterable followedBy(Iterable other) => - new FollowedByIterable.firstEfficient(this, other); - - List cast() => List.castFrom(this); - void set first(int value) { - if (this.length == 0) throw new RangeError.index(0, this); - this[0] = value; - } - - void set last(int value) { - if (this.length == 0) throw new RangeError.index(0, this); - this[this.length - 1] = value; - } - - int indexWhere(bool test(int element), [int start = 0]) { - if (start < 0) start = 0; - for (int i = start; i < length; i++) { - if (test(this[i])) return i; - } - return -1; - } - - int lastIndexWhere(bool test(int element), [int? start]) { - int startIndex = - (start == null || start >= this.length) ? this.length - 1 : start; - for (int i = startIndex; i >= 0; i--) { - if (test(this[i])) return i; - } - return -1; - } - - List operator +(List other) { - int totalLength = this.length + other.length; - return [] - ..length = totalLength - ..setRange(0, this.length, this) - ..setRange(this.length, totalLength, other); - } - - bool contains(Object? element) { - var len = this.length; - for (var i = 0; i < len; ++i) { - if (this[i] == element) return true; - } - return false; - } - - void shuffle([Random? random]) { - random ??= new Random(); - var i = this.length; - while (i > 1) { - int pos = random.nextInt(i); - i -= 1; - var tmp = this[i]; - this[i] = this[pos]; - this[pos] = tmp; - } - } - - Iterable where(bool f(int element)) => new WhereIterable(this, f); - - Iterable take(int n) => new SubListIterable(this, 0, n); - - Iterable takeWhile(bool test(int element)) => - new TakeWhileIterable(this, test); - - Iterable skip(int n) => new SubListIterable(this, n, null); - - Iterable skipWhile(bool test(int element)) => - new SkipWhileIterable(this, test); - - Iterable get reversed => new ReversedListIterable(this); - - Map asMap() => new ListMapView(this); - - Iterable getRange(int start, [int? end]) { - int endIndex = RangeError.checkValidRange(start, end, this.length); - return new SubListIterable(this, start, endIndex); - } - - Iterator get iterator => new _TypedListIterator(this); - - List toList({bool growable: true}) { - return new List.from(this, growable: growable); - } - - Set toSet() { - return new Set.from(this); - } - - void forEach(void f(int element)) { - var len = this.length; - for (var i = 0; i < len; i++) { - f(this[i]); - } - } - - int reduce(int combine(int value, int element)) { - var len = this.length; - if (len == 0) throw IterableElementError.noElement(); - var value = this[0]; - for (var i = 1; i < len; ++i) { - value = combine(value, this[i]); - } - return value; - } - - T fold(T initialValue, T combine(T initialValue, int element)) { - var len = this.length; - for (var i = 0; i < len; ++i) { - initialValue = combine(initialValue, this[i]); - } - return initialValue; - } - - Iterable map(T f(int element)) => new MappedIterable(this, f); - - Iterable expand(Iterable f(int element)) => - new ExpandIterable(this, f); - - bool every(bool f(int element)) { - var len = this.length; - for (var i = 0; i < len; ++i) { - if (!f(this[i])) return false; - } - return true; - } - - bool any(bool f(int element)) { - var len = this.length; - for (var i = 0; i < len; ++i) { - if (f(this[i])) return true; - } - return false; - } - - int firstWhere(bool test(int element), {int orElse()?}) { - var len = this.length; - for (var i = 0; i < len; ++i) { - var element = this[i]; - if (test(element)) return element; - } - if (orElse != null) return orElse(); - throw IterableElementError.noElement(); - } - - int lastWhere(bool test(int element), {int orElse()?}) { - var len = this.length; - for (var i = len - 1; i >= 0; --i) { - var element = this[i]; - if (test(element)) { - return element; - } - } - if (orElse != null) return orElse(); - throw IterableElementError.noElement(); - } - - int singleWhere(bool test(int element), {int orElse()?}) { - var result = null; - bool foundMatching = false; - var len = this.length; - for (var i = 0; i < len; ++i) { - var element = this[i]; - if (test(element)) { - if (foundMatching) { - throw IterableElementError.tooMany(); - } - result = element; - foundMatching = true; - } - } - if (foundMatching) return result; - if (orElse != null) return orElse(); - throw IterableElementError.noElement(); - } - - int elementAt(int index) { - return this[index]; - } - - void add(int value) { - throw new UnsupportedError("Cannot add to a fixed-length list"); - } - - void addAll(Iterable value) { - throw new UnsupportedError("Cannot add to a fixed-length list"); - } - - void insert(int index, int value) { - throw new UnsupportedError("Cannot insert into a fixed-length list"); - } - - void insertAll(int index, Iterable values) { - throw new UnsupportedError("Cannot insert into a fixed-length list"); - } - - void sort([int compare(int a, int b)?]) { - Sort.sort(this, compare ?? Comparable.compare); - } - - int indexOf(int element, [int start = 0]) { - if (start >= this.length) { - return -1; - } else if (start < 0) { - start = 0; - } - for (int i = start; i < this.length; i++) { - if (this[i] == element) return i; - } - return -1; - } - - int lastIndexOf(int element, [int? start]) { - int startIndex = - (start == null || start >= this.length) ? this.length - 1 : start; - for (int i = startIndex; i >= 0; i--) { - if (this[i] == element) return i; - } - return -1; - } - - int removeLast() { - throw new UnsupportedError("Cannot remove from a fixed-length list"); - } - - int removeAt(int index) { - throw new UnsupportedError("Cannot remove from a fixed-length list"); - } - - void removeWhere(bool test(int element)) { - throw new UnsupportedError("Cannot remove from a fixed-length list"); - } - - void retainWhere(bool test(int element)) { - throw new UnsupportedError("Cannot remove from a fixed-length list"); - } - - int get first { - if (length > 0) return this[0]; - throw IterableElementError.noElement(); - } - - int get last { - if (length > 0) return this[length - 1]; - throw IterableElementError.noElement(); - } - - int get single { - if (length == 1) return this[0]; - if (length == 0) throw IterableElementError.noElement(); - throw IterableElementError.tooMany(); - } - - void setAll(int index, Iterable iterable) { - final end = iterable.length + index; - setRange(index, end, iterable); - } - - void fillRange(int start, int end, [int? fillValue]) { - RangeError.checkValidRange(start, end, this.length); - if (start == end) return; - if (fillValue == null) { - throw ArgumentError.notNull("fillValue"); - } - for (var i = start; i < end; ++i) { - this[i] = fillValue; - } - } -} - -mixin _TypedIntListMixin> on _IntListMixin - implements List { - SpawnedType _createList(int length); - - void setRange(int start, int end, Iterable from, [int skipCount = 0]) { - // Check ranges. - if (0 > start || start > end || end > length) { - RangeError.checkValidRange(start, end, length); // Always throws. - assert(false); - } - if (skipCount < 0) { - throw RangeError.range(skipCount, 0, null, "skipCount"); - } - - final count = end - start; - if ((from.length - skipCount) < count) { - throw IterableElementError.tooFew(); - } - - if (count == 0) return; - - if (from is _TypedListBase) { - // Note: _TypedListBase is not related to Iterable so there is - // no promotion here. - final fromAsTypedList = from as _TypedListBase; - if (this.elementSizeInBytes == fromAsTypedList.elementSizeInBytes) { - if ((count < 10) && (fromAsTypedList.buffer != this.buffer)) { - Lists.copy(from as List, skipCount, this, start, count); - return; - } else if (this.buffer._data._setRange( - start * elementSizeInBytes + this.offsetInBytes, - count * elementSizeInBytes, - fromAsTypedList.buffer._data, - skipCount * elementSizeInBytes + fromAsTypedList.offsetInBytes, - ClassID.getID(this), - ClassID.getID(from))) { - return; - } - } else if (fromAsTypedList.buffer == this.buffer) { - // Different element sizes, but same buffer means that we need - // an intermediate structure. - // TODO(srdjan): Optimize to skip copying if the range does not overlap. - final fromAsList = from as List; - final tempBuffer = _createList(count); - for (var i = 0; i < count; i++) { - tempBuffer[i] = fromAsList[skipCount + i]; - } - for (var i = start; i < end; i++) { - this[i] = tempBuffer[i - start]; - } - return; - } - } - - List otherList; - int otherStart; - if (from is List) { - otherList = from; - otherStart = skipCount; - } else { - otherList = from.skip(skipCount).toList(growable: false); - otherStart = 0; - } - if (otherStart + count > otherList.length) { - throw IterableElementError.tooFew(); - } - Lists.copy(otherList, otherStart, this, start, count); - } - - SpawnedType sublist(int start, [int? end]) { - int endIndex = RangeError.checkValidRange(start, end, this.length); - var length = endIndex - start; - SpawnedType result = _createList(length); - result.setRange(0, length, this, start); - return result; - } -} - -mixin _DoubleListMixin implements List { - int get elementSizeInBytes; - int get offsetInBytes; - _ByteBuffer get buffer; - - Iterable whereType() => new WhereTypeIterable(this); - - Iterable followedBy(Iterable other) => - new FollowedByIterable.firstEfficient(this, other); - - List cast() => List.castFrom(this); - void set first(double value) { - if (this.length == 0) throw new RangeError.index(0, this); - this[0] = value; - } - - void set last(double value) { - if (this.length == 0) throw new RangeError.index(0, this); - this[this.length - 1] = value; - } - - int indexWhere(bool test(double element), [int start = 0]) { - if (start < 0) start = 0; - for (int i = start; i < length; i++) { - if (test(this[i])) return i; - } - return -1; - } - - int lastIndexWhere(bool test(double element), [int? start]) { - int startIndex = - (start == null || start >= this.length) ? this.length - 1 : start; - for (int i = startIndex; i >= 0; i--) { - if (test(this[i])) return i; - } - return -1; - } - - List operator +(List other) { - int totalLength = this.length + other.length; - return [] - ..length = totalLength - ..setRange(0, this.length, this) - ..setRange(this.length, totalLength, other); - } - - bool contains(Object? element) { - var len = this.length; - for (var i = 0; i < len; ++i) { - if (this[i] == element) return true; - } - return false; - } - - void shuffle([Random? random]) { - random ??= new Random(); - var i = this.length; - while (i > 1) { - int pos = random.nextInt(i); - i -= 1; - var tmp = this[i]; - this[i] = this[pos]; - this[pos] = tmp; - } - } - - Iterable where(bool f(double element)) => - new WhereIterable(this, f); - - Iterable take(int n) => new SubListIterable(this, 0, n); - - Iterable takeWhile(bool test(double element)) => - new TakeWhileIterable(this, test); - - Iterable skip(int n) => new SubListIterable(this, n, null); - - Iterable skipWhile(bool test(double element)) => - new SkipWhileIterable(this, test); - - Iterable get reversed => new ReversedListIterable(this); - - Map asMap() => new ListMapView(this); - - Iterable getRange(int start, [int? end]) { - int endIndex = RangeError.checkValidRange(start, end, this.length); - return new SubListIterable(this, start, endIndex); - } - - Iterator get iterator => new _TypedListIterator(this); - - List toList({bool growable: true}) { - return new List.from(this, growable: growable); - } - - Set toSet() { - return new Set.from(this); - } - - void forEach(void f(double element)) { - var len = this.length; - for (var i = 0; i < len; i++) { - f(this[i]); - } - } - - double reduce(double combine(double value, double element)) { - var len = this.length; - if (len == 0) throw IterableElementError.noElement(); - var value = this[0]; - for (var i = 1; i < len; ++i) { - value = combine(value, this[i]); - } - return value; - } - - T fold(T initialValue, T combine(T initialValue, double element)) { - var len = this.length; - for (var i = 0; i < len; ++i) { - initialValue = combine(initialValue, this[i]); - } - return initialValue; - } - - Iterable map(T f(double element)) => - new MappedIterable(this, f); - - Iterable expand(Iterable f(double element)) => - new ExpandIterable(this, f); - - bool every(bool f(double element)) { - var len = this.length; - for (var i = 0; i < len; ++i) { - if (!f(this[i])) return false; - } - return true; - } - - bool any(bool f(double element)) { - var len = this.length; - for (var i = 0; i < len; ++i) { - if (f(this[i])) return true; - } - return false; - } - - double firstWhere(bool test(double element), {double orElse()?}) { - var len = this.length; - for (var i = 0; i < len; ++i) { - var element = this[i]; - if (test(element)) return element; - } - if (orElse != null) return orElse(); - throw IterableElementError.noElement(); - } - - double lastWhere(bool test(double element), {double orElse()?}) { - var len = this.length; - for (var i = len - 1; i >= 0; --i) { - var element = this[i]; - if (test(element)) { - return element; - } - } - if (orElse != null) return orElse(); - throw IterableElementError.noElement(); - } - - double singleWhere(bool test(double element), {double orElse()?}) { - var result = null; - bool foundMatching = false; - var len = this.length; - for (var i = 0; i < len; ++i) { - var element = this[i]; - if (test(element)) { - if (foundMatching) { - throw IterableElementError.tooMany(); - } - result = element; - foundMatching = true; - } - } - if (foundMatching) return result; - if (orElse != null) return orElse(); - throw IterableElementError.noElement(); - } - - double elementAt(int index) { - return this[index]; - } - - void add(double value) { - throw new UnsupportedError("Cannot add to a fixed-length list"); - } - - void addAll(Iterable value) { - throw new UnsupportedError("Cannot add to a fixed-length list"); - } - - void insert(int index, double value) { - throw new UnsupportedError("Cannot insert into a fixed-length list"); - } - - void insertAll(int index, Iterable values) { - throw new UnsupportedError("Cannot insert into a fixed-length list"); - } - - void sort([int compare(double a, double b)?]) { - Sort.sort(this, compare ?? Comparable.compare); - } - - int indexOf(double element, [int start = 0]) { - if (start >= this.length) { - return -1; - } else if (start < 0) { - start = 0; - } - for (int i = start; i < this.length; i++) { - if (this[i] == element) return i; - } - return -1; - } - - int lastIndexOf(double element, [int? start]) { - int startIndex = - (start == null || start >= this.length) ? this.length - 1 : start; - for (int i = startIndex; i >= 0; i--) { - if (this[i] == element) return i; - } - return -1; - } - - double removeLast() { - throw new UnsupportedError("Cannot remove from a fixed-length list"); - } - - double removeAt(int index) { - throw new UnsupportedError("Cannot remove from a fixed-length list"); - } - - void removeWhere(bool test(double element)) { - throw new UnsupportedError("Cannot remove from a fixed-length list"); - } - - void retainWhere(bool test(double element)) { - throw new UnsupportedError("Cannot remove from a fixed-length list"); - } - - double get first { - if (length > 0) return this[0]; - throw IterableElementError.noElement(); - } - - double get last { - if (length > 0) return this[length - 1]; - throw IterableElementError.noElement(); - } - - double get single { - if (length == 1) return this[0]; - if (length == 0) throw IterableElementError.noElement(); - throw IterableElementError.tooMany(); - } - - void setAll(int index, Iterable iterable) { - final end = iterable.length + index; - setRange(index, end, iterable); - } - - void fillRange(int start, int end, [double? fillValue]) { - // TODO(eernst): Could use zero as default and not throw; issue . - RangeError.checkValidRange(start, end, this.length); - if (start == end) return; - if (fillValue == null) { - throw ArgumentError.notNull("fillValue"); - } - for (var i = start; i < end; ++i) { - this[i] = fillValue; - } - } -} - -mixin _TypedDoubleListMixin> - on _DoubleListMixin implements List { - SpawnedType _createList(int length); - - void setRange(int start, int end, Iterable from, - [int skipCount = 0]) { - // Check ranges. - if (0 > start || start > end || end > length) { - RangeError.checkValidRange(start, end, length); // Always throws. - assert(false); - } - if (skipCount < 0) { - throw RangeError.range(skipCount, 0, null, "skipCount"); - } - - final count = end - start; - if ((from.length - skipCount) < count) { - throw IterableElementError.tooFew(); - } - - if (count == 0) return; - - if (from is _TypedListBase) { - // Note: _TypedListBase is not related to Iterable so there is - // no promotion here. - final fromAsTypedList = from as _TypedListBase; - if (this.elementSizeInBytes == fromAsTypedList.elementSizeInBytes) { - if ((count < 10) && (fromAsTypedList.buffer != this.buffer)) { - Lists.copy(from as List, skipCount, this, start, count); - return; - } else if (this.buffer._data._setRange( - start * elementSizeInBytes + this.offsetInBytes, - count * elementSizeInBytes, - fromAsTypedList.buffer._data, - skipCount * elementSizeInBytes + fromAsTypedList.offsetInBytes, - ClassID.getID(this), - ClassID.getID(from))) { - return; - } - } else if (fromAsTypedList.buffer == this.buffer) { - // Different element sizes, but same buffer means that we need - // an intermediate structure. - // TODO(srdjan): Optimize to skip copying if the range does not overlap. - final fromAsList = from as List; - final tempBuffer = _createList(count); - for (var i = 0; i < count; i++) { - tempBuffer[i] = fromAsList[skipCount + i]; - } - for (var i = start; i < end; i++) { - this[i] = tempBuffer[i - start]; - } - return; - } - } - - List otherList; - int otherStart; - if (from is List) { - otherList = from; - otherStart = skipCount; - } else { - otherList = from.skip(skipCount).toList(growable: false); - otherStart = 0; - } - if (otherStart + count > otherList.length) { - throw IterableElementError.tooFew(); - } - Lists.copy(otherList, otherStart, this, start, count); - } - - SpawnedType sublist(int start, [int? end]) { - int endIndex = RangeError.checkValidRange(start, end, this.length); - var length = endIndex - start; - SpawnedType result = _createList(length); - result.setRange(0, length, this, start); - return result; - } -} - -abstract class _Float32x4ListMixin implements List { - int get elementSizeInBytes; - int get offsetInBytes; - _ByteBuffer get buffer; - - Float32x4List _createList(int length); - - Iterable whereType() => new WhereTypeIterable(this); - - Iterable followedBy(Iterable other) => - new FollowedByIterable.firstEfficient(this, other); - - List cast() => List.castFrom(this); - void set first(Float32x4 value) { - if (this.length == 0) throw new RangeError.index(0, this); - this[0] = value; - } - - void set last(Float32x4 value) { - if (this.length == 0) throw new RangeError.index(0, this); - this[this.length - 1] = value; - } - - int indexWhere(bool test(Float32x4 element), [int start = 0]) { - if (start < 0) start = 0; - for (int i = start; i < length; i++) { - if (test(this[i])) return i; - } - return -1; - } - - int lastIndexWhere(bool test(Float32x4 element), [int? start]) { - int startIndex = - (start == null || start >= this.length) ? this.length - 1 : start; - for (int i = startIndex; i >= 0; i--) { - if (test(this[i])) return i; - } - return -1; - } - - List operator +(List other) { - int totalLength = this.length + other.length; - return [] - ..length = totalLength - ..setRange(0, this.length, this) - ..setRange(this.length, totalLength, other); - } - - bool contains(Object? element) { - var len = this.length; - for (var i = 0; i < len; ++i) { - if (this[i] == element) return true; - } - return false; - } - - void shuffle([Random? random]) { - random ??= new Random(); - var i = this.length; - while (i > 1) { - int pos = random.nextInt(i); - i -= 1; - var tmp = this[i]; - this[i] = this[pos]; - this[pos] = tmp; - } - } - - void setRange(int start, int end, Iterable from, - [int skipCount = 0]) { - // Check ranges. - if (0 > start || start > end || end > length) { - RangeError.checkValidRange(start, end, length); // Always throws. - assert(false); - } - if (skipCount < 0) { - throw RangeError.range(skipCount, 0, null, "skipCount"); - } - - final count = end - start; - if ((from.length - skipCount) < count) { - throw IterableElementError.tooFew(); - } - - if (count == 0) return; - - if (from is _TypedListBase) { - // Note: _TypedListBase is not related to Iterable so there is - // no promotion here. - final fromAsTypedList = from as _TypedListBase; - if (this.elementSizeInBytes == fromAsTypedList.elementSizeInBytes) { - if ((count < 10) && (fromAsTypedList.buffer != this.buffer)) { - Lists.copy(from as List, skipCount, this, start, count); - return; - } else if (this.buffer._data._setRange( - start * elementSizeInBytes + this.offsetInBytes, - count * elementSizeInBytes, - fromAsTypedList.buffer._data, - skipCount * elementSizeInBytes + fromAsTypedList.offsetInBytes, - ClassID.getID(this), - ClassID.getID(from))) { - return; - } - } else if (fromAsTypedList.buffer == this.buffer) { - // Different element sizes, but same buffer means that we need - // an intermediate structure. - // TODO(srdjan): Optimize to skip copying if the range does not overlap. - final fromAsList = from as List; - final tempBuffer = _createList(count); - for (var i = 0; i < count; i++) { - tempBuffer[i] = fromAsList[skipCount + i]; - } - for (var i = start; i < end; i++) { - this[i] = tempBuffer[i - start]; - } - return; - } - } - - List otherList; - int otherStart; - if (from is List) { - otherList = from; - otherStart = skipCount; - } else { - otherList = from.skip(skipCount).toList(growable: false); - otherStart = 0; - } - if (otherStart + count > otherList.length) { - throw IterableElementError.tooFew(); - } - Lists.copy(otherList, otherStart, this, start, count); - } - - Iterable where(bool f(Float32x4 element)) => - new WhereIterable(this, f); - - Iterable take(int n) => new SubListIterable(this, 0, n); - - Iterable takeWhile(bool test(Float32x4 element)) => - new TakeWhileIterable(this, test); - - Iterable skip(int n) => - new SubListIterable(this, n, null); - - Iterable skipWhile(bool test(Float32x4 element)) => - new SkipWhileIterable(this, test); - - Iterable get reversed => new ReversedListIterable(this); - - Map asMap() => new ListMapView(this); - - Iterable getRange(int start, [int? end]) { - int endIndex = RangeError.checkValidRange(start, end, this.length); - return new SubListIterable(this, start, endIndex); - } - - Iterator get iterator => new _TypedListIterator(this); - - List toList({bool growable: true}) { - return new List.from(this, growable: growable); - } - - Set toSet() { - return new Set.from(this); - } - - void forEach(void f(Float32x4 element)) { - var len = this.length; - for (var i = 0; i < len; i++) { - f(this[i]); - } - } - - Float32x4 reduce(Float32x4 combine(Float32x4 value, Float32x4 element)) { - var len = this.length; - if (len == 0) throw IterableElementError.noElement(); - var value = this[0]; - for (var i = 1; i < len; ++i) { - value = combine(value, this[i]); - } - return value; - } - - T fold(T initialValue, T combine(T initialValue, Float32x4 element)) { - var len = this.length; - for (var i = 0; i < len; ++i) { - initialValue = combine(initialValue, this[i]); - } - return initialValue; - } - - Iterable map(T f(Float32x4 element)) => - new MappedIterable(this, f); - - Iterable expand(Iterable f(Float32x4 element)) => - new ExpandIterable(this, f); - - bool every(bool f(Float32x4 element)) { - var len = this.length; - for (var i = 0; i < len; ++i) { - if (!f(this[i])) return false; - } - return true; - } - - bool any(bool f(Float32x4 element)) { - var len = this.length; - for (var i = 0; i < len; ++i) { - if (f(this[i])) return true; - } - return false; - } - - Float32x4 firstWhere(bool test(Float32x4 element), {Float32x4 orElse()?}) { - var len = this.length; - for (var i = 0; i < len; ++i) { - var element = this[i]; - if (test(element)) return element; - } - if (orElse != null) return orElse(); - throw IterableElementError.noElement(); - } - - Float32x4 lastWhere(bool test(Float32x4 element), {Float32x4 orElse()?}) { - var len = this.length; - for (var i = len - 1; i >= 0; --i) { - var element = this[i]; - if (test(element)) { - return element; - } - } - if (orElse != null) return orElse(); - throw IterableElementError.noElement(); - } - - Float32x4 singleWhere(bool test(Float32x4 element), {Float32x4 orElse()?}) { - var result = null; - bool foundMatching = false; - var len = this.length; - for (var i = 0; i < len; ++i) { - var element = this[i]; - if (test(element)) { - if (foundMatching) { - throw IterableElementError.tooMany(); - } - result = element; - foundMatching = true; - } - } - if (foundMatching) return result; - if (orElse != null) return orElse(); - throw IterableElementError.noElement(); - } - - Float32x4 elementAt(int index) { - return this[index]; - } - - void add(Float32x4 value) { - throw new UnsupportedError("Cannot add to a fixed-length list"); - } - - void addAll(Iterable value) { - throw new UnsupportedError("Cannot add to a fixed-length list"); - } - - void insert(int index, Float32x4 value) { - throw new UnsupportedError("Cannot insert into a fixed-length list"); - } - - void insertAll(int index, Iterable values) { - throw new UnsupportedError("Cannot insert into a fixed-length list"); - } - - void sort([int compare(Float32x4 a, Float32x4 b)?]) { - if (compare == null) { - throw "SIMD don't have default compare."; - } - Sort.sort(this, compare); - } - - int indexOf(Float32x4 element, [int start = 0]) { - if (start >= this.length) { - return -1; - } else if (start < 0) { - start = 0; - } - for (int i = start; i < this.length; i++) { - if (this[i] == element) return i; - } - return -1; - } - - int lastIndexOf(Float32x4 element, [int? start]) { - int startIndex = - (start == null || start >= this.length) ? this.length - 1 : start; - for (int i = startIndex; i >= 0; i--) { - if (this[i] == element) return i; - } - return -1; - } - - Float32x4 removeLast() { - throw new UnsupportedError("Cannot remove from a fixed-length list"); - } - - Float32x4 removeAt(int index) { - throw new UnsupportedError("Cannot remove from a fixed-length list"); - } - - void removeWhere(bool test(Float32x4 element)) { - throw new UnsupportedError("Cannot remove from a fixed-length list"); - } - - void retainWhere(bool test(Float32x4 element)) { - throw new UnsupportedError("Cannot remove from a fixed-length list"); - } - - Float32x4 get first { - if (length > 0) return this[0]; - throw IterableElementError.noElement(); - } - - Float32x4 get last { - if (length > 0) return this[length - 1]; - throw IterableElementError.noElement(); - } - - Float32x4 get single { - if (length == 1) return this[0]; - if (length == 0) throw IterableElementError.noElement(); - throw IterableElementError.tooMany(); - } - - Float32x4List sublist(int start, [int? end]) { - int endIndex = RangeError.checkValidRange(start, end, this.length); - var length = endIndex - start; - Float32x4List result = _createList(length); - result.setRange(0, length, this, start); - return result; - } - - void setAll(int index, Iterable iterable) { - final end = iterable.length + index; - setRange(index, end, iterable); - } - - void fillRange(int start, int end, [Float32x4? fillValue]) { - RangeError.checkValidRange(start, end, this.length); - if (start == end) return; - if (fillValue == null) { - throw ArgumentError.notNull("fillValue"); - } - for (var i = start; i < end; ++i) { - this[i] = fillValue; - } - } -} - -abstract class _Int32x4ListMixin implements List { - int get elementSizeInBytes; - int get offsetInBytes; - _ByteBuffer get buffer; - - Int32x4List _createList(int length); - - Iterable whereType() => new WhereTypeIterable(this); - - Iterable followedBy(Iterable other) => - new FollowedByIterable.firstEfficient(this, other); - - List cast() => List.castFrom(this); - void set first(Int32x4 value) { - if (this.length == 0) throw new RangeError.index(0, this); - this[0] = value; - } - - void set last(Int32x4 value) { - if (this.length == 0) throw new RangeError.index(0, this); - this[this.length - 1] = value; - } - - int indexWhere(bool test(Int32x4 element), [int start = 0]) { - if (start < 0) start = 0; - for (int i = start; i < length; i++) { - if (test(this[i])) return i; - } - return -1; - } - - int lastIndexWhere(bool test(Int32x4 element), [int? start]) { - int startIndex = - (start == null || start >= this.length) ? this.length - 1 : start; - for (int i = startIndex; i >= 0; i--) { - if (test(this[i])) return i; - } - return -1; - } - - List operator +(List other) { - int totalLength = this.length + other.length; - return [] - ..length = totalLength - ..setRange(0, this.length, this) - ..setRange(this.length, totalLength, other); - } - - bool contains(Object? element) { - var len = this.length; - for (var i = 0; i < len; ++i) { - if (this[i] == element) return true; - } - return false; - } - - void shuffle([Random? random]) { - random ??= new Random(); - var i = this.length; - while (i > 1) { - int pos = random.nextInt(i); - i -= 1; - var tmp = this[i]; - this[i] = this[pos]; - this[pos] = tmp; - } - } - - void setRange(int start, int end, Iterable from, - [int skipCount = 0]) { - // Check ranges. - if (0 > start || start > end || end > length) { - RangeError.checkValidRange(start, end, length); // Always throws. - assert(false); - } - if (skipCount < 0) { - throw RangeError.range(skipCount, 0, null, "skipCount"); - } - - final count = end - start; - if ((from.length - skipCount) < count) { - throw IterableElementError.tooFew(); - } - - if (count == 0) return; - - if (from is _TypedListBase) { - // Note: _TypedListBase is not related to Iterable so there is - // no promotion here. - final fromAsTypedList = from as _TypedListBase; - if (this.elementSizeInBytes == fromAsTypedList.elementSizeInBytes) { - if ((count < 10) && (fromAsTypedList.buffer != this.buffer)) { - Lists.copy(from as List, skipCount, this, start, count); - return; - } else if (this.buffer._data._setRange( - start * elementSizeInBytes + this.offsetInBytes, - count * elementSizeInBytes, - fromAsTypedList.buffer._data, - skipCount * elementSizeInBytes + fromAsTypedList.offsetInBytes, - ClassID.getID(this), - ClassID.getID(from))) { - return; - } - } else if (fromAsTypedList.buffer == this.buffer) { - // Different element sizes, but same buffer means that we need - // an intermediate structure. - // TODO(srdjan): Optimize to skip copying if the range does not overlap. - final fromAsList = from as List; - final tempBuffer = _createList(count); - for (var i = 0; i < count; i++) { - tempBuffer[i] = fromAsList[skipCount + i]; - } - for (var i = start; i < end; i++) { - this[i] = tempBuffer[i - start]; - } - return; - } - } - - List otherList; - int otherStart; - if (from is List) { - otherList = from; - otherStart = skipCount; - } else { - otherList = from.skip(skipCount).toList(growable: false); - otherStart = 0; - } - if (otherStart + count > otherList.length) { - throw IterableElementError.tooFew(); - } - Lists.copy(otherList, otherStart, this, start, count); - } - - Iterable where(bool f(Int32x4 element)) => - new WhereIterable(this, f); - - Iterable take(int n) => new SubListIterable(this, 0, n); - - Iterable takeWhile(bool test(Int32x4 element)) => - new TakeWhileIterable(this, test); - - Iterable skip(int n) => new SubListIterable(this, n, null); - - Iterable skipWhile(bool test(Int32x4 element)) => - new SkipWhileIterable(this, test); - - Iterable get reversed => new ReversedListIterable(this); - - Map asMap() => new ListMapView(this); - - Iterable getRange(int start, [int? end]) { - int endIndex = RangeError.checkValidRange(start, end, this.length); - return new SubListIterable(this, start, endIndex); - } - - Iterator get iterator => new _TypedListIterator(this); - - List toList({bool growable: true}) { - return new List.from(this, growable: growable); - } - - Set toSet() { - return new Set.from(this); - } - - void forEach(void f(Int32x4 element)) { - var len = this.length; - for (var i = 0; i < len; i++) { - f(this[i]); - } - } - - Int32x4 reduce(Int32x4 combine(Int32x4 value, Int32x4 element)) { - var len = this.length; - if (len == 0) throw IterableElementError.noElement(); - var value = this[0]; - for (var i = 1; i < len; ++i) { - value = combine(value, this[i]); - } - return value; - } - - T fold(T initialValue, T combine(T initialValue, Int32x4 element)) { - var len = this.length; - for (var i = 0; i < len; ++i) { - initialValue = combine(initialValue, this[i]); - } - return initialValue; - } - - Iterable map(T f(Int32x4 element)) => - new MappedIterable(this, f); - - Iterable expand(Iterable f(Int32x4 element)) => - new ExpandIterable(this, f); - - bool every(bool f(Int32x4 element)) { - var len = this.length; - for (var i = 0; i < len; ++i) { - if (!f(this[i])) return false; - } - return true; - } - - bool any(bool f(Int32x4 element)) { - var len = this.length; - for (var i = 0; i < len; ++i) { - if (f(this[i])) return true; - } - return false; - } - - Int32x4 firstWhere(bool test(Int32x4 element), {Int32x4 orElse()?}) { - var len = this.length; - for (var i = 0; i < len; ++i) { - var element = this[i]; - if (test(element)) return element; - } - if (orElse != null) return orElse(); - throw IterableElementError.noElement(); - } - - Int32x4 lastWhere(bool test(Int32x4 element), {Int32x4 orElse()?}) { - var len = this.length; - for (var i = len - 1; i >= 0; --i) { - var element = this[i]; - if (test(element)) { - return element; - } - } - if (orElse != null) return orElse(); - throw IterableElementError.noElement(); - } - - Int32x4 singleWhere(bool test(Int32x4 element), {Int32x4 orElse()?}) { - var result = null; - bool foundMatching = false; - var len = this.length; - for (var i = 0; i < len; ++i) { - var element = this[i]; - if (test(element)) { - if (foundMatching) { - throw IterableElementError.tooMany(); - } - result = element; - foundMatching = true; - } - } - if (foundMatching) return result; - if (orElse != null) return orElse(); - throw IterableElementError.noElement(); - } - - Int32x4 elementAt(int index) { - return this[index]; - } - - void add(Int32x4 value) { - throw new UnsupportedError("Cannot add to a fixed-length list"); - } - - void addAll(Iterable value) { - throw new UnsupportedError("Cannot add to a fixed-length list"); - } - - void insert(int index, Int32x4 value) { - throw new UnsupportedError("Cannot insert into a fixed-length list"); - } - - void insertAll(int index, Iterable values) { - throw new UnsupportedError("Cannot insert into a fixed-length list"); - } - - void sort([int compare(Int32x4 a, Int32x4 b)?]) { - if (compare == null) { - throw "SIMD don't have default compare."; - } - Sort.sort(this, compare); - } - - int indexOf(Int32x4 element, [int start = 0]) { - if (start >= this.length) { - return -1; - } else if (start < 0) { - start = 0; - } - for (int i = start; i < this.length; i++) { - if (this[i] == element) return i; - } - return -1; - } - - int lastIndexOf(Int32x4 element, [int? start]) { - int startIndex = - (start == null || start >= this.length) ? this.length - 1 : start; - for (int i = startIndex; i >= 0; i--) { - if (this[i] == element) return i; - } - return -1; - } - - Int32x4 removeLast() { - throw new UnsupportedError("Cannot remove from a fixed-length list"); - } - - Int32x4 removeAt(int index) { - throw new UnsupportedError("Cannot remove from a fixed-length list"); - } - - void removeWhere(bool test(Int32x4 element)) { - throw new UnsupportedError("Cannot remove from a fixed-length list"); - } - - void retainWhere(bool test(Int32x4 element)) { - throw new UnsupportedError("Cannot remove from a fixed-length list"); - } - - Int32x4 get first { - if (length > 0) return this[0]; - throw IterableElementError.noElement(); - } - - Int32x4 get last { - if (length > 0) return this[length - 1]; - throw IterableElementError.noElement(); - } - - Int32x4 get single { - if (length == 1) return this[0]; - if (length == 0) throw IterableElementError.noElement(); - throw IterableElementError.tooMany(); - } - - Int32x4List sublist(int start, [int? end]) { - int endIndex = RangeError.checkValidRange(start, end, this.length); - var length = endIndex - start; - Int32x4List result = _createList(length); - result.setRange(0, length, this, start); - return result; - } - - void setAll(int index, Iterable iterable) { - final end = iterable.length + index; - setRange(index, end, iterable); - } - - void fillRange(int start, int end, [Int32x4? fillValue]) { - RangeError.checkValidRange(start, end, this.length); - if (start == end) return; - if (fillValue == null) { - throw ArgumentError.notNull("fillValue"); - } - for (var i = start; i < end; ++i) { - this[i] = fillValue; - } - } -} - -abstract class _Float64x2ListMixin implements List { - int get elementSizeInBytes; - int get offsetInBytes; - _ByteBuffer get buffer; - - Float64x2List _createList(int length); - - Iterable whereType() => new WhereTypeIterable(this); - - Iterable followedBy(Iterable other) => - new FollowedByIterable.firstEfficient(this, other); - - List cast() => List.castFrom(this); - void set first(Float64x2 value) { - if (this.length == 0) throw new RangeError.index(0, this); - this[0] = value; - } - - void set last(Float64x2 value) { - if (this.length == 0) throw new RangeError.index(0, this); - this[this.length - 1] = value; - } - - int indexWhere(bool test(Float64x2 element), [int start = 0]) { - if (start < 0) start = 0; - for (int i = start; i < length; i++) { - if (test(this[i])) return i; - } - return -1; - } - - int lastIndexWhere(bool test(Float64x2 element), [int? start]) { - int startIndex = - (start == null || start >= this.length) ? this.length - 1 : start; - for (int i = startIndex; i >= 0; i--) { - if (test(this[i])) return i; - } - return -1; - } - - List operator +(List other) { - int totalLength = this.length + other.length; - return [] - ..length = totalLength - ..setRange(0, this.length, this) - ..setRange(this.length, totalLength, other); - } - - bool contains(Object? element) { - var len = this.length; - for (var i = 0; i < len; ++i) { - if (this[i] == element) return true; - } - return false; - } - - void shuffle([Random? random]) { - random ??= new Random(); - var i = this.length; - while (i > 1) { - int pos = random.nextInt(i); - i -= 1; - var tmp = this[i]; - this[i] = this[pos]; - this[pos] = tmp; - } - } - - void setRange(int start, int end, Iterable from, - [int skipCount = 0]) { - // Check ranges. - if (0 > start || start > end || end > length) { - RangeError.checkValidRange(start, end, length); // Always throws. - assert(false); - } - if (skipCount < 0) { - throw RangeError.range(skipCount, 0, null, "skipCount"); - } - - final count = end - start; - if ((from.length - skipCount) < count) { - throw IterableElementError.tooFew(); - } - - if (count == 0) return; - - if (from is _TypedListBase) { - // Note: _TypedListBase is not related to Iterable so there is - // no promotion here. - final fromAsTypedList = from as _TypedListBase; - if (this.elementSizeInBytes == fromAsTypedList.elementSizeInBytes) { - if ((count < 10) && (fromAsTypedList.buffer != this.buffer)) { - Lists.copy(from as List, skipCount, this, start, count); - return; - } else if (this.buffer._data._setRange( - start * elementSizeInBytes + this.offsetInBytes, - count * elementSizeInBytes, - fromAsTypedList.buffer._data, - skipCount * elementSizeInBytes + fromAsTypedList.offsetInBytes, - ClassID.getID(this), - ClassID.getID(from))) { - return; - } - } else if (fromAsTypedList.buffer == this.buffer) { - // Different element sizes, but same buffer means that we need - // an intermediate structure. - // TODO(srdjan): Optimize to skip copying if the range does not overlap. - final fromAsList = from as List; - final tempBuffer = _createList(count); - for (var i = 0; i < count; i++) { - tempBuffer[i] = fromAsList[skipCount + i]; - } - for (var i = start; i < end; i++) { - this[i] = tempBuffer[i - start]; - } - return; - } - } - - List otherList; - int otherStart; - if (from is List) { - otherList = from; - otherStart = skipCount; - } else { - otherList = from.skip(skipCount).toList(growable: false); - otherStart = 0; - } - if (otherStart + count > otherList.length) { - throw IterableElementError.tooFew(); - } - Lists.copy(otherList, otherStart, this, start, count); - } - - Iterable where(bool f(Float64x2 element)) => - new WhereIterable(this, f); - - Iterable take(int n) => new SubListIterable(this, 0, n); - - Iterable takeWhile(bool test(Float64x2 element)) => - new TakeWhileIterable(this, test); - - Iterable skip(int n) => - new SubListIterable(this, n, null); - - Iterable skipWhile(bool test(Float64x2 element)) => - new SkipWhileIterable(this, test); - - Iterable get reversed => new ReversedListIterable(this); - - Map asMap() => new ListMapView(this); - - Iterable getRange(int start, [int? end]) { - int endIndex = RangeError.checkValidRange(start, end, this.length); - return new SubListIterable(this, start, endIndex); - } - - Iterator get iterator => new _TypedListIterator(this); - - List toList({bool growable: true}) { - return new List.from(this, growable: growable); - } - - Set toSet() { - return new Set.from(this); - } - - void forEach(void f(Float64x2 element)) { - var len = this.length; - for (var i = 0; i < len; i++) { - f(this[i]); - } - } - - Float64x2 reduce(Float64x2 combine(Float64x2 value, Float64x2 element)) { - var len = this.length; - if (len == 0) throw IterableElementError.noElement(); - var value = this[0]; - for (var i = 1; i < len; ++i) { - value = combine(value, this[i]); - } - return value; - } - - T fold(T initialValue, T combine(T initialValue, Float64x2 element)) { - var len = this.length; - for (var i = 0; i < len; ++i) { - initialValue = combine(initialValue, this[i]); - } - return initialValue; - } - - Iterable map(T f(Float64x2 element)) => - new MappedIterable(this, f); - - Iterable expand(Iterable f(Float64x2 element)) => - new ExpandIterable(this, f); - - bool every(bool f(Float64x2 element)) { - var len = this.length; - for (var i = 0; i < len; ++i) { - if (!f(this[i])) return false; - } - return true; - } - - bool any(bool f(Float64x2 element)) { - var len = this.length; - for (var i = 0; i < len; ++i) { - if (f(this[i])) return true; - } - return false; - } - - Float64x2 firstWhere(bool test(Float64x2 element), {Float64x2 orElse()?}) { - var len = this.length; - for (var i = 0; i < len; ++i) { - var element = this[i]; - if (test(element)) return element; - } - if (orElse != null) return orElse(); - throw IterableElementError.noElement(); - } - - Float64x2 lastWhere(bool test(Float64x2 element), {Float64x2 orElse()?}) { - var len = this.length; - for (var i = len - 1; i >= 0; --i) { - var element = this[i]; - if (test(element)) { - return element; - } - } - if (orElse != null) return orElse(); - throw IterableElementError.noElement(); - } - - Float64x2 singleWhere(bool test(Float64x2 element), {Float64x2 orElse()?}) { - var result = null; - bool foundMatching = false; - var len = this.length; - for (var i = 0; i < len; ++i) { - var element = this[i]; - if (test(element)) { - if (foundMatching) { - throw IterableElementError.tooMany(); - } - result = element; - foundMatching = true; - } - } - if (foundMatching) return result; - if (orElse != null) return orElse(); - throw IterableElementError.noElement(); - } - - Float64x2 elementAt(int index) { - return this[index]; - } - - void add(Float64x2 value) { - throw new UnsupportedError("Cannot add to a fixed-length list"); - } - - void addAll(Iterable value) { - throw new UnsupportedError("Cannot add to a fixed-length list"); - } - - void insert(int index, Float64x2 value) { - throw new UnsupportedError("Cannot insert into a fixed-length list"); - } - - void insertAll(int index, Iterable values) { - throw new UnsupportedError("Cannot insert into a fixed-length list"); - } - - void sort([int compare(Float64x2 a, Float64x2 b)?]) { - if (compare == null) { - throw "SIMD don't have default compare."; - } - Sort.sort(this, compare); - } - - int indexOf(Float64x2 element, [int start = 0]) { - if (start >= this.length) { - return -1; - } else if (start < 0) { - start = 0; - } - for (int i = start; i < this.length; i++) { - if (this[i] == element) return i; - } - return -1; - } - - int lastIndexOf(Float64x2 element, [int? start]) { - int startIndex = - (start == null || start >= this.length) ? this.length - 1 : start; - for (int i = startIndex; i >= 0; i--) { - if (this[i] == element) return i; - } - return -1; - } - - Float64x2 removeLast() { - throw new UnsupportedError("Cannot remove from a fixed-length list"); - } - - Float64x2 removeAt(int index) { - throw new UnsupportedError("Cannot remove from a fixed-length list"); - } - - void removeWhere(bool test(Float64x2 element)) { - throw new UnsupportedError("Cannot remove from a fixed-length list"); - } - - void retainWhere(bool test(Float64x2 element)) { - throw new UnsupportedError("Cannot remove from a fixed-length list"); - } - - Float64x2 get first { - if (length > 0) return this[0]; - throw IterableElementError.noElement(); - } - - Float64x2 get last { - if (length > 0) return this[length - 1]; - throw IterableElementError.noElement(); - } - - Float64x2 get single { - if (length == 1) return this[0]; - if (length == 0) throw IterableElementError.noElement(); - throw IterableElementError.tooMany(); - } - - Float64x2List sublist(int start, [int? end]) { - int endIndex = RangeError.checkValidRange(start, end, this.length); - var length = endIndex - start; - Float64x2List result = _createList(length); - result.setRange(0, length, this, start); - return result; - } - - void setAll(int index, Iterable iterable) { - final end = iterable.length + index; - setRange(index, end, iterable); - } - - void fillRange(int start, int end, [Float64x2? fillValue]) { - RangeError.checkValidRange(start, end, this.length); - if (start == end) return; - if (fillValue == null) { - throw ArgumentError.notNull("fillValue"); - } - for (var i = start; i < end; ++i) { - this[i] = fillValue; - } - } -} - -@pragma("vm:entry-point") -class _ByteBuffer implements ByteBuffer { - final _TypedList _data; - - _ByteBuffer(this._data); - - @pragma("vm:entry-point") - factory _ByteBuffer._New(data) => new _ByteBuffer(data); - - // Forward calls to _data. - int get lengthInBytes => _data.lengthInBytes; - int get hashCode => _data.hashCode; - bool operator ==(Object other) => - (other is _ByteBuffer) && identical(_data, other._data); - - ByteData asByteData([int offsetInBytes = 0, int? length]) { - length ??= this.lengthInBytes - offsetInBytes; - _rangeCheck(this._data.lengthInBytes, offsetInBytes, length); - return new _ByteDataView._(this._data, offsetInBytes, length); - } - - Int8List asInt8List([int offsetInBytes = 0, int? length]) { - length ??= (this.lengthInBytes - offsetInBytes) ~/ Int8List.bytesPerElement; - _rangeCheck( - this.lengthInBytes, offsetInBytes, length * Int8List.bytesPerElement); - return new _Int8ArrayView._(this._data, offsetInBytes, length); - } - - Uint8List asUint8List([int offsetInBytes = 0, int? length]) { - length ??= - (this.lengthInBytes - offsetInBytes) ~/ Uint8List.bytesPerElement; - _rangeCheck( - this.lengthInBytes, offsetInBytes, length * Uint8List.bytesPerElement); - return new _Uint8ArrayView._(this._data, offsetInBytes, length); - } - - Uint8ClampedList asUint8ClampedList([int offsetInBytes = 0, int? length]) { - length ??= (this.lengthInBytes - offsetInBytes) ~/ - Uint8ClampedList.bytesPerElement; - _rangeCheck(this.lengthInBytes, offsetInBytes, - length * Uint8ClampedList.bytesPerElement); - return new _Uint8ClampedArrayView._(this._data, offsetInBytes, length); - } - - Int16List asInt16List([int offsetInBytes = 0, int? length]) { - length ??= - (this.lengthInBytes - offsetInBytes) ~/ Int16List.bytesPerElement; - _rangeCheck( - this.lengthInBytes, offsetInBytes, length * Int16List.bytesPerElement); - _offsetAlignmentCheck(offsetInBytes, Int16List.bytesPerElement); - return new _Int16ArrayView._(this._data, offsetInBytes, length); - } - - Uint16List asUint16List([int offsetInBytes = 0, int? length]) { - length ??= - (this.lengthInBytes - offsetInBytes) ~/ Uint16List.bytesPerElement; - _rangeCheck( - this.lengthInBytes, offsetInBytes, length * Uint16List.bytesPerElement); - _offsetAlignmentCheck(offsetInBytes, Uint16List.bytesPerElement); - return new _Uint16ArrayView._(this._data, offsetInBytes, length); - } - - Int32List asInt32List([int offsetInBytes = 0, int? length]) { - length ??= - (this.lengthInBytes - offsetInBytes) ~/ Int32List.bytesPerElement; - _rangeCheck( - this.lengthInBytes, offsetInBytes, length * Int32List.bytesPerElement); - _offsetAlignmentCheck(offsetInBytes, Int32List.bytesPerElement); - return new _Int32ArrayView._(this._data, offsetInBytes, length); - } - - Uint32List asUint32List([int offsetInBytes = 0, int? length]) { - length ??= - (this.lengthInBytes - offsetInBytes) ~/ Uint32List.bytesPerElement; - _rangeCheck( - this.lengthInBytes, offsetInBytes, length * Uint32List.bytesPerElement); - _offsetAlignmentCheck(offsetInBytes, Uint32List.bytesPerElement); - return new _Uint32ArrayView._(this._data, offsetInBytes, length); - } - - Int64List asInt64List([int offsetInBytes = 0, int? length]) { - length ??= - (this.lengthInBytes - offsetInBytes) ~/ Int64List.bytesPerElement; - _rangeCheck( - this.lengthInBytes, offsetInBytes, length * Int64List.bytesPerElement); - _offsetAlignmentCheck(offsetInBytes, Int64List.bytesPerElement); - return new _Int64ArrayView._(this._data, offsetInBytes, length); - } - - Uint64List asUint64List([int offsetInBytes = 0, int? length]) { - length ??= - (this.lengthInBytes - offsetInBytes) ~/ Uint64List.bytesPerElement; - _rangeCheck( - this.lengthInBytes, offsetInBytes, length * Uint64List.bytesPerElement); - _offsetAlignmentCheck(offsetInBytes, Uint64List.bytesPerElement); - return new _Uint64ArrayView._(this._data, offsetInBytes, length); - } - - Float32List asFloat32List([int offsetInBytes = 0, int? length]) { - length ??= - (this.lengthInBytes - offsetInBytes) ~/ Float32List.bytesPerElement; - _rangeCheck(this.lengthInBytes, offsetInBytes, - length * Float32List.bytesPerElement); - _offsetAlignmentCheck(offsetInBytes, Float32List.bytesPerElement); - return new _Float32ArrayView._(this._data, offsetInBytes, length); - } - - Float64List asFloat64List([int offsetInBytes = 0, int? length]) { - length ??= - (this.lengthInBytes - offsetInBytes) ~/ Float64List.bytesPerElement; - _rangeCheck(this.lengthInBytes, offsetInBytes, - length * Float64List.bytesPerElement); - _offsetAlignmentCheck(offsetInBytes, Float64List.bytesPerElement); - return new _Float64ArrayView._(this._data, offsetInBytes, length); - } - - Float32x4List asFloat32x4List([int offsetInBytes = 0, int? length]) { - length ??= - (this.lengthInBytes - offsetInBytes) ~/ Float32x4List.bytesPerElement; - _rangeCheck(this.lengthInBytes, offsetInBytes, - length * Float32x4List.bytesPerElement); - _offsetAlignmentCheck(offsetInBytes, Float32x4List.bytesPerElement); - return new _Float32x4ArrayView._(this._data, offsetInBytes, length); - } - - Int32x4List asInt32x4List([int offsetInBytes = 0, int? length]) { - length ??= - (this.lengthInBytes - offsetInBytes) ~/ Int32x4List.bytesPerElement; - _rangeCheck(this.lengthInBytes, offsetInBytes, - length * Int32x4List.bytesPerElement); - _offsetAlignmentCheck(offsetInBytes, Int32x4List.bytesPerElement); - return new _Int32x4ArrayView._(this._data, offsetInBytes, length); - } - - Float64x2List asFloat64x2List([int offsetInBytes = 0, int? length]) { - length ??= - (this.lengthInBytes - offsetInBytes) ~/ Float64x2List.bytesPerElement; - _rangeCheck(this.lengthInBytes, offsetInBytes, - length * Float64x2List.bytesPerElement); - _offsetAlignmentCheck(offsetInBytes, Float64x2List.bytesPerElement); - return new _Float64x2ArrayView._(this._data, offsetInBytes, length); - } -} - -abstract class _TypedList extends _TypedListBase { - int get elementSizeInBytes; - - // Default method implementing parts of the TypedData interface. - int get offsetInBytes { - return 0; - } - - int get lengthInBytes { - return length * elementSizeInBytes; - } - - _ByteBuffer get buffer => new _ByteBuffer(this); - - // Methods implementing the collection interface. - - @pragma("vm:exact-result-type", "dart:core#_Smi") - @pragma("vm:prefer-inline") - int get length native "TypedData_length"; - - // Internal utility methods. - - @pragma("vm:exact-result-type", "dart:core#_Smi") - int _getInt8(int offsetInBytes) native "TypedData_GetInt8"; - void _setInt8(int offsetInBytes, int value) native "TypedData_SetInt8"; - - @pragma("vm:exact-result-type", "dart:core#_Smi") - int _getUint8(int offsetInBytes) native "TypedData_GetUint8"; - void _setUint8(int offsetInBytes, int value) native "TypedData_SetUint8"; - - @pragma("vm:exact-result-type", "dart:core#_Smi") - int _getInt16(int offsetInBytes) native "TypedData_GetInt16"; - void _setInt16(int offsetInBytes, int value) native "TypedData_SetInt16"; - - @pragma("vm:exact-result-type", "dart:core#_Smi") - int _getUint16(int offsetInBytes) native "TypedData_GetUint16"; - void _setUint16(int offsetInBytes, int value) native "TypedData_SetUint16"; - - int _getInt32(int offsetInBytes) native "TypedData_GetInt32"; - void _setInt32(int offsetInBytes, int value) native "TypedData_SetInt32"; - - int _getUint32(int offsetInBytes) native "TypedData_GetUint32"; - void _setUint32(int offsetInBytes, int value) native "TypedData_SetUint32"; - - int _getInt64(int offsetInBytes) native "TypedData_GetInt64"; - void _setInt64(int offsetInBytes, int value) native "TypedData_SetInt64"; - - int _getUint64(int offsetInBytes) native "TypedData_GetUint64"; - void _setUint64(int offsetInBytes, int value) native "TypedData_SetUint64"; - - @pragma("vm:exact-result-type", "dart:core#_Double") - double _getFloat32(int offsetInBytes) native "TypedData_GetFloat32"; - void _setFloat32(int offsetInBytes, double value) - native "TypedData_SetFloat32"; - - @pragma("vm:exact-result-type", "dart:core#_Double") - double _getFloat64(int offsetInBytes) native "TypedData_GetFloat64"; - void _setFloat64(int offsetInBytes, double value) - native "TypedData_SetFloat64"; - - @pragma("vm:exact-result-type", _Float32x4) - Float32x4 _getFloat32x4(int offsetInBytes) native "TypedData_GetFloat32x4"; - void _setFloat32x4(int offsetInBytes, Float32x4 value) - native "TypedData_SetFloat32x4"; - - @pragma("vm:exact-result-type", _Int32x4) - Int32x4 _getInt32x4(int offsetInBytes) native "TypedData_GetInt32x4"; - void _setInt32x4(int offsetInBytes, Int32x4 value) - native "TypedData_SetInt32x4"; - - Float64x2 _getFloat64x2(int offsetInBytes) native "TypedData_GetFloat64x2"; - void _setFloat64x2(int offsetInBytes, Float64x2 value) - native "TypedData_SetFloat64x2"; - - /** - * Stores the [CodeUnits] as UTF-16 units into this TypedData at - * positions [start]..[end] (uint16 indices). - */ - void _setCodeUnits( - CodeUnits units, int byteStart, int length, int skipCount) { - assert(byteStart + length * Uint16List.bytesPerElement <= lengthInBytes); - String string = CodeUnits.stringOf(units); - int sliceEnd = skipCount + length; - RangeError.checkValidRange( - skipCount, sliceEnd, string.length, "skipCount", "skipCount + length"); - for (int i = 0; i < length; i++) { - _setUint16(byteStart + i * Uint16List.bytesPerElement, - string.codeUnitAt(skipCount + i)); - } - } -} - -@patch -class Int8List { - @patch - @pragma("vm:exact-result-type", _Int8List) - factory Int8List(int length) native "TypedData_Int8Array_new"; - - @patch - factory Int8List.fromList(List elements) { - return new Int8List(elements.length) - ..setRange(0, elements.length, elements); - } -} - -@pragma("vm:entry-point") -class _Int8List extends _TypedList - with _IntListMixin, _TypedIntListMixin - implements Int8List { - factory _Int8List._uninstantiable() { - throw "Unreachable"; - } - - // Method(s) implementing List interface. - @pragma("vm:exact-result-type", "dart:core#_Smi") - int operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getInt8(index); - } - - void operator []=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setInt8(index, _toInt8(value)); - } - - // Method(s) implementing TypedData interface. - int get elementSizeInBytes { - return Int8List.bytesPerElement; - } - - // Internal utility methods. - Int8List _createList(int length) { - return new Int8List(length); - } -} - -@patch -class Uint8List { - @patch - @pragma("vm:exact-result-type", _Uint8List) - factory Uint8List(int length) native "TypedData_Uint8Array_new"; - - @patch - factory Uint8List.fromList(List elements) { - return new Uint8List(elements.length) - ..setRange(0, elements.length, elements); - } -} - -@pragma("vm:entry-point") -class _Uint8List extends _TypedList - with _IntListMixin, _TypedIntListMixin - implements Uint8List { - factory _Uint8List._uninstantiable() { - throw "Unreachable"; - } - - // Methods implementing List interface. - @pragma("vm:exact-result-type", "dart:core#_Smi") - int operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getUint8(index); - } - - void operator []=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setUint8(index, _toUint8(value)); - } - - // Methods implementing TypedData interface. - int get elementSizeInBytes { - return Uint8List.bytesPerElement; - } - - // Internal utility methods. - Uint8List _createList(int length) { - return new Uint8List(length); - } -} - -@patch -class Uint8ClampedList { - @patch - @pragma("vm:exact-result-type", _Uint8ClampedList) - factory Uint8ClampedList(int length) native "TypedData_Uint8ClampedArray_new"; - - @patch - factory Uint8ClampedList.fromList(List elements) { - return new Uint8ClampedList(elements.length) - ..setRange(0, elements.length, elements); - } -} - -@pragma("vm:entry-point") -class _Uint8ClampedList extends _TypedList - with _IntListMixin, _TypedIntListMixin - implements Uint8ClampedList { - factory _Uint8ClampedList._uninstantiable() { - throw "Unreachable"; - } - - // Methods implementing List interface. - @pragma("vm:exact-result-type", "dart:core#_Smi") - int operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getUint8(index); - } - - void operator []=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setUint8(index, _toClampedUint8(value)); - } - - // Methods implementing TypedData interface. - int get elementSizeInBytes { - return Uint8List.bytesPerElement; - } - - // Internal utility methods. - Uint8ClampedList _createList(int length) { - return new Uint8ClampedList(length); - } -} - -@patch -class Int16List { - @patch - @pragma("vm:exact-result-type", _Int16List) - factory Int16List(int length) native "TypedData_Int16Array_new"; - - @patch - factory Int16List.fromList(List elements) { - return new Int16List(elements.length) - ..setRange(0, elements.length, elements); - } -} - -@pragma("vm:entry-point") -class _Int16List extends _TypedList - with _IntListMixin, _TypedIntListMixin - implements Int16List { - factory _Int16List._uninstantiable() { - throw "Unreachable"; - } - - // Method(s) implementing List interface. - @pragma("vm:exact-result-type", "dart:core#_Smi") - int operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedInt16(index); - } - - void operator []=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedInt16(index, _toInt16(value)); - } - - void setRange(int start, int end, Iterable iterable, - [int skipCount = 0]) { - if (iterable is CodeUnits) { - end = RangeError.checkValidRange(start, end, this.length); - int length = end - start; - int byteStart = this.offsetInBytes + start * Int16List.bytesPerElement; - _setCodeUnits(iterable, byteStart, length, skipCount); - } else { - super.setRange(start, end, iterable, skipCount); - } - } - - // Method(s) implementing TypedData interface. - int get elementSizeInBytes { - return Int16List.bytesPerElement; - } - - // Internal utility methods. - Int16List _createList(int length) { - return new Int16List(length); - } - - int _getIndexedInt16(int index) { - return _getInt16(index * Int16List.bytesPerElement); - } - - void _setIndexedInt16(int index, int value) { - _setInt16(index * Int16List.bytesPerElement, value); - } -} - -@patch -class Uint16List { - @patch - @pragma("vm:exact-result-type", _Uint16List) - factory Uint16List(int length) native "TypedData_Uint16Array_new"; - - @patch - factory Uint16List.fromList(List elements) { - return new Uint16List(elements.length) - ..setRange(0, elements.length, elements); - } -} - -@pragma("vm:entry-point") -class _Uint16List extends _TypedList - with _IntListMixin, _TypedIntListMixin - implements Uint16List { - factory _Uint16List._uninstantiable() { - throw "Unreachable"; - } - - // Method(s) implementing the List interface. - @pragma("vm:exact-result-type", "dart:core#_Smi") - int operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedUint16(index); - } - - void operator []=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedUint16(index, _toUint16(value)); - } - - void setRange(int start, int end, Iterable iterable, - [int skipCount = 0]) { - if (iterable is CodeUnits) { - end = RangeError.checkValidRange(start, end, this.length); - int length = end - start; - int byteStart = this.offsetInBytes + start * Uint16List.bytesPerElement; - _setCodeUnits(iterable, byteStart, length, skipCount); - } else { - super.setRange(start, end, iterable, skipCount); - } - } - - // Method(s) implementing the TypedData interface. - int get elementSizeInBytes { - return Uint16List.bytesPerElement; - } - - // Internal utility methods. - Uint16List _createList(int length) { - return new Uint16List(length); - } - - int _getIndexedUint16(int index) { - return _getUint16(index * Uint16List.bytesPerElement); - } - - void _setIndexedUint16(int index, int value) { - _setUint16(index * Uint16List.bytesPerElement, value); - } -} - -@patch -class Int32List { - @patch - @pragma("vm:exact-result-type", _Int32List) - factory Int32List(int length) native "TypedData_Int32Array_new"; - - @patch - factory Int32List.fromList(List elements) { - return new Int32List(elements.length) - ..setRange(0, elements.length, elements); - } -} - -@pragma("vm:entry-point") -class _Int32List extends _TypedList - with _IntListMixin, _TypedIntListMixin - implements Int32List { - factory _Int32List._uninstantiable() { - throw "Unreachable"; - } - - // Method(s) implementing the List interface. - int operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedInt32(index); - } - - void operator []=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedInt32(index, _toInt32(value)); - } - - // Method(s) implementing TypedData interface. - int get elementSizeInBytes { - return Int32List.bytesPerElement; - } - - // Internal utility methods. - Int32List _createList(int length) { - return new Int32List(length); - } - - int _getIndexedInt32(int index) { - return _getInt32(index * Int32List.bytesPerElement); - } - - void _setIndexedInt32(int index, int value) { - _setInt32(index * Int32List.bytesPerElement, value); - } -} - -@patch -class Uint32List { - @patch - @pragma("vm:exact-result-type", _Uint32List) - factory Uint32List(int length) native "TypedData_Uint32Array_new"; - - @patch - factory Uint32List.fromList(List elements) { - return new Uint32List(elements.length) - ..setRange(0, elements.length, elements); - } -} - -@pragma("vm:entry-point") -class _Uint32List extends _TypedList - with _IntListMixin, _TypedIntListMixin - implements Uint32List { - factory _Uint32List._uninstantiable() { - throw "Unreachable"; - } - - // Method(s) implementing the List interface. - int operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedUint32(index); - } - - void operator []=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedUint32(index, _toUint32(value)); - } - - // Method(s) implementing the TypedData interface. - int get elementSizeInBytes { - return Uint32List.bytesPerElement; - } - - // Internal utility methods. - Uint32List _createList(int length) { - return new Uint32List(length); - } - - int _getIndexedUint32(int index) { - return _getUint32(index * Uint32List.bytesPerElement); - } - - void _setIndexedUint32(int index, int value) { - _setUint32(index * Uint32List.bytesPerElement, value); - } -} - -@patch -class Int64List { - @patch - @pragma("vm:exact-result-type", _Int64List) - factory Int64List(int length) native "TypedData_Int64Array_new"; - - @patch - factory Int64List.fromList(List elements) { - return new Int64List(elements.length) - ..setRange(0, elements.length, elements); - } -} - -@pragma("vm:entry-point") -class _Int64List extends _TypedList - with _IntListMixin, _TypedIntListMixin - implements Int64List { - factory _Int64List._uninstantiable() { - throw "Unreachable"; - } - - // Method(s) implementing the List interface. - int operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedInt64(index); - } - - void operator []=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedInt64(index, value); - } - - // Method(s) implementing the TypedData interface. - int get elementSizeInBytes { - return Int64List.bytesPerElement; - } - - // Internal utility methods. - Int64List _createList(int length) { - return new Int64List(length); - } - - int _getIndexedInt64(int index) { - return _getInt64(index * Int64List.bytesPerElement); - } - - void _setIndexedInt64(int index, int value) { - _setInt64(index * Int64List.bytesPerElement, value); - } -} - -@patch -class Uint64List { - @patch - @pragma("vm:exact-result-type", _Uint64List) - factory Uint64List(int length) native "TypedData_Uint64Array_new"; - - @patch - factory Uint64List.fromList(List elements) { - return new Uint64List(elements.length) - ..setRange(0, elements.length, elements); - } -} - -@pragma("vm:entry-point") -class _Uint64List extends _TypedList - with _IntListMixin, _TypedIntListMixin - implements Uint64List { - factory _Uint64List._uninstantiable() { - throw "Unreachable"; - } - - // Method(s) implementing the List interface. - int operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedUint64(index); - } - - void operator []=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedUint64(index, value); - } - - // Method(s) implementing the TypedData interface. - int get elementSizeInBytes { - return Uint64List.bytesPerElement; - } - - // Internal utility methods. - Uint64List _createList(int length) { - return new Uint64List(length); - } - - int _getIndexedUint64(int index) { - return _getUint64(index * Uint64List.bytesPerElement); - } - - void _setIndexedUint64(int index, int value) { - _setUint64(index * Uint64List.bytesPerElement, value); - } -} - -@patch -class Float32List { - @patch - @pragma("vm:exact-result-type", _Float32List) - factory Float32List(int length) native "TypedData_Float32Array_new"; - - @patch - factory Float32List.fromList(List elements) { - return new Float32List(elements.length) - ..setRange(0, elements.length, elements); - } -} - -@pragma("vm:entry-point") -class _Float32List extends _TypedList - with _DoubleListMixin, _TypedDoubleListMixin - implements Float32List { - factory _Float32List._uninstantiable() { - throw "Unreachable"; - } - - // Method(s) implementing the List interface. - @pragma("vm:exact-result-type", "dart:core#_Double") - double operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedFloat32(index); - } - - void operator []=(int index, double value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedFloat32(index, value); - } - - // Method(s) implementing the TypedData interface. - int get elementSizeInBytes { - return Float32List.bytesPerElement; - } - - // Internal utility methods. - Float32List _createList(int length) { - return new Float32List(length); - } - - double _getIndexedFloat32(int index) { - return _getFloat32(index * Float32List.bytesPerElement); - } - - void _setIndexedFloat32(int index, double value) { - _setFloat32(index * Float32List.bytesPerElement, value); - } -} - -@patch -class Float64List { - @patch - @pragma("vm:exact-result-type", _Float64List) - factory Float64List(int length) native "TypedData_Float64Array_new"; - - @patch - factory Float64List.fromList(List elements) { - return new Float64List(elements.length) - ..setRange(0, elements.length, elements); - } -} - -@pragma("vm:entry-point") -class _Float64List extends _TypedList - with _DoubleListMixin, _TypedDoubleListMixin - implements Float64List { - factory _Float64List._uninstantiable() { - throw "Unreachable"; - } - - // Method(s) implementing the List interface. - @pragma("vm:exact-result-type", "dart:core#_Double") - double operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedFloat64(index); - } - - void operator []=(int index, double value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedFloat64(index, value); - } - - // Method(s) implementing the TypedData interface. - int get elementSizeInBytes { - return Float64List.bytesPerElement; - } - - // Internal utility methods. - Float64List _createList(int length) { - return new Float64List(length); - } - - double _getIndexedFloat64(int index) { - return _getFloat64(index * Float64List.bytesPerElement); - } - - void _setIndexedFloat64(int index, double value) { - _setFloat64(index * Float64List.bytesPerElement, value); - } -} - -@patch -class Float32x4List { - @patch - @pragma("vm:exact-result-type", _Float32x4List) - factory Float32x4List(int length) native "TypedData_Float32x4Array_new"; - - @patch - factory Float32x4List.fromList(List elements) { - return new Float32x4List(elements.length) - ..setRange(0, elements.length, elements); - } -} - -@pragma("vm:entry-point") -class _Float32x4List extends _TypedList - with _Float32x4ListMixin - implements Float32x4List { - factory _Float32x4List._uninstantiable() { - throw "Unreachable"; - } - - @pragma("vm:exact-result-type", _Float32x4) - Float32x4 operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedFloat32x4(index); - } - - void operator []=(int index, Float32x4 value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedFloat32x4(index, value); - } - - // Method(s) implementing the TypedData interface. - int get elementSizeInBytes { - return Float32x4List.bytesPerElement; - } - - // Internal utility methods. - Float32x4List _createList(int length) { - return new Float32x4List(length); - } - - Float32x4 _getIndexedFloat32x4(int index) { - return _getFloat32x4(index * Float32x4List.bytesPerElement); - } - - void _setIndexedFloat32x4(int index, Float32x4 value) { - _setFloat32x4(index * Float32x4List.bytesPerElement, value); - } -} - -@patch -class Int32x4List { - @patch - @pragma("vm:exact-result-type", _Int32x4List) - factory Int32x4List(int length) native "TypedData_Int32x4Array_new"; - - @patch - factory Int32x4List.fromList(List elements) { - return new Int32x4List(elements.length) - ..setRange(0, elements.length, elements); - } -} - -@pragma("vm:entry-point") -class _Int32x4List extends _TypedList - with _Int32x4ListMixin - implements Int32x4List { - factory _Int32x4List._uninstantiable() { - throw "Unreachable"; - } - - @pragma("vm:exact-result-type", _Int32x4) - Int32x4 operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedInt32x4(index); - } - - void operator []=(int index, Int32x4 value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedInt32x4(index, value); - } - - // Method(s) implementing the TypedData interface. - int get elementSizeInBytes { - return Int32x4List.bytesPerElement; - } - - // Internal utility methods. - Int32x4List _createList(int length) { - return new Int32x4List(length); - } - - Int32x4 _getIndexedInt32x4(int index) { - return _getInt32x4(index * Int32x4List.bytesPerElement); - } - - void _setIndexedInt32x4(int index, Int32x4 value) { - _setInt32x4(index * Int32x4List.bytesPerElement, value); - } -} - -@patch -class Float64x2List { - @patch - @pragma("vm:exact-result-type", _Float64x2List) - factory Float64x2List(int length) native "TypedData_Float64x2Array_new"; - - @patch - factory Float64x2List.fromList(List elements) { - return new Float64x2List(elements.length) - ..setRange(0, elements.length, elements); - } -} - -@pragma("vm:entry-point") -class _Float64x2List extends _TypedList - with _Float64x2ListMixin - implements Float64x2List { - factory _Float64x2List._uninstantiable() { - throw "Unreachable"; - } - - @pragma("vm:exact-result-type", _Float64x2) - Float64x2 operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedFloat64x2(index); - } - - void operator []=(int index, Float64x2 value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedFloat64x2(index, value); - } - - // Method(s) implementing the TypedData interface. - int get elementSizeInBytes { - return Float64x2List.bytesPerElement; - } - - // Internal utility methods. - Float64x2List _createList(int length) { - return new Float64x2List(length); - } - - Float64x2 _getIndexedFloat64x2(int index) { - return _getFloat64x2(index * Float64x2List.bytesPerElement); - } - - void _setIndexedFloat64x2(int index, Float64x2 value) { - _setFloat64x2(index * Float64x2List.bytesPerElement, value); - } -} - -@pragma("vm:entry-point") -class _ExternalInt8Array extends _TypedList - with _IntListMixin, _TypedIntListMixin - implements Int8List { - factory _ExternalInt8Array._uninstantiable() { - throw "Unreachable"; - } - - // Method(s) implementing the List interface. - int operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getInt8(index); - } - - void operator []=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setInt8(index, value); - } - - // Method(s) implementing the TypedData interface. - int get elementSizeInBytes { - return Int8List.bytesPerElement; - } - - // Internal utility methods. - Int8List _createList(int length) { - return new Int8List(length); - } -} - -@pragma("vm:entry-point") -class _ExternalUint8Array extends _TypedList - with _IntListMixin, _TypedIntListMixin - implements Uint8List { - factory _ExternalUint8Array._uninstantiable() { - throw "Unreachable"; - } - - // Method(s) implementing the List interface. - @pragma("vm:exact-result-type", "dart:core#_Smi") - int operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getUint8(index); - } - - void operator []=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setUint8(index, _toUint8(value)); - } - - // Method(s) implementing the TypedData interface. - int get elementSizeInBytes { - return Uint8List.bytesPerElement; - } - - // Internal utility methods. - Uint8List _createList(int length) { - return new Uint8List(length); - } -} - -@pragma("vm:entry-point") -class _ExternalUint8ClampedArray extends _TypedList - with _IntListMixin, _TypedIntListMixin - implements Uint8ClampedList { - factory _ExternalUint8ClampedArray._uninstantiable() { - throw "Unreachable"; - } - - // Method(s) implementing the List interface. - @pragma("vm:exact-result-type", "dart:core#_Smi") - int operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getUint8(index); - } - - void operator []=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setUint8(index, _toClampedUint8(value)); - } - - // Method(s) implementing the TypedData interface. - int get elementSizeInBytes { - return Uint8List.bytesPerElement; - } - - // Internal utility methods. - Uint8ClampedList _createList(int length) { - return new Uint8ClampedList(length); - } -} - -@pragma("vm:entry-point") -class _ExternalInt16Array extends _TypedList - with _IntListMixin, _TypedIntListMixin - implements Int16List { - factory _ExternalInt16Array._uninstantiable() { - throw "Unreachable"; - } - - // Method(s) implementing the List interface. - int operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedInt16(index); - } - - void operator []=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedInt16(index, _toInt16(value)); - } - - // Method(s) implementing the TypedData interface. - int get elementSizeInBytes { - return Int16List.bytesPerElement; - } - - // Internal utility methods. - Int16List _createList(int length) { - return new Int16List(length); - } - - int _getIndexedInt16(int index) { - return _getInt16(index * Int16List.bytesPerElement); - } - - void _setIndexedInt16(int index, int value) { - _setInt16(index * Int16List.bytesPerElement, value); - } -} - -@pragma("vm:entry-point") -class _ExternalUint16Array extends _TypedList - with _IntListMixin, _TypedIntListMixin - implements Uint16List { - factory _ExternalUint16Array._uninstantiable() { - throw "Unreachable"; - } - - // Method(s) implementing the List interface. - int operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedUint16(index); - } - - void operator []=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedUint16(index, _toUint16(value)); - } - - // Method(s) implementing the TypedData interface. - int get elementSizeInBytes { - return Uint16List.bytesPerElement; - } - - // Internal utility methods. - Uint16List _createList(int length) { - return new Uint16List(length); - } - - int _getIndexedUint16(int index) { - return _getUint16(index * Uint16List.bytesPerElement); - } - - void _setIndexedUint16(int index, int value) { - _setUint16(index * Uint16List.bytesPerElement, value); - } -} - -@pragma("vm:entry-point") -class _ExternalInt32Array extends _TypedList - with _IntListMixin, _TypedIntListMixin - implements Int32List { - factory _ExternalInt32Array._uninstantiable() { - throw "Unreachable"; - } - - // Method(s) implementing the List interface. - int operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedInt32(index); - } - - void operator []=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedInt32(index, _toInt32(value)); - } - - // Method(s) implementing the TypedData interface. - int get elementSizeInBytes { - return Int32List.bytesPerElement; - } - - // Internal utility methods. - Int32List _createList(int length) { - return new Int32List(length); - } - - int _getIndexedInt32(int index) { - return _getInt32(index * Int32List.bytesPerElement); - } - - void _setIndexedInt32(int index, int value) { - _setInt32(index * Int32List.bytesPerElement, value); - } -} - -@pragma("vm:entry-point") -class _ExternalUint32Array extends _TypedList - with _IntListMixin, _TypedIntListMixin - implements Uint32List { - factory _ExternalUint32Array._uninstantiable() { - throw "Unreachable"; - } - - // Method(s) implementing the List interface. - int operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedUint32(index); - } - - void operator []=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedUint32(index, _toUint32(value)); - } - - // Method(s) implementing the TypedData interface. - int get elementSizeInBytes { - return Uint32List.bytesPerElement; - } - - // Internal utility methods. - Uint32List _createList(int length) { - return new Uint32List(length); - } - - int _getIndexedUint32(int index) { - return _getUint32(index * Uint32List.bytesPerElement); - } - - void _setIndexedUint32(int index, int value) { - _setUint32(index * Uint32List.bytesPerElement, value); - } -} - -@pragma("vm:entry-point") -class _ExternalInt64Array extends _TypedList - with _IntListMixin, _TypedIntListMixin - implements Int64List { - factory _ExternalInt64Array._uninstantiable() { - throw "Unreachable"; - } - - // Method(s) implementing the List interface. - int operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedInt64(index); - } - - void operator []=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedInt64(index, value); - } - - // Method(s) implementing the TypedData interface. - int get elementSizeInBytes { - return Int64List.bytesPerElement; - } - - // Internal utility methods. - Int64List _createList(int length) { - return new Int64List(length); - } - - int _getIndexedInt64(int index) { - return _getInt64(index * Int64List.bytesPerElement); - } - - void _setIndexedInt64(int index, int value) { - _setInt64(index * Int64List.bytesPerElement, value); - } -} - -@pragma("vm:entry-point") -class _ExternalUint64Array extends _TypedList - with _IntListMixin, _TypedIntListMixin - implements Uint64List { - factory _ExternalUint64Array._uninstantiable() { - throw "Unreachable"; - } - - // Method(s) implementing the List interface. - int operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedUint64(index); - } - - void operator []=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedUint64(index, value); - } - - // Method(s) implementing the TypedData interface. - int get elementSizeInBytes { - return Uint64List.bytesPerElement; - } - - // Internal utility methods. - Uint64List _createList(int length) { - return new Uint64List(length); - } - - int _getIndexedUint64(int index) { - return _getUint64(index * Uint64List.bytesPerElement); - } - - void _setIndexedUint64(int index, int value) { - _setUint64(index * Uint64List.bytesPerElement, value); - } -} - -@pragma("vm:entry-point") -class _ExternalFloat32Array extends _TypedList - with _DoubleListMixin, _TypedDoubleListMixin - implements Float32List { - factory _ExternalFloat32Array._uninstantiable() { - throw "Unreachable"; - } - - // Method(s) implementing the List interface. - double operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedFloat32(index); - } - - void operator []=(int index, double value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedFloat32(index, value); - } - - // Method(s) implementing the TypedData interface. - int get elementSizeInBytes { - return Float32List.bytesPerElement; - } - - // Internal utility methods. - Float32List _createList(int length) { - return new Float32List(length); - } - - double _getIndexedFloat32(int index) { - return _getFloat32(index * Float32List.bytesPerElement); - } - - void _setIndexedFloat32(int index, double value) { - _setFloat32(index * Float32List.bytesPerElement, value); - } -} - -@pragma("vm:entry-point") -class _ExternalFloat64Array extends _TypedList - with _DoubleListMixin, _TypedDoubleListMixin - implements Float64List { - factory _ExternalFloat64Array._uninstantiable() { - throw "Unreachable"; - } - - // Method(s) implementing the List interface. - double operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedFloat64(index); - } - - void operator []=(int index, double value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedFloat64(index, value); - } - - // Method(s) implementing the TypedData interface. - int get elementSizeInBytes { - return Float64List.bytesPerElement; - } - - // Internal utility methods. - Float64List _createList(int length) { - return new Float64List(length); - } - - double _getIndexedFloat64(int index) { - return _getFloat64(index * Float64List.bytesPerElement); - } - - void _setIndexedFloat64(int index, double value) { - _setFloat64(index * Float64List.bytesPerElement, value); - } -} - -@pragma("vm:entry-point") -class _ExternalFloat32x4Array extends _TypedList - with _Float32x4ListMixin - implements Float32x4List { - factory _ExternalFloat32x4Array._uninstantiable() { - throw "Unreachable"; - } - - // Method(s) implementing the List interface. - Float32x4 operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedFloat32x4(index); - } - - void operator []=(int index, Float32x4 value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedFloat32x4(index, value); - } - - // Method(s) implementing the TypedData interface. - int get elementSizeInBytes { - return Float32x4List.bytesPerElement; - } - - // Internal utility methods. - Float32x4List _createList(int length) { - return new Float32x4List(length); - } - - Float32x4 _getIndexedFloat32x4(int index) { - return _getFloat32x4(index * Float32x4List.bytesPerElement); - } - - void _setIndexedFloat32x4(int index, Float32x4 value) { - _setFloat32x4(index * Float32x4List.bytesPerElement, value); - } -} - -@pragma("vm:entry-point") -class _ExternalInt32x4Array extends _TypedList - with _Int32x4ListMixin - implements Int32x4List { - factory _ExternalInt32x4Array._uninstantiable() { - throw "Unreachable"; - } - - // Method(s) implementing the List interface. - Int32x4 operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedInt32x4(index); - } - - void operator []=(int index, Int32x4 value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedInt32x4(index, value); - } - - // Method(s) implementing the TypedData interface. - int get elementSizeInBytes { - return Int32x4List.bytesPerElement; - } - - // Internal utility methods. - Int32x4List _createList(int length) { - return new Int32x4List(length); - } - - Int32x4 _getIndexedInt32x4(int index) { - return _getInt32x4(index * Int32x4List.bytesPerElement); - } - - void _setIndexedInt32x4(int index, Int32x4 value) { - _setInt32x4(index * Int32x4List.bytesPerElement, value); - } -} - -@pragma("vm:entry-point") -class _ExternalFloat64x2Array extends _TypedList - with _Float64x2ListMixin - implements Float64x2List { - factory _ExternalFloat64x2Array._uninstantiable() { - throw "Unreachable"; - } - - // Method(s) implementing the List interface. - Float64x2 operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _getIndexedFloat64x2(index); - } - - void operator []=(int index, Float64x2 value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _setIndexedFloat64x2(index, value); - } - - // Method(s) implementing the TypedData interface. - int get elementSizeInBytes { - return Float64x2List.bytesPerElement; - } - - // Internal utility methods. - Float64x2List _createList(int length) { - return new Float64x2List(length); - } - - Float64x2 _getIndexedFloat64x2(int index) { - return _getFloat64x2(index * Float64x2List.bytesPerElement); - } - - void _setIndexedFloat64x2(int index, Float64x2 value) { - _setFloat64x2(index * Float64x2List.bytesPerElement, value); - } -} - -@patch -class Float32x4 { - @patch - @pragma("vm:prefer-inline") - factory Float32x4(double x, double y, double z, double w) { - _throwIfNull(x, 'x'); - _throwIfNull(y, 'y'); - _throwIfNull(z, 'z'); - _throwIfNull(w, 'w'); - return _Float32x4FromDoubles(x, y, z, w); - } - - @pragma("vm:exact-result-type", _Float32x4) - static _Float32x4 _Float32x4FromDoubles( - double x, double y, double z, double w) native "Float32x4_fromDoubles"; - - @patch - @pragma("vm:prefer-inline") - factory Float32x4.splat(double v) { - _throwIfNull(v, 'v'); - return _Float32x4Splat(v); - } - - @pragma("vm:exact-result-type", _Float32x4) - static _Float32x4 _Float32x4Splat(double v) native "Float32x4_splat"; - - @patch - @pragma("vm:exact-result-type", _Float32x4) - factory Float32x4.zero() native "Float32x4_zero"; - - @patch - @pragma("vm:exact-result-type", _Float32x4) - factory Float32x4.fromInt32x4Bits(Int32x4 x) - native "Float32x4_fromInt32x4Bits"; - - @patch - @pragma("vm:exact-result-type", _Float32x4) - factory Float32x4.fromFloat64x2(Float64x2 v) native "Float32x4_fromFloat64x2"; -} - -@pragma("vm:entry-point") -class _Float32x4 implements Float32x4 { - @pragma("vm:exact-result-type", _Float32x4) - Float32x4 operator +(Float32x4 other) native "Float32x4_add"; - @pragma("vm:exact-result-type", _Float32x4) - Float32x4 operator -() native "Float32x4_negate"; - @pragma("vm:exact-result-type", _Float32x4) - Float32x4 operator -(Float32x4 other) native "Float32x4_sub"; - @pragma("vm:exact-result-type", _Float32x4) - Float32x4 operator *(Float32x4 other) native "Float32x4_mul"; - Float32x4 operator /(Float32x4 other) native "Float32x4_div"; - @pragma("vm:exact-result-type", _Int32x4) - Int32x4 lessThan(Float32x4 other) native "Float32x4_cmplt"; - @pragma("vm:exact-result-type", _Int32x4) - Int32x4 lessThanOrEqual(Float32x4 other) native "Float32x4_cmplte"; - @pragma("vm:exact-result-type", _Int32x4) - Int32x4 greaterThan(Float32x4 other) native "Float32x4_cmpgt"; - @pragma("vm:exact-result-type", _Int32x4) - Int32x4 greaterThanOrEqual(Float32x4 other) native "Float32x4_cmpgte"; - @pragma("vm:exact-result-type", _Int32x4) - Int32x4 equal(Float32x4 other) native "Float32x4_cmpequal"; - @pragma("vm:exact-result-type", _Int32x4) - Int32x4 notEqual(Float32x4 other) native "Float32x4_cmpnequal"; - @pragma("vm:exact-result-type", _Float32x4) - Float32x4 scale(double s) native "Float32x4_scale"; - @pragma("vm:exact-result-type", _Float32x4) - Float32x4 abs() native "Float32x4_abs"; - @pragma("vm:exact-result-type", _Float32x4) - Float32x4 clamp(Float32x4 lowerLimit, Float32x4 upperLimit) - native "Float32x4_clamp"; - @pragma("vm:exact-result-type", "dart:core#_Double") - double get x native "Float32x4_getX"; - @pragma("vm:exact-result-type", "dart:core#_Double") - double get y native "Float32x4_getY"; - @pragma("vm:exact-result-type", "dart:core#_Double") - double get z native "Float32x4_getZ"; - @pragma("vm:exact-result-type", "dart:core#_Double") - double get w native "Float32x4_getW"; - int get signMask native "Float32x4_getSignMask"; - - @pragma("vm:exact-result-type", _Float32x4) - Float32x4 shuffle(int mask) native "Float32x4_shuffle"; - @pragma("vm:exact-result-type", _Float32x4) - Float32x4 shuffleMix(Float32x4 zw, int mask) native "Float32x4_shuffleMix"; - - @pragma("vm:prefer-inline") - Float32x4 withX(double x) { - _throwIfNull(x, 'x'); - return _withX(x); - } - - @pragma("vm:exact-result-type", _Float32x4) - Float32x4 _withX(double x) native "Float32x4_setX"; - - @pragma("vm:prefer-inline") - Float32x4 withY(double y) { - _throwIfNull(y, 'y'); - return _withY(y); - } - - @pragma("vm:exact-result-type", _Float32x4) - Float32x4 _withY(double y) native "Float32x4_setY"; - - @pragma("vm:prefer-inline") - Float32x4 withZ(double z) { - _throwIfNull(z, 'z'); - return _withZ(z); - } - - @pragma("vm:exact-result-type", _Float32x4) - Float32x4 _withZ(double z) native "Float32x4_setZ"; - - @pragma("vm:prefer-inline") - Float32x4 withW(double w) { - _throwIfNull(w, 'w'); - return _withW(w); - } - - @pragma("vm:exact-result-type", _Float32x4) - Float32x4 _withW(double w) native "Float32x4_setW"; - - @pragma("vm:exact-result-type", _Float32x4) - Float32x4 min(Float32x4 other) native "Float32x4_min"; - @pragma("vm:exact-result-type", _Float32x4) - Float32x4 max(Float32x4 other) native "Float32x4_max"; - @pragma("vm:exact-result-type", _Float32x4) - Float32x4 sqrt() native "Float32x4_sqrt"; - @pragma("vm:exact-result-type", _Float32x4) - Float32x4 reciprocal() native "Float32x4_reciprocal"; - @pragma("vm:exact-result-type", _Float32x4) - Float32x4 reciprocalSqrt() native "Float32x4_reciprocalSqrt"; -} - -@patch -class Int32x4 { - @patch - @pragma("vm:prefer-inline") - factory Int32x4(int x, int y, int z, int w) { - _throwIfNull(x, 'x'); - _throwIfNull(y, 'y'); - _throwIfNull(z, 'z'); - _throwIfNull(w, 'w'); - return _Int32x4FromInts(x, y, z, w); - } - - @pragma("vm:exact-result-type", _Int32x4) - static _Int32x4 _Int32x4FromInts(int x, int y, int z, int w) - native "Int32x4_fromInts"; - - @patch - @pragma("vm:prefer-inline") - factory Int32x4.bool(bool x, bool y, bool z, bool w) { - _throwIfNull(x, 'x'); - _throwIfNull(y, 'y'); - _throwIfNull(z, 'z'); - _throwIfNull(w, 'w'); - return _Int32x4FromBools(x, y, z, w); - } - - @pragma("vm:exact-result-type", _Int32x4) - static _Int32x4 _Int32x4FromBools(bool x, bool y, bool z, bool w) - native "Int32x4_fromBools"; - - @patch - @pragma("vm:exact-result-type", _Int32x4) - factory Int32x4.fromFloat32x4Bits(Float32x4 x) - native "Int32x4_fromFloat32x4Bits"; -} - -@pragma("vm:entry-point") -class _Int32x4 implements Int32x4 { - Int32x4 operator |(Int32x4 other) native "Int32x4_or"; - Int32x4 operator &(Int32x4 other) native "Int32x4_and"; - Int32x4 operator ^(Int32x4 other) native "Int32x4_xor"; - Int32x4 operator +(Int32x4 other) native "Int32x4_add"; - Int32x4 operator -(Int32x4 other) native "Int32x4_sub"; - int get x native "Int32x4_getX"; - int get y native "Int32x4_getY"; - int get z native "Int32x4_getZ"; - int get w native "Int32x4_getW"; - int get signMask native "Int32x4_getSignMask"; - @pragma("vm:exact-result-type", _Int32x4) - Int32x4 shuffle(int mask) native "Int32x4_shuffle"; - @pragma("vm:exact-result-type", _Int32x4) - Int32x4 shuffleMix(Int32x4 zw, int mask) native "Int32x4_shuffleMix"; - - @pragma("vm:prefer-inline") - Int32x4 withX(int x) { - _throwIfNull(x, 'x'); - return _withX(x); - } - - @pragma("vm:exact-result-type", _Int32x4) - Int32x4 _withX(int x) native "Int32x4_setX"; - - @pragma("vm:prefer-inline") - Int32x4 withY(int y) { - _throwIfNull(y, 'y'); - return _withY(y); - } - - @pragma("vm:exact-result-type", _Int32x4) - Int32x4 _withY(int y) native "Int32x4_setY"; - - @pragma("vm:prefer-inline") - Int32x4 withZ(int z) { - _throwIfNull(z, 'z'); - return _withZ(z); - } - - @pragma("vm:exact-result-type", _Int32x4) - Int32x4 _withZ(int z) native "Int32x4_setZ"; - - @pragma("vm:prefer-inline") - Int32x4 withW(int w) { - _throwIfNull(w, 'w'); - return _withW(w); - } - - @pragma("vm:exact-result-type", _Int32x4) - Int32x4 _withW(int w) native "Int32x4_setW"; - - @pragma("vm:exact-result-type", bool) - bool get flagX native "Int32x4_getFlagX"; - @pragma("vm:exact-result-type", bool) - bool get flagY native "Int32x4_getFlagY"; - @pragma("vm:exact-result-type", bool) - bool get flagZ native "Int32x4_getFlagZ"; - @pragma("vm:exact-result-type", bool) - bool get flagW native "Int32x4_getFlagW"; - - @pragma("vm:prefer-inline", _Int32x4) - Int32x4 withFlagX(bool x) { - _throwIfNull(x, 'x'); - return _withFlagX(x); - } - - @pragma("vm:exact-result-type", _Int32x4) - Int32x4 _withFlagX(bool x) native "Int32x4_setFlagX"; - - @pragma("vm:prefer-inline", _Int32x4) - Int32x4 withFlagY(bool y) { - _throwIfNull(y, 'y'); - return _withFlagY(y); - } - - @pragma("vm:exact-result-type", _Int32x4) - Int32x4 _withFlagY(bool y) native "Int32x4_setFlagY"; - - @pragma("vm:prefer-inline", _Int32x4) - Int32x4 withFlagZ(bool z) { - _throwIfNull(z, 'z'); - return _withFlagZ(z); - } - - @pragma("vm:exact-result-type", _Int32x4) - Int32x4 _withFlagZ(bool z) native "Int32x4_setFlagZ"; - - @pragma("vm:prefer-inline", _Int32x4) - Int32x4 withFlagW(bool w) { - _throwIfNull(w, 'w'); - return _withFlagW(w); - } - - @pragma("vm:exact-result-type", _Int32x4) - Int32x4 _withFlagW(bool w) native "Int32x4_setFlagW"; - - @pragma("vm:exact-result-type", _Float32x4) - Float32x4 select(Float32x4 trueValue, Float32x4 falseValue) - native "Int32x4_select"; -} - -@patch -class Float64x2 { - @patch - @pragma("vm:prefer-inline") - factory Float64x2(double x, double y) { - _throwIfNull(x, 'x'); - _throwIfNull(y, 'y'); - return _Float64x2FromDoubles(x, y); - } - - @pragma("vm:exact-result-type", _Float64x2) - static _Float64x2 _Float64x2FromDoubles(double x, double y) - native "Float64x2_fromDoubles"; - - @patch - @pragma("vm:prefer-inline") - factory Float64x2.splat(double v) { - _throwIfNull(v, 'v'); - return _Float64x2Splat(v); - } - - @pragma("vm:exact-result-type", _Float64x2) - static _Float64x2 _Float64x2Splat(double v) native "Float64x2_splat"; - - @patch - @pragma("vm:exact-result-type", _Float64x2) - factory Float64x2.zero() native "Float64x2_zero"; - - @patch - @pragma("vm:exact-result-type", _Float64x2) - factory Float64x2.fromFloat32x4(Float32x4 v) native "Float64x2_fromFloat32x4"; -} - -@pragma("vm:entry-point") -class _Float64x2 implements Float64x2 { - Float64x2 operator +(Float64x2 other) native "Float64x2_add"; - @pragma("vm:exact-result-type", _Float64x2) - Float64x2 operator -() native "Float64x2_negate"; - Float64x2 operator -(Float64x2 other) native "Float64x2_sub"; - Float64x2 operator *(Float64x2 other) native "Float64x2_mul"; - Float64x2 operator /(Float64x2 other) native "Float64x2_div"; - @pragma("vm:exact-result-type", _Float64x2) - Float64x2 scale(double s) native "Float64x2_scale"; - @pragma("vm:exact-result-type", _Float64x2) - Float64x2 abs() native "Float64x2_abs"; - Float64x2 clamp(Float64x2 lowerLimit, Float64x2 upperLimit) - native "Float64x2_clamp"; - @pragma("vm:exact-result-type", "dart:core#_Double") - double get x native "Float64x2_getX"; - @pragma("vm:exact-result-type", "dart:core#_Double") - double get y native "Float64x2_getY"; - int get signMask native "Float64x2_getSignMask"; - - @pragma("vm:prefer-inline") - Float64x2 withX(double x) { - _throwIfNull(x, 'x'); - return _withX(x); - } - - @pragma("vm:exact-result-type", _Float64x2) - Float64x2 _withX(double x) native "Float64x2_setX"; - - @pragma("vm:prefer-inline") - Float64x2 withY(double y) { - _throwIfNull(y, 'y'); - return _withY(y); - } - - @pragma("vm:exact-result-type", _Float64x2) - Float64x2 _withY(double y) native "Float64x2_setY"; - - @pragma("vm:exact-result-type", _Float64x2) - Float64x2 min(Float64x2 other) native "Float64x2_min"; - @pragma("vm:exact-result-type", _Float64x2) - Float64x2 max(Float64x2 other) native "Float64x2_max"; - @pragma("vm:exact-result-type", _Float64x2) - Float64x2 sqrt() native "Float64x2_sqrt"; -} - -class _TypedListIterator implements Iterator { - final List _array; - final int _length; - int _position; - E? _current; - - _TypedListIterator(List array) - : _array = array, - _length = array.length, - _position = -1 { - assert(array is _TypedList || array is _TypedListView); - } - - bool moveNext() { - int nextPosition = _position + 1; - if (nextPosition < _length) { - _current = _array[nextPosition]; - _position = nextPosition; - return true; - } - _position = _length; - _current = null; - return false; - } - - E get current { - final cur = _current; - return (cur != null) ? cur : cur as E; - } -} - -abstract class _TypedListView extends _TypedListBase implements TypedData { - // Method(s) implementing the TypedData interface. - - int get lengthInBytes { - return length * elementSizeInBytes; - } - - _ByteBuffer get buffer { - return _typedData.buffer; - } - - @pragma("vm:non-nullable-result-type") - @pragma("vm:prefer-inline") - _TypedList get _typedData native "TypedDataView_typedData"; - - @pragma("vm:exact-result-type", "dart:core#_Smi") - @pragma("vm:prefer-inline") - int get offsetInBytes native "TypedDataView_offsetInBytes"; - - @pragma("vm:exact-result-type", "dart:core#_Smi") - @pragma("vm:prefer-inline") - int get length native "TypedDataView_length"; -} - -@pragma("vm:entry-point") -class _Int8ArrayView extends _TypedListView - with _IntListMixin, _TypedIntListMixin - implements Int8List { - // Constructor. - @pragma("vm:exact-result-type", _Int8ArrayView) - factory _Int8ArrayView._(_TypedList buffer, int offsetInBytes, int length) - native "TypedDataView_Int8ArrayView_new"; - - // Method(s) implementing List interface. - @pragma("vm:prefer-inline") - int operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _typedData - ._getInt8(offsetInBytes + (index * Int8List.bytesPerElement)); - } - - @pragma("vm:prefer-inline") - void operator []=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _typedData._setInt8( - offsetInBytes + (index * Int8List.bytesPerElement), _toInt8(value)); - } - - // Method(s) implementing TypedData interface. - int get elementSizeInBytes { - return Int8List.bytesPerElement; - } - - // Internal utility methods. - Int8List _createList(int length) { - return new Int8List(length); - } -} - -@pragma("vm:entry-point") -class _Uint8ArrayView extends _TypedListView - with _IntListMixin, _TypedIntListMixin - implements Uint8List { - // Constructor. - @pragma("vm:exact-result-type", _Uint8ArrayView) - factory _Uint8ArrayView._(_TypedList buffer, int offsetInBytes, int length) - native "TypedDataView_Uint8ArrayView_new"; - - // Method(s) implementing List interface. - @pragma("vm:prefer-inline") - int operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _typedData - ._getUint8(offsetInBytes + (index * Uint8List.bytesPerElement)); - } - - @pragma("vm:prefer-inline") - void operator []=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _typedData._setUint8( - offsetInBytes + (index * Uint8List.bytesPerElement), _toUint8(value)); - } - - // Method(s) implementing TypedData interface. - int get elementSizeInBytes { - return Uint8List.bytesPerElement; - } - - // Internal utility methods. - Uint8List _createList(int length) { - return new Uint8List(length); - } -} - -@pragma("vm:entry-point") -class _Uint8ClampedArrayView extends _TypedListView - with _IntListMixin, _TypedIntListMixin - implements Uint8ClampedList { - // Constructor. - @pragma("vm:exact-result-type", _Uint8ClampedArrayView) - factory _Uint8ClampedArrayView._(_TypedList buffer, int offsetInBytes, - int length) native "TypedDataView_Uint8ClampedArrayView_new"; - - // Method(s) implementing List interface. - @pragma("vm:prefer-inline") - int operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _typedData - ._getUint8(offsetInBytes + (index * Uint8List.bytesPerElement)); - } - - @pragma("vm:prefer-inline") - void operator []=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _typedData._setUint8(offsetInBytes + (index * Uint8List.bytesPerElement), - _toClampedUint8(value)); - } - - // Method(s) implementing TypedData interface. - int get elementSizeInBytes { - return Uint8List.bytesPerElement; - } - - // Internal utility methods. - Uint8ClampedList _createList(int length) { - return new Uint8ClampedList(length); - } -} - -@pragma("vm:entry-point") -class _Int16ArrayView extends _TypedListView - with _IntListMixin, _TypedIntListMixin - implements Int16List { - // Constructor. - @pragma("vm:exact-result-type", _Int16ArrayView) - factory _Int16ArrayView._(_TypedList buffer, int offsetInBytes, int length) - native "TypedDataView_Int16ArrayView_new"; - - // Method(s) implementing List interface. - @pragma("vm:prefer-inline") - int operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _typedData - ._getInt16(offsetInBytes + (index * Int16List.bytesPerElement)); - } - - @pragma("vm:prefer-inline") - void operator []=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _typedData._setInt16( - offsetInBytes + (index * Int16List.bytesPerElement), _toInt16(value)); - } - - void setRange(int start, int end, Iterable iterable, - [int skipCount = 0]) { - if (iterable is CodeUnits) { - end = RangeError.checkValidRange(start, end, this.length); - int length = end - start; - int byteStart = this.offsetInBytes + start * Int16List.bytesPerElement; - _typedData._setCodeUnits(iterable, byteStart, length, skipCount); - } else { - super.setRange(start, end, iterable, skipCount); - } - } - - // Method(s) implementing TypedData interface. - - int get elementSizeInBytes { - return Int16List.bytesPerElement; - } - - // Internal utility methods. - Int16List _createList(int length) { - return new Int16List(length); - } -} - -@pragma("vm:entry-point") -class _Uint16ArrayView extends _TypedListView - with _IntListMixin, _TypedIntListMixin - implements Uint16List { - // Constructor. - @pragma("vm:exact-result-type", _Uint16ArrayView) - factory _Uint16ArrayView._(_TypedList buffer, int offsetInBytes, int length) - native "TypedDataView_Uint16ArrayView_new"; - - // Method(s) implementing List interface. - @pragma("vm:prefer-inline") - int operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _typedData - ._getUint16(offsetInBytes + (index * Uint16List.bytesPerElement)); - } - - @pragma("vm:prefer-inline") - void operator []=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _typedData._setUint16( - offsetInBytes + (index * Uint16List.bytesPerElement), _toUint16(value)); - } - - void setRange(int start, int end, Iterable iterable, - [int skipCount = 0]) { - if (iterable is CodeUnits) { - end = RangeError.checkValidRange(start, end, this.length); - int length = end - start; - int byteStart = this.offsetInBytes + start * Uint16List.bytesPerElement; - _typedData._setCodeUnits(iterable, byteStart, length, skipCount); - } else { - super.setRange(start, end, iterable, skipCount); - } - } - - // Method(s) implementing TypedData interface. - - int get elementSizeInBytes { - return Uint16List.bytesPerElement; - } - - // Internal utility methods. - - Uint16List _createList(int length) { - return new Uint16List(length); - } -} - -@pragma("vm:entry-point") -class _Int32ArrayView extends _TypedListView - with _IntListMixin, _TypedIntListMixin - implements Int32List { - // Constructor. - @pragma("vm:exact-result-type", _Int32ArrayView) - factory _Int32ArrayView._(_TypedList buffer, int offsetInBytes, int length) - native "TypedDataView_Int32ArrayView_new"; - - // Method(s) implementing List interface. - @pragma("vm:prefer-inline") - int operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _typedData - ._getInt32(offsetInBytes + (index * Int32List.bytesPerElement)); - } - - @pragma("vm:prefer-inline") - void operator []=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _typedData._setInt32( - offsetInBytes + (index * Int32List.bytesPerElement), _toInt32(value)); - } - - // Method(s) implementing TypedData interface. - int get elementSizeInBytes { - return Int32List.bytesPerElement; - } - - // Internal utility methods. - Int32List _createList(int length) { - return new Int32List(length); - } -} - -@pragma("vm:entry-point") -class _Uint32ArrayView extends _TypedListView - with _IntListMixin, _TypedIntListMixin - implements Uint32List { - // Constructor. - @pragma("vm:exact-result-type", _Uint32ArrayView) - factory _Uint32ArrayView._(_TypedList buffer, int offsetInBytes, int length) - native "TypedDataView_Uint32ArrayView_new"; - - // Method(s) implementing List interface. - @pragma("vm:prefer-inline") - int operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _typedData - ._getUint32(offsetInBytes + (index * Uint32List.bytesPerElement)); - } - - @pragma("vm:prefer-inline") - void operator []=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _typedData._setUint32( - offsetInBytes + (index * Uint32List.bytesPerElement), _toUint32(value)); - } - - // Method(s) implementing TypedData interface. - int get elementSizeInBytes { - return Uint32List.bytesPerElement; - } - - // Internal utility methods. - Uint32List _createList(int length) { - return new Uint32List(length); - } -} - -@pragma("vm:entry-point") -class _Int64ArrayView extends _TypedListView - with _IntListMixin, _TypedIntListMixin - implements Int64List { - // Constructor. - @pragma("vm:exact-result-type", _Int64ArrayView) - factory _Int64ArrayView._(_TypedList buffer, int offsetInBytes, int length) - native "TypedDataView_Int64ArrayView_new"; - - // Method(s) implementing List interface. - @pragma("vm:prefer-inline") - int operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _typedData - ._getInt64(offsetInBytes + (index * Int64List.bytesPerElement)); - } - - @pragma("vm:prefer-inline") - void operator []=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _typedData._setInt64( - offsetInBytes + (index * Int64List.bytesPerElement), value); - } - - // Method(s) implementing TypedData interface. - int get elementSizeInBytes { - return Int64List.bytesPerElement; - } - - // Internal utility methods. - Int64List _createList(int length) { - return new Int64List(length); - } -} - -@pragma("vm:entry-point") -class _Uint64ArrayView extends _TypedListView - with _IntListMixin, _TypedIntListMixin - implements Uint64List { - // Constructor. - @pragma("vm:exact-result-type", _Uint64ArrayView) - factory _Uint64ArrayView._(_TypedList buffer, int offsetInBytes, int length) - native "TypedDataView_Uint64ArrayView_new"; - - // Method(s) implementing List interface. - @pragma("vm:prefer-inline") - int operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _typedData - ._getUint64(offsetInBytes + (index * Uint64List.bytesPerElement)); - } - - @pragma("vm:prefer-inline") - void operator []=(int index, int value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _typedData._setUint64( - offsetInBytes + (index * Uint64List.bytesPerElement), value); - } - - // Method(s) implementing TypedData interface. - int get elementSizeInBytes { - return Uint64List.bytesPerElement; - } - - // Internal utility methods. - Uint64List _createList(int length) { - return new Uint64List(length); - } -} - -@pragma("vm:entry-point") -class _Float32ArrayView extends _TypedListView - with _DoubleListMixin, _TypedDoubleListMixin - implements Float32List { - // Constructor. - @pragma("vm:exact-result-type", _Float32ArrayView) - factory _Float32ArrayView._(_TypedList buffer, int offsetInBytes, int length) - native "TypedDataView_Float32ArrayView_new"; - - // Method(s) implementing List interface. - @pragma("vm:prefer-inline") - double operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _typedData - ._getFloat32(offsetInBytes + (index * Float32List.bytesPerElement)); - } - - @pragma("vm:prefer-inline") - void operator []=(int index, double value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _typedData._setFloat32( - offsetInBytes + (index * Float32List.bytesPerElement), value); - } - - // Method(s) implementing TypedData interface. - int get elementSizeInBytes { - return Float32List.bytesPerElement; - } - - // Internal utility methods. - Float32List _createList(int length) { - return new Float32List(length); - } -} - -@pragma("vm:entry-point") -class _Float64ArrayView extends _TypedListView - with _DoubleListMixin, _TypedDoubleListMixin - implements Float64List { - // Constructor. - @pragma("vm:exact-result-type", _Float64ArrayView) - factory _Float64ArrayView._(_TypedList buffer, int offsetInBytes, int length) - native "TypedDataView_Float64ArrayView_new"; - - // Method(s) implementing List interface. - @pragma("vm:prefer-inline") - double operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _typedData - ._getFloat64(offsetInBytes + (index * Float64List.bytesPerElement)); - } - - @pragma("vm:prefer-inline") - void operator []=(int index, double value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _typedData._setFloat64( - offsetInBytes + (index * Float64List.bytesPerElement), value); - } - - // Method(s) implementing TypedData interface. - int get elementSizeInBytes { - return Float64List.bytesPerElement; - } - - // Internal utility methods. - Float64List _createList(int length) { - return new Float64List(length); - } -} - -@pragma("vm:entry-point") -class _Float32x4ArrayView extends _TypedListView - with _Float32x4ListMixin - implements Float32x4List { - // Constructor. - @pragma("vm:exact-result-type", _Float32x4ArrayView) - factory _Float32x4ArrayView._(_TypedList buffer, int offsetInBytes, - int length) native "TypedDataView_Float32x4ArrayView_new"; - - // Method(s) implementing List interface. - Float32x4 operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _typedData - ._getFloat32x4(offsetInBytes + (index * Float32x4List.bytesPerElement)); - } - - void operator []=(int index, Float32x4 value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _typedData._setFloat32x4( - offsetInBytes + (index * Float32x4List.bytesPerElement), value); - } - - // Method(s) implementing TypedData interface. - int get elementSizeInBytes { - return Float32x4List.bytesPerElement; - } - - // Internal utility methods. - Float32x4List _createList(int length) { - return new Float32x4List(length); - } -} - -@pragma("vm:entry-point") -class _Int32x4ArrayView extends _TypedListView - with _Int32x4ListMixin - implements Int32x4List { - // Constructor. - @pragma("vm:exact-result-type", _Int32x4ArrayView) - factory _Int32x4ArrayView._(_TypedList buffer, int offsetInBytes, int length) - native "TypedDataView_Int32x4ArrayView_new"; - - // Method(s) implementing List interface. - Int32x4 operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _typedData - ._getInt32x4(offsetInBytes + (index * Int32x4List.bytesPerElement)); - } - - void operator []=(int index, Int32x4 value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _typedData._setInt32x4( - offsetInBytes + (index * Int32x4List.bytesPerElement), value); - } - - // Method(s) implementing TypedData interface. - int get elementSizeInBytes { - return Int32x4List.bytesPerElement; - } - - // Internal utility methods. - Int32x4List _createList(int length) { - return new Int32x4List(length); - } -} - -@pragma("vm:entry-point") -class _Float64x2ArrayView extends _TypedListView - with _Float64x2ListMixin - implements Float64x2List { - // Constructor. - @pragma("vm:exact-result-type", _Float64x2ArrayView) - factory _Float64x2ArrayView._(_TypedList buffer, int offsetInBytes, - int length) native "TypedDataView_Float64x2ArrayView_new"; - - // Method(s) implementing List interface. - Float64x2 operator [](int index) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - return _typedData - ._getFloat64x2(offsetInBytes + (index * Float64x2List.bytesPerElement)); - } - - void operator []=(int index, Float64x2 value) { - if (index < 0 || index >= length) { - throw new RangeError.index(index, this, "index"); - } - _typedData._setFloat64x2( - offsetInBytes + (index * Float64x2List.bytesPerElement), value); - } - - // Method(s) implementing TypedData interface. - int get elementSizeInBytes { - return Float64x2List.bytesPerElement; - } - - // Internal utility methods. - Float64x2List _createList(int length) { - return new Float64x2List(length); - } -} - -@pragma("vm:entry-point") -class _ByteDataView implements ByteData { - @pragma("vm:exact-result-type", _ByteDataView) - factory _ByteDataView._(_TypedList buffer, int offsetInBytes, int length) - native "TypedDataView_ByteDataView_new"; - - // Method(s) implementing TypedData interface. - _ByteBuffer get buffer { - return _typedData.buffer; - } - - int get lengthInBytes { - return length; - } - - int get elementSizeInBytes { - return 1; - } - - // Method(s) implementing ByteData interface. - - @pragma("vm:prefer-inline") - int getInt8(int byteOffset) { - if (byteOffset < 0 || byteOffset >= length) { - throw new RangeError.index(byteOffset, this, "byteOffset"); - } - return _typedData._getInt8(offsetInBytes + byteOffset); - } - - @pragma("vm:prefer-inline") - void setInt8(int byteOffset, int value) { - if (byteOffset < 0 || byteOffset >= length) { - throw new RangeError.index(byteOffset, this, "byteOffset"); - } - _typedData._setInt8(offsetInBytes + byteOffset, value); - } - - @pragma("vm:prefer-inline") - int getUint8(int byteOffset) { - if (byteOffset < 0 || byteOffset >= length) { - throw new RangeError.index(byteOffset, this, "byteOffset"); - } - return _typedData._getUint8(offsetInBytes + byteOffset); - } - - @pragma("vm:prefer-inline") - void setUint8(int byteOffset, int value) { - if (byteOffset < 0 || byteOffset >= length) { - throw new RangeError.index(byteOffset, this, "byteOffset"); - } - _typedData._setUint8(offsetInBytes + byteOffset, value); - } - - @pragma("vm:prefer-inline") - int getInt16(int byteOffset, [Endian endian = Endian.big]) { - if (byteOffset < 0 || byteOffset + 1 >= length) { - throw new RangeError.range(byteOffset, 0, length - 2, "byteOffset"); - } - var result = _typedData._getInt16(offsetInBytes + byteOffset); - if (identical(endian, Endian.host)) { - return result; - } - return _byteSwap16(result).toSigned(16); - } - - @pragma("vm:prefer-inline") - void setInt16(int byteOffset, int value, [Endian endian = Endian.big]) { - if (byteOffset < 0 || byteOffset + 1 >= length) { - throw new RangeError.range(byteOffset, 0, length - 2, "byteOffset"); - } - _typedData._setInt16(offsetInBytes + byteOffset, - identical(endian, Endian.host) ? value : _byteSwap16(value)); - } - - @pragma("vm:prefer-inline") - int getUint16(int byteOffset, [Endian endian = Endian.big]) { - if (byteOffset < 0 || byteOffset + 1 >= length) { - throw new RangeError.range(byteOffset, 0, length - 2, "byteOffset"); - } - var result = _typedData._getUint16(offsetInBytes + byteOffset); - if (identical(endian, Endian.host)) { - return result; - } - return _byteSwap16(result); - } - - @pragma("vm:prefer-inline") - void setUint16(int byteOffset, int value, [Endian endian = Endian.big]) { - if (byteOffset < 0 || byteOffset + 1 >= length) { - throw new RangeError.range(byteOffset, 0, length - 2, "byteOffset"); - } - _typedData._setUint16(offsetInBytes + byteOffset, - identical(endian, Endian.host) ? value : _byteSwap16(value)); - } - - @pragma("vm:prefer-inline") - int getInt32(int byteOffset, [Endian endian = Endian.big]) { - if (byteOffset < 0 || byteOffset + 3 >= length) { - throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset"); - } - var result = _typedData._getInt32(offsetInBytes + byteOffset); - if (identical(endian, Endian.host)) { - return result; - } - return _byteSwap32(result).toSigned(32); - } - - @pragma("vm:prefer-inline") - void setInt32(int byteOffset, int value, [Endian endian = Endian.big]) { - if (byteOffset < 0 || byteOffset + 3 >= length) { - throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset"); - } - _typedData._setInt32(offsetInBytes + byteOffset, - identical(endian, Endian.host) ? value : _byteSwap32(value)); - } - - @pragma("vm:prefer-inline") - int getUint32(int byteOffset, [Endian endian = Endian.big]) { - if (byteOffset < 0 || byteOffset + 3 >= length) { - throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset"); - } - var result = _typedData._getUint32(offsetInBytes + byteOffset); - if (identical(endian, Endian.host)) { - return result; - } - return _byteSwap32(result); - } - - @pragma("vm:prefer-inline") - void setUint32(int byteOffset, int value, [Endian endian = Endian.big]) { - if (byteOffset < 0 || byteOffset + 3 >= length) { - throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset"); - } - _typedData._setUint32(offsetInBytes + byteOffset, - identical(endian, Endian.host) ? value : _byteSwap32(value)); - } - - @pragma("vm:prefer-inline") - int getInt64(int byteOffset, [Endian endian = Endian.big]) { - if (byteOffset < 0 || byteOffset + 7 >= length) { - throw new RangeError.range(byteOffset, 0, length - 8, "byteOffset"); - } - var result = _typedData._getInt64(offsetInBytes + byteOffset); - if (identical(endian, Endian.host)) { - return result; - } - return _byteSwap64(result).toSigned(64); - } - - @pragma("vm:prefer-inline") - void setInt64(int byteOffset, int value, [Endian endian = Endian.big]) { - if (byteOffset < 0 || byteOffset + 7 >= length) { - throw new RangeError.range(byteOffset, 0, length - 8, "byteOffset"); - } - _typedData._setInt64(offsetInBytes + byteOffset, - identical(endian, Endian.host) ? value : _byteSwap64(value)); - } - - @pragma("vm:prefer-inline") - int getUint64(int byteOffset, [Endian endian = Endian.big]) { - if (byteOffset < 0 || byteOffset + 7 >= length) { - throw new RangeError.range(byteOffset, 0, length - 8, "byteOffset"); - } - var result = _typedData._getUint64(offsetInBytes + byteOffset); - if (identical(endian, Endian.host)) { - return result; - } - return _byteSwap64(result); - } - - @pragma("vm:prefer-inline") - void setUint64(int byteOffset, int value, [Endian endian = Endian.big]) { - if (byteOffset < 0 || byteOffset + 7 >= length) { - throw new RangeError.range(byteOffset, 0, length - 8, "byteOffset"); - } - _typedData._setUint64(offsetInBytes + byteOffset, - identical(endian, Endian.host) ? value : _byteSwap64(value)); - } - - @pragma("vm:prefer-inline") - double getFloat32(int byteOffset, [Endian endian = Endian.big]) { - if (byteOffset < 0 || byteOffset + 3 >= length) { - throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset"); - } - if (identical(endian, Endian.host)) { - return _typedData._getFloat32(offsetInBytes + byteOffset); - } - _convU32[0] = - _byteSwap32(_typedData._getUint32(offsetInBytes + byteOffset)); - return _convF32[0]; - } - - @pragma("vm:prefer-inline") - void setFloat32(int byteOffset, double value, [Endian endian = Endian.big]) { - if (byteOffset < 0 || byteOffset + 3 >= length) { - throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset"); - } - if (identical(endian, Endian.host)) { - _typedData._setFloat32(offsetInBytes + byteOffset, value); - return; - } - _convF32[0] = value; - _typedData._setUint32(offsetInBytes + byteOffset, _byteSwap32(_convU32[0])); - } - - @pragma("vm:prefer-inline") - double getFloat64(int byteOffset, [Endian endian = Endian.big]) { - if (byteOffset < 0 || byteOffset + 7 >= length) { - throw new RangeError.range(byteOffset, 0, length - 8, "byteOffset"); - } - if (identical(endian, Endian.host)) { - return _typedData._getFloat64(offsetInBytes + byteOffset); - } - _convU64[0] = - _byteSwap64(_typedData._getUint64(offsetInBytes + byteOffset)); - return _convF64[0]; - } - - @pragma("vm:prefer-inline") - void setFloat64(int byteOffset, double value, [Endian endian = Endian.big]) { - if (byteOffset < 0 || byteOffset + 7 >= length) { - throw new RangeError.range(byteOffset, 0, length - 8, "byteOffset"); - } - if (identical(endian, Endian.host)) { - _typedData._setFloat64(offsetInBytes + byteOffset, value); - return; - } - _convF64[0] = value; - _typedData._setUint64(offsetInBytes + byteOffset, _byteSwap64(_convU64[0])); - } - - Float32x4 getFloat32x4(int byteOffset, [Endian endian = Endian.big]) { - if (byteOffset < 0 || byteOffset + 3 >= length) { - throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset"); - } - // TODO(johnmccutchan) : Need to resolve this for endianity. - return _typedData._getFloat32x4(offsetInBytes + byteOffset); - } - - void setFloat32x4(int byteOffset, Float32x4 value, - [Endian endian = Endian.big]) { - if (byteOffset < 0 || byteOffset + 3 >= length) { - throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset"); - } - // TODO(johnmccutchan) : Need to resolve this for endianity. - _typedData._setFloat32x4(offsetInBytes + byteOffset, value); - } - - @pragma("vm:non-nullable-result-type") - @pragma("vm:prefer-inline") - _TypedList get _typedData native "TypedDataView_typedData"; - - @pragma("vm:exact-result-type", "dart:core#_Smi") - @pragma("vm:prefer-inline") - int get offsetInBytes native "TypedDataView_offsetInBytes"; - - @pragma("vm:exact-result-type", "dart:core#_Smi") - @pragma("vm:prefer-inline") - int get length native "TypedDataView_length"; -} - -@pragma("vm:prefer-inline") -int _byteSwap16(int value) { - return ((value & 0xFF00) >> 8) | ((value & 0x00FF) << 8); -} - -@pragma("vm:prefer-inline") -int _byteSwap32(int value) { - value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8); - value = ((value & 0xFFFF0000) >> 16) | ((value & 0x0000FFFF) << 16); - return value; -} - -@pragma("vm:prefer-inline") -int _byteSwap64(int value) { - return (_byteSwap32(value) << 32) | _byteSwap32(value >> 32); -} - -final _convU32 = new Uint32List(2); -final _convU64 = new Uint64List.view(_convU32.buffer); -final _convF32 = new Float32List.view(_convU32.buffer); -final _convF64 = new Float64List.view(_convU32.buffer); - -// Top level utility methods. -@pragma("vm:prefer-inline") -int _toInt(int value, int mask) { - value &= mask; - if (value > (mask >> 1)) value -= mask + 1; - return value; -} - -@pragma("vm:prefer-inline") -int _toInt8(int value) { - return _toInt(value, 0xFF); -} - -@pragma("vm:prefer-inline") -int _toUint8(int value) { - return value & 0xFF; -} - -@pragma("vm:exact-result-type", "dart:core#_Smi") -int _toClampedUint8(int value) { - if (value < 0) return 0; - if (value > 0xFF) return 0xFF; - return value; -} - -@pragma("vm:prefer-inline") -int _toInt16(int value) { - return _toInt(value, 0xFFFF); -} - -@pragma("vm:prefer-inline") -int _toUint16(int value) { - return value & 0xFFFF; -} - -@pragma("vm:prefer-inline") -int _toInt32(int value) { - return _toInt(value, 0xFFFFFFFF); -} - -@pragma("vm:prefer-inline") -int _toUint32(int value) { - return value & 0xFFFFFFFF; -} - -@pragma("vm:prefer-inline") -void _throwIfNull(val, String name) { - if (val == null) { - throw ArgumentError.notNull(name); - } -} - -// In addition to explicitly checking the range, this method implicitly ensures -// that all arguments are non-null (a no such method error gets thrown -// otherwise). -void _rangeCheck(int listLength, int start, int length) { - if (length < 0) { - throw new RangeError.value(length); - } - if (start < 0) { - throw new RangeError.value(start); - } - if (start + length > listLength) { - throw new RangeError.value(start + length); - } -} - -void _offsetAlignmentCheck(int offset, int alignment) { - if ((offset % alignment) != 0) { - throw new RangeError('Offset ($offset) must be a multiple of ' - 'BYTES_PER_ELEMENT ($alignment)'); - } -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/uri_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/uri_patch.dart deleted file mode 100644 index de10c9e008c..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/uri_patch.dart +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (c) 2013, 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. - -// part of "core_patch.dart"; - -typedef Uri _UriBaseClosure(); - -Uri _unsupportedUriBase() { - throw new UnsupportedError("'Uri.base' is not supported"); -} - -// _uriBaseClosure can be overwritten by the embedder to supply a different -// value for Uri.base. -@pragma("vm:entry-point") -_UriBaseClosure _uriBaseClosure = _unsupportedUriBase; - -@patch -class Uri { - @patch - static Uri get base => _uriBaseClosure(); -} - -/// VM implementation of Uri. -@patch -class _Uri { - static final bool _isWindowsCached = _isWindowsPlatform; - - static bool get _isWindowsPlatform native "Uri_isWindowsPlatform"; - - @patch - static bool get _isWindows => _isWindowsCached; - - @patch - static String _uriEncode(List canonicalTable, String text, - Encoding encoding, bool spaceToPlus) { - // First check if the text will be changed by encoding. - int i = 0; - if (identical(encoding, utf8) || - identical(encoding, latin1) || - identical(encoding, ascii)) { - // Encoding is compatible with the original string. - // Find first character that needs encoding. - for (; i < text.length; i++) { - var char = text.codeUnitAt(i); - if (char >= 128 || - canonicalTable[char >> 4] & (1 << (char & 0x0f)) == 0) { - break; - } - } - } - if (i == text.length) return text; - - // Encode the string into bytes then generate an ASCII only string - // by percent encoding selected bytes. - StringBuffer result = new StringBuffer(); - for (int j = 0; j < i; j++) { - result.writeCharCode(text.codeUnitAt(j)); - } - - // TODO(lrn): Is there a way to only encode from index i and forwards. - var bytes = encoding.encode(text); - for (; i < bytes.length; i++) { - int byte = bytes[i]; - if (byte < 128 && - ((canonicalTable[byte >> 4] & (1 << (byte & 0x0f))) != 0)) { - result.writeCharCode(byte); - } else if (spaceToPlus && byte == _SPACE) { - result.writeCharCode(_PLUS); - } else { - const String hexDigits = '0123456789ABCDEF'; - result - ..writeCharCode(_PERCENT) - ..writeCharCode(hexDigits.codeUnitAt(byte >> 4)) - ..writeCharCode(hexDigits.codeUnitAt(byte & 0x0f)); - } - } - return result.toString(); - } -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/wasm_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/wasm_patch.dart deleted file mode 100644 index f3a996d2b51..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/wasm_patch.dart +++ /dev/null @@ -1,181 +0,0 @@ -// Copyright (c) 2019, 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 'dart:_internal' show patch; -import "dart:nativewrappers" show NativeFieldWrapperClass1; -import 'dart:typed_data'; - -@patch -@pragma("vm:entry-point") -class Int32 {} - -@patch -@pragma("vm:entry-point") -class Int64 {} - -@patch -@pragma("vm:entry-point") -class Float {} - -@patch -@pragma("vm:entry-point") -class Double {} - -@patch -@pragma("vm:entry-point") -class Void {} - -@patch -class WasmModule { - @patch - factory WasmModule(Uint8List data) { - return _NativeWasmModule(data); - } -} - -@patch -class WasmMemory { - @patch - factory WasmMemory(int initialPages, [int? maxPages]) { - return _NativeWasmMemory(initialPages, maxPages); - } -} - -@patch -class WasmImports { - @patch - factory WasmImports() { - return _NativeWasmImports(); - } -} - -class _NativeWasmModule extends NativeFieldWrapperClass1 implements WasmModule { - _NativeWasmModule(Uint8List data) { - _init(data); - } - - WasmInstance instantiate(covariant _NativeWasmImports imports) { - return _NativeWasmInstance(this, imports); - } - - void _init(Uint8List data) native 'Wasm_initModule'; - String describe() native 'Wasm_describeModule'; -} - -class _NativeWasmImports extends NativeFieldWrapperClass1 - implements WasmImports { - List _memories; - List _fns; - - _NativeWasmImports() - : _memories = [], - _fns = [] { - _init(); - } - - void addMemory(String moduleName, String name, WasmMemory memory) { - _memories.add(memory); - _addMemory(moduleName, name, memory); - } - - void addGlobal(String moduleName, String name, num value, bool mutable) { - _addGlobal(moduleName, name, value, T, mutable); - } - - void addFunction( - String moduleName, String name, Function fn) { - int id = _fns.length; - _fns.add(fn); - _addFunction(moduleName, name, id, T); - } - - @pragma("vm:entry-point") - static Function getFunction(_NativeWasmImports imp, int id) { - return imp._fns[id]; - } - - void _init() native 'Wasm_initImports'; - void _addMemory(String moduleName, String name, WasmMemory memory) - native 'Wasm_addMemoryImport'; - void _addGlobal(String moduleName, String name, num value, Type type, - bool mutable) native 'Wasm_addGlobalImport'; - void _addFunction(String moduleName, String name, int id, Type type) - native 'Wasm_addFunctionImport'; -} - -class _NativeWasmMemory extends NativeFieldWrapperClass1 implements WasmMemory { - late int _pages; - late Uint8List _buffer; - - _NativeWasmMemory(int initialPages, int? maxPages) { - _buffer = _init(initialPages, maxPages); - _pages = initialPages; - } - - _NativeWasmMemory.fromInstance(_NativeWasmInstance inst) { - _buffer = _initFromInstance(inst); - _pages = _getPages(); - } - - int get lengthInPages => _pages; - int get lengthInBytes => _buffer.lengthInBytes; - int operator [](int index) => _buffer[index]; - void operator []=(int index, int value) { - _buffer[index] = value; - } - - int grow(int deltaPages) { - int oldPages = _pages; - _buffer = _grow(deltaPages); - _pages += deltaPages; - return oldPages; - } - - Uint8List _init(int initialPages, int? maxPages) native 'Wasm_initMemory'; - Uint8List _grow(int deltaPages) native 'Wasm_growMemory'; - Uint8List _initFromInstance(_NativeWasmInstance inst) - native 'Wasm_initMemoryFromInstance'; - int _getPages() native 'Wasm_getMemoryPages'; -} - -class _NativeWasmInstance extends NativeFieldWrapperClass1 - implements WasmInstance { - _NativeWasmModule _module; - _NativeWasmImports _imports; - - _NativeWasmInstance(_NativeWasmModule module, _NativeWasmImports imports) - : _module = module, - _imports = imports { - _init(module, imports); - } - - WasmFunction lookupFunction(String name) { - return _NativeWasmFunction(this, name); - } - - WasmMemory get memory { - return _NativeWasmMemory.fromInstance(this); - } - - void _init(_NativeWasmModule module, _NativeWasmImports imports) - native 'Wasm_initInstance'; -} - -class _NativeWasmFunction extends NativeFieldWrapperClass1 - implements WasmFunction { - _NativeWasmInstance _inst; - - _NativeWasmFunction(_NativeWasmInstance inst, String name) : _inst = inst { - _init(inst, name, T); - } - - num call(List args) { - var arg_copy = List.from(args, growable: false); - return _call(arg_copy); - } - - void _init(_NativeWasmInstance inst, String name, Type fnType) - native 'Wasm_initFunction'; - num _call(List args) native 'Wasm_callFunction'; -} diff --git a/sdk_nnbd/lib/_internal/vm/lib/weak_property.dart b/sdk_nnbd/lib/_internal/vm/lib/weak_property.dart deleted file mode 100644 index bc903e9f988..00000000000 --- a/sdk_nnbd/lib/_internal/vm/lib/weak_property.dart +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) 2012, 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. - -// part of "core_patch.dart"; - -@pragma("vm:entry-point") -class _WeakProperty { - factory _WeakProperty(key, value) => _new(key, value); - - get key => _getKey(); - get value => _getValue(); - set value(value) => _setValue(value); - - static _WeakProperty _new(key, value) native "WeakProperty_new"; - - _getKey() native "WeakProperty_getKey"; - _getValue() native "WeakProperty_getValue"; - _setValue(value) native "WeakProperty_setValue"; -} diff --git a/sdk_nnbd/lib/async/async.dart b/sdk_nnbd/lib/async/async.dart deleted file mode 100644 index 8cce95923bf..00000000000 --- a/sdk_nnbd/lib/async/async.dart +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright (c) 2012, 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. - -/** - * Support for asynchronous programming, - * with classes such as Future and Stream. - * - * Understanding [Future]s and [Stream]s is a prerequisite for - * writing just about any Dart program. - * - * To use this library in your code: - * - * import 'dart:async'; - * - * ## Future - * - * A Future object represents a computation whose return value - * might not yet be available. - * The Future returns the value of the computation - * when it completes at some time in the future. - * Futures are often used for potentially lengthy computations - * such as I/O and interaction with users. - * - * Many methods in the Dart libraries return Futures when - * performing tasks. For example, when binding an HttpServer - * to a host and port, the `bind()` method returns a Future. - * - * HttpServer.bind('127.0.0.1', 4444) - * .then((server) => print('${server.isBroadcast}')) - * .catchError(print); - * - * [Future.then] registers a callback function that runs - * when the Future's operation, in this case the `bind()` method, - * completes successfully. - * The value returned by the operation - * is passed into the callback function. - * In this example, the `bind()` method returns the HttpServer - * object. The callback function prints one of its properties. - * [Future.catchError] registers a callback function that - * runs if an error occurs within the Future. - * - * ## Stream - * - * A Stream provides an asynchronous sequence of data. - * Examples of data sequences include individual events, like mouse clicks, - * or sequential chunks of larger data, like multiple byte lists with the - * contents of a file - * such as mouse clicks, and a stream of byte lists read from a file. - * The following example opens a file for reading. - * [Stream.listen] registers a callback function that runs - * each time more data is available. - * - * Stream> stream = new File('quotes.txt').openRead(); - * stream.transform(utf8.decoder).listen(print); - * - * The stream emits a sequence of a list of bytes. - * The program must interpret the bytes or handle the raw byte data. - * Here, the code uses a UTF-8 decoder (provided in the `dart:convert` library) - * to convert the sequence of bytes into a sequence - * of Dart strings. - * - * Another common use of streams is for user-generated events - * in a web app: The following code listens for mouse clicks on a button. - * - * querySelector('#myButton').onClick.listen((_) => print('Click.')); - * - * ## Other resources - * - * * The [dart:async section of the library tour][asynchronous-programming]: - * A brief overview of asynchronous programming. - * - * * [Use Future-Based APIs][futures-tutorial]: A closer look at Futures and - * how to use them to write asynchronous Dart code. - * - * * [Futures and Error Handling][futures-error-handling]: Everything you - * wanted to know about handling errors and exceptions when working with - * Futures (but were afraid to ask). - * - * * [The Event Loop and Dart](https://www.dartlang.org/articles/event-loop/): - * Learn how Dart handles the event queue and microtask queue, so you can - * write better asynchronous code with fewer surprises. - * - * * [test package: Asynchronous Tests][test-readme]: How to test asynchronous - * code. - * - * [asynchronous-programming]: https://www.dartlang.org/docs/dart-up-and-running/ch03.html#dartasync---asynchronous-programming - * [futures-tutorial]: https://www.dartlang.org/docs/tutorials/futures/ - * [futures-error-handling]: https://www.dartlang.org/articles/futures-and-error-handling/ - * [test-readme]: https://pub.dev/packages/test - * - * {@category Core} - */ -library dart.async; - -import "dart:collection" show HashMap; -import "dart:_internal" - show - CastStream, - CastStreamTransformer, - EmptyIterator, - IterableElementError, - printToZone, - printToConsole, - Since, - typeAcceptsNull; - -part 'async_error.dart'; -part 'broadcast_stream_controller.dart'; -part 'deferred_load.dart'; -part 'future.dart'; -part 'future_impl.dart'; -part 'schedule_microtask.dart'; -part 'stream.dart'; -part 'stream_controller.dart'; -part 'stream_impl.dart'; -part 'stream_pipe.dart'; -part 'stream_transformers.dart'; -part 'timer.dart'; -part 'zone.dart'; diff --git a/sdk_nnbd/lib/async/async_error.dart b/sdk_nnbd/lib/async/async_error.dart deleted file mode 100644 index a7172bde6a5..00000000000 --- a/sdk_nnbd/lib/async/async_error.dart +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) 2012, 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. - -part of dart.async; - -_invokeErrorHandler( - Function errorHandler, Object error, StackTrace stackTrace) { - var handler = errorHandler; // Rename to avoid promotion. - if (handler is ZoneBinaryCallback) { - // Dynamic invocation because we don't know the actual type of the - // first argument or the error object, but we should successfully call - // the handler if they match up. - return errorHandler(error, stackTrace); - } else { - return errorHandler(error); - } -} diff --git a/sdk_nnbd/lib/async/async_sources.gni b/sdk_nnbd/lib/async/async_sources.gni deleted file mode 100644 index 3299cd40500..00000000000 --- a/sdk_nnbd/lib/async/async_sources.gni +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright (c) 2017, 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. - -# This file contains all sources for the dart:async library. -async_sdk_sources = [ - "async.dart", - - # The above file needs to be first as it lists the parts below. - "async_error.dart", - "broadcast_stream_controller.dart", - "deferred_load.dart", - "future.dart", - "future_impl.dart", - "schedule_microtask.dart", - "stream.dart", - "stream_controller.dart", - "stream_impl.dart", - "stream_pipe.dart", - "stream_transformers.dart", - "timer.dart", - "zone.dart", -] diff --git a/sdk_nnbd/lib/async/broadcast_stream_controller.dart b/sdk_nnbd/lib/async/broadcast_stream_controller.dart deleted file mode 100644 index c362eeabe06..00000000000 --- a/sdk_nnbd/lib/async/broadcast_stream_controller.dart +++ /dev/null @@ -1,528 +0,0 @@ -// Copyright (c) 2012, 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. - -part of dart.async; - -class _BroadcastStream extends _ControllerStream { - _BroadcastStream(_StreamControllerLifecycle controller) - : super(controller); - - bool get isBroadcast => true; -} - -class _BroadcastSubscription extends _ControllerSubscription { - static const int _STATE_EVENT_ID = 1; - static const int _STATE_FIRING = 2; - static const int _STATE_REMOVE_AFTER_FIRING = 4; - // TODO(lrn): Use the _state field on _ControllerSubscription to - // also store this state. Requires that the subscription implementation - // does not assume that it's use of the state integer is the only use. - int _eventState = 0; // Initialized to help dart2js type inference. - - _BroadcastSubscription? _next; - _BroadcastSubscription? _previous; - - _BroadcastSubscription( - _StreamControllerLifecycle controller, - void onData(T data)?, - Function? onError, - void onDone()?, - bool cancelOnError) - : super(controller, onData, onError, onDone, cancelOnError) { - _next = _previous = this; - } - - bool _expectsEvent(int eventId) => (_eventState & _STATE_EVENT_ID) == eventId; - - void _toggleEventId() { - _eventState ^= _STATE_EVENT_ID; - } - - bool get _isFiring => (_eventState & _STATE_FIRING) != 0; - - void _setRemoveAfterFiring() { - assert(_isFiring); - _eventState |= _STATE_REMOVE_AFTER_FIRING; - } - - bool get _removeAfterFiring => - (_eventState & _STATE_REMOVE_AFTER_FIRING) != 0; - - // The controller._recordPause doesn't do anything for a broadcast controller, - // so we don't bother calling it. - void _onPause() {} - - // The controller._recordResume doesn't do anything for a broadcast - // controller, so we don't bother calling it. - void _onResume() {} - - // _onCancel is inherited. -} - -abstract class _BroadcastStreamController - implements _StreamControllerBase { - static const int _STATE_INITIAL = 0; - static const int _STATE_EVENT_ID = 1; - static const int _STATE_FIRING = 2; - static const int _STATE_CLOSED = 4; - static const int _STATE_ADDSTREAM = 8; - - void Function()? onListen; - FutureOr Function()? onCancel; - - // State of the controller. - int _state; - - // Double-linked list of active listeners. - _BroadcastSubscription? _firstSubscription; - _BroadcastSubscription? _lastSubscription; - - // Extra state used during an [addStream] call. - _AddStreamState? _addStreamState; - - /** - * Future returned by [close] and [done]. - * - * The future is completed whenever the done event has been sent to all - * relevant listeners. - * The relevant listeners are the ones that were listening when [close] was - * called. When all of these have been canceled (sending the done event makes - * them cancel, but they can also be canceled before sending the event), - * this future completes. - * - * Any attempt to listen after calling [close] will throw, so there won't - * be any further listeners. - */ - _Future? _doneFuture; - - _BroadcastStreamController(this.onListen, this.onCancel) - : _state = _STATE_INITIAL; - - void Function() get onPause { - throw new UnsupportedError( - "Broadcast stream controllers do not support pause callbacks"); - } - - void set onPause(void onPauseHandler()?) { - throw new UnsupportedError( - "Broadcast stream controllers do not support pause callbacks"); - } - - void Function() get onResume { - throw new UnsupportedError( - "Broadcast stream controllers do not support pause callbacks"); - } - - void set onResume(void onResumeHandler()?) { - throw new UnsupportedError( - "Broadcast stream controllers do not support pause callbacks"); - } - - // StreamController interface. - - Stream get stream => new _BroadcastStream(this); - - StreamSink get sink => new _StreamSinkWrapper(this); - - bool get isClosed => (_state & _STATE_CLOSED) != 0; - - /** - * A broadcast controller is never paused. - * - * Each receiving stream may be paused individually, and they handle their - * own buffering. - */ - bool get isPaused => false; - - /** Whether there are currently one or more subscribers. */ - bool get hasListener => !_isEmpty; - - /** - * Test whether the stream has exactly one listener. - * - * Assumes that the stream has a listener (not [_isEmpty]). - */ - bool get _hasOneListener { - assert(!_isEmpty); - return identical(_firstSubscription, _lastSubscription); - } - - /** Whether an event is being fired (sent to some, but not all, listeners). */ - bool get _isFiring => (_state & _STATE_FIRING) != 0; - - bool get _isAddingStream => (_state & _STATE_ADDSTREAM) != 0; - - bool get _mayAddEvent => (_state < _STATE_CLOSED); - - _Future _ensureDoneFuture() => _doneFuture ??= _Future(); - - // Linked list helpers - - bool get _isEmpty => _firstSubscription == null; - - /** Adds subscription to linked list of active listeners. */ - void _addListener(_BroadcastSubscription subscription) { - assert(identical(subscription._next, subscription)); - subscription._eventState = (_state & _STATE_EVENT_ID); - // Insert in linked list as last subscription. - _BroadcastSubscription? oldLast = _lastSubscription; - _lastSubscription = subscription; - subscription._next = null; - subscription._previous = oldLast; - if (oldLast == null) { - _firstSubscription = subscription; - } else { - oldLast._next = subscription; - } - } - - void _removeListener(_BroadcastSubscription subscription) { - assert(identical(subscription._controller, this)); - assert(!identical(subscription._next, subscription)); - _BroadcastSubscription? previous = subscription._previous; - _BroadcastSubscription? next = subscription._next; - if (previous == null) { - // This was the first subscription. - _firstSubscription = next; - } else { - previous._next = next; - } - if (next == null) { - // This was the last subscription. - _lastSubscription = previous; - } else { - next._previous = previous; - } - - subscription._next = subscription._previous = subscription; - } - - // _StreamControllerLifecycle interface. - - StreamSubscription _subscribe(void onData(T data)?, Function? onError, - void onDone()?, bool cancelOnError) { - if (isClosed) { - return new _DoneStreamSubscription(onDone); - } - var subscription = new _BroadcastSubscription( - this, onData, onError, onDone, cancelOnError); - _addListener(subscription); - if (identical(_firstSubscription, _lastSubscription)) { - // Only one listener, so it must be the first listener. - _runGuarded(onListen); - } - return subscription; - } - - Future? _recordCancel(StreamSubscription sub) { - _BroadcastSubscription subscription = sub as _BroadcastSubscription; - // If already removed by the stream, don't remove it again. - if (identical(subscription._next, subscription)) return null; - if (subscription._isFiring) { - subscription._setRemoveAfterFiring(); - } else { - _removeListener(subscription); - // If we are currently firing an event, the empty-check is performed at - // the end of the listener loop instead of here. - if (!_isFiring && _isEmpty) { - _callOnCancel(); - } - } - return null; - } - - void _recordPause(StreamSubscription subscription) {} - void _recordResume(StreamSubscription subscription) {} - - // EventSink interface. - - Error _addEventError() { - if (isClosed) { - return new StateError("Cannot add new events after calling close"); - } - assert(_isAddingStream); - return new StateError("Cannot add new events while doing an addStream"); - } - - void add(T data) { - if (!_mayAddEvent) throw _addEventError(); - _sendData(data); - } - - void addError(Object error, [StackTrace? stackTrace]) { - // TODO(40614): Remove once non-nullability is sound. - ArgumentError.checkNotNull(error, "error"); - if (!_mayAddEvent) throw _addEventError(); - AsyncError? replacement = Zone.current.errorCallback(error, stackTrace); - if (replacement != null) { - error = replacement.error; - stackTrace = replacement.stackTrace; - } else { - stackTrace ??= AsyncError.defaultStackTrace(error); - } - if (stackTrace == null) throw "unreachable"; // TODO(40088) - _sendError(error, stackTrace); - } - - Future close() { - if (isClosed) { - assert(_doneFuture != null); - return _doneFuture!; - } - if (!_mayAddEvent) throw _addEventError(); - _state |= _STATE_CLOSED; - Future doneFuture = _ensureDoneFuture(); - _sendDone(); - return doneFuture; - } - - Future get done => _ensureDoneFuture(); - - Future addStream(Stream stream, {bool? cancelOnError}) { - if (!_mayAddEvent) throw _addEventError(); - _state |= _STATE_ADDSTREAM; - var addStreamState = - new _AddStreamState(this, stream, cancelOnError ?? false); - _addStreamState = addStreamState; - return addStreamState.addStreamFuture; - } - - // _EventSink interface, called from AddStreamState. - void _add(T data) { - _sendData(data); - } - - void _addError(Object error, StackTrace stackTrace) { - _sendError(error, stackTrace); - } - - void _close() { - assert(_isAddingStream); - _AddStreamState addState = _addStreamState!; - _addStreamState = null; - _state &= ~_STATE_ADDSTREAM; - addState.complete(); - } - - // Event handling. - void _forEachListener( - void action(_BufferingStreamSubscription subscription)) { - if (_isFiring) { - throw new StateError( - "Cannot fire new event. Controller is already firing an event"); - } - if (_isEmpty) return; - - // Get event id of this event. - int id = (_state & _STATE_EVENT_ID); - // Start firing (set the _STATE_FIRING bit). We don't do [onCancel] - // callbacks while firing, and we prevent reentrancy of this function. - // - // Set [_state]'s event id to the next event's id. - // Any listeners added while firing this event will expect the next event, - // not this one, and won't get notified. - _state ^= _STATE_EVENT_ID | _STATE_FIRING; - _BroadcastSubscription? subscription = _firstSubscription; - while (subscription != null) { - if (subscription._expectsEvent(id)) { - subscription._eventState |= _BroadcastSubscription._STATE_FIRING; - action(subscription); - subscription._toggleEventId(); - _BroadcastSubscription? next = subscription._next; - if (subscription._removeAfterFiring) { - _removeListener(subscription); - } - subscription._eventState &= ~_BroadcastSubscription._STATE_FIRING; - subscription = next; - } else { - subscription = subscription._next; - } - } - _state &= ~_STATE_FIRING; - - if (_isEmpty) { - _callOnCancel(); - } - } - - void _callOnCancel() { - assert(_isEmpty); - if (isClosed) { - // When closed, _doneFuture is not null. - var doneFuture = _doneFuture!; - if (doneFuture._mayComplete) { - doneFuture._asyncComplete(null); - } - } - _runGuarded(onCancel); - } -} - -class _SyncBroadcastStreamController extends _BroadcastStreamController - implements SynchronousStreamController { - _SyncBroadcastStreamController(void onListen()?, void onCancel()?) - : super(onListen, onCancel); - - // EventDispatch interface. - - bool get _mayAddEvent => super._mayAddEvent && !_isFiring; - - _addEventError() { - if (_isFiring) { - return new StateError( - "Cannot fire new event. Controller is already firing an event"); - } - return super._addEventError(); - } - - void _sendData(T data) { - if (_isEmpty) return; - if (_hasOneListener) { - _state |= _BroadcastStreamController._STATE_FIRING; - _BroadcastSubscription firstSubscription = - _firstSubscription as dynamic; - firstSubscription._add(data); - _state &= ~_BroadcastStreamController._STATE_FIRING; - if (_isEmpty) { - _callOnCancel(); - } - return; - } - _forEachListener((_BufferingStreamSubscription subscription) { - subscription._add(data); - }); - } - - void _sendError(Object error, StackTrace stackTrace) { - if (_isEmpty) return; - _forEachListener((_BufferingStreamSubscription subscription) { - subscription._addError(error, stackTrace); - }); - } - - void _sendDone() { - if (!_isEmpty) { - _forEachListener((_BufferingStreamSubscription subscription) { - subscription._close(); - }); - } else { - assert(_doneFuture != null && _doneFuture!._mayComplete); - _doneFuture!._asyncComplete(null); - } - } -} - -class _AsyncBroadcastStreamController extends _BroadcastStreamController { - _AsyncBroadcastStreamController(void onListen()?, void onCancel()?) - : super(onListen, onCancel); - - // EventDispatch interface. - - void _sendData(T data) { - for (var subscription = _firstSubscription; - subscription != null; - subscription = subscription._next) { - subscription._addPending(new _DelayedData(data)); - } - } - - void _sendError(Object error, StackTrace stackTrace) { - for (var subscription = _firstSubscription; - subscription != null; - subscription = subscription._next) { - subscription._addPending(new _DelayedError(error, stackTrace)); - } - } - - void _sendDone() { - if (!_isEmpty) { - for (var subscription = _firstSubscription; - subscription != null; - subscription = subscription._next) { - subscription._addPending(const _DelayedDone()); - } - } else { - assert(_doneFuture != null && _doneFuture!._mayComplete); - _doneFuture!._asyncComplete(null); - } - } -} - -/** - * Stream controller that is used by [Stream.asBroadcastStream]. - * - * This stream controller allows incoming events while it is firing - * other events. This is handled by delaying the events until the - * current event is done firing, and then fire the pending events. - * - * This class extends [_SyncBroadcastStreamController]. Events of - * an "asBroadcastStream" stream are always initiated by events - * on another stream, and it is fine to forward them synchronously. - */ -class _AsBroadcastStreamController extends _SyncBroadcastStreamController - implements _EventDispatch { - _StreamImplEvents? _pending; - - _AsBroadcastStreamController(void onListen()?, void onCancel()?) - : super(onListen, onCancel); - - bool get _hasPending { - var pending = _pending; - return pending != null && !pending.isEmpty; - } - - void _addPendingEvent(_DelayedEvent event) { - (_pending ??= new _StreamImplEvents()).add(event); - } - - void add(T data) { - if (!isClosed && _isFiring) { - _addPendingEvent(new _DelayedData(data)); - return; - } - super.add(data); - _flushPending(); - } - - void addError(Object error, [StackTrace? stackTrace]) { - // TODO(40614): Remove once non-nullability is sound. - ArgumentError.checkNotNull(error, "error"); - stackTrace ??= AsyncError.defaultStackTrace(error); - if (!isClosed && _isFiring) { - _addPendingEvent(new _DelayedError(error, stackTrace)); - return; - } - if (!_mayAddEvent) throw _addEventError(); - _sendError(error, stackTrace); - _flushPending(); - } - - void _flushPending() { - var pending = _pending; - while (pending != null && !pending.isEmpty) { - pending.handleNext(this); - pending = _pending; - } - } - - Future close() { - if (!isClosed && _isFiring) { - _addPendingEvent(const _DelayedDone()); - _state |= _BroadcastStreamController._STATE_CLOSED; - return super.done; - } - Future result = super.close(); - assert(!_hasPending); - return result; - } - - void _callOnCancel() { - var pending = _pending; - if (pending != null) { - pending.clear(); - _pending = null; - } - super._callOnCancel(); - } -} diff --git a/sdk_nnbd/lib/async/deferred_load.dart b/sdk_nnbd/lib/async/deferred_load.dart deleted file mode 100644 index 419db5863cc..00000000000 --- a/sdk_nnbd/lib/async/deferred_load.dart +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) 2013, 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. - -part of dart.async; - -/** - * Indicates that loading of [libraryName] is deferred. - * - * This class is obsolete. Instead use the syntax: - * import "library.dart" deferred as prefix; - */ -@Deprecated("Dart sdk v. 1.8") -class DeferredLibrary { - final String libraryName; - final String? uri; - - const DeferredLibrary(this.libraryName, {this.uri}); - - /** - * Ensure that [libraryName] has been loaded. - * - * If the library fails to load, the Future will complete with a - * DeferredLoadException. - */ - external Future load(); -} - -/** - * Thrown when a deferred library fails to load. - */ -class DeferredLoadException implements Exception { - DeferredLoadException(String message) : _s = message; - String toString() => "DeferredLoadException: '$_s'"; - final String _s; -} diff --git a/sdk_nnbd/lib/async/future.dart b/sdk_nnbd/lib/async/future.dart deleted file mode 100644 index 6449304df41..00000000000 --- a/sdk_nnbd/lib/async/future.dart +++ /dev/null @@ -1,952 +0,0 @@ -// Copyright (c) 2012, 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. - -part of dart.async; - -/// A type representing values that are either `Future` or `T`. -/// -/// This class declaration is a public stand-in for an internal -/// future-or-value generic type. References to this class are resolved to the -/// internal type. -/// -/// It is a compile-time error for any class to extend, mix in or implement -/// `FutureOr`. -/// -/// # Examples -/// ``` dart -/// // The `Future.then` function takes a callback [f] that returns either -/// // an `S` or a `Future`. -/// Future then(FutureOr f(T x), ...); -/// -/// // `Completer.complete` takes either a `T` or `Future`. -/// void complete(FutureOr value); -/// ``` -/// -/// # Advanced -/// The `FutureOr` type is actually the "type union" of the types `int` and -/// `Future`. This type union is defined in such a way that -/// `FutureOr` is both a super- and sub-type of `Object` (sub-type -/// because `Object` is one of the types of the union, super-type because -/// `Object` is a super-type of both of the types of the union). Together it -/// means that `FutureOr` is equivalent to `Object`. -/// -/// As a corollary, `FutureOr` is equivalent to -/// `FutureOr>`, `FutureOr>` is equivalent to -/// `Future`. -@pragma("vm:entry-point") -abstract class FutureOr { - // Private generative constructor, so that it is not subclassable, mixable, or - // instantiable. - FutureOr._() { - throw new UnsupportedError("FutureOr can't be instantiated"); - } -} - -/** - * An object representing a delayed computation. - * - * A [Future] is used to represent a potential value, or error, - * that will be available at some time in the future. - * Receivers of a [Future] can register callbacks - * that handle the value or error once it is available. - * For example: - * - * Future future = getFuture(); - * future.then((value) => handleValue(value)) - * .catchError((error) => handleError(error)); - * - * A [Future] can be completed in two ways: - * with a value ("the future succeeds") - * or with an error ("the future fails"). - * Users can install callbacks for each case. - * - * In some cases we say that a future is completed with another future. - * This is a short way of stating that the future is completed in the same way, - * with the same value or error, - * as the other future once that completes. - * Whenever a function in the core library may complete a future - * (for example [Completer.complete] or [new Future.value]), - * then it also accepts another future and does this work for the developer. - * - * The result of registering a pair of callbacks is a new Future (the - * "successor") which in turn is completed with the result of invoking the - * corresponding callback. - * The successor is completed with an error if the invoked callback throws. - * For example: - * ``` - * Future successor = future.then((int value) { - * // Invoked when the future is completed with a value. - * return 42; // The successor is completed with the value 42. - * }, - * onError: (e) { - * // Invoked when the future is completed with an error. - * if (canHandle(e)) { - * return 499; // The successor is completed with the value 499. - * } else { - * throw e; // The successor is completed with the error e. - * } - * }); - * ``` - * - * If a future does not have a successor when it completes with an error, - * it forwards the error message to the global error-handler. - * This behavior makes sure that no error is silently dropped. - * However, it also means that error handlers should be installed early, - * so that they are present as soon as a future is completed with an error. - * The following example demonstrates this potential bug: - * ``` - * var future = getFuture(); - * new Timer(new Duration(milliseconds: 5), () { - * // The error-handler is not attached until 5 ms after the future has - * // been received. If the future fails before that, the error is - * // forwarded to the global error-handler, even though there is code - * // (just below) to eventually handle the error. - * future.then((value) { useValue(value); }, - * onError: (e) { handleError(e); }); - * }); - * ``` - * - * When registering callbacks, it's often more readable to register the two - * callbacks separately, by first using [then] with one argument - * (the value handler) and using a second [catchError] for handling errors. - * Each of these will forward the result that they don't handle - * to their successors, and together they handle both value and error result. - * It also has the additional benefit of the [catchError] handling errors in the - * [then] value callback too. - * Using sequential handlers instead of parallel ones often leads to code that - * is easier to reason about. - * It also makes asynchronous code very similar to synchronous code: - * ``` - * // Synchronous code. - * try { - * int value = foo(); - * return bar(value); - * } catch (e) { - * return 499; - * } - * ``` - * - * Equivalent asynchronous code, based on futures: - * ``` - * Future future = new Future(foo); // Result of foo() as a future. - * future.then((int value) => bar(value)) - * .catchError((e) => 499); - * ``` - * - * Similar to the synchronous code, the error handler (registered with - * [catchError]) is handling any errors thrown by either `foo` or `bar`. - * If the error-handler had been registered as the `onError` parameter of - * the `then` call, it would not catch errors from the `bar` call. - * - * Futures can have more than one callback-pair registered. Each successor is - * treated independently and is handled as if it was the only successor. - * - * A future may also fail to ever complete. In that case, no callbacks are - * called. - */ -abstract class Future { - /// A `Future` completed with `null`. - static final _Future _nullFuture = - new _Future.zoneValue(null, _rootZone); - - /// A `Future` completed with `false`. - static final _Future _falseFuture = - new _Future.zoneValue(false, _rootZone); - - /** - * Creates a future containing the result of calling [computation] - * asynchronously with [Timer.run]. - * - * If the result of executing [computation] throws, the returned future is - * completed with the error. - * - * If the returned value is itself a [Future], completion of - * the created future will wait until the returned future completes, - * and will then complete with the same result. - * - * If a non-future value is returned, the returned future is completed - * with that value. - */ - factory Future(FutureOr computation()) { - _Future result = new _Future(); - Timer.run(() { - try { - result._complete(computation()); - } catch (e, s) { - _completeWithErrorCallback(result, e, s); - } - }); - return result; - } - - /** - * Creates a future containing the result of calling [computation] - * asynchronously with [scheduleMicrotask]. - * - * If executing [computation] throws, - * the returned future is completed with the thrown error. - * - * If calling [computation] returns a [Future], completion of - * the created future will wait until the returned future completes, - * and will then complete with the same result. - * - * If calling [computation] returns a non-future value, - * the returned future is completed with that value. - */ - factory Future.microtask(FutureOr computation()) { - _Future result = new _Future(); - scheduleMicrotask(() { - try { - result._complete(computation()); - } catch (e, s) { - _completeWithErrorCallback(result, e, s); - } - }); - return result; - } - - /** - * Returns a future containing the result of immediately calling - * [computation]. - * - * If calling [computation] throws, the returned future is completed with the - * error. - * - * If calling [computation] returns a `Future`, that future is returned. - * - * If calling [computation] returns a non-future value, - * a future is returned which has been completed with that value. - */ - factory Future.sync(FutureOr computation()) { - try { - var result = computation(); - if (result is Future) { - return result; - } else { - // TODO(40014): Remove cast when type promotion works. - return new _Future.value(result as dynamic); - } - } catch (error, stackTrace) { - var future = new _Future(); - AsyncError? replacement = Zone.current.errorCallback(error, stackTrace); - if (replacement != null) { - future._asyncCompleteError(replacement.error, replacement.stackTrace); - } else { - future._asyncCompleteError(error, stackTrace); - } - return future; - } - } - - /** - * Creates a future completed with [value]. - * - * If [value] is a future, the created future waits for the - * [value] future to complete, and then completes with the same result. - * Since a [value] future can complete with an error, so can the future - * created by [Future.value], even if the name suggests otherwise. - * - * If [value] is not a [Future], the created future is completed - * with the [value] value, - * equivalently to `new Future.sync(() => value)`. - * - * If [value] is omitted or `null`, it is converted to `FutureOr` by - * `value as FutureOr`. If `T` is not nullable, then the [value] is - * required, otherwise the construction throws. - * - * Use [Completer] to create a future and complete it later. - */ - @pragma("vm:entry-point") - factory Future.value([FutureOr? value]) { - return new _Future.immediate(value == null ? value as dynamic : value); - } - - /** - * Creates a future that completes with an error. - * - * The created future will be completed with an error in a future microtask. - * This allows enough time for someone to add an error handler on the future. - * If an error handler isn't added before the future completes, the error - * will be considered unhandled. - * - * Use [Completer] to create a future and complete it later. - */ - factory Future.error(Object error, [StackTrace? stackTrace]) { - // TODO(40614): Remove once non-nullability is sound. - ArgumentError.checkNotNull(error, "error"); - if (!identical(Zone.current, _rootZone)) { - AsyncError? replacement = Zone.current.errorCallback(error, stackTrace); - if (replacement != null) { - error = replacement.error; - stackTrace = replacement.stackTrace; - } - } - stackTrace ??= AsyncError.defaultStackTrace(error); - return new _Future.immediateError(error, stackTrace); - } - - /** - * Creates a future that runs its computation after a delay. - * - * The [computation] will be executed after the given [duration] has passed, - * and the future is completed with the result of the computation. - * - * If [computation] returns a future, - * the future returned by this constructor will complete with the value or - * error of that future. - * - * If the duration is 0 or less, - * it completes no sooner than in the next event-loop iteration, - * after all microtasks have run. - * - * If [computation] is omitted, - * it will be treated as if [computation] was `() => null`, - * and the future will eventually complete with the `null` value. - * In that case, [T] must be nullable. - * - * If calling [computation] throws, the created future will complete with the - * error. - * - * See also [Completer] for a way to create and complete a future at a - * later time that isn't necessarily after a known fixed duration. - */ - factory Future.delayed(Duration duration, [FutureOr computation()?]) { - if (computation == null && !typeAcceptsNull()) { - throw ArgumentError.value( - null, "computation", "The type parameter is not nullable"); - } - _Future result = new _Future(); - new Timer(duration, () { - if (computation == null) { - result._complete(null as T); - } else { - try { - result._complete(computation()); - } catch (e, s) { - _completeWithErrorCallback(result, e, s); - } - } - }); - return result; - } - - /** - * Waits for multiple futures to complete and collects their results. - * - * Returns a future which will complete once all the provided futures - * have completed, either with their results, or with an error if any - * of the provided futures fail. - * - * The value of the returned future will be a list of all the values that - * were produced in the order that the futures are provided by iterating - * [futures]. - * - * If any future completes with an error, - * then the returned future completes with that error. - * If further futures also complete with errors, those errors are discarded. - * - * If `eagerError` is true, the returned future completes with an error - * immediately on the first error from one of the futures. Otherwise all - * futures must complete before the returned future is completed (still with - * the first error; the remaining errors are silently dropped). - * - * In the case of an error, [cleanUp] (if provided), is invoked on any - * non-null result of successful futures. - * This makes it possible to `cleanUp` resources that would otherwise be - * lost (since the returned future does not provide access to these values). - * The [cleanUp] function is unused if there is no error. - * - * The call to [cleanUp] should not throw. If it does, the error will be an - * uncaught asynchronous error. - */ - static Future> wait(Iterable> futures, - {bool eagerError = false, void cleanUp(T successValue)?}) { - final _Future> result = new _Future>(); - List? values; // Collects the values. Set to null on error. - int remaining = 0; // How many futures are we waiting for. - late Object error; // The first error from a future. - late StackTrace stackTrace; // The stackTrace that came with the error. - - // Handle an error from any of the futures. - void handleError(Object theError, StackTrace theStackTrace) { - remaining--; - List? valueList = values; - if (valueList != null) { - if (cleanUp != null) { - for (var value in valueList) { - if (value != null) { - // Ensure errors from cleanUp are uncaught. - T cleanUpValue = value; - new Future.sync(() { - cleanUp(cleanUpValue); - }); - } - } - } - values = null; - if (remaining == 0 || eagerError) { - result._completeError(theError, theStackTrace); - } else { - error = theError; - stackTrace = theStackTrace; - } - } else if (remaining == 0 && !eagerError) { - result._completeError(error, stackTrace); - } - } - - try { - // As each future completes, put its value into the corresponding - // position in the list of values. - for (var future in futures) { - int pos = remaining; - future.then((T value) { - remaining--; - List? valueList = values; - if (valueList != null) { - valueList[pos] = value; - if (remaining == 0) { - result._completeWithValue(List.from(valueList)); - } - } else { - if (cleanUp != null && value != null) { - // Ensure errors from cleanUp are uncaught. - new Future.sync(() { - cleanUp(value); - }); - } - if (remaining == 0 && !eagerError) { - // If eagerError is false, and valueList is null, then - // error and stackTrace have been set in handleError above. - result._completeError(error, stackTrace); - } - } - }, onError: handleError); - // Increment the 'remaining' after the call to 'then'. - // If that call throws, we don't expect any future callback from - // the future, and we also don't increment remaining. - remaining++; - } - if (remaining == 0) { - return new Future>.value(const []); - } - values = new List.filled(remaining, null); - } catch (e, st) { - // The error must have been thrown while iterating over the futures - // list, or while installing a callback handler on the future. - // This is a breach of the `Future` protocol, but we try to handle it - // gracefully. - if (remaining == 0 || eagerError) { - // Throw a new Future.error. - // Don't just call `result._completeError` since that would propagate - // the error too eagerly, not giving the callers time to install - // error handlers. - // Also, don't use `_asyncCompleteError` since that one doesn't give - // zones the chance to intercept the error. - return new Future.error(e, st); - } else { - // Don't allocate a list for values, thus indicating that there was an - // error. - // Set error to the caught exception. - error = e; - stackTrace = st; - } - } - return result; - } - - /** - * Returns the result of the first future in [futures] to complete. - * - * The returned future is completed with the result of the first - * future in [futures] to report that it is complete, - * whether it's with a value or an error. - * The results of all the other futures are discarded. - * - * If [futures] is empty, or if none of its futures complete, - * the returned future never completes. - */ - static Future any(Iterable> futures) { - var completer = new Completer.sync(); - void onValue(T value) { - if (!completer.isCompleted) completer.complete(value); - } - - void onError(Object error, StackTrace stack) { - if (!completer.isCompleted) completer.completeError(error, stack); - } - - for (var future in futures) { - future.then(onValue, onError: onError); - } - return completer.future; - } - - /** - * Performs an action for each element of the iterable, in turn. - * - * The [action] may be either synchronous or asynchronous. - * - * Calls [action] with each element in [elements] in order. - * If the call to [action] returns a `Future`, the iteration waits - * until the future is completed before continuing with the next element. - * - * Returns a [Future] that completes with `null` when all elements have been - * processed. - * - * Non-[Future] return values, and completion-values of returned [Future]s, - * are discarded. - * - * Any error from [action], synchronous or asynchronous, - * will stop the iteration and be reported in the returned [Future]. - */ - static Future forEach(Iterable elements, FutureOr action(T element)) { - var iterator = elements.iterator; - return doWhile(() { - if (!iterator.moveNext()) return false; - var result = action(iterator.current); - if (result is Future) return result.then(_kTrue); - return true; - }); - } - - // Constant `true` function, used as callback by [forEach]. - static bool _kTrue(Object? _) => true; - - /** - * Performs an operation repeatedly until it returns `false`. - * - * The operation, [action], may be either synchronous or asynchronous. - * - * The operation is called repeatedly as long as it returns either the [bool] - * value `true` or a `Future` which completes with the value `true`. - * - * If a call to [action] returns `false` or a [Future] that completes to - * `false`, iteration ends and the future returned by [doWhile] is completed - * with a `null` value. - * - * If a call to [action] throws or a future returned by [action] completes - * with an error, iteration ends and the future returned by [doWhile] - * completes with the same error. - * - * Calls to [action] may happen at any time, - * including immediately after calling `doWhile`. - * The only restriction is a new call to [action] won't happen before - * the previous call has returned, and if it returned a `Future`, not - * until that future has completed. - */ - static Future doWhile(FutureOr action()) { - _Future doneSignal = new _Future(); - late void Function(bool) nextIteration; - // Bind this callback explicitly so that each iteration isn't bound in the - // context of all the previous iterations' callbacks. - // This avoids, e.g., deeply nested stack traces from the stack trace - // package. - nextIteration = Zone.current.bindUnaryCallbackGuarded((bool keepGoing) { - while (keepGoing) { - FutureOr result; - try { - result = action(); - } catch (error, stackTrace) { - // Cannot use _completeWithErrorCallback because it completes - // the future synchronously. - _asyncCompleteWithErrorCallback(doneSignal, error, stackTrace); - return; - } - if (result is Future) { - result.then(nextIteration, onError: doneSignal._completeError); - return; - } - // TODO(40014): Remove cast when type promotion works. - keepGoing = result as bool; - } - doneSignal._complete(null); - }); - nextIteration(true); - return doneSignal; - } - - /** - * Register callbacks to be called when this future completes. - * - * When this future completes with a value, - * the [onValue] callback will be called with that value. - * If this future is already completed, the callback will not be called - * immediately, but will be scheduled in a later microtask. - * - * If [onError] is provided, and this future completes with an error, - * the `onError` callback is called with that error and its stack trace. - * The `onError` callback must accept either one argument or two arguments - * where the latter is a [StackTrace]. - * If `onError` accepts two arguments, - * it is called with both the error and the stack trace, - * otherwise it is called with just the error object. - * The `onError` callback must return a value or future that can be used - * to complete the returned future, so it must be something assignable to - * `FutureOr`. - * - * Returns a new [Future] - * which is completed with the result of the call to `onValue` - * (if this future completes with a value) - * or to `onError` (if this future completes with an error). - * - * If the invoked callback throws, - * the returned future is completed with the thrown error - * and a stack trace for the error. - * In the case of `onError`, - * if the exception thrown is `identical` to the error argument to `onError`, - * the throw is considered a rethrow, - * and the original stack trace is used instead. - * - * If the callback returns a [Future], - * the future returned by `then` will be completed with - * the same result as the future returned by the callback. - * - * If [onError] is not given, and this future completes with an error, - * the error is forwarded directly to the returned future. - * - * In most cases, it is more readable to use [catchError] separately, possibly - * with a `test` parameter, instead of handling both value and error in a - * single [then] call. - * - * Note that futures don't delay reporting of errors until listeners are - * added. If the first `then` or `catchError` call happens after this future - * has completed with an error then the error is reported as unhandled error. - * See the description on [Future]. - */ - Future then(FutureOr onValue(T value), {Function? onError}); - - /** - * Handles errors emitted by this [Future]. - * - * This is the asynchronous equivalent of a "catch" block. - * - * Returns a new [Future] that will be completed with either the result of - * this future or the result of calling the `onError` callback. - * - * If this future completes with a value, - * the returned future completes with the same value. - * - * If this future completes with an error, - * then [test] is first called with the error value. - * - * If `test` returns false, the exception is not handled by this `catchError`, - * and the returned future completes with the same error and stack trace - * as this future. - * - * If `test` returns `true`, - * [onError] is called with the error and possibly stack trace, - * and the returned future is completed with the result of this call - * in exactly the same way as for [then]'s `onError`. - * - * If `test` is omitted, it defaults to a function that always returns true. - * The `test` function should not throw, but if it does, it is handled as - * if the `onError` function had thrown. - * - * Note that futures don't delay reporting of errors until listeners are - * added. If the first `catchError` (or `then`) call happens after this future - * has completed with an error then the error is reported as unhandled error. - * See the description on [Future]. - */ - // The `Function` below stands for one of two types: - // - (dynamic) -> FutureOr - // - (dynamic, StackTrace) -> FutureOr - // Given that there is a `test` function that is usually used to do an - // `isCheck` we should also expect functions that take a specific argument. - Future catchError(Function onError, {bool test(Object error)?}); - - /** - * Registers a function to be called when this future completes. - * - * The [action] function is called when this future completes, whether it - * does so with a value or with an error. - * - * This is the asynchronous equivalent of a "finally" block. - * - * The future returned by this call, `f`, will complete the same way - * as this future unless an error occurs in the [action] call, or in - * a [Future] returned by the [action] call. If the call to [action] - * does not return a future, its return value is ignored. - * - * If the call to [action] throws, then `f` is completed with the - * thrown error. - * - * If the call to [action] returns a [Future], `f2`, then completion of - * `f` is delayed until `f2` completes. If `f2` completes with - * an error, that will be the result of `f` too. The value of `f2` is always - * ignored. - * - * This method is equivalent to: - * - * Future whenComplete(action()) { - * return this.then((v) { - * var f2 = action(); - * if (f2 is Future) return f2.then((_) => v); - * return v - * }, onError: (e) { - * var f2 = action(); - * if (f2 is Future) return f2.then((_) { throw e; }); - * throw e; - * }); - * } - */ - Future whenComplete(FutureOr action()); - - /** - * Creates a [Stream] containing the result of this future. - * - * The stream will produce single data or error event containing the - * completion result of this future, and then it will close with a - * done event. - * - * If the future never completes, the stream will not produce any events. - */ - Stream asStream(); - - /** - * Time-out the future computation after [timeLimit] has passed. - * - * Returns a new future that completes with the same value as this future, - * if this future completes in time. - * - * If this future does not complete before `timeLimit` has passed, - * the [onTimeout] action is executed instead, and its result (whether it - * returns or throws) is used as the result of the returned future. - * The [onTimeout] function must return a [T] or a `Future`. - * - * If `onTimeout` is omitted, a timeout will cause the returned future to - * complete with a [TimeoutException]. - */ - Future timeout(Duration timeLimit, {FutureOr onTimeout()?}); -} - -/** - * Thrown when a scheduled timeout happens while waiting for an async result. - */ -class TimeoutException implements Exception { - /** Description of the cause of the timeout. */ - final String? message; - /** The duration that was exceeded. */ - final Duration? duration; - - TimeoutException(this.message, [this.duration]); - - String toString() { - String result = "TimeoutException"; - if (duration != null) result = "TimeoutException after $duration"; - if (message != null) result = "$result: $message"; - return result; - } -} - -/** - * A way to produce Future objects and to complete them later - * with a value or error. - * - * Most of the time, the simplest way to create a future is to just use - * one of the [Future] constructors to capture the result of a single - * asynchronous computation: - * ``` - * new Future(() { doSomething(); return result; }); - * ``` - * or, if the future represents the result of a sequence of asynchronous - * computations, they can be chained using [Future.then] or similar functions - * on [Future]: - * ``` - * Future doStuff(){ - * return someAsyncOperation().then((result) { - * return someOtherAsyncOperation(result); - * }); - * } - * ``` - * If you do need to create a Future from scratch — for example, - * when you're converting a callback-based API into a Future-based - * one — you can use a Completer as follows: - * ``` - * class AsyncOperation { - * Completer _completer = new Completer(); - * - * Future doOperation() { - * _startOperation(); - * return _completer.future; // Send future object back to client. - * } - * - * // Something calls this when the value is ready. - * void _finishOperation(T result) { - * _completer.complete(result); - * } - * - * // If something goes wrong, call this. - * void _errorHappened(error) { - * _completer.completeError(error); - * } - * } - * ``` - */ -abstract class Completer { - /** - * Creates a new completer. - * - * The general workflow for creating a new future is to 1) create a - * new completer, 2) hand out its future, and, at a later point, 3) invoke - * either [complete] or [completeError]. - * - * The completer completes the future asynchronously. That means that - * callbacks registered on the future are not called immediately when - * [complete] or [completeError] is called. Instead the callbacks are - * delayed until a later microtask. - * - * Example: - * ``` - * var completer = new Completer(); - * handOut(completer.future); - * later: { - * completer.complete('completion value'); - * } - * ``` - */ - factory Completer() => new _AsyncCompleter(); - - /** - * Completes the future synchronously. - * - * This constructor should be avoided unless the completion of the future is - * known to be the final result of another asynchronous operation. If in doubt - * use the default [Completer] constructor. - * - * Using an normal, asynchronous, completer will never give the wrong - * behavior, but using a synchronous completer incorrectly can cause - * otherwise correct programs to break. - * - * A synchronous completer is only intended for optimizing event - * propagation when one asynchronous event immediately triggers another. - * It should not be used unless the calls to [complete] and [completeError] - * are guaranteed to occur in places where it won't break `Future` invariants. - * - * Completing synchronously means that the completer's future will be - * completed immediately when calling the [complete] or [completeError] - * method on a synchronous completer, which also calls any callbacks - * registered on that future. - * - * Completing synchronously must not break the rule that when you add a - * callback on a future, that callback must not be called until the code - * that added the callback has completed. - * For that reason, a synchronous completion must only occur at the very end - * (in "tail position") of another synchronous event, - * because at that point, completing the future immediately is be equivalent - * to returning to the event loop and completing the future in the next - * microtask. - * - * Example: - * - * var completer = new Completer.sync(); - * // The completion is the result of the asynchronous onDone event. - * // No other operation is performed after the completion. It is safe - * // to use the Completer.sync constructor. - * stream.listen(print, onDone: () { completer.complete("done"); }); - * - * Bad example. Do not use this code. Only for illustrative purposes: - * - * var completer = new Completer.sync(); - * completer.future.then((_) { bar(); }); - * // The completion is the result of the asynchronous onDone event. - * // However, there is still code executed after the completion. This - * // operation is *not* safe. - * stream.listen(print, onDone: () { - * completer.complete("done"); - * foo(); // In this case, foo() runs after bar(). - * }); - */ - factory Completer.sync() => new _SyncCompleter(); - - /** - * The future that is completed by this completer. - * - * The future that is completed when [complete] or [completeError] is called. - */ - Future get future; - - /** - * Completes [future] with the supplied values. - * - * The value must be either a value of type [T] - * or a future of type `Future`. - * If the value is omitted or null, and `T` is not nullable, the call - * to `complete` throws. - * - * If the value is itself a future, the completer will wait for that future - * to complete, and complete with the same result, whether it is a success - * or an error. - * - * Calling [complete] or [completeError] must be done at most once. - * - * All listeners on the future are informed about the value. - */ - void complete([FutureOr? value]); - - /** - * Complete [future] with an error. - * - * Calling [complete] or [completeError] must be done at most once. - * - * Completing a future with an error indicates that an exception was thrown - * while trying to produce a value. - * - * If `error` is a `Future`, the future itself is used as the error value. - * If you want to complete with the result of the future, you can use: - * ``` - * thisCompleter.complete(theFuture) - * ``` - * or if you only want to handle an error from the future: - * ``` - * theFuture.catchError(thisCompleter.completeError); - * ``` - */ - void completeError(Object error, [StackTrace? stackTrace]); - - /** - * Whether the [future] has been completed. - * - * Reflects whether [complete] or [completeError] has been called. - * A `true` value doesn't necessarily mean that listeners of this future - * have been invoked yet, either because the completer usually waits until - * a later microtask to propagate the result, or because [complete] - * was called with a future that hasn't completed yet. - * - * When this value is `true`, [complete] and [completeError] must not be - * called again. - */ - bool get isCompleted; -} - -// Helper function completing a _Future with error, but checking the zone -// for error replacement and missing stack trace first. -void _completeWithErrorCallback( - _Future result, Object error, StackTrace? stackTrace) { - AsyncError? replacement = Zone.current.errorCallback(error, stackTrace); - if (replacement != null) { - error = replacement.error; - stackTrace = replacement.stackTrace; - } else { - stackTrace ??= AsyncError.defaultStackTrace(error); - } - if (stackTrace == null) throw "unreachable"; // TODO(40088). - result._completeError(error, stackTrace); -} - -// Like [_completeWithErrorCallback] but completes asynchronously. -void _asyncCompleteWithErrorCallback( - _Future result, Object error, StackTrace? stackTrace) { - AsyncError? replacement = Zone.current.errorCallback(error, stackTrace); - if (replacement != null) { - error = replacement.error; - stackTrace = replacement.stackTrace; - } else { - stackTrace ??= AsyncError.defaultStackTrace(error); - } - if (stackTrace == null) { - throw "unreachable"; // TODO(lrn): Remove when type promotion works. - } - result._asyncCompleteError(error, stackTrace); -} diff --git a/sdk_nnbd/lib/async/future_impl.dart b/sdk_nnbd/lib/async/future_impl.dart deleted file mode 100644 index 3f337371d3d..00000000000 --- a/sdk_nnbd/lib/async/future_impl.dart +++ /dev/null @@ -1,833 +0,0 @@ -// Copyright (c) 2012, 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. - -part of dart.async; - -/** The onValue and onError handlers return either a value or a future */ -typedef FutureOr _FutureOnValue(S value); -/** Test used by [Future.catchError] to handle skip some errors. */ -typedef bool _FutureErrorTest(Object error); -/** Used by [WhenFuture]. */ -typedef dynamic _FutureAction(); - -abstract class _Completer implements Completer { - final _Future future = new _Future(); - - void complete([FutureOr? value]); - - void completeError(Object error, [StackTrace? stackTrace]) { - // TODO(40614): Remove once non-nullability is sound. - ArgumentError.checkNotNull(error, "error"); - if (!future._mayComplete) throw new StateError("Future already completed"); - AsyncError? replacement = Zone.current.errorCallback(error, stackTrace); - if (replacement != null) { - error = replacement.error; - stackTrace = replacement.stackTrace; - } else { - stackTrace ??= AsyncError.defaultStackTrace(error); - } - if (stackTrace == null) throw "unreachable"; // TODO(40088) - _completeError(error, stackTrace); - } - - void _completeError(Object error, StackTrace stackTrace); - - // The future's _isComplete doesn't take into account pending completions. - // We therefore use _mayComplete. - bool get isCompleted => !future._mayComplete; -} - -class _AsyncCompleter extends _Completer { - void complete([FutureOr? value]) { - if (!future._mayComplete) throw new StateError("Future already completed"); - future._asyncComplete(value == null ? value as dynamic : value); - } - - void _completeError(Object error, StackTrace stackTrace) { - future._asyncCompleteError(error, stackTrace); - } -} - -class _SyncCompleter extends _Completer { - void complete([FutureOr? value]) { - if (!future._mayComplete) throw new StateError("Future already completed"); - future._complete(value == null ? value as dynamic : value); - } - - void _completeError(Object error, StackTrace stackTrace) { - future._completeError(error, stackTrace); - } -} - -class _FutureListener { - static const int maskValue = 1; - static const int maskError = 2; - static const int maskTestError = 4; - static const int maskWhencomplete = 8; - static const int stateChain = 0; - static const int stateThen = maskValue; - static const int stateThenOnerror = maskValue | maskError; - static const int stateCatcherror = maskError; - static const int stateCatcherrorTest = maskError | maskTestError; - static const int stateWhencomplete = maskWhencomplete; - static const int maskType = - maskValue | maskError | maskTestError | maskWhencomplete; - static const int stateIsAwait = 16; - // Listeners on the same future are linked through this link. - _FutureListener? _nextListener; - // The future to complete when this listener is activated. - final _Future result; - // Which fields means what. - final int state; - // Used for then/whenDone callback and error test - @pragma("vm:entry-point") - final Function? callback; - // Used for error callbacks. - final Function? errorCallback; - - _FutureListener.then( - this.result, FutureOr Function(S) onValue, Function? errorCallback) - : callback = onValue, - errorCallback = errorCallback, - state = (errorCallback == null) ? stateThen : stateThenOnerror; - - _FutureListener.thenAwait( - this.result, _FutureOnValue onValue, Function errorCallback) - : callback = onValue, - errorCallback = errorCallback, - state = ((errorCallback == null) ? stateThen : stateThenOnerror) | - stateIsAwait; - - _FutureListener.catchError(this.result, this.errorCallback, this.callback) - : state = (callback == null) ? stateCatcherror : stateCatcherrorTest; - - _FutureListener.whenComplete(this.result, this.callback) - : errorCallback = null, - state = stateWhencomplete; - - _Zone get _zone => result._zone; - - bool get handlesValue => (state & maskValue != 0); - bool get handlesError => (state & maskError != 0); - bool get hasErrorTest => (state & maskType == stateCatcherrorTest); - bool get handlesComplete => (state & maskType == stateWhencomplete); - bool get isAwait => (state & stateIsAwait != 0); - - FutureOr Function(S) get _onValue { - assert(handlesValue); - return callback as dynamic; - } - - Function? get _onError => errorCallback; - - _FutureErrorTest get _errorTest { - assert(hasErrorTest); - return callback as dynamic; - } - - _FutureAction get _whenCompleteAction { - assert(handlesComplete); - return callback as dynamic; - } - - /// Whether this listener has an error callback. - /// - /// This function must only be called if the listener [handlesError]. - bool get hasErrorCallback { - assert(handlesError); - return _onError != null; - } - - FutureOr handleValue(S sourceResult) { - return _zone.runUnary, S>(_onValue, sourceResult); - } - - bool matchesErrorTest(AsyncError asyncError) { - if (!hasErrorTest) return true; - return _zone.runUnary(_errorTest, asyncError.error); - } - - FutureOr handleError(AsyncError asyncError) { - assert(handlesError && hasErrorCallback); - var errorCallback = this.errorCallback; // To enable promotion. - // If the errorCallback returns something which is not a FutureOr, - // this return statement throws, and the caller handles the error. - if (errorCallback is dynamic Function(Object, StackTrace)) { - return _zone.runBinary( - errorCallback, asyncError.error, asyncError.stackTrace); - } else { - return _zone.runUnary( - errorCallback as dynamic, asyncError.error); - } - } - - dynamic handleWhenComplete() { - assert(!handlesError); - return _zone.run(_whenCompleteAction); - } -} - -class _Future implements Future { - /// Initial state, waiting for a result. In this state, the - /// [resultOrListeners] field holds a single-linked list of - /// [_FutureListener] listeners. - static const int _stateIncomplete = 0; - - /// Pending completion. Set when completed using [_asyncComplete] or - /// [_asyncCompleteError]. It is an error to try to complete it again. - /// [resultOrListeners] holds listeners. - static const int _statePendingComplete = 1; - - /// The future has been chained to another future. The result of that - /// other future becomes the result of this future as well. - /// [resultOrListeners] contains the source future. - static const int _stateChained = 2; - - /// The future has been completed with a value result. - static const int _stateValue = 4; - - /// The future has been completed with an error result. - static const int _stateError = 8; - - /** Whether the future is complete, and as what. */ - int _state = _stateIncomplete; - - /** - * Zone that the future was completed from. - * This is the zone that an error result belongs to. - * - * Until the future is completed, the field may hold the zone that - * listener callbacks used to create this future should be run in. - */ - final _Zone _zone; - - /** - * Either the result, a list of listeners or another future. - * - * The result of the future is either a value or an error. - * A result is only stored when the future has completed. - * - * The listeners is an internally linked list of [_FutureListener]s. - * Listeners are only remembered while the future is not yet complete, - * and it is not chained to another future. - * - * The future is another future that his future is chained to. This future - * is waiting for the other future to complete, and when it does, this future - * will complete with the same result. - * All listeners are forwarded to the other future. - */ - @pragma("vm:entry-point") - var _resultOrListeners; - - // This constructor is used by async/await. - _Future() : _zone = Zone._current; - - _Future.immediate(FutureOr result) : _zone = Zone._current { - _asyncComplete(result); - } - - /** Creates a future with the value and the specified zone. */ - _Future.zoneValue(T value, this._zone) { - _setValue(value); - } - - _Future.immediateError(var error, StackTrace stackTrace) - : _zone = Zone._current { - _asyncCompleteError(error, stackTrace); - } - - /** Creates a future that is already completed with the value. */ - _Future.value(T value) : this.zoneValue(value, Zone._current); - - bool get _mayComplete => _state == _stateIncomplete; - bool get _isPendingComplete => _state == _statePendingComplete; - bool get _mayAddListener => _state <= _statePendingComplete; - bool get _isChained => _state == _stateChained; - bool get _isComplete => _state >= _stateValue; - bool get _hasError => _state == _stateError; - - static List? _continuationFunctions(_Future future) { - List? result = null; - while (true) { - if (future._mayAddListener) return result; - assert(!future._isComplete); - assert(!future._isChained); - // So _resultOrListeners contains listeners. - _FutureListener? listener = future._resultOrListeners; - if (listener != null && - listener._nextListener == null && - listener.isAwait) { - (result ??= []).add(listener.handleValue); - future = listener.result; - assert(!future._isComplete); - } else { - break; - } - } - return result; - } - - void _setChained(_Future source) { - assert(_mayAddListener); - _state = _stateChained; - _resultOrListeners = source; - } - - Future then(FutureOr f(T value), {Function? onError}) { - Zone currentZone = Zone.current; - if (!identical(currentZone, _rootZone)) { - f = currentZone.registerUnaryCallback, T>(f); - if (onError != null) { - // In checked mode, this checks that onError is assignable to one of: - // dynamic Function(Object) - // dynamic Function(Object, StackTrace) - onError = _registerErrorHandler(onError, currentZone); - } - } - _Future result = new _Future(); - _addListener(new _FutureListener.then(result, f, onError)); - return result; - } - - /// Registers a system created result and error continuation. - /// - /// Used by the implementation of `await` to listen to a future. - /// The system created liseners are not registered in the zone, - /// and the listener is marked as being from an `await`. - /// This marker is used in [_continuationFunctions]. - Future _thenAwait(FutureOr f(T value), Function onError) { - _Future result = new _Future(); - _addListener(new _FutureListener.thenAwait(result, f, onError)); - return result; - } - - Future catchError(Function onError, {bool test(Object error)?}) { - _Future result = new _Future(); - if (!identical(result._zone, _rootZone)) { - onError = _registerErrorHandler(onError, result._zone); - if (test != null) test = result._zone.registerUnaryCallback(test); - } - _addListener(new _FutureListener.catchError(result, onError, test)); - return result; - } - - Future whenComplete(dynamic action()) { - _Future result = new _Future(); - if (!identical(result._zone, _rootZone)) { - action = result._zone.registerCallback(action); - } - _addListener(new _FutureListener.whenComplete(result, action)); - return result; - } - - Stream asStream() => new Stream.fromFuture(this); - - void _setPendingComplete() { - assert(_mayComplete); - _state = _statePendingComplete; - } - - void _clearPendingComplete() { - assert(_isPendingComplete); - _state = _stateIncomplete; - } - - AsyncError get _error { - assert(_hasError); - return _resultOrListeners; - } - - _Future get _chainSource { - assert(_isChained); - return _resultOrListeners; - } - - // This method is used by async/await. - void _setValue(T value) { - assert(!_isComplete); // But may have a completion pending. - _state = _stateValue; - _resultOrListeners = value; - } - - void _setErrorObject(AsyncError error) { - assert(!_isComplete); // But may have a completion pending. - _state = _stateError; - _resultOrListeners = error; - } - - void _setError(Object error, StackTrace stackTrace) { - _setErrorObject(new AsyncError(error, stackTrace)); - } - - /// Copy the completion result of [source] into this future. - /// - /// Used when a chained future notices that its source is completed. - void _cloneResult(_Future source) { - assert(!_isComplete); - assert(source._isComplete); - _state = source._state; - _resultOrListeners = source._resultOrListeners; - } - - void _addListener(_FutureListener listener) { - assert(listener._nextListener == null); - if (_mayAddListener) { - listener._nextListener = _resultOrListeners; - _resultOrListeners = listener; - } else { - if (_isChained) { - // Delegate listeners to chained source future. - // If the source is complete, instead copy its values and - // drop the chaining. - _Future source = _chainSource; - if (!source._isComplete) { - source._addListener(listener); - return; - } - _cloneResult(source); - } - assert(_isComplete); - // Handle late listeners asynchronously. - _zone.scheduleMicrotask(() { - _propagateToListeners(this, listener); - }); - } - } - - void _prependListeners(_FutureListener? listeners) { - if (listeners == null) return; - if (_mayAddListener) { - _FutureListener? existingListeners = _resultOrListeners; - _resultOrListeners = listeners; - if (existingListeners != null) { - _FutureListener cursor = listeners; - _FutureListener? next = cursor._nextListener; - while (next != null) { - cursor = next; - next = cursor._nextListener; - } - cursor._nextListener = existingListeners; - } - } else { - if (_isChained) { - // Delegate listeners to chained source future. - // If the source is complete, instead copy its values and - // drop the chaining. - _Future source = _chainSource; - if (!source._isComplete) { - source._prependListeners(listeners); - return; - } - _cloneResult(source); - } - assert(_isComplete); - listeners = _reverseListeners(listeners); - _zone.scheduleMicrotask(() { - _propagateToListeners(this, listeners); - }); - } - } - - _FutureListener? _removeListeners() { - // Reverse listeners before returning them, so the resulting list is in - // subscription order. - assert(!_isComplete); - _FutureListener? current = _resultOrListeners; - _resultOrListeners = null; - return _reverseListeners(current); - } - - _FutureListener? _reverseListeners(_FutureListener? listeners) { - _FutureListener? prev = null; - _FutureListener? current = listeners; - while (current != null) { - _FutureListener? next = current._nextListener; - current._nextListener = prev; - prev = current; - current = next; - } - return prev; - } - - // Take the value (when completed) of source and complete target with that - // value (or error). This function could chain all Futures, but is slower - // for _Future than _chainCoreFuture, so you must use _chainCoreFuture - // in that case. - static void _chainForeignFuture(Future source, _Future target) { - assert(!target._isComplete); - assert(source is! _Future); - - // Mark the target as chained (and as such half-completed). - target._setPendingComplete(); - try { - source.then((value) { - assert(target._isPendingComplete); - // The "value" may be another future if the foreign future - // implementation is mis-behaving, - // so use _complete instead of _completeWithValue. - target._clearPendingComplete(); // Clear this first, it's set again. - target._complete(value); - }, onError: (Object error, StackTrace stackTrace) { - assert(target._isPendingComplete); - target._completeError(error, stackTrace); - }); - } catch (e, s) { - // This only happens if the `then` call threw synchronously when given - // valid arguments. - // That requires a non-conforming implementation of the Future interface, - // which should, hopefully, never happen. - scheduleMicrotask(() { - target._completeError(e, s); - }); - } - } - - // Take the value (when completed) of source and complete target with that - // value (or error). This function expects that source is a _Future. - static void _chainCoreFuture(_Future source, _Future target) { - assert(target._mayAddListener); // Not completed, not already chained. - while (source._isChained) { - source = source._chainSource; - } - if (source._isComplete) { - _FutureListener? listeners = target._removeListeners(); - target._cloneResult(source); - _propagateToListeners(target, listeners); - } else { - _FutureListener? listeners = target._resultOrListeners; - target._setChained(source); - source._prependListeners(listeners); - } - } - - void _complete(FutureOr value) { - assert(!_isComplete); - if (value is Future) { - if (value is _Future) { - _chainCoreFuture(value, this); - } else { - _chainForeignFuture(value, this); - } - } else { - _FutureListener? listeners = _removeListeners(); - // TODO(40014): Remove cast when type promotion works. - // This would normally be `as T` but we use `as dynamic` to make the - // unneeded check be implict to match dart2js unsound optimizations in the - // user code. - _setValue(value as dynamic); // Value promoted to T. - _propagateToListeners(this, listeners); - } - } - - void _completeWithValue(T value) { - assert(!_isComplete); - assert(value is! Future); - - _FutureListener? listeners = _removeListeners(); - _setValue(value); - _propagateToListeners(this, listeners); - } - - void _completeError(Object error, StackTrace stackTrace) { - assert(!_isComplete); - - _FutureListener? listeners = _removeListeners(); - _setError(error, stackTrace); - _propagateToListeners(this, listeners); - } - - void _asyncComplete(FutureOr value) { - assert(!_isComplete); - // Two corner cases if the value is a future: - // 1. the future is already completed and an error. - // 2. the future is not yet completed but might become an error. - // The first case means that we must not immediately complete the Future, - // as our code would immediately start propagating the error without - // giving the time to install error-handlers. - // However the second case requires us to deal with the value immediately. - // Otherwise the value could complete with an error and report an - // unhandled error, even though we know we are already going to listen to - // it. - - if (value is Future) { - _chainFuture(value); - return; - } - // TODO(40014): Remove cast when type promotion works. - // This would normally be `as T` but we use `as dynamic` to make the - // unneeded check be implict to match dart2js unsound optimizations in the - // user code. - _asyncCompleteWithValue(value as dynamic); // Value promoted to T. - } - - void _asyncCompleteWithValue(T value) { - _setPendingComplete(); - _zone.scheduleMicrotask(() { - _completeWithValue(value); - }); - } - - void _chainFuture(Future value) { - if (value is _Future) { - if (value._hasError) { - // Delay completion to allow the user to register callbacks. - _setPendingComplete(); - _zone.scheduleMicrotask(() { - _chainCoreFuture(value, this); - }); - } else { - _chainCoreFuture(value, this); - } - return; - } - // Just listen on the foreign future. This guarantees an async delay. - _chainForeignFuture(value, this); - } - - void _asyncCompleteError(Object error, StackTrace stackTrace) { - assert(!_isComplete); - - _setPendingComplete(); - _zone.scheduleMicrotask(() { - _completeError(error, stackTrace); - }); - } - - /** - * Propagates the value/error of [source] to its [listeners], executing the - * listeners' callbacks. - */ - static void _propagateToListeners( - _Future source, _FutureListener? listeners) { - while (true) { - assert(source._isComplete); - bool hasError = source._hasError; - if (listeners == null) { - if (hasError) { - AsyncError asyncError = source._error; - source._zone - .handleUncaughtError(asyncError.error, asyncError.stackTrace); - } - return; - } - // Usually futures only have one listener. If they have several, we - // call handle them separately in recursive calls, continuing - // here only when there is only one listener left. - _FutureListener listener = listeners; - _FutureListener? nextListener = listener._nextListener; - while (nextListener != null) { - listener._nextListener = null; - _propagateToListeners(source, listener); - listener = nextListener; - nextListener = listener._nextListener; - } - - final sourceResult = source._resultOrListeners; - // Do the actual propagation. - // Set initial state of listenerHasError and listenerValueOrError. These - // variables are updated with the outcome of potential callbacks. - // Non-error results, including futures, are stored in - // listenerValueOrError and listenerHasError is set to false. Errors - // are stored in listenerValueOrError as an [AsyncError] and - // listenerHasError is set to true. - bool listenerHasError = hasError; - var listenerValueOrError = sourceResult; - - // Only if we either have an error or callbacks, go into this, somewhat - // expensive, branch. Here we'll enter/leave the zone. Many futures - // don't have callbacks, so this is a significant optimization. - if (hasError || listener.handlesValue || listener.handlesComplete) { - _Zone zone = listener._zone; - if (hasError && !source._zone.inSameErrorZone(zone)) { - // Don't cross zone boundaries with errors. - AsyncError asyncError = source._error; - source._zone - .handleUncaughtError(asyncError.error, asyncError.stackTrace); - return; - } - - _Zone? oldZone; - if (!identical(Zone._current, zone)) { - // Change zone if it's not current. - oldZone = Zone._enter(zone); - } - - // These callbacks are abstracted to isolate the try/catch blocks - // from the rest of the code to work around a V8 glass jaw. - void handleWhenCompleteCallback() { - // The whenComplete-handler is not combined with normal value/error - // handling. This means at most one handleX method is called per - // listener. - assert(!listener.handlesValue); - assert(!listener.handlesError); - var completeResult; - try { - completeResult = listener.handleWhenComplete(); - } catch (e, s) { - if (hasError && identical(source._error.error, e)) { - listenerValueOrError = source._error; - } else { - listenerValueOrError = new AsyncError(e, s); - } - listenerHasError = true; - return; - } - if (completeResult is _Future && completeResult._isComplete) { - if (completeResult._hasError) { - listenerValueOrError = completeResult._error; - listenerHasError = true; - } - // Otherwise use the existing result of source. - return; - } - if (completeResult is Future) { - // We have to wait for the completeResult future to complete - // before knowing if it's an error or we should use the result - // of source. - var originalSource = source; - listenerValueOrError = completeResult.then((_) => originalSource); - listenerHasError = false; - } - } - - void handleValueCallback() { - try { - listenerValueOrError = listener.handleValue(sourceResult); - } catch (e, s) { - listenerValueOrError = new AsyncError(e, s); - listenerHasError = true; - } - } - - void handleError() { - try { - AsyncError asyncError = source._error; - if (listener.matchesErrorTest(asyncError) && - listener.hasErrorCallback) { - listenerValueOrError = listener.handleError(asyncError); - listenerHasError = false; - } - } catch (e, s) { - if (identical(source._error.error, e)) { - listenerValueOrError = source._error; - } else { - listenerValueOrError = new AsyncError(e, s); - } - listenerHasError = true; - } - } - - if (listener.handlesComplete) { - handleWhenCompleteCallback(); - } else if (!hasError) { - if (listener.handlesValue) { - handleValueCallback(); - } - } else { - if (listener.handlesError) { - handleError(); - } - } - - // If we changed zone, oldZone will not be null. - if (oldZone != null) Zone._leave(oldZone); - - // If the listener's value is a future we need to chain it. Note that - // this can only happen if there is a callback. - if (listenerValueOrError is Future) { - Future chainSource = listenerValueOrError; - // Shortcut if the chain-source is already completed. Just continue - // the loop. - _Future result = listener.result; - if (chainSource is _Future) { - if (chainSource._isComplete) { - listeners = result._removeListeners(); - result._cloneResult(chainSource); - source = chainSource; - continue; - } else { - _chainCoreFuture(chainSource, result); - } - } else { - _chainForeignFuture(chainSource, result); - } - return; - } - } - _Future result = listener.result; - listeners = result._removeListeners(); - if (!listenerHasError) { - result._setValue(listenerValueOrError); - } else { - AsyncError asyncError = listenerValueOrError; - result._setErrorObject(asyncError); - } - // Prepare for next round. - source = result; - } - } - - Future timeout(Duration timeLimit, {FutureOr onTimeout()?}) { - if (_isComplete) return new _Future.immediate(this); - _Future result = new _Future(); - Timer timer; - if (onTimeout == null) { - timer = new Timer(timeLimit, () { - result._completeError( - new TimeoutException("Future not completed", timeLimit), - StackTrace.empty); - }); - } else { - Zone zone = Zone.current; - FutureOr Function() onTimeoutHandler = - zone.registerCallback(onTimeout); - - timer = new Timer(timeLimit, () { - try { - result._complete(zone.run(onTimeoutHandler)); - } catch (e, s) { - result._completeError(e, s); - } - }); - } - this.then((T v) { - if (timer.isActive) { - timer.cancel(); - result._completeWithValue(v); - } - }, onError: (Object e, StackTrace s) { - if (timer.isActive) { - timer.cancel(); - result._completeError(e, s); - } - }); - return result; - } -} - -/// Registers errorHandler in zone if it has the correct type. -/// -/// Checks that the function accepts either an [Object] and a [StackTrace] -/// or just one [Object]. Does not check the return type. -/// The actually returned value must be `FutureOr` where `R` is the -/// value type of the future that the call will complete (either returned -/// by [Future.then] or [Future.catchError]). We check the returned value -/// dynamically because the functions are passed as arguments in positions -/// without inference, so a function expression won't infer the return type. -/// -/// Throws if the type is not valid. -Function _registerErrorHandler(Function errorHandler, Zone zone) { - if (errorHandler is dynamic Function(Object, StackTrace)) { - return zone - .registerBinaryCallback(errorHandler); - } - if (errorHandler is dynamic Function(Object)) { - return zone.registerUnaryCallback(errorHandler); - } - throw new ArgumentError.value( - errorHandler, - "onError", - "Error handler must accept one Object or one Object and a StackTrace" - " as arguments, and return a a valid result"); -} diff --git a/sdk_nnbd/lib/async/schedule_microtask.dart b/sdk_nnbd/lib/async/schedule_microtask.dart deleted file mode 100644 index 940989ca495..00000000000 --- a/sdk_nnbd/lib/async/schedule_microtask.dart +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright (c) 2013, 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. - -part of dart.async; - -typedef void _AsyncCallback(); - -class _AsyncCallbackEntry { - final _AsyncCallback callback; - _AsyncCallbackEntry? next; - _AsyncCallbackEntry(this.callback); -} - -/** Head of single linked list of pending callbacks. */ -_AsyncCallbackEntry? _nextCallback; -/** Tail of single linked list of pending callbacks. */ -_AsyncCallbackEntry? _lastCallback; -/** - * Tail of priority callbacks added by the currently executing callback. - * - * Priority callbacks are put at the beginning of the - * callback queue, so that if one callback schedules more than one - * priority callback, they are still enqueued in scheduling order. - */ -_AsyncCallbackEntry? _lastPriorityCallback; -/** - * Whether we are currently inside the callback loop. - * - * If we are inside the loop, we never need to schedule the loop, - * even if adding a first element. - */ -bool _isInCallbackLoop = false; - -void _microtaskLoop() { - for (var entry = _nextCallback; entry != null; entry = _nextCallback) { - _lastPriorityCallback = null; - var next = entry.next; - _nextCallback = next; - if (next == null) _lastCallback = null; - (entry.callback)(); - } -} - -void _startMicrotaskLoop() { - _isInCallbackLoop = true; - try { - // Moved to separate function because try-finally prevents - // good optimization. - _microtaskLoop(); - } finally { - _lastPriorityCallback = null; - _isInCallbackLoop = false; - if (_nextCallback != null) { - _AsyncRun._scheduleImmediate(_startMicrotaskLoop); - } - } -} - -/** - * Schedules a callback to be called as a microtask. - * - * The microtask is called after all other currently scheduled - * microtasks, but as part of the current system event. - */ -void _scheduleAsyncCallback(_AsyncCallback callback) { - _AsyncCallbackEntry newEntry = new _AsyncCallbackEntry(callback); - _AsyncCallbackEntry? lastCallback = _lastCallback; - if (lastCallback == null) { - _nextCallback = _lastCallback = newEntry; - if (!_isInCallbackLoop) { - _AsyncRun._scheduleImmediate(_startMicrotaskLoop); - } - } else { - lastCallback.next = newEntry; - _lastCallback = newEntry; - } -} - -/** - * Schedules a callback to be called before all other currently scheduled ones. - * - * This callback takes priority over existing scheduled callbacks. - * It is only used internally to give higher priority to error reporting. - * - * Is always run in the root zone. - */ -void _schedulePriorityAsyncCallback(_AsyncCallback callback) { - if (_nextCallback == null) { - _scheduleAsyncCallback(callback); - _lastPriorityCallback = _lastCallback; - return; - } - _AsyncCallbackEntry entry = new _AsyncCallbackEntry(callback); - _AsyncCallbackEntry? lastPriorityCallback = _lastPriorityCallback; - if (lastPriorityCallback == null) { - entry.next = _nextCallback; - _nextCallback = _lastPriorityCallback = entry; - } else { - var next = lastPriorityCallback.next; - entry.next = next; - lastPriorityCallback.next = entry; - _lastPriorityCallback = entry; - if (next == null) { - _lastCallback = entry; - } - } -} - -/** - * Runs a function asynchronously. - * - * Callbacks registered through this function are always executed in order and - * are guaranteed to run before other asynchronous events (like [Timer] events, - * or DOM events). - * - * **Warning:** it is possible to starve the DOM by registering asynchronous - * callbacks through this method. For example the following program runs - * the callbacks without ever giving the Timer callback a chance to execute: - * - * main() { - * Timer.run(() { print("executed"); }); // Will never be executed. - * foo() { - * scheduleMicrotask(foo); // Schedules [foo] in front of other events. - * } - * foo(); - * } - * - * ## Other resources - * - * * [The Event Loop and Dart](https://www.dartlang.org/articles/event-loop/): - * Learn how Dart handles the event queue and microtask queue, so you can write - * better asynchronous code with fewer surprises. - */ -void scheduleMicrotask(void Function() callback) { - _Zone currentZone = Zone._current; - if (identical(_rootZone, currentZone)) { - // No need to bind the callback. We know that the root's scheduleMicrotask - // will be invoked in the root zone. - _rootScheduleMicrotask(null, null, _rootZone, callback); - return; - } - _ZoneFunction implementation = currentZone._scheduleMicrotask; - if (identical(_rootZone, implementation.zone) && - _rootZone.inSameErrorZone(currentZone)) { - _rootScheduleMicrotask( - null, null, currentZone, currentZone.registerCallback(callback)); - return; - } - Zone.current.scheduleMicrotask(Zone.current.bindCallbackGuarded(callback)); -} - -class _AsyncRun { - /** Schedule the given callback before any other event in the event-loop. */ - external static void _scheduleImmediate(void Function() callback); -} diff --git a/sdk_nnbd/lib/async/stream.dart b/sdk_nnbd/lib/async/stream.dart deleted file mode 100644 index 46ec1617af3..00000000000 --- a/sdk_nnbd/lib/async/stream.dart +++ /dev/null @@ -1,2232 +0,0 @@ -// Copyright (c) 2013, 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. - -part of dart.async; - -// ------------------------------------------------------------------- -// Core Stream types -// ------------------------------------------------------------------- - -typedef void _TimerCallback(); - -/** - * A source of asynchronous data events. - * - * A Stream provides a way to receive a sequence of events. - * Each event is either a data event, also called an *element* of the stream, - * or an error event, which is a notification that something has failed. - * When a stream has emitted all its event, - * a single "done" event will notify the listener that the end has been reached. - * - * You [listen] on a stream to make it start generating events, - * and to set up listeners that receive the events. - * When you listen, you receive a [StreamSubscription] object - * which is the active object providing the events, - * and which can be used to stop listening again, - * or to temporarily pause events from the subscription. - * - * There are two kinds of streams: "Single-subscription" streams and - * "broadcast" streams. - * - * *A single-subscription stream* allows only a single listener during the whole - * lifetime of the stream. - * It doesn't start generating events until it has a listener, - * and it stops sending events when the listener is unsubscribed, - * even if the source of events could still provide more. - * - * Listening twice on a single-subscription stream is not allowed, even after - * the first subscription has been canceled. - * - * Single-subscription streams are generally used for streaming chunks of - * larger contiguous data like file I/O. - * - * *A broadcast stream* allows any number of listeners, and it fires - * its events when they are ready, whether there are listeners or not. - * - * Broadcast streams are used for independent events/observers. - * - * If several listeners want to listen to a single subscription stream, - * use [asBroadcastStream] to create a broadcast stream on top of the - * non-broadcast stream. - * - * On either kind of stream, stream transformations, such as [where] and - * [skip], return the same type of stream as the one the method was called on, - * unless otherwise noted. - * - * When an event is fired, the listener(s) at that time will receive the event. - * If a listener is added to a broadcast stream while an event is being fired, - * that listener will not receive the event currently being fired. - * If a listener is canceled, it immediately stops receiving events. - * Listening on a broadcast stream can be treated as listening on a new stream - * containing only the events that have not yet been emitted when the [listen] - * call occurs. - * For example, the [first] getter listens to the stream, then returns the first - * event that listener receives. - * This is not necessarily the first even emitted by the stream, but the first - * of the *remaining* events of the broadcast stream. - * - * When the "done" event is fired, subscribers are unsubscribed before - * receiving the event. After the event has been sent, the stream has no - * subscribers. Adding new subscribers to a broadcast stream after this point - * is allowed, but they will just receive a new "done" event as soon - * as possible. - * - * Stream subscriptions always respect "pause" requests. If necessary they need - * to buffer their input, but often, and preferably, they can simply request - * their input to pause too. - * - * The default implementation of [isBroadcast] returns false. - * A broadcast stream inheriting from [Stream] must override [isBroadcast] - * to return `true`. - */ -abstract class Stream { - Stream(); - - /** - * Internal use only. We do not want to promise that Stream stays const. - * - * If mixins become compatible with const constructors, we may use a - * stream mixin instead of extending Stream from a const class. - */ - const Stream._internal(); - - /** - * Creates an empty broadcast stream. - * - * This is a stream which does nothing except sending a done event - * when it's listened to. - */ - const factory Stream.empty() = _EmptyStream; - - /** - * Creates a stream which emits a single data event before completing. - * - * This stream emits a single data event of [value] - * and then completes with a done event. - * - * Example: - * ```dart - * Future printThings(Stream data) async { - * await for (var x in data) { - * print(x); - * } - * } - * printThings(Stream.value("ok")); // prints "ok". - * ``` - * - * The returned stream is effectively equivalent to one created by - * `(() async* { yield value; } ())` or `Future.value(value).asStream()`. - */ - @Since("2.5") - factory Stream.value(T value) => - (_AsyncStreamController(null, null, null, null) - .._add(value) - .._closeUnchecked()) - .stream; - - /** - * Creates a stream which emits a single error event before completing. - * - * This stream emits a single error event of [error] and [stackTrace] - * and then completes with a done event. - * - * Example: - * ```dart - * Future tryThings(Stream data) async { - * try { - * await for (var x in data) { - * print("Data: $x"); - * } - * } catch (e) { - * print(e); - * } - * } - * tryThings(Stream.error("Error")); // prints "Error". - * ``` - * The returned stream is effectively equivalent to one created by - * `Future.error(error, stackTrace).asStream()`, by or - * `(() async* { throw error; } ())`, except that you can control the - * stack trace as well. - */ - @Since("2.5") - factory Stream.error(Object error, [StackTrace? stackTrace]) { - // TODO(40614): Remove once non-nullability is sound. - ArgumentError.checkNotNull(error, "error"); - return (_AsyncStreamController(null, null, null, null) - .._addError(error, stackTrace ?? AsyncError.defaultStackTrace(error)) - .._closeUnchecked()) - .stream; - } - - /** - * Creates a new single-subscription stream from the future. - * - * When the future completes, the stream will fire one event, either - * data or error, and then close with a done-event. - */ - factory Stream.fromFuture(Future future) { - // Use the controller's buffering to fill in the value even before - // the stream has a listener. For a single value, it's not worth it - // to wait for a listener before doing the `then` on the future. - _StreamController controller = - new _SyncStreamController(null, null, null, null); - future.then((value) { - controller._add(value); - controller._closeUnchecked(); - }, onError: (error, stackTrace) { - controller._addError(error, stackTrace); - controller._closeUnchecked(); - }); - return controller.stream; - } - - /** - * Create a stream from a group of futures. - * - * The stream reports the results of the futures on the stream in the order - * in which the futures complete. - * Each future provides either a data event or an error event, - * depending on how the future completes. - * - * If some futures have already completed when `Stream.fromFutures` is called, - * their results will be emitted in some unspecified order. - * - * When all futures have completed, the stream is closed. - * - * If [futures] is empty, the stream closes as soon as possible. - */ - factory Stream.fromFutures(Iterable> futures) { - _StreamController controller = - new _SyncStreamController(null, null, null, null); - int count = 0; - // Declare these as variables holding closures instead of as - // function declarations. - // This avoids creating a new closure from the functions for each future. - void onValue(T value) { - if (!controller.isClosed) { - controller._add(value); - if (--count == 0) controller._closeUnchecked(); - } - } - - void onError(Object error, StackTrace stack) { - if (!controller.isClosed) { - controller._addError(error, stack); - if (--count == 0) controller._closeUnchecked(); - } - } - - // The futures are already running, so start listening to them immediately - // (instead of waiting for the stream to be listened on). - // If we wait, we might not catch errors in the futures in time. - for (var future in futures) { - count++; - future.then(onValue, onError: onError); - } - // Use schedule microtask since controller is sync. - if (count == 0) scheduleMicrotask(controller.close); - return controller.stream; - } - - /** - * Creates a single-subscription stream that gets its data from [elements]. - * - * The iterable is iterated when the stream receives a listener, and stops - * iterating if the listener cancels the subscription, or if the - * [Iterator.moveNext] method returns `false` or throws. - * Iteration is suspended while the stream subscription is paused. - * - * If calling [Iterator.moveNext] on `elements.iterator` throws, - * the stream emits that error and then it closes. - * If reading [Iterator.current] on `elements.iterator` throws, - * the stream emits that error, but keeps iterating. - */ - factory Stream.fromIterable(Iterable elements) { - return new _GeneratedStreamImpl( - () => new _IterablePendingEvents(elements)); - } - - /** - * Creates a stream that repeatedly emits events at [period] intervals. - * - * The event values are computed by invoking [computation]. The argument to - * this callback is an integer that starts with 0 and is incremented for - * every event. - * - * The [period] must a non-negative [Duration]. - * - * If [computation] is omitted the event values will all be `null`. - * - * The [computation] must not be omitted if the event type [T] does not - * allow `null` as a value. - */ - factory Stream.periodic(Duration period, - [T computation(int computationCount)?]) { - if (computation == null && !typeAcceptsNull()) { - throw ArgumentError.value(null, "computation", - "Must not be omitted when the event type is non-nullable"); - } - var controller = _SyncStreamController(null, null, null, null); - // Counts the time that the Stream was running (and not paused). - Stopwatch watch = new Stopwatch(); - controller.onListen = () { - int computationCount = 0; - void sendEvent(_) { - watch.reset(); - if (computation != null) { - T event; - try { - event = computation(computationCount++); - } catch (e, s) { - controller.addError(e, s); - return; - } - controller.add(event); - } else { - controller.add(null as T); // We have checked that null is T. - } - } - - Timer timer = Timer.periodic(period, sendEvent); - controller - ..onCancel = () { - timer.cancel(); - return Future._nullFuture; - } - ..onPause = () { - watch.stop(); - timer.cancel(); - } - ..onResume = () { - Duration elapsed = watch.elapsed; - watch.start(); - timer = new Timer(period - elapsed, () { - timer = Timer.periodic(period, sendEvent); - sendEvent(null); - }); - }; - }; - return controller.stream; - } - - /** - * Creates a stream where all events of an existing stream are piped through - * a sink-transformation. - * - * The given [mapSink] closure is invoked when the returned stream is - * listened to. All events from the [source] are added into the event sink - * that is returned from the invocation. The transformation puts all - * transformed events into the sink the [mapSink] closure received during - * its invocation. Conceptually the [mapSink] creates a transformation pipe - * with the input sink being the returned [EventSink] and the output sink - * being the sink it received. - * - * This constructor is frequently used to build transformers. - * - * Example use for a duplicating transformer: - * - * class DuplicationSink implements EventSink { - * final EventSink _outputSink; - * DuplicationSink(this._outputSink); - * - * void add(String data) { - * _outputSink.add(data); - * _outputSink.add(data); - * } - * - * void addError(e, [st]) { _outputSink.addError(e, st); } - * void close() { _outputSink.close(); } - * } - * - * class DuplicationTransformer extends StreamTransformerBase { - * // Some generic types omitted for brevity. - * Stream bind(Stream stream) => new Stream.eventTransformed( - * stream, - * (EventSink sink) => new DuplicationSink(sink)); - * } - * - * stringStream.transform(new DuplicationTransformer()); - * - * The resulting stream is a broadcast stream if [source] is. - */ - factory Stream.eventTransformed( - Stream source, EventSink mapSink(EventSink sink)) { - return new _BoundSinkStream(source, mapSink); - } - - /** - * Adapts [source] to be a `Stream`. - * - * This allows [source] to be used at the new type, but at run-time it - * must satisfy the requirements of both the new type and its original type. - * - * Data events created by the source stream must also be instances of [T]. - */ - static Stream castFrom(Stream source) => - new CastStream(source); - - /** - * Whether this stream is a broadcast stream. - */ - bool get isBroadcast => false; - - /** - * Returns a multi-subscription stream that produces the same events as this. - * - * The returned stream will subscribe to this stream when its first - * subscriber is added, and will stay subscribed until this stream ends, - * or a callback cancels the subscription. - * - * If [onListen] is provided, it is called with a subscription-like object - * that represents the underlying subscription to this stream. It is - * possible to pause, resume or cancel the subscription during the call - * to [onListen]. It is not possible to change the event handlers, including - * using [StreamSubscription.asFuture]. - * - * If [onCancel] is provided, it is called in a similar way to [onListen] - * when the returned stream stops having listener. If it later gets - * a new listener, the [onListen] function is called again. - * - * Use the callbacks, for example, for pausing the underlying subscription - * while having no subscribers to prevent losing events, or canceling the - * subscription when there are no listeners. - */ - Stream asBroadcastStream( - {void onListen(StreamSubscription subscription)?, - void onCancel(StreamSubscription subscription)?}) { - return new _AsBroadcastStream(this, onListen, onCancel); - } - - /** - * Adds a subscription to this stream. - * - * Returns a [StreamSubscription] which handles events from this stream using - * the provided [onData], [onError] and [onDone] handlers. - * The handlers can be changed on the subscription, but they start out - * as the provided functions. - * - * On each data event from this stream, the subscriber's [onData] handler - * is called. If [onData] is `null`, nothing happens. - * - * On errors from this stream, the [onError] handler is called with the - * error object and possibly a stack trace. - * - * The [onError] callback must be of type `void onError(Object error)` or - * `void onError(Object error, StackTrace stackTrace)`. If [onError] accepts - * two arguments it is called with the error object and the stack trace - * (which could be `null` if this stream itself received an error without - * stack trace). - * Otherwise it is called with just the error object. - * If [onError] is omitted, any errors on this stream are considered unhandled, - * and will be passed to the current [Zone]'s error handler. - * By default unhandled async errors are treated - * as if they were uncaught top-level errors. - * - * If this stream closes and sends a done event, the [onDone] handler is - * called. If [onDone] is `null`, nothing happens. - * - * If [cancelOnError] is true, the subscription is automatically canceled - * when the first error event is delivered. The default is `false`. - * - * While a subscription is paused, or when it has been canceled, - * the subscription doesn't receive events and none of the - * event handler functions are called. - */ - StreamSubscription listen(void onData(T event)?, - {Function? onError, void onDone()?, bool? cancelOnError}); - - /** - * Creates a new stream from this stream that discards some elements. - * - * The new stream sends the same error and done events as this stream, - * but it only sends the data events that satisfy the [test]. - * - * If the [test] function throws, the data event is dropped and the - * error is emitted on the returned stream instead. - * - * The returned stream is a broadcast stream if this stream is. - * If a broadcast stream is listened to more than once, each subscription - * will individually perform the `test`. - */ - Stream where(bool test(T event)) { - return new _WhereStream(this, test); - } - - /** - * Transforms each element of this stream into a new stream event. - * - * Creates a new stream that converts each element of this stream - * to a new value using the [convert] function, and emits the result. - * - * For each data event, `o`, in this stream, the returned stream - * provides a data event with the value `convert(o)`. - * If [convert] throws, the returned stream reports it as an error - * event instead. - * - * Error and done events are passed through unchanged to the returned stream. - * - * The returned stream is a broadcast stream if this stream is. - * The [convert] function is called once per data event per listener. - * If a broadcast stream is listened to more than once, each subscription - * will individually call [convert] on each data event. - * - * Unlike [transform], this method does not treat the stream as - * chunks of a single value. Instead each event is converted independently - * of the previous and following events, which may not always be correct. - * For example, UTF-8 encoding, or decoding, will give wrong results - * if a surrogate pair, or a multibyte UTF-8 encoding, is split into - * separate events, and those events are attempted encoded or decoded - * independently. - */ - Stream map(S convert(T event)) { - return new _MapStream(this, convert); - } - - /** - * Creates a new stream with each data event of this stream asynchronously - * mapped to a new event. - * - * This acts like [map], except that [convert] may return a [Future], - * and in that case, this stream waits for that future to complete before - * continuing with its result. - * - * The returned stream is a broadcast stream if this stream is. - */ - Stream asyncMap(FutureOr convert(T event)) { - _StreamControllerBase controller; - if (isBroadcast) { - controller = _SyncBroadcastStreamController(null, null); - } else { - controller = _SyncStreamController(null, null, null, null); - } - - controller.onListen = () { - StreamSubscription subscription = this.listen(null, - onError: controller._addError, // Avoid Zone error replacement. - onDone: controller.close); - FutureOr add(E value) { - controller.add(value); - } - - final addError = controller._addError; - final resume = subscription.resume; - subscription.onData((T event) { - FutureOr newValue; - try { - newValue = convert(event); - } catch (e, s) { - controller.addError(e, s); - return; - } - if (newValue is Future) { - subscription.pause(); - newValue.then(add, onError: addError).whenComplete(resume); - } else { - // TODO(40014): Remove cast when type promotion works. - controller.add(newValue as dynamic); - } - }); - controller.onCancel = subscription.cancel; - if (!isBroadcast) { - controller - ..onPause = subscription.pause - ..onResume = resume; - } - }; - return controller.stream; - } - - /** - * Transforms each element into a sequence of asynchronous events. - * - * Returns a new stream and for each event of this stream, do the following: - * - * * If the event is an error event or a done event, it is emitted directly - * by the returned stream. - * * Otherwise it is an element. Then the [convert] function is called - * with the element as argument to produce a convert-stream for the element. - * * If that call throws, the error is emitted on the returned stream. - * * If the call returns `null`, no further action is taken for the elements. - * * Otherwise, this stream is paused and convert-stream is listened to. - * Every data and error event of the convert-stream is emitted on the returned - * stream in the order it is produced. - * When the convert-stream ends, this stream is resumed. - * - * The returned stream is a broadcast stream if this stream is. - */ - Stream asyncExpand(Stream? convert(T event)) { - _StreamControllerBase controller; - if (isBroadcast) { - controller = _SyncBroadcastStreamController(null, null); - } else { - controller = _SyncStreamController(null, null, null, null); - } - - controller.onListen = () { - StreamSubscription subscription = this.listen(null, - onError: controller._addError, // Avoid Zone error replacement. - onDone: controller.close); - subscription.onData((T event) { - Stream? newStream; - try { - newStream = convert(event); - } catch (e, s) { - controller.addError(e, s); - return; - } - if (newStream != null) { - subscription.pause(); - controller.addStream(newStream).whenComplete(subscription.resume); - } - }); - controller.onCancel = subscription.cancel; - if (!isBroadcast) { - controller - ..onPause = subscription.pause - ..onResume = subscription.resume; - } - }; - return controller.stream; - } - - /** - * Creates a wrapper Stream that intercepts some errors from this stream. - * - * If this stream sends an error that matches [test], then it is intercepted - * by the [onError] function. - * - * The [onError] callback must be of type `void onError(Object error)` or - * `void onError(Object error, StackTrace stackTrace)`. - * The function type determines whether [onError] is invoked with a stack - * trace argument. - * The stack trace argument may be `null` if this stream received an error - * without a stack trace. - * - * An asynchronous error `error` is matched by a test function if - *`test(error)` returns true. If [test] is omitted, every error is considered - * matching. - * - * If the error is intercepted, the [onError] function can decide what to do - * with it. It can throw if it wants to raise a new (or the same) error, - * or simply return to make this stream forget the error. - * If the received `error` value is thrown again by the [onError] function, - * it acts like a `rethrow` and it is emitted along with its original - * stack trace, not the stack trace of the `throw` inside [onError]. - * - * If you need to transform an error into a data event, use the more generic - * [Stream.transform] to handle the event by writing a data event to - * the output sink. - * - * The returned stream is a broadcast stream if this stream is. - * If a broadcast stream is listened to more than once, each subscription - * will individually perform the `test` and handle the error. - */ - Stream handleError(Function onError, {bool test(error)?}) { - return new _HandleErrorStream(this, onError, test); - } - - /** - * Transforms each element of this stream into a sequence of elements. - * - * Returns a new stream where each element of this stream is replaced - * by zero or more data events. - * The event values are provided as an [Iterable] by a call to [convert] - * with the element as argument, and the elements of that iterable is - * emitted in iteration order. - * If calling [convert] throws, or if the iteration of the returned values - * throws, the error is emitted on the returned stream and iteration ends - * for that element of this stream. - * - * Error events and the done event of this stream are forwarded directly - * to the returned stream. - * - * The returned stream is a broadcast stream if this stream is. - * If a broadcast stream is listened to more than once, each subscription - * will individually call `convert` and expand the events. - */ - Stream expand(Iterable convert(T element)) { - return new _ExpandStream(this, convert); - } - - /** - * Pipes the events of this stream into [streamConsumer]. - * - * All events of this stream are added to `streamConsumer` using - * [StreamConsumer.addStream]. - * The `streamConsumer` is closed when this stream has been successfully added - * to it - when the future returned by `addStream` completes without an error. - * - * Returns a future which completes when this stream has been consumed - * and the consumer has been closed. - * - * The returned future completes with the same result as the future returned - * by [StreamConsumer.close]. - * If the call to [StreamConsumer.addStream] fails in some way, this - * method fails in the same way. - */ - Future pipe(StreamConsumer streamConsumer) { - return streamConsumer.addStream(this).then((_) => streamConsumer.close()); - } - - /** - * Applies [streamTransformer] to this stream. - * - * Returns the transformed stream, - * that is, the result of `streamTransformer.bind(this)`. - * This method simply allows writing the call to `streamTransformer.bind` - * in a chained fashion, like - * ``` - * stream.map(mapping).transform(transformation).toList() - * ``` - * which can be more convenient than calling `bind` directly. - * - * The [streamTransformer] can return any stream. - * Whether the returned stream is a broadcast stream or not, - * and which elements it will contain, - * is entirely up to the transformation. - * - * This method should always be used for transformations which treat - * the entire stream as representing a single value - * which has perhaps been split into several parts for transport, - * like a file being read from disk or being fetched over a network. - * The transformation will then produce a new stream which - * transforms the stream's value incrementally (perhaps using - * [Converter.startChunkedConversion]). The resulting stream - * may again be chunks of the result, but does not have to - * correspond to specific events from the source string. - */ - Stream transform(StreamTransformer streamTransformer) { - return streamTransformer.bind(this); - } - - /** - * Combines a sequence of values by repeatedly applying [combine]. - * - * Similar to [Iterable.reduce], this function maintains a value, - * starting with the first element of this stream - * and updated for each further element of this stream. - * For each element after the first, - * the value is updated to the result of calling [combine] - * with the previous value and the element. - * - * When this stream is done, the returned future is completed with - * the value at that time. - * - * If this stream is empty, the returned future is completed with - * an error. - * If this stream emits an error, or the call to [combine] throws, - * the returned future is completed with that error, - * and processing is stopped. - */ - Future reduce(T combine(T previous, T element)) { - _Future result = new _Future(); - bool seenFirst = false; - late T value; - StreamSubscription subscription = - this.listen(null, onError: result._completeError, onDone: () { - if (!seenFirst) { - try { - // Throw and recatch, instead of just doing - // _completeWithErrorCallback, e, theError, StackTrace.current), - // to ensure that the stackTrace is set on the error. - throw IterableElementError.noElement(); - } catch (e, s) { - _completeWithErrorCallback(result, e, s); - } - } else { - result._complete(value); - } - }, cancelOnError: true); - subscription.onData((T element) { - if (seenFirst) { - _runUserCode(() => combine(value, element), (T newValue) { - value = newValue; - }, _cancelAndErrorClosure(subscription, result)); - } else { - value = element; - seenFirst = true; - } - }); - return result; - } - - /** - * Combines a sequence of values by repeatedly applying [combine]. - * - * Similar to [Iterable.fold], this function maintains a value, - * starting with [initialValue] and updated for each element of - * this stream. - * For each element, the value is updated to the result of calling - * [combine] with the previous value and the element. - * - * When this stream is done, the returned future is completed with - * the value at that time. - * For an empty stream, the future is completed with [initialValue]. - * - * If this stream emits an error, or the call to [combine] throws, - * the returned future is completed with that error, - * and processing is stopped. - */ - Future fold(S initialValue, S combine(S previous, T element)) { - _Future result = new _Future(); - S value = initialValue; - StreamSubscription subscription = - this.listen(null, onError: result._completeError, onDone: () { - result._complete(value); - }, cancelOnError: true); - subscription.onData((T element) { - _runUserCode(() => combine(value, element), (S newValue) { - value = newValue; - }, _cancelAndErrorClosure(subscription, result)); - }); - return result; - } - - /** - * Combines the string representation of elements into a single string. - * - * Each element is converted to a string using its [Object.toString] method. - * If [separator] is provided, it is inserted between element string - * representations. - * - * The returned future is completed with the combined string when this stream - * is done. - * - * If this stream emits an error, or the call to [Object.toString] throws, - * the returned future is completed with that error, - * and processing stops. - */ - Future join([String separator = ""]) { - _Future result = new _Future(); - StringBuffer buffer = new StringBuffer(); - bool first = true; - StreamSubscription subscription = - this.listen(null, onError: result._completeError, onDone: () { - result._complete(buffer.toString()); - }, cancelOnError: true); - subscription.onData(separator.isEmpty - ? (T element) { - try { - buffer.write(element); - } catch (e, s) { - _cancelAndErrorWithReplacement(subscription, result, e, s); - } - } - : (T element) { - if (!first) { - buffer.write(separator); - } - first = false; - try { - buffer.write(element); - } catch (e, s) { - _cancelAndErrorWithReplacement(subscription, result, e, s); - } - }); - return result; - } - - /** - * Returns whether [needle] occurs in the elements provided by this stream. - * - * Compares each element of this stream to [needle] using [Object.==]. - * If an equal element is found, the returned future is completed with `true`. - * If this stream ends without finding a match, the future is completed with - * `false`. - * - * If this stream emits an error, or the call to [Object.==] throws, - * the returned future is completed with that error, - * and processing stops. - */ - Future contains(Object? needle) { - _Future future = new _Future(); - StreamSubscription subscription = - this.listen(null, onError: future._completeError, onDone: () { - future._complete(false); - }, cancelOnError: true); - subscription.onData((T element) { - _runUserCode(() => (element == needle), (bool isMatch) { - if (isMatch) { - _cancelAndValue(subscription, future, true); - } - }, _cancelAndErrorClosure(subscription, future)); - }); - return future; - } - - /** - * Executes [action] on each element of this stream. - * - * Completes the returned [Future] when all elements of this stream - * have been processed. - * - * If this stream emits an error, or if the call to [action] throws, - * the returned future completes with that error, - * and processing stops. - */ - Future forEach(void action(T element)) { - _Future future = new _Future(); - StreamSubscription subscription = - this.listen(null, onError: future._completeError, onDone: () { - future._complete(null); - }, cancelOnError: true); - subscription.onData((T element) { - _runUserCode(() => action(element), (_) {}, - _cancelAndErrorClosure(subscription, future)); - }); - return future; - } - - /** - * Checks whether [test] accepts all elements provided by this stream. - * - * Calls [test] on each element of this stream. - * If the call returns `false`, the returned future is completed with `false` - * and processing stops. - * - * If this stream ends without finding an element that [test] rejects, - * the returned future is completed with `true`. - * - * If this stream emits an error, or if the call to [test] throws, - * the returned future is completed with that error, - * and processing stops. - */ - Future every(bool test(T element)) { - _Future future = new _Future(); - StreamSubscription subscription = - this.listen(null, onError: future._completeError, onDone: () { - future._complete(true); - }, cancelOnError: true); - subscription.onData((T element) { - _runUserCode(() => test(element), (bool isMatch) { - if (!isMatch) { - _cancelAndValue(subscription, future, false); - } - }, _cancelAndErrorClosure(subscription, future)); - }); - return future; - } - - /** - * Checks whether [test] accepts any element provided by this stream. - * - * Calls [test] on each element of this stream. - * If the call returns `true`, the returned future is completed with `true` - * and processing stops. - * - * If this stream ends without finding an element that [test] accepts, - * the returned future is completed with `false`. - * - * If this stream emits an error, or if the call to [test] throws, - * the returned future is completed with that error, - * and processing stops. - */ - Future any(bool test(T element)) { - _Future future = new _Future(); - StreamSubscription subscription = - this.listen(null, onError: future._completeError, onDone: () { - future._complete(false); - }, cancelOnError: true); - subscription.onData((T element) { - _runUserCode(() => test(element), (bool isMatch) { - if (isMatch) { - _cancelAndValue(subscription, future, true); - } - }, _cancelAndErrorClosure(subscription, future)); - }); - return future; - } - - /** - * The number of elements in this stream. - * - * Waits for all elements of this stream. When this stream ends, - * the returned future is completed with the number of elements. - * - * If this stream emits an error, - * the returned future is completed with that error, - * and processing stops. - * - * This operation listens to this stream, and a non-broadcast stream cannot - * be reused after finding its length. - */ - Future get length { - _Future future = new _Future(); - int count = 0; - this.listen( - (_) { - count++; - }, - onError: future._completeError, - onDone: () { - future._complete(count); - }, - cancelOnError: true); - return future; - } - - /** - * Whether this stream contains any elements. - * - * Waits for the first element of this stream, then completes the returned - * future with `false`. - * If this stream ends without emitting any elements, the returned future is - * completed with `true`. - * - * If the first event is an error, the returned future is completed with that - * error. - * - * This operation listens to this stream, and a non-broadcast stream cannot - * be reused after checking whether it is empty. - */ - Future get isEmpty { - _Future future = new _Future(); - StreamSubscription subscription = - this.listen(null, onError: future._completeError, onDone: () { - future._complete(true); - }, cancelOnError: true); - subscription.onData((_) { - _cancelAndValue(subscription, future, false); - }); - return future; - } - - /** - * Adapt this stream to be a `Stream`. - * - * This stream is wrapped as a `Stream` which checks at run-time that - * each data event emitted by this stream is also an instance of [R]. - */ - Stream cast() => Stream.castFrom(this); - /** - * Collects all elements of this stream in a [List]. - * - * Creates a `List` and adds all elements of this stream to the list - * in the order they arrive. - * When this stream ends, the returned future is completed with that list. - * - * If this stream emits an error, - * the returned future is completed with that error, - * and processing stops. - */ - Future> toList() { - List result = []; - _Future> future = new _Future>(); - this.listen( - (T data) { - result.add(data); - }, - onError: future._completeError, - onDone: () { - future._complete(result); - }, - cancelOnError: true); - return future; - } - - /** - * Collects the data of this stream in a [Set]. - * - * Creates a `Set` and adds all elements of this stream to the set. - * in the order they arrive. - * When this stream ends, the returned future is completed with that set. - * - * The returned set is the same type as returned by `new Set()`. - * If another type of set is needed, either use [forEach] to add each - * element to the set, or use - * `toList().then((list) => new SomeOtherSet.from(list))` - * to create the set. - * - * If this stream emits an error, - * the returned future is completed with that error, - * and processing stops. - */ - Future> toSet() { - Set result = new Set(); - _Future> future = new _Future>(); - this.listen( - (T data) { - result.add(data); - }, - onError: future._completeError, - onDone: () { - future._complete(result); - }, - cancelOnError: true); - return future; - } - - /** - * Discards all data on this stream, but signals when it is done or an error - * occurred. - * - * When subscribing using [drain], cancelOnError will be true. This means - * that the future will complete with the first error on this stream and then - * cancel the subscription. - * - * If this stream emits an error, the returned future is completed with - * that error, and processing is stopped. - * - * In case of a `done` event the future completes with the given - * [futureValue]. - * - * The [futureValue] must not be omitted if `null` is not assignable to [E]. - */ - Future drain([E? futureValue]) { - if (futureValue == null) { - futureValue = futureValue as E; - } - return listen(null, cancelOnError: true).asFuture(futureValue); - } - - /** - * Provides at most the first [count] data events of this stream. - * - * Returns a stream that emits the same events that this stream would - * if listened to at the same time, - * until either this stream ends or it has emitted [count] data events, - * at which point the returned stream is done. - * - * If this stream produces fewer than [count] data events before it's done, - * so will the returned stream. - * - * Starts listening to this stream when the returned stream is listened to - * and stops listening when the first [count] data events have been received. - * - * This means that if this is a single-subscription (non-broadcast) streams - * it cannot be reused after the returned stream has been listened to. - * - * If this is a broadcast stream, the returned stream is a broadcast stream. - * In that case, the events are only counted from the time - * the returned stream is listened to. - */ - Stream take(int count) { - return new _TakeStream(this, count); - } - - /** - * Forwards data events while [test] is successful. - * - * Returns a stream that provides the same events as this stream - * until [test] fails for a data event. - * The returned stream is done when either this stream is done, - * or when this stream first emits a data event that fails [test]. - * - * The `test` call is considered failing if it returns a non-`true` value - * or if it throws. If the `test` call throws, the error is emitted as the - * last event on the returned streams. - * - * Stops listening to this stream after the accepted elements. - * - * Internally the method cancels its subscription after these elements. This - * means that single-subscription (non-broadcast) streams are closed and - * cannot be reused after a call to this method. - * - * The returned stream is a broadcast stream if this stream is. - * For a broadcast stream, the events are only tested from the time - * the returned stream is listened to. - */ - Stream takeWhile(bool test(T element)) { - return new _TakeWhileStream(this, test); - } - - /** - * Skips the first [count] data events from this stream. - * - * Returns a stream that emits the same events as this stream would - * if listened to at the same time, except that the first [count] - * data events are not emitted. - * The returned stream is done when this stream is. - * - * If this stream emits fewer than [count] data events - * before being done, the returned stream emits no data events. - * - * The returned stream is a broadcast stream if this stream is. - * For a broadcast stream, the events are only counted from the time - * the returned stream is listened to. - */ - Stream skip(int count) { - return new _SkipStream(this, count); - } - - /** - * Skip data events from this stream while they are matched by [test]. - * - * Returns a stream that emits the same events as this stream, - * except that data events are not emitted until a data event fails `test`. - * The test fails when called with a data event - * if it returns a non-`true` value or if the call to `test` throws. - * If the call throws, the error is emitted as an error event - * on the returned stream instead of the data event, - * otherwise the event that made `test` return non-true is emitted as the - * first data event. - * - * Error and done events are provided by the returned stream unmodified. - * - * The returned stream is a broadcast stream if this stream is. - * For a broadcast stream, the events are only tested from the time - * the returned stream is listened to. - */ - Stream skipWhile(bool test(T element)) { - return new _SkipWhileStream(this, test); - } - - /** - * Skips data events if they are equal to the previous data event. - * - * The returned stream provides the same events as this stream, except - * that it never provides two consecutive data events that are equal. - * That is, errors are passed through to the returned stream, and - * data events are passed through if they are distinct from the most - * recently emitted data event. - * - * Equality is determined by the provided [equals] method. If that is - * omitted, the '==' operator on the last provided data element is used. - * - * If [equals] throws, the data event is replaced by an error event - * containing the thrown error. The behavior is equivalent to the - * original stream emitting the error event, and it doesn't change - * the what the most recently emitted data event is. - * - * The returned stream is a broadcast stream if this stream is. - * If a broadcast stream is listened to more than once, each subscription - * will individually perform the `equals` test. - */ - Stream distinct([bool equals(T previous, T next)?]) { - return new _DistinctStream(this, equals); - } - - /** - * The first element of this stream. - * - * Stops listening to this stream after the first element has been received. - * - * Internally the method cancels its subscription after the first element. - * This means that single-subscription (non-broadcast) streams are closed - * and cannot be reused after a call to this getter. - * - * If an error event occurs before the first data event, the returned future - * is completed with that error. - * - * If this stream is empty (a done event occurs before the first data event), - * the returned future completes with an error. - * - * Except for the type of the error, this method is equivalent to - * `this.elementAt(0)`. - */ - Future get first { - _Future future = new _Future(); - StreamSubscription subscription = - this.listen(null, onError: future._completeError, onDone: () { - try { - throw IterableElementError.noElement(); - } catch (e, s) { - _completeWithErrorCallback(future, e, s); - } - }, cancelOnError: true); - subscription.onData((T value) { - _cancelAndValue(subscription, future, value); - }); - return future; - } - - /** - * The last element of this stream. - * - * If this stream emits an error event, - * the returned future is completed with that error - * and processing stops. - * - * If this stream is empty (the done event is the first event), - * the returned future completes with an error. - */ - Future get last { - _Future future = new _Future(); - late T result; - bool foundResult = false; - listen( - (T value) { - foundResult = true; - result = value; - }, - onError: future._completeError, - onDone: () { - if (foundResult) { - future._complete(result); - return; - } - try { - throw IterableElementError.noElement(); - } catch (e, s) { - _completeWithErrorCallback(future, e, s); - } - }, - cancelOnError: true); - return future; - } - - /** - * The single element of this stream. - * - * If this stream emits an error event, - * the returned future is completed with that error - * and processing stops. - * - * If [this] is empty or has more than one element, - * the returned future completes with an error. - */ - Future get single { - _Future future = new _Future(); - late T result; - bool foundResult = false; - StreamSubscription subscription = - this.listen(null, onError: future._completeError, onDone: () { - if (foundResult) { - future._complete(result); - return; - } - try { - throw IterableElementError.noElement(); - } catch (e, s) { - _completeWithErrorCallback(future, e, s); - } - }, cancelOnError: true); - subscription.onData((T value) { - if (foundResult) { - // This is the second element we get. - try { - throw IterableElementError.tooMany(); - } catch (e, s) { - _cancelAndErrorWithReplacement(subscription, future, e, s); - } - return; - } - foundResult = true; - result = value; - }); - return future; - } - - /** - * Finds the first element of this stream matching [test]. - * - * Returns a future that is completed with the first element of this stream - * that [test] returns `true` for. - * - * If no such element is found before this stream is done, and a - * [orElse] function is provided, the result of calling [orElse] - * becomes the value of the future. If [orElse] throws, the returned - * future is completed with that error. - * - * If this stream emits an error before the first matching element, - * the returned future is completed with that error, and processing stops. - * - * Stops listening to this stream after the first matching element or error - * has been received. - * - * Internally the method cancels its subscription after the first element that - * matches the predicate. This means that single-subscription (non-broadcast) - * streams are closed and cannot be reused after a call to this method. - * - * If an error occurs, or if this stream ends without finding a match and - * with no [orElse] function provided, - * the returned future is completed with an error. - */ - Future firstWhere(bool test(T element), {T orElse()?}) { - _Future future = new _Future(); - StreamSubscription subscription = - this.listen(null, onError: future._completeError, onDone: () { - if (orElse != null) { - _runUserCode(orElse, future._complete, future._completeError); - return; - } - try { - // Sets stackTrace on error. - throw IterableElementError.noElement(); - } catch (e, s) { - _completeWithErrorCallback(future, e, s); - } - }, cancelOnError: true); - - subscription.onData((T value) { - _runUserCode(() => test(value), (bool isMatch) { - if (isMatch) { - _cancelAndValue(subscription, future, value); - } - }, _cancelAndErrorClosure(subscription, future)); - }); - return future; - } - - /** - * Finds the last element in this stream matching [test]. - * - * If this stream emits an error, the returned future is completed with that - * error, and processing stops. - * - * Otherwise as [firstWhere], except that the last matching element is found - * instead of the first. - * That means that a non-error result cannot be provided before this stream - * is done. - */ - Future lastWhere(bool test(T element), {T orElse()?}) { - _Future future = new _Future(); - late T result; - bool foundResult = false; - StreamSubscription subscription = - this.listen(null, onError: future._completeError, onDone: () { - if (foundResult) { - future._complete(result); - return; - } - if (orElse != null) { - _runUserCode(orElse, future._complete, future._completeError); - return; - } - try { - throw IterableElementError.noElement(); - } catch (e, s) { - _completeWithErrorCallback(future, e, s); - } - }, cancelOnError: true); - - subscription.onData((T value) { - _runUserCode(() => test(value), (bool isMatch) { - if (isMatch) { - foundResult = true; - result = value; - } - }, _cancelAndErrorClosure(subscription, future)); - }); - return future; - } - - /** - * Finds the single element in this stream matching [test]. - * - * Like [lastWhere], except that it is an error if more than one - * matching element occurs in this stream. - */ - Future singleWhere(bool test(T element), {T orElse()?}) { - _Future future = new _Future(); - late T result; - bool foundResult = false; - StreamSubscription subscription = - this.listen(null, onError: future._completeError, onDone: () { - if (foundResult) { - future._complete(result); - return; - } - if (orElse != null) { - _runUserCode(orElse, future._complete, future._completeError); - return; - } - try { - throw IterableElementError.noElement(); - } catch (e, s) { - _completeWithErrorCallback(future, e, s); - } - }, cancelOnError: true); - - subscription.onData((T value) { - _runUserCode(() => test(value), (bool isMatch) { - if (isMatch) { - if (foundResult) { - try { - throw IterableElementError.tooMany(); - } catch (e, s) { - _cancelAndErrorWithReplacement(subscription, future, e, s); - } - return; - } - foundResult = true; - result = value; - } - }, _cancelAndErrorClosure(subscription, future)); - }); - return future; - } - - /** - * Returns the value of the [index]th data event of this stream. - * - * Stops listening to this stream after the [index]th data event has been - * received. - * - * Internally the method cancels its subscription after these elements. This - * means that single-subscription (non-broadcast) streams are closed and - * cannot be reused after a call to this method. - * - * If an error event occurs before the value is found, the future completes - * with this error. - * - * If a done event occurs before the value is found, the future completes - * with a [RangeError]. - */ - Future elementAt(int index) { - RangeError.checkNotNegative(index, "index"); - _Future result = new _Future(); - int elementIndex = 0; - StreamSubscription subscription; - subscription = - this.listen(null, onError: result._completeError, onDone: () { - result._completeError( - new RangeError.index(index, this, "index", null, elementIndex), - StackTrace.empty); - }, cancelOnError: true); - subscription.onData((T value) { - if (index == elementIndex) { - _cancelAndValue(subscription, result, value); - return; - } - elementIndex += 1; - }); - - return result; - } - - /** - * Creates a new stream with the same events as this stream. - * - * Whenever more than [timeLimit] passes between two events from this stream, - * the [onTimeout] function is called, which can emit further events on - * the returned stream. - * - * The countdown doesn't start until the returned stream is listened to. - * The countdown is reset every time an event is forwarded from this stream, - * or when this stream is paused and resumed. - * - * The [onTimeout] function is called with one argument: an - * [EventSink] that allows putting events into the returned stream. - * This `EventSink` is only valid during the call to [onTimeout]. - * Calling [EventSink.close] on the sink passed to [onTimeout] closes the - * returned stream, and no further events are processed. - * - * If [onTimeout] is omitted, a timeout will just put a [TimeoutException] - * into the error channel of the returned stream. - * If the call to [onTimeout] throws, the error is emitted on the returned - * stream. - * - * The returned stream is a broadcast stream if this stream is. - * If a broadcast stream is listened to more than once, each subscription - * will have its individually timer that starts counting on listen, - * and the subscriptions' timers can be paused individually. - */ - Stream timeout(Duration timeLimit, {void onTimeout(EventSink sink)?}) { - _StreamControllerBase controller; - if (isBroadcast) { - controller = new _SyncBroadcastStreamController(null, null); - } else { - controller = new _SyncStreamController(null, null, null, null); - } - - Zone zone = Zone.current; - // Register callback immediately. - _TimerCallback timeoutCallback; - if (onTimeout == null) { - timeoutCallback = () { - controller.addError( - new TimeoutException("No stream event", timeLimit), null); - }; - } else { - // TODO(floitsch): the return type should be 'void', and the type - // should be inferred. - var registeredOnTimeout = - zone.registerUnaryCallback>(onTimeout); - var wrapper = new _ControllerEventSinkWrapper(null); - timeoutCallback = () { - wrapper._sink = controller; // Only valid during call. - zone.runUnaryGuarded(registeredOnTimeout, wrapper); - wrapper._sink = null; - }; - } - - // All further setup happens inside `onListen`. - controller.onListen = () { - Timer timer = zone.createTimer(timeLimit, timeoutCallback); - var subscription = this.listen(null); - // Set up event forwarding. Each data or error event resets the timer - subscription - ..onData((T event) { - timer.cancel(); - timer = zone.createTimer(timeLimit, timeoutCallback); - // Controller is synchronous, and the call might close the stream - // and cancel the timer, - // so create the Timer before calling into add(); - // issue: https://github.com/dart-lang/sdk/issues/37565 - controller.add(event); - }) - ..onError((Object error, StackTrace stackTrace) { - timer.cancel(); - timer = zone.createTimer(timeLimit, timeoutCallback); - controller._addError( - error, stackTrace); // Avoid Zone error replacement. - }) - ..onDone(() { - timer.cancel(); - controller.close(); - }); - // Set up further controller callbacks. - controller.onCancel = () { - timer.cancel(); - return subscription.cancel(); - }; - if (!isBroadcast) { - controller - ..onPause = () { - timer.cancel(); - subscription.pause(); - } - ..onResume = () { - subscription.resume(); - timer = zone.createTimer(timeLimit, timeoutCallback); - }; - } - }; - - return controller.stream; - } -} - -/** - * A subscription on events from a [Stream]. - * - * When you listen on a [Stream] using [Stream.listen], - * a [StreamSubscription] object is returned. - * - * The subscription provides events to the listener, - * and holds the callbacks used to handle the events. - * The subscription can also be used to unsubscribe from the events, - * or to temporarily pause the events from the stream. - */ -abstract class StreamSubscription { - /** - * Cancels this subscription. - * - * After this call, the subscription no longer receives events. - * - * The stream may need to shut down the source of events and clean up after - * the subscription is canceled. - * - * Returns a future that is completed once the stream has finished - * its cleanup. - * - * Typically, cleanup happens when the stream needs to release resources. - * For example, a stream might need to close an open file (as an asynchronous - * operation). If the listener wants to delete the file after having - * canceled the subscription, it must wait for the cleanup future to complete. - * - * If the cleanup throws, which it really shouldn't, the returned future - * completes with that error. - */ - Future cancel(); - - /** - * Replaces the data event handler of this subscription. - * - * The [handleData] function is called for each element of the stream - * after this function is called. - * If [handleData] is `null`, further elements are ignored. - * - * This method replaces the current handler set by the invocation of - * [Stream.listen] or by a previous call to [onData]. - */ - void onData(void handleData(T data)?); - - /** - * Replaces the error event handler of this subscription. - * - * The [handleError] function must be able to be called with either - * one positional argument, or with two positional arguments - * where the seconds is always a [StackTrace]. - * - * The [handleError] argument may be `null`, in which case further - * error events are considered unhandled, and will be reported to - * [Zone.handleUncaughtError]. - * - * The provided function is called for all error events from the - * stream subscription. - * - * This method replaces the current handler set by the invocation of - * [Stream.listen], by calling [asFuture], or by a previous call to [onError]. - */ - void onError(Function? handleError); - - /** - * Replaces the done event handler of this subscription. - * - * The [handleDone] function is called when the stream closes. - * The value may be `null`, in which case no function is called. - * - * This method replaces the current handler set by the invocation of - * [Stream.listen], by calling [asFuture], or by a previous call to [onDone]. - */ - void onDone(void handleDone()?); - - /** - * Request that the stream pauses events until further notice. - * - * While paused, the subscription will not fire any events. - * If it receives events from its source, they will be buffered until - * the subscription is resumed. - * For non-broadcast streams, the underlying source is usually informed - * about the pause, - * so it can stop generating events until the subscription is resumed. - * - * To avoid buffering events on a broadcast stream, it is better to - * cancel this subscription, and start to listen again when events - * are needed, if the intermediate events are not important. - * - * If [resumeSignal] is provided, the stream subscription will undo the pause - * when the future completes, as if by a call to [resume]. - * If the future completes with an error, - * the stream will still resume, but the error will be considered unhandled - * and is passed to [Zone.handleUncaughtError]. - * - * A call to [resume] will also undo a pause. - * - * If the subscription is paused more than once, an equal number - * of resumes must be performed to resume the stream. - * Calls to [resume] and the completion of a [resumeSignal] are - * interchangeable - the [pause] which was passed a [resumeSignal] may be - * ended by a call to [resume], and completing the [resumeSignal] may end a - * different [pause]. - * - * It is safe to [resume] or complete a [resumeSignal] even when the - * subscription is not paused, and the resume will have no effect. - * - * Currently DOM streams silently drop events when the stream is paused. This - * is a bug and will be fixed. - */ - void pause([Future? resumeSignal]); - - /** - * Resume after a pause. - * - * This undoes one previous call to [pause]. - * When all previously calls to [pause] have been matched by a calls to - * [resume], possibly through a `resumeSignal` passed to [pause], - * the stream subscription may emit events again. - * - * It is safe to [resume] even when the subscription is not paused, and the - * resume will have no effect. - */ - void resume(); - - /** - * Whether the [StreamSubscription] is currently paused. - * - * If there have been more calls to [pause] than to [resume] on this - * stream subscription, the subscription is paused, and this getter - * returns `true`. - * - * Returns `false` if the stream can currently emit events, or if - * the subscription has completed or been cancelled. - */ - bool get isPaused; - - /** - * Returns a future that handles the [onDone] and [onError] callbacks. - * - * This method *overwrites* the existing [onDone] and [onError] callbacks - * with new ones that complete the returned future. - * - * In case of an error the subscription will automatically cancel (even - * when it was listening with `cancelOnError` set to `false`). - * - * In case of a `done` event the future completes with the given - * [futureValue]. - * - * If [futureValue] is omitted, the value `null as E` is used as a default. - * If `E` is not nullable, this will throw immediately when [asFuture] - * is called. - */ - Future asFuture([E? futureValue]); -} - -/** - * A [Sink] that supports adding errors. - * - * This makes it suitable for capturing the results of asynchronous - * computations, which can complete with a value or an error. - * - * The [EventSink] has been designed to handle asynchronous events from - * [Stream]s. See, for example, [Stream.eventTransformed] which uses - * `EventSink`s to transform events. - */ -abstract class EventSink implements Sink { - /** - * Adds a data [event] to the sink. - * - * Must not be called on a closed sink. - */ - void add(T event); - - /** - * Adds an [error] to the sink. - * - * Must not be called on a closed sink. - */ - void addError(Object error, [StackTrace? stackTrace]); - - /** - * Closes the sink. - * - * Calling this method more than once is allowed, but does nothing. - * - * Neither [add] nor [addError] must be called after this method. - */ - void close(); -} - -/** [Stream] wrapper that only exposes the [Stream] interface. */ -class StreamView extends Stream { - final Stream _stream; - - const StreamView(Stream stream) - : _stream = stream, - super._internal(); - - bool get isBroadcast => _stream.isBroadcast; - - Stream asBroadcastStream( - {void onListen(StreamSubscription subscription)?, - void onCancel(StreamSubscription subscription)?}) => - _stream.asBroadcastStream(onListen: onListen, onCancel: onCancel); - - StreamSubscription listen(void onData(T value)?, - {Function? onError, void onDone()?, bool? cancelOnError}) { - return _stream.listen(onData, - onError: onError, onDone: onDone, cancelOnError: cancelOnError); - } -} - -/** - * Abstract interface for a "sink" accepting multiple entire streams. - * - * A consumer can accept a number of consecutive streams using [addStream], - * and when no further data need to be added, the [close] method tells the - * consumer to complete its work and shut down. - * - * The [Stream.pipe] accepts a `StreamConsumer` and will pass the stream - * to the consumer's [addStream] method. When that completes, it will - * call [close] and then complete its own returned future. - */ -abstract class StreamConsumer { - /** - * Consumes the elements of [stream]. - * - * Listens on [stream] and does something for each event. - * - * Returns a future which is completed when the stream is done being added, - * and the consumer is ready to accept a new stream. - * No further calls to [addStream] or [close] should happen before the - * returned future has completed. - * - * The consumer may stop listening to the stream after an error, - * it may consume all the errors and only stop at a done event, - * or it may be canceled early if the receiver don't want any further events. - * - * If the consumer stops listening because of some error preventing it - * from continuing, it may report this error in the returned future, - * otherwise it will just complete the future with `null`. - */ - Future addStream(Stream stream); - - /** - * Tells the consumer that no further streams will be added. - * - * This allows the consumer to complete any remaining work and release - * resources that are no longer needed - * - * Returns a future which is completed when the consumer has shut down. - * If cleaning up can fail, the error may be reported in the returned future, - * otherwise it completes with `null`. - */ - Future close(); -} - -/** - * A object that accepts stream events both synchronously and asynchronously. - * - * A [StreamSink] combines the methods from [StreamConsumer] and [EventSink]. - * - * The [EventSink] methods can't be used while the [addStream] is called. - * As soon as the [addStream]'s [Future] completes with a value, the - * [EventSink] methods can be used again. - * - * If [addStream] is called after any of the [EventSink] methods, it'll - * be delayed until the underlying system has consumed the data added by the - * [EventSink] methods. - * - * When [EventSink] methods are used, the [done] [Future] can be used to - * catch any errors. - * - * When [close] is called, it will return the [done] [Future]. - */ -abstract class StreamSink implements EventSink, StreamConsumer { - /** - * Tells the stream sink that no further streams will be added. - * - * This allows the stream sink to complete any remaining work and release - * resources that are no longer needed - * - * Returns a future which is completed when the stream sink has shut down. - * If cleaning up can fail, the error may be reported in the returned future, - * otherwise it completes with `null`. - * - * Returns the same future as [done]. - * - * The stream sink may close before the [close] method is called, either due - * to an error or because it is itself providing events to someone who has - * stopped listening. In that case, the [done] future is completed first, - * and the `close` method will return the `done` future when called. - * - * Unifies [StreamConsumer.close] and [EventSink.close] which both mark their - * object as not expecting any further events. - */ - Future close(); - - /** - * Return a future which is completed when the [StreamSink] is finished. - * - * If the `StreamSink` fails with an error, - * perhaps in response to adding events using [add], [addError] or [close], - * the [done] future will complete with that error. - * - * Otherwise, the returned future will complete when either: - * - * * all events have been processed and the sink has been closed, or - * * the sink has otherwise been stopped from handling more events - * (for example by canceling a stream subscription). - */ - Future get done; -} - -/** - * Transforms a Stream. - * - * When a stream's [Stream.transform] method is invoked with a - * [StreamTransformer], the stream calls the [bind] method on the provided - * transformer. The resulting stream is then returned from the - * [Stream.transform] method. - * - * Conceptually, a transformer is simply a function from [Stream] to [Stream] - * that is encapsulated into a class. - * - * It is good practice to write transformers that can be used multiple times. - * - * All other transforming methods on [Stream], such as [Stream.map], - * [Stream.where] or [Stream.expand] can be implemented using - * [Stream.transform]. A [StreamTransformer] is thus very powerful but often - * also a bit more complicated to use. - */ -abstract class StreamTransformer { - /** - * Creates a [StreamTransformer] based on the given [onListen] callback. - * - * The returned stream transformer uses the provided [onListen] callback - * when a transformed stream is listened to. At that time, the callback - * receives the input stream (the one passed to [bind]) and a - * boolean flag `cancelOnError` to create a [StreamSubscription]. - * - * If the transformed stream is a broadcast stream, so is the stream - * returned by the [StreamTransformer.bind] method by this transformer. - * - * If the transformed stream is listened to multiple times, the [onListen] - * callback is called again for each new [Stream.listen] call. - * This happens whether the stream is a broadcast stream or not, - * but the call will usually fail for non-broadcast streams. - * - * The [onListen] callback does *not* receive the handlers that were passed - * to [Stream.listen]. These are automatically set after the call to the - * [onListen] callback (using [StreamSubscription.onData], - * [StreamSubscription.onError] and [StreamSubscription.onDone]). - * - * Most commonly, an [onListen] callback will first call [Stream.listen] on - * the provided stream (with the corresponding `cancelOnError` flag), and then - * return a new [StreamSubscription]. - * - * There are two common ways to create a StreamSubscription: - * - * 1. by allocating a [StreamController] and to return the result of - * listening to its stream. It's important to forward pause, resume and - * cancel events (unless the transformer intentionally wants to change - * this behavior). - * 2. by creating a new class that implements [StreamSubscription]. - * Note that the subscription should run callbacks in the [Zone] the - * stream was listened to (see [Zone] and [Zone.bindCallback]). - * - * Example: - * - * ``` - * /// Starts listening to [input] and duplicates all non-error events. - * StreamSubscription _onListen(Stream input, bool cancelOnError) { - * StreamSubscription subscription; - * // Create controller that forwards pause, resume and cancel events. - * var controller = new StreamController( - * onPause: () { - * subscription.pause(); - * }, - * onResume: () { - * subscription.resume(); - * }, - * onCancel: () => subscription.cancel(), - * sync: true); // "sync" is correct here, since events are forwarded. - * - * // Listen to the provided stream using `cancelOnError`. - * subscription = input.listen((data) { - * // Duplicate the data. - * controller.add(data); - * controller.add(data); - * }, - * onError: controller.addError, - * onDone: controller.close, - * cancelOnError: cancelOnError); - * - * // Return a new [StreamSubscription] by listening to the controller's - * // stream. - * return controller.stream.listen(null); - * } - * - * // Instantiate a transformer: - * var duplicator = const StreamTransformer(_onListen); - * - * // Use as follows: - * intStream.transform(duplicator); - * ``` - */ - const factory StreamTransformer( - StreamSubscription onListen( - Stream stream, bool cancelOnError)) = - _StreamSubscriptionTransformer; - - /** - * Creates a [StreamTransformer] that delegates events to the given functions. - * - * Example use of a duplicating transformer: - * - * ``` - * stringStream.transform(new StreamTransformer.fromHandlers( - * handleData: (String value, EventSink sink) { - * sink.add(value); - * sink.add(value); // Duplicate the incoming events. - * })); - * ``` - * - * Transformers that are constructed this way cannot use captured state if - * they are used in streams that can be listened to multiple times. - * ``` - * StreamController controller; - * controller = new StreamController.broadcast(onListen: () { - * scheduleMicrotask(() { - * controller.addError("Bad"); - * controller.addError("Worse"); - * controller.addError("Worst"); - * }); - * }); - * var sharedState = 0; - * var transformedStream = controller.stream.transform( - * new StreamTransformer.fromHandlers( - * handleError: (error, stackTrace, sink) { - * sharedState++; // Increment shared error-counter. - * sink.add("Error $sharedState: $error"); - * })); - * - * transformedStream.listen(print); - * transformedStream.listen(print); // Listen twice. - * // Listening twice to the same stream makes the transformer share the same - * // state. Instead of having "Error 1: Bad", "Error 2: Worse", - * // "Error 3: Worst" as output (each twice for the separate subscriptions), - * // this program emits: - * // Error 1: Bad - * // Error 2: Bad - * // Error 3: Worse - * // Error 4: Worse - * // Error 5: Worst - * // Error 6: Worst - * ``` - */ - factory StreamTransformer.fromHandlers( - {void handleData(S data, EventSink sink)?, - void handleError(Object error, StackTrace stackTrace, EventSink sink)?, - void handleDone(EventSink sink)?}) = _StreamHandlerTransformer; - - /** - * Creates a [StreamTransformer] based on a [bind] callback. - * - * The returned stream transformer uses the [bind] argument to implement the - * [StreamTransformer.bind] API and can be used when the transformation is - * available as a stream-to-stream function. - * - * ```dart - * final splitDecoded = StreamTransformer, String>.fromBind( - * (stream) => stream.transform(utf8.decoder).transform(LineSplitter())); - * ``` - */ - @Since("2.1") - factory StreamTransformer.fromBind(Stream Function(Stream) bind) = - _StreamBindTransformer; - - /** - * Adapts [source] to be a `StreamTransformer`. - * - * This allows [source] to be used at the new type, but at run-time it - * must satisfy the requirements of both the new type and its original type. - * - * Data events passed into the returned transformer must also be instances - * of [SS], and data events produced by [source] for those events must - * also be instances of [TT]. - */ - static StreamTransformer castFrom( - StreamTransformer source) { - return new CastStreamTransformer(source); - } - - /** - * Transforms the provided [stream]. - * - * Returns a new stream with events that are computed from events of the - * provided [stream]. - * - * The [StreamTransformer] interface is completely generic, - * so it cannot say what subclasses do. - * Each [StreamTransformer] should document clearly how it transforms the - * stream (on the class or variable used to access the transformer), - * as well as any differences from the following typical behavior: - * - * * When the returned stream is listened to, it starts listening to the - * input [stream]. - * * Subscriptions of the returned stream forward (in a reasonable time) - * a [StreamSubscription.pause] call to the subscription of the input - * [stream]. - * * Similarly, canceling a subscription of the returned stream eventually - * (in reasonable time) cancels the subscription of the input [stream]. - * - * "Reasonable time" depends on the transformer and stream. Some transformers, - * like a "timeout" transformer, might make these operations depend on a - * duration. Others might not delay them at all, or just by a microtask. - * - * Transformers are free to handle errors in any way. - * A transformer implementation may choose to propagate errors, - * or convert them to other events, or ignore them completely, - * but if errors are ignored, it should be documented explicitly. - */ - Stream bind(Stream stream); - - /** - * Provides a `StreamTransformer` view of this stream transformer. - * - * The resulting transformer will check at run-time that all data events - * of the stream it transforms are actually instances of [S], - * and it will check that all data events produced by this transformer - * are actually instances of [RT]. - */ - StreamTransformer cast(); -} - -/** - * Base class for implementing [StreamTransformer]. - * - * Contains default implementations of every method except [bind]. - */ -abstract class StreamTransformerBase implements StreamTransformer { - const StreamTransformerBase(); - - StreamTransformer cast() => - StreamTransformer.castFrom(this); -} - -/** - * An [Iterator] like interface for the values of a [Stream]. - * - * This wraps a [Stream] and a subscription on the stream. It listens - * on the stream, and completes the future returned by [moveNext] when the - * next value becomes available. - * - * The stream may be paused between calls to [moveNext]. - */ -abstract class StreamIterator { - /** Create a [StreamIterator] on [stream]. */ - factory StreamIterator(Stream stream) - // TODO(lrn): use redirecting factory constructor when type - // arguments are supported. - => - new _StreamIterator(stream); - - /** - * Wait for the next stream value to be available. - * - * Returns a future which will complete with either `true` or `false`. - * Completing with `true` means that another event has been received and - * can be read as [current]. - * Completing with `false` means that the stream iteration is done and - * no further events will ever be available. - * The future may complete with an error, if the stream produces an error, - * which also ends iteration. - * - * The function must not be called again until the future returned by a - * previous call is completed. - */ - Future moveNext(); - - /** - * The current value of the stream. - * - * Is `null` before the first call to [moveNext] and after a call to - * `moveNext` completes with a `false` result or an error. - * - * When a `moveNext` call completes with `true`, the `current` field holds - * the most recent event of the stream, and it stays like that until the next - * call to `moveNext`. - * Between a call to `moveNext` and when its returned future completes, - * the value is unspecified. - */ - T get current; - - /** - * Cancels the stream iterator (and the underlying stream subscription) early. - * - * The stream iterator is automatically canceled if the [moveNext] future - * completes with either `false` or an error. - * - * If you need to stop listening for values before the stream iterator is - * automatically closed, you must call [cancel] to ensure that the stream - * is properly closed. - * - * If [moveNext] has been called when the iterator is canceled, - * its returned future will complete with `false` as value, - * as will all further calls to [moveNext]. - * - * Returns a future if the cancel-operation is not completed synchronously. - * Otherwise returns `null`. - */ - Future cancel(); -} - -/** - * Wraps an [_EventSink] so it exposes only the [EventSink] interface. - */ -class _ControllerEventSinkWrapper implements EventSink { - EventSink? _sink; - _ControllerEventSinkWrapper(this._sink); - - EventSink _ensureSink() { - var sink = _sink; - if (sink == null) throw StateError("Sink not available"); - return sink; - } - - void add(T data) { - _ensureSink().add(data); - } - - void addError(error, [StackTrace? stackTrace]) { - _ensureSink().addError(error, stackTrace); - } - - void close() { - _ensureSink().close(); - } -} diff --git a/sdk_nnbd/lib/async/stream_controller.dart b/sdk_nnbd/lib/async/stream_controller.dart deleted file mode 100644 index 9688dd17ab8..00000000000 --- a/sdk_nnbd/lib/async/stream_controller.dart +++ /dev/null @@ -1,987 +0,0 @@ -// Copyright (c) 2012, 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. - -part of dart.async; - -// ------------------------------------------------------------------- -// Controller for creating and adding events to a stream. -// ------------------------------------------------------------------- - -/** - * Type of a stream controller's `onListen`, `onPause` and `onResume` callbacks. - */ -typedef void ControllerCallback(); - -/** - * Type of stream controller `onCancel` callbacks. - */ -typedef FutureOr ControllerCancelCallback(); - -/** - * A controller with the stream it controls. - * - * This controller allows sending data, error and done events on - * its [stream]. - * This class can be used to create a simple stream that others - * can listen on, and to push events to that stream. - * - * It's possible to check whether the stream is paused or not, and whether - * it has subscribers or not, as well as getting a callback when either of - * these change. - */ -abstract class StreamController implements StreamSink { - /** The stream that this controller is controlling. */ - Stream get stream; - - /** - * A controller with a [stream] that supports only one single subscriber. - * - * If [sync] is true, the returned stream controller is a - * [SynchronousStreamController], and must be used with the care - * and attention necessary to not break the [Stream] contract. If in doubt, - * use the non-sync version. - * - * Using an asynchronous controller will never give the wrong - * behavior, but using a synchronous controller incorrectly can cause - * otherwise correct programs to break. - * - * A synchronous controller is only intended for optimizing event - * propagation when one asynchronous event immediately triggers another. - * It should not be used unless the calls to [add] or [addError] - * are guaranteed to occur in places where it won't break `Stream` invariants. - * - * Use synchronous controllers only to forward (potentially transformed) - * events from another stream or a future. - * - * A Stream should be inert until a subscriber starts listening on it (using - * the [onListen] callback to start producing events). Streams should not - * leak resources (like websockets) when no user ever listens on the stream. - * - * The controller buffers all incoming events until a subscriber is - * registered, but this feature should only be used in rare circumstances. - * - * The [onPause] function is called when the stream becomes - * paused. [onResume] is called when the stream resumed. - * - * The [onListen] callback is called when the stream - * receives its listener and [onCancel] when the listener ends - * its subscription. If [onCancel] needs to perform an asynchronous operation, - * [onCancel] should return a future that completes when the cancel operation - * is done. - * - * If the stream is canceled before the controller needs data the - * [onResume] call might not be executed. - */ - factory StreamController( - {void onListen()?, - void onPause()?, - void onResume()?, - FutureOr onCancel()?, - bool sync = false}) { - return sync - ? _SyncStreamController(onListen, onPause, onResume, onCancel) - : _AsyncStreamController(onListen, onPause, onResume, onCancel); - } - - /** - * A controller where [stream] can be listened to more than once. - * - * The [Stream] returned by [stream] is a broadcast stream. - * It can be listened to more than once. - * - * A Stream should be inert until a subscriber starts listening on it (using - * the [onListen] callback to start producing events). Streams should not - * leak resources (like websockets) when no user ever listens on the stream. - * - * Broadcast streams do not buffer events when there is no listener. - * - * The controller distributes any events to all currently subscribed - * listeners at the time when [add], [addError] or [close] is called. - * It is not allowed to call `add`, `addError`, or `close` before a previous - * call has returned. The controller does not have any internal queue of - * events, and if there are no listeners at the time the event is added, - * it will just be dropped, or, if it is an error, be reported as uncaught. - * - * Each listener subscription is handled independently, - * and if one pauses, only the pausing listener is affected. - * A paused listener will buffer events internally until unpaused or canceled. - * - * If [sync] is true, events may be fired directly by the stream's - * subscriptions during an [add], [addError] or [close] call. - * The returned stream controller is a [SynchronousStreamController], - * and must be used with the care and attention necessary to not break - * the [Stream] contract. - * See [Completer.sync] for some explanations on when a synchronous - * dispatching can be used. - * If in doubt, keep the controller non-sync. - * - * If [sync] is false, the event will always be fired at a later time, - * after the code adding the event has completed. - * In that case, no guarantees are given with regard to when - * multiple listeners get the events, except that each listener will get - * all events in the correct order. Each subscription handles the events - * individually. - * If two events are sent on an async controller with two listeners, - * one of the listeners may get both events - * before the other listener gets any. - * A listener must be subscribed both when the event is initiated - * (that is, when [add] is called) - * and when the event is later delivered, - * in order to receive the event. - * - * The [onListen] callback is called when the first listener is subscribed, - * and the [onCancel] is called when there are no longer any active listeners. - * If a listener is added again later, after the [onCancel] was called, - * the [onListen] will be called again. - */ - factory StreamController.broadcast( - {void onListen()?, void onCancel()?, bool sync = false}) { - return sync - ? _SyncBroadcastStreamController(onListen, onCancel) - : _AsyncBroadcastStreamController(onListen, onCancel); - } - - /** - * The callback which is called when the stream is listened to. - * - * May be set to `null`, in which case no callback will happen. - */ - void Function()? get onListen; - - void set onListen(void onListenHandler()?); - - /** - * The callback which is called when the stream is paused. - * - * May be set to `null`, in which case no callback will happen. - * - * Pause related callbacks are not supported on broadcast stream controllers. - */ - void Function()? get onPause; - - void set onPause(void onPauseHandler()?); - - /** - * The callback which is called when the stream is resumed. - * - * May be set to `null`, in which case no callback will happen. - * - * Pause related callbacks are not supported on broadcast stream controllers. - */ - void Function()? get onResume; - - void set onResume(void onResumeHandler()?); - - /** - * The callback which is called when the stream is canceled. - * - * May be set to `null`, in which case no callback will happen. - */ - FutureOr Function()? get onCancel; - - void set onCancel(FutureOr onCancelHandler()?); - - /** - * Returns a view of this object that only exposes the [StreamSink] interface. - */ - StreamSink get sink; - - /** - * Whether the stream controller is closed for adding more events. - * - * The controller becomes closed by calling the [close] method. - * New events cannot be added, by calling [add] or [addError], - * to a closed controller. - * - * If the controller is closed, - * the "done" event might not have been delivered yet, - * but it has been scheduled, and it is too late to add more events. - */ - bool get isClosed; - - /** - * Whether the subscription would need to buffer events. - * - * This is the case if the controller's stream has a listener and it is - * paused, or if it has not received a listener yet. In that case, the - * controller is considered paused as well. - * - * A broadcast stream controller is never considered paused. It always - * forwards its events to all uncanceled subscriptions, if any, - * and let the subscriptions handle their own pausing and buffering. - */ - bool get isPaused; - - /** Whether there is a subscriber on the [Stream]. */ - bool get hasListener; - - /** - * Sends a data [event]. - * - * Listeners receive this event in a later microtask. - * - * Note that a synchronous controller (created by passing true to the `sync` - * parameter of the `StreamController` constructor) delivers events - * immediately. Since this behavior violates the contract mentioned here, - * synchronous controllers should only be used as described in the - * documentation to ensure that the delivered events always *appear* as if - * they were delivered in a separate microtask. - */ - void add(T event); - - /** - * Sends or enqueues an error event. - * - * If [error] is `null`, it is replaced by a [NullThrownError]. - * - * Listeners receive this event at a later microtask. This behavior can be - * overridden by using `sync` controllers. Note, however, that sync - * controllers have to satisfy the preconditions mentioned in the - * documentation of the constructors. - */ - void addError(Object error, [StackTrace? stackTrace]); - - /** - * Closes the stream. - * - * No further events can be added to a closed stream. - * - * The returned future is the same future provided by [done]. - * It is completed when the stream listeners is done sending events, - * This happens either when the done event has been sent, - * or when the subscriber on a single-subscription stream is canceled. - * - * A broadcast stream controller will send the done event - * even if listeners are paused, so some broadcast events may not have been - * received yet when the returned future completes. - * - * If noone listens to a non-broadcast stream, - * or the listener pauses and never resumes, - * the done event will not be sent and this future will never complete. - */ - Future close(); - - /** - * A future which is completed when the stream controller is done - * sending events. - * - * This happens either when the done event has been sent, or if the - * subscriber on a single-subscription stream is canceled. - * - * A broadcast stream controller will send the done event - * even if listeners are paused, so some broadcast events may not have been - * received yet when the returned future completes. - * - * If there is no listener on a non-broadcast stream, - * or the listener pauses and never resumes, - * the done event will not be sent and this future will never complete. - */ - Future get done; - - /** - * Receives events from [source] and puts them into this controller's stream. - * - * Returns a future which completes when the source stream is done. - * - * Events must not be added directly to this controller using [add], - * [addError], [close] or [addStream], until the returned future - * is complete. - * - * Data and error events are forwarded to this controller's stream. A done - * event on the source will end the `addStream` operation and complete the - * returned future. - * - * If [cancelOnError] is true, only the first error on [source] is - * forwarded to the controller's stream, and the `addStream` ends - * after this. If [cancelOnError] is false, all errors are forwarded - * and only a done event will end the `addStream`. - * If [cancelOnError] is omitted or `null`, it defaults to false. - */ - Future addStream(Stream source, {bool? cancelOnError}); -} - -/** - * A stream controller that delivers its events synchronously. - * - * A synchronous stream controller is intended for cases where - * an already asynchronous event triggers an event on a stream. - * - * Instead of adding the event to the stream in a later microtask, - * causing extra latency, the event is instead fired immediately by the - * synchronous stream controller, as if the stream event was - * the current event or microtask. - * - * The synchronous stream controller can be used to break the contract - * on [Stream], and it must be used carefully to avoid doing so. - * - * The only advantage to using a [SynchronousStreamController] over a - * normal [StreamController] is the improved latency. - * Only use the synchronous version if the improvement is significant, - * and if its use is safe. Otherwise just use a normal stream controller, - * which will always have the correct behavior for a [Stream], and won't - * accidentally break other code. - * - * Adding events to a synchronous controller should only happen as the - * very last part of the handling of the original event. - * At that point, adding an event to the stream is equivalent to - * returning to the event loop and adding the event in the next microtask. - * - * Each listener callback will be run as if it was a top-level event - * or microtask. This means that if it throws, the error will be reported as - * uncaught as soon as possible. - * This is one reason to add the event as the last thing in the original event - * handler - any action done after adding the event will delay the report of - * errors in the event listener callbacks. - * - * If an event is added in a setting that isn't known to be another event, - * it may cause the stream's listener to get that event before the listener - * is ready to handle it. We promise that after calling [Stream.listen], - * you won't get any events until the code doing the listen has completed. - * Calling [add] in response to a function call of unknown origin may break - * that promise. - * - * An [onListen] callback from the controller is *not* an asynchronous event, - * and adding events to the controller in the `onListen` callback is always - * wrong. The events will be delivered before the listener has even received - * the subscription yet. - * - * The synchronous broadcast stream controller also has a restrictions that a - * normal stream controller does not: - * The [add], [addError], [close] and [addStream] methods *must not* be - * called while an event is being delivered. - * That is, if a callback on a subscription on the controller's stream causes - * a call to any of the functions above, the call will fail. - * A broadcast stream may have more than one listener, and if an - * event is added synchronously while another is being also in the process - * of being added, the latter event might reach some listeners before - * the former. To prevent that, an event cannot be added while a previous - * event is being fired. - * This guarantees that an event is fully delivered when the - * first [add], [addError] or [close] returns, - * and further events will be delivered in the correct order. - * - * This still only guarantees that the event is delivered to the subscription. - * If the subscription is paused, the actual callback may still happen later, - * and the event will instead be buffered by the subscription. - * Barring pausing, and the following buffered events that haven't been - * delivered yet, callbacks will be called synchronously when an event is added. - * - * Adding an event to a synchronous non-broadcast stream controller while - * another event is in progress may cause the second event to be delayed - * and not be delivered synchronously, and until that event is delivered, - * the controller will not act synchronously. - */ -abstract class SynchronousStreamController implements StreamController { - /** - * Adds event to the controller's stream. - * - * As [StreamController.add], but must not be called while an event is - * being added by [add], [addError] or [close]. - */ - void add(T data); - - /** - * Adds error to the controller's stream. - * - * As [StreamController.addError], but must not be called while an event is - * being added by [add], [addError] or [close]. - */ - void addError(Object error, [StackTrace? stackTrace]); - - /** - * Closes the controller's stream. - * - * As [StreamController.close], but must not be called while an event is - * being added by [add], [addError] or [close]. - */ - Future close(); -} - -abstract class _StreamControllerLifecycle { - StreamSubscription _subscribe(void onData(T data)?, Function? onError, - void onDone()?, bool cancelOnError); - void _recordPause(StreamSubscription subscription) {} - void _recordResume(StreamSubscription subscription) {} - Future? _recordCancel(StreamSubscription subscription) => null; -} - -// Base type for implementations of stream controllers. -abstract class _StreamControllerBase - implements - StreamController, - _StreamControllerLifecycle, - _EventSink, - _EventDispatch {} - -/** - * Default implementation of [StreamController]. - * - * Controls a stream that only supports a single controller. - */ -abstract class _StreamController implements _StreamControllerBase { - // The states are bit-flags. More than one can be set at a time. - // - // The "subscription state" goes through the states: - // initial -> subscribed -> canceled. - // These are mutually exclusive. - // The "closed" state records whether the [close] method has been called - // on the controller. This can be done at any time. If done before - // subscription, the done event is queued. If done after cancel, the done - // event is ignored (just as any other event after a cancel). - - /** The controller is in its initial state with no subscription. */ - static const int _STATE_INITIAL = 0; - /** - * The controller has a subscription, but hasn't been closed or canceled. - * - * Keep in sync with - * runtime/vm/stack_trace.cc:kStreamController_StateSubscribed. - */ - static const int _STATE_SUBSCRIBED = 1; - /** The subscription is canceled. */ - static const int _STATE_CANCELED = 2; - /** Mask for the subscription state. */ - static const int _STATE_SUBSCRIPTION_MASK = 3; - - // The following state relate to the controller, not the subscription. - // If closed, adding more events is not allowed. - // If executing an [addStream], new events are not allowed either, but will - // be added by the stream. - - /** - * The controller is closed due to calling [close]. - * - * When the stream is closed, you can neither add new events nor add new - * listeners. - */ - static const int _STATE_CLOSED = 4; - /** - * The controller is in the middle of an [addStream] operation. - * - * While adding events from a stream, no new events can be added directly - * on the controller. - */ - static const int _STATE_ADDSTREAM = 8; - - /** - * Field containing different data depending on the current subscription - * state. - * - * If [_state] is [_STATE_INITIAL], the field may contain a [_PendingEvents] - * for events added to the controller before a subscription. - * - * While [_state] is [_STATE_SUBSCRIBED], the field contains the subscription. - * - * When [_state] is [_STATE_CANCELED] the field is currently not used, - * and will contain `null`. - */ - @pragma("vm:entry-point") - Object? _varData; - - /** Current state of the controller. */ - @pragma("vm:entry-point") - int _state = _STATE_INITIAL; - - /** - * Future completed when the stream sends its last event. - * - * This is also the future returned by [close]. - */ - // TODO(lrn): Could this be stored in the varData field too, if it's not - // accessed until the call to "close"? Then we need to special case if it's - // accessed earlier, or if close is called before subscribing. - _Future? _doneFuture; - - void Function()? onListen; - void Function()? onPause; - void Function()? onResume; - FutureOr Function()? onCancel; - - _StreamController(this.onListen, this.onPause, this.onResume, this.onCancel); - - // Return a new stream every time. The streams are equal, but not identical. - Stream get stream => _ControllerStream(this); - - /** - * Returns a view of this object that only exposes the [StreamSink] interface. - */ - StreamSink get sink => _StreamSinkWrapper(this); - - /** - * Whether a listener has existed and been canceled. - * - * After this, adding more events will be ignored. - */ - bool get _isCanceled => (_state & _STATE_CANCELED) != 0; - - /** Whether there is an active listener. */ - bool get hasListener => (_state & _STATE_SUBSCRIBED) != 0; - - /** Whether there has not been a listener yet. */ - bool get _isInitialState => - (_state & _STATE_SUBSCRIPTION_MASK) == _STATE_INITIAL; - - bool get isClosed => (_state & _STATE_CLOSED) != 0; - - bool get isPaused => - hasListener ? _subscription._isInputPaused : !_isCanceled; - - bool get _isAddingStream => (_state & _STATE_ADDSTREAM) != 0; - - /** New events may not be added after close, or during addStream. */ - bool get _mayAddEvent => (_state < _STATE_CLOSED); - - // Returns the pending events. - // Pending events are events added before a subscription exists. - // They are added to the subscription when it is created. - // Pending events, if any, are kept in the _varData field until the - // stream is listened to. - // While adding a stream, pending events are moved into the - // state object to allow the state object to use the _varData field. - _PendingEvents? get _pendingEvents { - assert(_isInitialState); - if (!_isAddingStream) { - return _varData as dynamic; - } - _StreamControllerAddStreamState state = _varData as dynamic; - return state.varData; - } - - // Returns the pending events, and creates the object if necessary. - _StreamImplEvents _ensurePendingEvents() { - assert(_isInitialState); - if (!_isAddingStream) { - Object? events = _varData; - if (events == null) { - _varData = events = _StreamImplEvents(); - } - return events as dynamic; - } - _StreamControllerAddStreamState state = _varData as dynamic; - Object? events = state.varData; - if (events == null) { - state.varData = events = _StreamImplEvents(); - } - return events as dynamic; - } - - // Get the current subscription. - // If we are adding a stream, the subscription is moved into the state - // object to allow the state object to use the _varData field. - _ControllerSubscription get _subscription { - assert(hasListener); - Object? varData = _varData; - if (_isAddingStream) { - _StreamControllerAddStreamState streamState = varData as dynamic; - varData = streamState.varData; - } - return varData as dynamic; - } - - /** - * Creates an error describing why an event cannot be added. - * - * The reason, and therefore the error message, depends on the current state. - */ - Error _badEventState() { - if (isClosed) { - return StateError("Cannot add event after closing"); - } - assert(_isAddingStream); - return StateError("Cannot add event while adding a stream"); - } - - // StreamSink interface. - Future addStream(Stream source, {bool? cancelOnError}) { - if (!_mayAddEvent) throw _badEventState(); - if (_isCanceled) return _Future.immediate(null); - _StreamControllerAddStreamState addState = - _StreamControllerAddStreamState( - this, _varData, source, cancelOnError ?? false); - _varData = addState; - _state |= _STATE_ADDSTREAM; - return addState.addStreamFuture; - } - - /** - * Returns a future that is completed when the stream is done - * processing events. - * - * This happens either when the done event has been sent, or if the - * subscriber of a single-subscription stream is cancelled. - */ - Future get done => _ensureDoneFuture(); - - Future _ensureDoneFuture() => - _doneFuture ??= _isCanceled ? Future._nullFuture : _Future(); - - /** - * Send or enqueue a data event. - */ - void add(T value) { - if (!_mayAddEvent) throw _badEventState(); - _add(value); - } - - /** - * Send or enqueue an error event. - */ - void addError(Object error, [StackTrace? stackTrace]) { - // TODO(40614): Remove once non-nullability is sound. - ArgumentError.checkNotNull(error, "error"); - if (!_mayAddEvent) throw _badEventState(); - AsyncError? replacement = Zone.current.errorCallback(error, stackTrace); - if (replacement != null) { - error = replacement.error; - stackTrace = replacement.stackTrace; - } else { - stackTrace ??= AsyncError.defaultStackTrace(error); - } - if (stackTrace == null) throw "unreachable"; // TODO(40088) - _addError(error, stackTrace); - } - - /** - * Closes this controller and sends a done event on the stream. - * - * The first time a controller is closed, a "done" event is added to its - * stream. - * - * You are allowed to close the controller more than once, but only the first - * call has any effect. - * - * After closing, no further events may be added using [add], [addError] - * or [addStream]. - * - * The returned future is completed when the done event has been delivered. - */ - Future close() { - if (isClosed) { - return _ensureDoneFuture(); - } - if (!_mayAddEvent) throw _badEventState(); - _closeUnchecked(); - return _ensureDoneFuture(); - } - - void _closeUnchecked() { - _state |= _STATE_CLOSED; - if (hasListener) { - _sendDone(); - } else if (_isInitialState) { - _ensurePendingEvents().add(const _DelayedDone()); - } - } - - // EventSink interface. Used by the [addStream] events. - - // Add data event, used both by the [addStream] events and by [add]. - void _add(T value) { - if (hasListener) { - _sendData(value); - } else if (_isInitialState) { - _ensurePendingEvents().add(_DelayedData(value)); - } - } - - void _addError(Object error, StackTrace stackTrace) { - if (hasListener) { - _sendError(error, stackTrace); - } else if (_isInitialState) { - _ensurePendingEvents().add(_DelayedError(error, stackTrace)); - } - } - - void _close() { - // End of addStream stream. - assert(_isAddingStream); - _StreamControllerAddStreamState addState = _varData as dynamic; - _varData = addState.varData; - _state &= ~_STATE_ADDSTREAM; - addState.complete(); - } - - // _StreamControllerLifeCycle interface - - StreamSubscription _subscribe(void onData(T data)?, Function? onError, - void onDone()?, bool cancelOnError) { - if (!_isInitialState) { - throw StateError("Stream has already been listened to."); - } - _ControllerSubscription subscription = _ControllerSubscription( - this, onData, onError, onDone, cancelOnError); - - _PendingEvents? pendingEvents = _pendingEvents; - _state |= _STATE_SUBSCRIBED; - if (_isAddingStream) { - _StreamControllerAddStreamState addState = _varData as dynamic; - addState.varData = subscription; - addState.resume(); - } else { - _varData = subscription; - } - subscription._setPendingEvents(pendingEvents); - subscription._guardCallback(() { - _runGuarded(onListen); - }); - - return subscription; - } - - Future? _recordCancel(StreamSubscription subscription) { - // When we cancel, we first cancel any stream being added, - // Then we call `onCancel`, and finally the _doneFuture is completed. - // If either of addStream's cancel or `onCancel` returns a future, - // we wait for it before continuing. - // Any error during this process ends up in the returned future. - // If more errors happen, we act as if it happens inside nested try/finallys - // or whenComplete calls, and only the last error ends up in the - // returned future. - Future? result; - if (_isAddingStream) { - _StreamControllerAddStreamState addState = _varData as dynamic; - result = addState.cancel(); - } - _varData = null; - _state = - (_state & ~(_STATE_SUBSCRIBED | _STATE_ADDSTREAM)) | _STATE_CANCELED; - - var onCancel = this.onCancel; - if (onCancel != null) { - if (result == null) { - // Only introduce a future if one is needed. - // If _onCancel returns null, no future is needed. - try { - var cancelResult = onCancel(); - if (cancelResult is Future) { - result = cancelResult; - } - } catch (e, s) { - // Return the error in the returned future. - // Complete it asynchronously, so there is time for a listener - // to handle the error. - result = _Future().._asyncCompleteError(e, s); - } - } else { - // Simpler case when we already know that we will return a future. - result = result.whenComplete(onCancel); - } - } - - void complete() { - var doneFuture = _doneFuture; - if (doneFuture != null && doneFuture._mayComplete) { - doneFuture._asyncComplete(null); - } - } - - if (result != null) { - result = result.whenComplete(complete); - } else { - complete(); - } - - return result; - } - - void _recordPause(StreamSubscription subscription) { - if (_isAddingStream) { - _StreamControllerAddStreamState addState = _varData as dynamic; - addState.pause(); - } - _runGuarded(onPause); - } - - void _recordResume(StreamSubscription subscription) { - if (_isAddingStream) { - _StreamControllerAddStreamState addState = _varData as dynamic; - addState.resume(); - } - _runGuarded(onResume); - } -} - -abstract class _SyncStreamControllerDispatch - implements _StreamController, SynchronousStreamController { - int get _state; - void set _state(int state); - - void _sendData(T data) { - _subscription._add(data); - } - - void _sendError(Object error, StackTrace stackTrace) { - _subscription._addError(error, stackTrace); - } - - void _sendDone() { - _subscription._close(); - } -} - -abstract class _AsyncStreamControllerDispatch - implements _StreamController { - void _sendData(T data) { - _subscription._addPending(_DelayedData(data)); - } - - void _sendError(Object error, StackTrace stackTrace) { - _subscription._addPending(_DelayedError(error, stackTrace)); - } - - void _sendDone() { - _subscription._addPending(const _DelayedDone()); - } -} - -// TODO(lrn): Use common superclass for callback-controllers when VM supports -// constructors in mixin superclasses. - -class _AsyncStreamController = _StreamController - with _AsyncStreamControllerDispatch; - -class _SyncStreamController = _StreamController - with _SyncStreamControllerDispatch; - -void _runGuarded(void Function()? notificationHandler) { - if (notificationHandler == null) return; - try { - notificationHandler(); - } catch (e, s) { - Zone.current.handleUncaughtError(e, s); - } -} - -class _ControllerStream extends _StreamImpl { - _StreamControllerLifecycle _controller; - - _ControllerStream(this._controller); - - StreamSubscription _createSubscription(void onData(T data)?, - Function? onError, void onDone()?, bool cancelOnError) => - _controller._subscribe(onData, onError, onDone, cancelOnError); - - // Override == and hashCode so that new streams returned by the same - // controller are considered equal. The controller returns a new stream - // each time it's queried, but doesn't have to cache the result. - - int get hashCode => _controller.hashCode ^ 0x35323532; - - bool operator ==(Object other) { - if (identical(this, other)) return true; - return other is _ControllerStream && - identical(other._controller, this._controller); - } -} - -class _ControllerSubscription extends _BufferingStreamSubscription { - final _StreamControllerLifecycle _controller; - - _ControllerSubscription(this._controller, void onData(T data)?, - Function? onError, void onDone()?, bool cancelOnError) - : super(onData, onError, onDone, cancelOnError); - - Future? _onCancel() { - return _controller._recordCancel(this); - } - - void _onPause() { - _controller._recordPause(this); - } - - void _onResume() { - _controller._recordResume(this); - } -} - -/** A class that exposes only the [StreamSink] interface of an object. */ -class _StreamSinkWrapper implements StreamSink { - final StreamController _target; - _StreamSinkWrapper(this._target); - void add(T data) { - _target.add(data); - } - - void addError(Object error, [StackTrace? stackTrace]) { - _target.addError(error, stackTrace); - } - - Future close() => _target.close(); - - Future addStream(Stream source) => _target.addStream(source); - - Future get done => _target.done; -} - -/** - * Object containing the state used to handle [StreamController.addStream]. - */ -class _AddStreamState { - // [_Future] returned by call to addStream. - final _Future addStreamFuture; - - // Subscription on stream argument to addStream. - final StreamSubscription addSubscription; - - _AddStreamState( - _EventSink controller, Stream source, bool cancelOnError) - : addStreamFuture = _Future(), - addSubscription = source.listen(controller._add, - onError: cancelOnError - ? makeErrorHandler(controller) - : controller._addError, - onDone: controller._close, - cancelOnError: cancelOnError); - - static makeErrorHandler(_EventSink controller) => (Object e, StackTrace s) { - controller._addError(e, s); - controller._close(); - }; - - void pause() { - addSubscription.pause(); - } - - void resume() { - addSubscription.resume(); - } - - /** - * Stop adding the stream. - * - * Complete the future returned by `StreamController.addStream` when - * the cancel is complete. - * - * Return a future if the cancel takes time, otherwise return `null`. - */ - Future cancel() { - var cancel = addSubscription.cancel(); - if (cancel == null) { - addStreamFuture._asyncComplete(null); - return Future._nullFuture; - } - return cancel.whenComplete(() { - addStreamFuture._asyncComplete(null); - }); - } - - void complete() { - addStreamFuture._asyncComplete(null); - } -} - -class _StreamControllerAddStreamState extends _AddStreamState { - // The subscription or pending data of a _StreamController. - // Stored here because we reuse the `_varData` field in the _StreamController - // to store this state object. - var varData; - - _StreamControllerAddStreamState(_StreamController controller, this.varData, - Stream source, bool cancelOnError) - : super(controller, source, cancelOnError) { - if (controller.isPaused) { - addSubscription.pause(); - } - } -} diff --git a/sdk_nnbd/lib/async/stream_impl.dart b/sdk_nnbd/lib/async/stream_impl.dart deleted file mode 100644 index 1c6fa50c7f7..00000000000 --- a/sdk_nnbd/lib/async/stream_impl.dart +++ /dev/null @@ -1,1099 +0,0 @@ -// Copyright (c) 2012, 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. - -part of dart.async; - -/** Abstract and private interface for a place to put events. */ -abstract class _EventSink { - void _add(T data); - void _addError(Object error, StackTrace stackTrace); - void _close(); -} - -/** - * Abstract and private interface for a place to send events. - * - * Used by event buffering to finally dispatch the pending event, where - * [_EventSink] is where the event first enters the stream subscription, - * and may yet be buffered. - */ -abstract class _EventDispatch { - void _sendData(T data); - void _sendError(Object error, StackTrace stackTrace); - void _sendDone(); -} - -/** - * Default implementation of stream subscription of buffering events. - * - * The only public methods are those of [StreamSubscription], so instances of - * [_BufferingStreamSubscription] can be returned directly as a - * [StreamSubscription] without exposing internal functionality. - * - * The [StreamController] is a public facing version of [Stream] and this class, - * with some methods made public. - * - * The user interface of [_BufferingStreamSubscription] are the following - * methods: - * - * * [_add]: Add a data event to the stream. - * * [_addError]: Add an error event to the stream. - * * [_close]: Request to close the stream. - * * [_onCancel]: Called when the subscription will provide no more events, - * either due to being actively canceled, or after sending a done event. - * * [_onPause]: Called when the subscription wants the event source to pause. - * * [_onResume]: Called when allowing new events after a pause. - * - * The user should not add new events when the subscription requests a paused, - * but if it happens anyway, the subscription will enqueue the events just as - * when new events arrive while still firing an old event. - */ -class _BufferingStreamSubscription - implements StreamSubscription, _EventSink, _EventDispatch { - /** The `cancelOnError` flag from the `listen` call. */ - static const int _STATE_CANCEL_ON_ERROR = 1; - /** - * Whether the "done" event has been received. - * No further events are accepted after this. - */ - static const int _STATE_CLOSED = 2; - /** - * Set if the input has been asked not to send events. - * - * This is not the same as being paused, since the input will remain paused - * after a call to [resume] if there are pending events. - */ - static const int _STATE_INPUT_PAUSED = 4; - /** - * Whether the subscription has been canceled. - * - * Set by calling [cancel], or by handling a "done" event, or an "error" event - * when `cancelOnError` is true. - */ - static const int _STATE_CANCELED = 8; - /** - * Set when either: - * - * * an error is sent, and [cancelOnError] is true, or - * * a done event is sent. - * - * If the subscription is canceled while _STATE_WAIT_FOR_CANCEL is set, the - * state is unset, and no further events must be delivered. - */ - static const int _STATE_WAIT_FOR_CANCEL = 16; - static const int _STATE_IN_CALLBACK = 32; - static const int _STATE_HAS_PENDING = 64; - static const int _STATE_PAUSE_COUNT = 128; - - /* Event handlers provided in constructor. */ - @pragma("vm:entry-point") - _DataHandler _onData; - Function _onError; - _DoneHandler _onDone; - - final Zone _zone; - - /** Bit vector based on state-constants above. */ - int _state; - - // TODO(floitsch): reuse another field - /** The future [_onCancel] may return. */ - Future? _cancelFuture; - - /** - * Queue of pending events. - * - * Is created when necessary, or set in constructor for preconfigured events. - */ - _PendingEvents? _pending; - - _BufferingStreamSubscription(void onData(T data)?, Function? onError, - void onDone()?, bool cancelOnError) - : this.zoned(Zone.current, onData, onError, onDone, cancelOnError); - - _BufferingStreamSubscription.zoned(this._zone, void onData(T data)?, - Function? onError, void onDone()?, bool cancelOnError) - : _state = (cancelOnError ? _STATE_CANCEL_ON_ERROR : 0), - _onData = _registerDataHandler(_zone, onData), - _onError = _registerErrorHandler(_zone, onError), - _onDone = _registerDoneHandler(_zone, onDone); - - /** - * Sets the subscription's pending events object. - * - * This can only be done once. The pending events object is used for the - * rest of the subscription's life cycle. - */ - void _setPendingEvents(_PendingEvents? pendingEvents) { - assert(_pending == null); - if (pendingEvents == null) return; - _pending = pendingEvents; - if (!pendingEvents.isEmpty) { - _state |= _STATE_HAS_PENDING; - pendingEvents.schedule(this); - } - } - - // StreamSubscription interface. - - void onData(void handleData(T event)?) { - _onData = _registerDataHandler(_zone, handleData); - } - - static void Function(T) _registerDataHandler( - Zone zone, void Function(T)? handleData) { - return zone.registerUnaryCallback(handleData ?? _nullDataHandler); - } - - void onError(Function? handleError) { - _onError = _registerErrorHandler(_zone, handleError); - } - - static Function _registerErrorHandler(Zone zone, Function? handleError) { - // TODO(lrn): Consider whether we need to register the null handler. - handleError ??= _nullErrorHandler; - if (handleError is void Function(Object, StackTrace)) { - return zone - .registerBinaryCallback(handleError); - } - if (handleError is void Function(Object)) { - return zone.registerUnaryCallback(handleError); - } - throw new ArgumentError("handleError callback must take either an Object " - "(the error), or both an Object (the error) and a StackTrace."); - } - - void onDone(void handleDone()?) { - _onDone = _registerDoneHandler(_zone, handleDone); - } - - static void Function() _registerDoneHandler( - Zone zone, void Function()? handleDone) { - return zone.registerCallback(handleDone ?? _nullDoneHandler); - } - - void pause([Future? resumeSignal]) { - if (_isCanceled) return; - bool wasPaused = _isPaused; - bool wasInputPaused = _isInputPaused; - // Increment pause count and mark input paused (if it isn't already). - _state = (_state + _STATE_PAUSE_COUNT) | _STATE_INPUT_PAUSED; - resumeSignal?.whenComplete(resume); - if (!wasPaused) _pending?.cancelSchedule(); - if (!wasInputPaused && !_inCallback) _guardCallback(_onPause); - } - - void resume() { - if (_isCanceled) return; - if (_isPaused) { - _decrementPauseCount(); - if (!_isPaused) { - if (_hasPending && !_pending!.isEmpty) { - // Input is still paused. - _pending!.schedule(this); - } else { - assert(_mayResumeInput); - _state &= ~_STATE_INPUT_PAUSED; - if (!_inCallback) _guardCallback(_onResume); - } - } - } - } - - Future cancel() { - // The user doesn't want to receive any further events. If there is an - // error or done event pending (waiting for the cancel to be done) discard - // that event. - _state &= ~_STATE_WAIT_FOR_CANCEL; - if (!_isCanceled) { - _cancel(); - } - return _cancelFuture ?? Future._nullFuture; - } - - Future asFuture([E? futureValue]) { - E resultValue; - if (futureValue == null) { - if (!typeAcceptsNull()) { - throw ArgumentError.notNull("futureValue"); - } - resultValue = futureValue as dynamic; - } else { - resultValue = futureValue; - } - // Overwrite the onDone and onError handlers. - _Future result = new _Future(); - _onDone = () { - result._complete(resultValue); - }; - _onError = (Object error, StackTrace stackTrace) { - Future cancelFuture = cancel(); - if (!identical(cancelFuture, Future._nullFuture)) { - cancelFuture.whenComplete(() { - result._completeError(error, stackTrace); - }); - } else { - result._completeError(error, stackTrace); - } - }; - return result; - } - - // State management. - - bool get _isInputPaused => (_state & _STATE_INPUT_PAUSED) != 0; - bool get _isClosed => (_state & _STATE_CLOSED) != 0; - bool get _isCanceled => (_state & _STATE_CANCELED) != 0; - bool get _waitsForCancel => (_state & _STATE_WAIT_FOR_CANCEL) != 0; - bool get _inCallback => (_state & _STATE_IN_CALLBACK) != 0; - bool get _hasPending => (_state & _STATE_HAS_PENDING) != 0; - bool get _isPaused => _state >= _STATE_PAUSE_COUNT; - bool get _canFire => _state < _STATE_IN_CALLBACK; - bool get _mayResumeInput => !_isPaused && (_pending?.isEmpty ?? true); - bool get _cancelOnError => (_state & _STATE_CANCEL_ON_ERROR) != 0; - - bool get isPaused => _isPaused; - - void _cancel() { - _state |= _STATE_CANCELED; - if (_hasPending) { - _pending!.cancelSchedule(); - } - if (!_inCallback) _pending = null; - _cancelFuture = _onCancel(); - } - - /** - * Decrements the pause count. - * - * Does not automatically unpause the input (call [_onResume]) when - * the pause count reaches zero. This is handled elsewhere, and only - * if there are no pending events buffered. - */ - void _decrementPauseCount() { - assert(_isPaused); - _state -= _STATE_PAUSE_COUNT; - } - - // _EventSink interface. - - void _add(T data) { - assert(!_isClosed); - if (_isCanceled) return; - if (_canFire) { - _sendData(data); - } else { - _addPending(new _DelayedData(data)); - } - } - - void _addError(Object error, StackTrace stackTrace) { - if (_isCanceled) return; - if (_canFire) { - _sendError(error, stackTrace); // Reports cancel after sending. - } else { - _addPending(new _DelayedError(error, stackTrace)); - } - } - - void _close() { - assert(!_isClosed); - if (_isCanceled) return; - _state |= _STATE_CLOSED; - if (_canFire) { - _sendDone(); - } else { - _addPending(const _DelayedDone()); - } - } - - // Hooks called when the input is paused, unpaused or canceled. - // These must not throw. If overwritten to call user code, include suitable - // try/catch wrapping and send any errors to - // [_Zone.current.handleUncaughtError]. - void _onPause() { - assert(_isInputPaused); - } - - void _onResume() { - assert(!_isInputPaused); - } - - Future? _onCancel() { - assert(_isCanceled); - return null; - } - - // Handle pending events. - - /** - * Add a pending event. - * - * If the subscription is not paused, this also schedules a firing - * of pending events later (if necessary). - */ - void _addPending(_DelayedEvent event) { - _StreamImplEvents? pending = _pending as dynamic; - pending ??= _StreamImplEvents(); - _pending = pending; - pending.add(event); - if (!_hasPending) { - _state |= _STATE_HAS_PENDING; - if (!_isPaused) { - pending.schedule(this); - } - } - } - - /* _EventDispatch interface. */ - - void _sendData(T data) { - assert(!_isCanceled); - assert(!_isPaused); - assert(!_inCallback); - bool wasInputPaused = _isInputPaused; - _state |= _STATE_IN_CALLBACK; - _zone.runUnaryGuarded(_onData, data); - _state &= ~_STATE_IN_CALLBACK; - _checkState(wasInputPaused); - } - - void _sendError(Object error, StackTrace stackTrace) { - assert(!_isCanceled); - assert(!_isPaused); - assert(!_inCallback); - bool wasInputPaused = _isInputPaused; - - void sendError() { - // If the subscription has been canceled while waiting for the cancel - // future to finish we must not report the error. - if (_isCanceled && !_waitsForCancel) return; - _state |= _STATE_IN_CALLBACK; - // TODO(floitsch): this dynamic should be 'void'. - var onError = _onError; - if (onError is void Function(Object, StackTrace)) { - _zone.runBinaryGuarded(onError, error, stackTrace); - } else { - _zone.runUnaryGuarded(_onError as dynamic, error); - } - _state &= ~_STATE_IN_CALLBACK; - } - - if (_cancelOnError) { - _state |= _STATE_WAIT_FOR_CANCEL; - _cancel(); - var cancelFuture = _cancelFuture; - if (cancelFuture != null && - !identical(cancelFuture, Future._nullFuture)) { - cancelFuture.whenComplete(sendError); - } else { - sendError(); - } - } else { - sendError(); - // Only check state if not cancelOnError. - _checkState(wasInputPaused); - } - } - - void _sendDone() { - assert(!_isCanceled); - assert(!_isPaused); - assert(!_inCallback); - - void sendDone() { - // If the subscription has been canceled while waiting for the cancel - // future to finish we must not report the done event. - if (!_waitsForCancel) return; - _state |= (_STATE_CANCELED | _STATE_CLOSED | _STATE_IN_CALLBACK); - _zone.runGuarded(_onDone); - _state &= ~_STATE_IN_CALLBACK; - } - - _cancel(); - _state |= _STATE_WAIT_FOR_CANCEL; - var cancelFuture = _cancelFuture; - if (cancelFuture != null && !identical(cancelFuture, Future._nullFuture)) { - cancelFuture.whenComplete(sendDone); - } else { - sendDone(); - } - } - - /** - * Call a hook function. - * - * The call is properly wrapped in code to avoid other callbacks - * during the call, and it checks for state changes after the call - * that should cause further callbacks. - */ - void _guardCallback(void Function() callback) { - assert(!_inCallback); - bool wasInputPaused = _isInputPaused; - _state |= _STATE_IN_CALLBACK; - callback(); - _state &= ~_STATE_IN_CALLBACK; - _checkState(wasInputPaused); - } - - /** - * Check if the input needs to be informed of state changes. - * - * State changes are pausing, resuming and canceling. - * - * After canceling, no further callbacks will happen. - * - * The cancel callback is called after a user cancel, or after - * the final done event is sent. - */ - void _checkState(bool wasInputPaused) { - assert(!_inCallback); - if (_hasPending && _pending!.isEmpty) { - _state &= ~_STATE_HAS_PENDING; - if (_isInputPaused && _mayResumeInput) { - _state &= ~_STATE_INPUT_PAUSED; - } - } - // If the state changes during a callback, we immediately - // make a new state-change callback. Loop until the state didn't change. - while (true) { - if (_isCanceled) { - _pending = null; - return; - } - bool isInputPaused = _isInputPaused; - if (wasInputPaused == isInputPaused) break; - _state ^= _STATE_IN_CALLBACK; - if (isInputPaused) { - _onPause(); - } else { - _onResume(); - } - _state &= ~_STATE_IN_CALLBACK; - wasInputPaused = isInputPaused; - } - if (_hasPending && !_isPaused) { - _pending!.schedule(this); - } - } -} - -// ------------------------------------------------------------------- -// Common base class for single and multi-subscription streams. -// ------------------------------------------------------------------- -abstract class _StreamImpl extends Stream { - // ------------------------------------------------------------------ - // Stream interface. - - StreamSubscription listen(void onData(T data)?, - {Function? onError, void onDone()?, bool? cancelOnError}) { - cancelOnError ??= false; - StreamSubscription subscription = - _createSubscription(onData, onError, onDone, cancelOnError); - _onListen(subscription); - return subscription; - } - - // ------------------------------------------------------------------- - /** Create a subscription object. Called by [subcribe]. */ - StreamSubscription _createSubscription(void onData(T data)?, - Function? onError, void onDone()?, bool cancelOnError) { - return new _BufferingStreamSubscription( - onData, onError, onDone, cancelOnError); - } - - /** Hook called when the subscription has been created. */ - void _onListen(StreamSubscription subscription) {} -} - -typedef _PendingEvents _EventGenerator(); - -/** Stream that generates its own events. */ -class _GeneratedStreamImpl extends _StreamImpl { - final _EventGenerator _pending; - bool _isUsed = false; - /** - * Initializes the stream to have only the events provided by a - * [_PendingEvents]. - * - * A new [_PendingEvents] must be generated for each listen. - */ - _GeneratedStreamImpl(this._pending); - - StreamSubscription _createSubscription(void onData(T data)?, - Function? onError, void onDone()?, bool cancelOnError) { - if (_isUsed) throw new StateError("Stream has already been listened to."); - _isUsed = true; - return new _BufferingStreamSubscription( - onData, onError, onDone, cancelOnError) - .._setPendingEvents(_pending()); - } -} - -/** Pending events object that gets its events from an [Iterable]. */ -class _IterablePendingEvents extends _PendingEvents { - // The iterator providing data for data events. - // Set to null when iteration has completed. - Iterator? _iterator; - - _IterablePendingEvents(Iterable data) : _iterator = data.iterator; - - bool get isEmpty => _iterator == null; - - void handleNext(_EventDispatch dispatch) { - var iterator = _iterator; - if (iterator == null) { - throw new StateError("No events pending."); - } - // Send one event per call to moveNext. - // If moveNext returns true, send the current element as data. - // If current throws, send that error, but keep iterating. - // If moveNext returns false, send a done event and clear the _iterator. - // If moveNext throws an error, send an error and prepare to send a done - // event afterwards. - bool movedNext = false; - try { - if (iterator.moveNext()) { - movedNext = true; - dispatch._sendData(iterator.current); - } else { - _iterator = null; - dispatch._sendDone(); - } - } catch (e, s) { - if (!movedNext) { - // Threw in .moveNext(). - // Ensure that we send a done afterwards. - _iterator = const EmptyIterator(); - } - // Else threw in .current. - dispatch._sendError(e, s); - } - } - - void clear() { - if (isScheduled) cancelSchedule(); - _iterator = null; - } -} - -// Internal helpers. - -// Types of the different handlers on a stream. Types used to type fields. -typedef void _DataHandler(T value); -typedef void _DoneHandler(); - -/** Default data handler, does nothing. */ -void _nullDataHandler(dynamic value) {} - -/** Default error handler, reports the error to the current zone's handler. */ -void _nullErrorHandler(Object error, StackTrace stackTrace) { - Zone.current.handleUncaughtError(error, stackTrace); -} - -/** Default done handler, does nothing. */ -void _nullDoneHandler() {} - -/** A delayed event on a buffering stream subscription. */ -abstract class _DelayedEvent { - /** Added as a linked list on the [StreamController]. */ - _DelayedEvent? next; - /** Execute the delayed event on the [StreamController]. */ - void perform(_EventDispatch dispatch); -} - -/** A delayed data event. */ -class _DelayedData extends _DelayedEvent { - final T value; - _DelayedData(this.value); - void perform(_EventDispatch dispatch) { - dispatch._sendData(value); - } -} - -/** A delayed error event. */ -class _DelayedError extends _DelayedEvent { - final Object error; - final StackTrace stackTrace; - - _DelayedError(this.error, this.stackTrace); - void perform(_EventDispatch dispatch) { - dispatch._sendError(error, stackTrace); - } -} - -/** A delayed done event. */ -class _DelayedDone implements _DelayedEvent { - const _DelayedDone(); - void perform(_EventDispatch dispatch) { - dispatch._sendDone(); - } - - _DelayedEvent? get next => null; - - void set next(_DelayedEvent? _) { - throw new StateError("No events after a done."); - } -} - -/** Superclass for provider of pending events. */ -abstract class _PendingEvents { - // No async event has been scheduled. - static const int _STATE_UNSCHEDULED = 0; - // An async event has been scheduled to run a function. - static const int _STATE_SCHEDULED = 1; - // An async event has been scheduled, but it will do nothing when it runs. - // Async events can't be preempted. - static const int _STATE_CANCELED = 3; - - /** - * State of being scheduled. - * - * Set to [_STATE_SCHEDULED] when pending events are scheduled for - * async dispatch. Since we can't cancel a [scheduleMicrotask] call, if - * scheduling is "canceled", the _state is simply set to [_STATE_CANCELED] - * which will make the async code do nothing except resetting [_state]. - * - * If events are scheduled while the state is [_STATE_CANCELED], it is - * merely switched back to [_STATE_SCHEDULED], but no new call to - * [scheduleMicrotask] is performed. - */ - int _state = _STATE_UNSCHEDULED; - - bool get isEmpty; - - bool get isScheduled => _state == _STATE_SCHEDULED; - bool get _eventScheduled => _state >= _STATE_SCHEDULED; - - /** - * Schedule an event to run later. - * - * If called more than once, it should be called with the same dispatch as - * argument each time. It may reuse an earlier argument in some cases. - */ - void schedule(_EventDispatch dispatch) { - if (isScheduled) return; - assert(!isEmpty); - if (_eventScheduled) { - assert(_state == _STATE_CANCELED); - _state = _STATE_SCHEDULED; - return; - } - scheduleMicrotask(() { - int oldState = _state; - _state = _STATE_UNSCHEDULED; - if (oldState == _STATE_CANCELED) return; - handleNext(dispatch); - }); - _state = _STATE_SCHEDULED; - } - - void cancelSchedule() { - if (isScheduled) _state = _STATE_CANCELED; - } - - void handleNext(_EventDispatch dispatch); - - /** Throw away any pending events and cancel scheduled events. */ - void clear(); -} - -/** Class holding pending events for a [_StreamImpl]. */ -class _StreamImplEvents extends _PendingEvents { - /// Single linked list of [_DelayedEvent] objects. - _DelayedEvent? firstPendingEvent; - - /// Last element in the list of pending events. New events are added after it. - _DelayedEvent? lastPendingEvent; - - bool get isEmpty => lastPendingEvent == null; - - void add(_DelayedEvent event) { - var lastEvent = lastPendingEvent; - if (lastEvent == null) { - firstPendingEvent = lastPendingEvent = event; - } else { - lastPendingEvent = lastEvent.next = event; - } - } - - void handleNext(_EventDispatch dispatch) { - assert(!isScheduled); - assert(!isEmpty); - _DelayedEvent event = firstPendingEvent!; - _DelayedEvent? nextEvent = event.next; - firstPendingEvent = nextEvent; - if (nextEvent == null) { - lastPendingEvent = null; - } - event.perform(dispatch); - } - - void clear() { - if (isScheduled) cancelSchedule(); - firstPendingEvent = lastPendingEvent = null; - } -} - -typedef void _BroadcastCallback(StreamSubscription subscription); - -/** - * Done subscription that will send one done event as soon as possible. - */ -class _DoneStreamSubscription implements StreamSubscription { - static const int _DONE_SENT = 1; - static const int _SCHEDULED = 2; - static const int _PAUSED = 4; - - final Zone _zone; - int _state = 0; - _DoneHandler? _onDone; - - _DoneStreamSubscription(this._onDone) : _zone = Zone.current { - _schedule(); - } - - bool get _isSent => (_state & _DONE_SENT) != 0; - bool get _isScheduled => (_state & _SCHEDULED) != 0; - bool get isPaused => _state >= _PAUSED; - - void _schedule() { - if (_isScheduled) return; - _zone.scheduleMicrotask(_sendDone); - _state |= _SCHEDULED; - } - - void onData(void handleData(T data)?) {} - void onError(Function? handleError) {} - void onDone(void handleDone()?) { - _onDone = handleDone; - } - - void pause([Future? resumeSignal]) { - _state += _PAUSED; - if (resumeSignal != null) resumeSignal.whenComplete(resume); - } - - void resume() { - if (isPaused) { - _state -= _PAUSED; - if (!isPaused && !_isSent) { - _schedule(); - } - } - } - - Future cancel() => Future._nullFuture; - - Future asFuture([E? futureValue]) { - E resultValue; - if (futureValue == null) { - if (!typeAcceptsNull()) { - throw ArgumentError.notNull("futureValue"); - } - resultValue = futureValue as dynamic; - } else { - resultValue = futureValue; - } - _Future result = new _Future(); - _onDone = () { - result._completeWithValue(resultValue); - }; - return result; - } - - void _sendDone() { - _state &= ~_SCHEDULED; - if (isPaused) return; - _state |= _DONE_SENT; - var doneHandler = _onDone; - if (doneHandler != null) _zone.runGuarded(doneHandler); - } -} - -class _AsBroadcastStream extends Stream { - final Stream _source; - final _BroadcastCallback? _onListenHandler; - final _BroadcastCallback? _onCancelHandler; - final Zone _zone; - - _AsBroadcastStreamController? _controller; - StreamSubscription? _subscription; - - _AsBroadcastStream( - this._source, - void onListenHandler(StreamSubscription subscription)?, - void onCancelHandler(StreamSubscription subscription)?) - : _onListenHandler = onListenHandler == null - ? null - : Zone.current.registerUnaryCallback>( - onListenHandler), - _onCancelHandler = onCancelHandler == null - ? null - : Zone.current.registerUnaryCallback>( - onCancelHandler), - _zone = Zone.current { - _controller = new _AsBroadcastStreamController(_onListen, _onCancel); - } - - bool get isBroadcast => true; - - StreamSubscription listen(void onData(T data)?, - {Function? onError, void onDone()?, bool? cancelOnError}) { - var controller = _controller; - if (controller == null || controller.isClosed) { - // Return a dummy subscription backed by nothing, since - // it will only ever send one done event. - return new _DoneStreamSubscription(onDone); - } - _subscription ??= _source.listen(controller.add, - onError: controller.addError, onDone: controller.close); - return controller._subscribe( - onData, onError, onDone, cancelOnError ?? false); - } - - void _onCancel() { - var controller = _controller; - bool shutdown = (controller == null) || controller.isClosed; - var cancelHandler = _onCancelHandler; - if (cancelHandler != null) { - _zone.runUnary(cancelHandler, new _BroadcastSubscriptionWrapper(this)); - } - if (shutdown) { - var subscription = _subscription; - if (subscription != null) { - subscription.cancel(); - _subscription = null; - } - } - } - - void _onListen() { - var listenHandler = _onListenHandler; - if (listenHandler != null) { - _zone.runUnary(listenHandler, new _BroadcastSubscriptionWrapper(this)); - } - } - - // Methods called from _BroadcastSubscriptionWrapper. - void _cancelSubscription() { - // Called by [_controller] when it has no subscribers left. - var subscription = _subscription; - if (subscription != null) { - _subscription = null; - _controller = null; // Marks the stream as no longer listenable. - subscription.cancel(); - } - } - - void _pauseSubscription(Future? resumeSignal) { - _subscription?.pause(resumeSignal); - } - - void _resumeSubscription() { - _subscription?.resume(); - } - - bool get _isSubscriptionPaused { - return _subscription?.isPaused ?? false; - } -} - -/** - * Wrapper for subscription that disallows changing handlers. - */ -class _BroadcastSubscriptionWrapper implements StreamSubscription { - final _AsBroadcastStream _stream; - - _BroadcastSubscriptionWrapper(this._stream); - - void onData(void handleData(T data)?) { - throw new UnsupportedError( - "Cannot change handlers of asBroadcastStream source subscription."); - } - - void onError(Function? handleError) { - throw new UnsupportedError( - "Cannot change handlers of asBroadcastStream source subscription."); - } - - void onDone(void handleDone()?) { - throw new UnsupportedError( - "Cannot change handlers of asBroadcastStream source subscription."); - } - - void pause([Future? resumeSignal]) { - _stream._pauseSubscription(resumeSignal); - } - - void resume() { - _stream._resumeSubscription(); - } - - Future cancel() { - _stream._cancelSubscription(); - return Future._nullFuture; - } - - bool get isPaused { - return _stream._isSubscriptionPaused; - } - - Future asFuture([E? futureValue]) { - throw new UnsupportedError( - "Cannot change handlers of asBroadcastStream source subscription."); - } -} - -/** - * Simple implementation of [StreamIterator]. - * - * Pauses the stream between calls to [moveNext]. - */ -class _StreamIterator implements StreamIterator { - // The stream iterator is always in one of four states. - // The value of the [_stateData] field depends on the state. - // - // When `_subscription == null` and `_stateData != null`: - // The stream iterator has been created, but [moveNext] has not been called - // yet. The [_stateData] field contains the stream to listen to on the first - // call to [moveNext] and [current] returns `null`. - // - // When `_subscription != null` and `!_isPaused`: - // The user has called [moveNext] and the iterator is waiting for the next - // event. The [_stateData] field contains the [_Future] returned by the - // [_moveNext] call and [current] returns `null.` - // - // When `_subscription != null` and `_isPaused`: - // The most recent call to [moveNext] has completed with a `true` value - // and [current] provides the value of the data event. - // The [_stateData] field contains the [current] value. - // - // When `_subscription == null` and `_stateData == null`: - // The stream has completed or been canceled using [cancel]. - // The stream completes on either a done event or an error event. - // The last call to [moveNext] has completed with `false` and [current] - // returns `null`. - - /// Subscription being listened to. - /// - /// Set to `null` when the stream subscription is done or canceled. - StreamSubscription? _subscription; - - /// Data value depending on the current state. - /// - /// Before first call to [moveNext]: The stream to listen to. - /// - /// After calling [moveNext] but before the returned future completes: - /// The returned future. - /// - /// After calling [moveNext] and the returned future has completed - /// with `true`: The value of [current]. - /// - /// After calling [moveNext] and the returned future has completed - /// with `false`, or after calling [cancel]: `null`. - @pragma("vm:entry-point") - Object? _stateData; - - /// Whether the iterator is between calls to `moveNext`. - /// This will usually cause the [_subscription] to be paused, but as an - /// optimization, we only pause after the [moveNext] future has been - /// completed. - bool _isPaused = false; - - _StreamIterator(final Stream stream) : _stateData = stream { - ArgumentError.checkNotNull(stream, "stream"); - } - - T get current { - if (_subscription != null && _isPaused) { - return _stateData as dynamic; - } - return null as dynamic; - } - - Future moveNext() { - var subscription = _subscription; - if (subscription != null) { - if (_isPaused) { - var future = new _Future(); - _stateData = future; - _isPaused = false; - subscription.resume(); - return future; - } - throw new StateError("Already waiting for next."); - } - return _initializeOrDone(); - } - - /// Called if there is no active subscription when [moveNext] is called. - /// - /// Either starts listening on the stream if this is the first call to - /// [moveNext], or returns a `false` future because the stream has already - /// ended. - Future _initializeOrDone() { - assert(_subscription == null); - var stateData = _stateData; - if (stateData != null) { - Stream stream = stateData as dynamic; - _subscription = stream.listen(_onData, - onError: _onError, onDone: _onDone, cancelOnError: true); - var future = new _Future(); - _stateData = future; - return future; - } - return Future._falseFuture; - } - - Future cancel() { - StreamSubscription? subscription = _subscription; - Object? stateData = _stateData; - _stateData = null; - if (subscription != null) { - _subscription = null; - if (!_isPaused) { - _Future future = stateData as dynamic; - future._asyncComplete(false); - } - return subscription.cancel(); - } - return Future._nullFuture; - } - - void _onData(T data) { - assert(_subscription != null && !_isPaused); - _Future moveNextFuture = _stateData as dynamic; - _stateData = data; - _isPaused = true; - moveNextFuture._complete(true); - if (_isPaused) _subscription?.pause(); - } - - void _onError(Object error, StackTrace stackTrace) { - assert(_subscription != null && !_isPaused); - _Future moveNextFuture = _stateData as dynamic; - _subscription = null; - _stateData = null; - moveNextFuture._completeError(error, stackTrace); - } - - void _onDone() { - assert(_subscription != null && !_isPaused); - _Future moveNextFuture = _stateData as dynamic; - _subscription = null; - _stateData = null; - moveNextFuture._complete(false); - } -} - -/** An empty broadcast stream, sending a done event as soon as possible. */ -class _EmptyStream extends Stream { - const _EmptyStream() : super._internal(); - bool get isBroadcast => true; - StreamSubscription listen(void onData(T data)?, - {Function? onError, void onDone()?, bool? cancelOnError}) { - return new _DoneStreamSubscription(onDone); - } -} diff --git a/sdk_nnbd/lib/async/stream_pipe.dart b/sdk_nnbd/lib/async/stream_pipe.dart deleted file mode 100644 index fd202283b5a..00000000000 --- a/sdk_nnbd/lib/async/stream_pipe.dart +++ /dev/null @@ -1,475 +0,0 @@ -// Copyright (c) 2012, 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. - -part of dart.async; - -/** Runs user code and takes actions depending on success or failure. */ -_runUserCode(T userCode(), onSuccess(T value), - onError(Object error, StackTrace stackTrace)) { - try { - onSuccess(userCode()); - } catch (e, s) { - AsyncError? replacement = Zone.current.errorCallback(e, s); - if (replacement == null) { - onError(e, s); - } else { - var error = replacement.error; - var stackTrace = replacement.stackTrace; - onError(error, stackTrace); - } - } -} - -/** Helper function to cancel a subscription and wait for the potential future, - before completing with an error. */ -void _cancelAndError(StreamSubscription subscription, _Future future, - Object error, StackTrace stackTrace) { - var cancelFuture = subscription.cancel(); - if (cancelFuture != null && !identical(cancelFuture, Future._nullFuture)) { - cancelFuture.whenComplete(() => future._completeError(error, stackTrace)); - } else { - future._completeError(error, stackTrace); - } -} - -void _cancelAndErrorWithReplacement(StreamSubscription subscription, - _Future future, Object error, StackTrace stackTrace) { - AsyncError? replacement = Zone.current.errorCallback(error, stackTrace); - if (replacement != null) { - error = replacement.error; - stackTrace = replacement.stackTrace; - } - _cancelAndError(subscription, future, error, stackTrace); -} - -/** Helper function to make an onError argument to [_runUserCode]. */ -void Function(Object error, StackTrace stackTrace) _cancelAndErrorClosure( - StreamSubscription subscription, _Future future) { - return (Object error, StackTrace stackTrace) { - _cancelAndError(subscription, future, error, stackTrace); - }; -} - -/** Helper function to cancel a subscription and wait for the potential future, - before completing with a value. */ -void _cancelAndValue(StreamSubscription subscription, _Future future, value) { - var cancelFuture = subscription.cancel(); - if (cancelFuture != null && !identical(cancelFuture, Future._nullFuture)) { - cancelFuture.whenComplete(() => future._complete(value)); - } else { - future._complete(value); - } -} - -/** - * A [Stream] that forwards subscriptions to another stream. - * - * This stream implements [Stream], but forwards all subscriptions - * to an underlying stream, and wraps the returned subscription to - * modify the events on the way. - * - * This class is intended for internal use only. - */ -abstract class _ForwardingStream extends Stream { - final Stream _source; - - _ForwardingStream(this._source); - - bool get isBroadcast => _source.isBroadcast; - - StreamSubscription listen(void onData(T value)?, - {Function? onError, void onDone()?, bool? cancelOnError}) { - return _createSubscription(onData, onError, onDone, cancelOnError ?? false); - } - - StreamSubscription _createSubscription(void onData(T data)?, - Function? onError, void onDone()?, bool cancelOnError) { - return new _ForwardingStreamSubscription( - this, onData, onError, onDone, cancelOnError); - } - - // Override the following methods in subclasses to change the behavior. - - void _handleData(S data, _EventSink sink); - - void _handleError(Object error, StackTrace stackTrace, _EventSink sink) { - sink._addError(error, stackTrace); - } - - void _handleDone(_EventSink sink) { - sink._close(); - } -} - -/** - * Abstract superclass for subscriptions that forward to other subscriptions. - */ -class _ForwardingStreamSubscription - extends _BufferingStreamSubscription { - final _ForwardingStream _stream; - - StreamSubscription? _subscription; - - _ForwardingStreamSubscription(this._stream, void onData(T data)?, - Function? onError, void onDone()?, bool cancelOnError) - : super(onData, onError, onDone, cancelOnError) { - _subscription = _stream._source - .listen(_handleData, onError: _handleError, onDone: _handleDone); - } - - // _StreamSink interface. - // Transformers sending more than one event have no way to know if the stream - // is canceled or closed after the first, so we just ignore remaining events. - - void _add(T data) { - if (_isClosed) return; - super._add(data); - } - - void _addError(Object error, StackTrace stackTrace) { - if (_isClosed) return; - super._addError(error, stackTrace); - } - - // StreamSubscription callbacks. - - void _onPause() { - _subscription?.pause(); - } - - void _onResume() { - _subscription?.resume(); - } - - Future? _onCancel() { - var subscription = _subscription; - if (subscription != null) { - _subscription = null; - return subscription.cancel(); - } - return null; - } - - // Methods used as listener on source subscription. - - void _handleData(S data) { - _stream._handleData(data, this); - } - - void _handleError(error, StackTrace stackTrace) { - _stream._handleError(error, stackTrace, this); - } - - void _handleDone() { - _stream._handleDone(this); - } -} - -// ------------------------------------------------------------------- -// Stream transformers used by the default Stream implementation. -// ------------------------------------------------------------------- - -void _addErrorWithReplacement( - _EventSink sink, Object error, StackTrace stackTrace) { - AsyncError? replacement = Zone.current.errorCallback(error, stackTrace); - if (replacement != null) { - error = replacement.error; - stackTrace = replacement.stackTrace; - } - sink._addError(error, stackTrace); -} - -class _WhereStream extends _ForwardingStream { - final bool Function(T) _test; - - _WhereStream(Stream source, bool test(T value)) - : _test = test, - super(source); - - void _handleData(T inputEvent, _EventSink sink) { - bool satisfies; - try { - satisfies = _test(inputEvent); - } catch (e, s) { - _addErrorWithReplacement(sink, e, s); - return; - } - if (satisfies) { - sink._add(inputEvent); - } - } -} - -typedef T _Transformation(S value); - -/** - * A stream pipe that converts data events before passing them on. - */ -class _MapStream extends _ForwardingStream { - final _Transformation _transform; - - _MapStream(Stream source, T transform(S event)) - : this._transform = transform, - super(source); - - void _handleData(S inputEvent, _EventSink sink) { - T outputEvent; - try { - outputEvent = _transform(inputEvent); - } catch (e, s) { - _addErrorWithReplacement(sink, e, s); - return; - } - sink._add(outputEvent); - } -} - -/** - * A stream pipe that converts data events before passing them on. - */ -class _ExpandStream extends _ForwardingStream { - final _Transformation> _expand; - - _ExpandStream(Stream source, Iterable expand(S event)) - : this._expand = expand, - super(source); - - void _handleData(S inputEvent, _EventSink sink) { - try { - for (T value in _expand(inputEvent)) { - sink._add(value); - } - } catch (e, s) { - // If either _expand or iterating the generated iterator throws, - // we abort the iteration. - _addErrorWithReplacement(sink, e, s); - } - } -} - -/** - * A stream pipe that converts or disposes error events - * before passing them on. - */ -class _HandleErrorStream extends _ForwardingStream { - final Function _transform; - final bool Function(Object)? _test; - - _HandleErrorStream( - Stream source, Function onError, bool test(Object error)?) - : this._transform = onError, - this._test = test, - super(source); - - void _handleData(T data, _EventSink sink) { - sink._add(data); - } - - void _handleError(Object error, StackTrace stackTrace, _EventSink sink) { - bool matches = true; - var test = _test; - if (test != null) { - try { - matches = test(error); - } catch (e, s) { - _addErrorWithReplacement(sink, e, s); - return; - } - } - if (matches) { - try { - _invokeErrorHandler(_transform, error, stackTrace); - } catch (e, s) { - if (identical(e, error)) { - sink._addError(error, stackTrace); - } else { - _addErrorWithReplacement(sink, e, s); - } - return; - } - } else { - sink._addError(error, stackTrace); - } - } -} - -class _TakeStream extends _ForwardingStream { - final int _count; - - _TakeStream(Stream source, int count) - : this._count = count, - super(source); - - StreamSubscription _createSubscription(void onData(T data)?, - Function? onError, void onDone()?, bool cancelOnError) { - if (_count == 0) { - _source.listen(null).cancel(); - return new _DoneStreamSubscription(onDone); - } - return new _StateStreamSubscription( - this, onData, onError, onDone, cancelOnError, _count); - } - - void _handleData(T inputEvent, _EventSink sink) { - var subscription = sink as _StateStreamSubscription; - int count = subscription._subState; - if (count > 0) { - sink._add(inputEvent); - count -= 1; - subscription._subState = count; - if (count == 0) { - // Closing also unsubscribes all subscribers, which unsubscribes - // this from source. - sink._close(); - } - } - } -} - -/** - * A [_ForwardingStreamSubscription] with one extra state field. - * - * Use by several different classes, storing an integer, bool or general. - */ -class _StateStreamSubscription - extends _ForwardingStreamSubscription { - S _subState; - - _StateStreamSubscription(_ForwardingStream stream, void onData(T data)?, - Function? onError, void onDone()?, bool cancelOnError, this._subState) - : super(stream, onData, onError, onDone, cancelOnError); -} - -class _TakeWhileStream extends _ForwardingStream { - final bool Function(T) _test; - - _TakeWhileStream(Stream source, bool test(T value)) - : this._test = test, - super(source); - - void _handleData(T inputEvent, _EventSink sink) { - bool satisfies; - try { - satisfies = _test(inputEvent); - } catch (e, s) { - _addErrorWithReplacement(sink, e, s); - // The test didn't say true. Didn't say false either, but we stop anyway. - sink._close(); - return; - } - if (satisfies) { - sink._add(inputEvent); - } else { - sink._close(); - } - } -} - -class _SkipStream extends _ForwardingStream { - final int _count; - - _SkipStream(Stream source, int count) - : this._count = count, - super(source) { - // This test is done early to avoid handling an async error - // in the _handleData method. - RangeError.checkNotNegative(count, "count"); - } - - StreamSubscription _createSubscription(void onData(T data)?, - Function? onError, void onDone()?, bool cancelOnError) { - return new _StateStreamSubscription( - this, onData, onError, onDone, cancelOnError, _count); - } - - void _handleData(T inputEvent, _EventSink sink) { - var subscription = sink as _StateStreamSubscription; - int count = subscription._subState; - if (count > 0) { - subscription._subState = count - 1; - return; - } - sink._add(inputEvent); - } -} - -class _SkipWhileStream extends _ForwardingStream { - final bool Function(T) _test; - - _SkipWhileStream(Stream source, bool test(T value)) - : this._test = test, - super(source); - - StreamSubscription _createSubscription(void onData(T data)?, - Function? onError, void onDone()?, bool cancelOnError) { - return new _StateStreamSubscription( - this, onData, onError, onDone, cancelOnError, false); - } - - void _handleData(T inputEvent, _EventSink sink) { - var subscription = sink as _StateStreamSubscription; - bool hasFailed = subscription._subState; - if (hasFailed) { - sink._add(inputEvent); - return; - } - bool satisfies; - try { - satisfies = _test(inputEvent); - } catch (e, s) { - _addErrorWithReplacement(sink, e, s); - // A failure to return a boolean is considered "not matching". - subscription._subState = true; - return; - } - if (!satisfies) { - subscription._subState = true; - sink._add(inputEvent); - } - } -} - -class _DistinctStream extends _ForwardingStream { - static final _SENTINEL = new Object(); - - final bool Function(T, T)? _equals; - - _DistinctStream(Stream source, bool equals(T a, T b)?) - : _equals = equals, - super(source); - - StreamSubscription _createSubscription(void onData(T data)?, - Function? onError, void onDone()?, bool cancelOnError) { - return new _StateStreamSubscription( - this, onData, onError, onDone, cancelOnError, _SENTINEL); - } - - void _handleData(T inputEvent, _EventSink sink) { - var subscription = sink as _StateStreamSubscription; - var previous = subscription._subState; - if (identical(previous, _SENTINEL)) { - // First event. Cannot use [_equals]. - subscription._subState = inputEvent; - sink._add(inputEvent); - } else { - T previousEvent = previous as T; - var equals = _equals; - bool isEqual; - try { - if (equals == null) { - isEqual = (previousEvent == inputEvent); - } else { - isEqual = equals(previousEvent, inputEvent); - } - } catch (e, s) { - _addErrorWithReplacement(sink, e, s); - return; - } - if (!isEqual) { - sink._add(inputEvent); - subscription._subState = inputEvent; - } - } - } -} diff --git a/sdk_nnbd/lib/async/stream_transformers.dart b/sdk_nnbd/lib/async/stream_transformers.dart deleted file mode 100644 index ca7934c5c40..00000000000 --- a/sdk_nnbd/lib/async/stream_transformers.dart +++ /dev/null @@ -1,338 +0,0 @@ -// Copyright (c) 2013, 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. - -part of dart.async; - -/** - * Wraps an [_EventSink] so it exposes only the [EventSink] interface. - */ -class _EventSinkWrapper implements EventSink { - _EventSink _sink; - _EventSinkWrapper(this._sink); - - void add(T data) { - _sink._add(data); - } - - void addError(Object error, [StackTrace? stackTrace]) { - _sink._addError(error, stackTrace ?? AsyncError.defaultStackTrace(error)); - } - - void close() { - _sink._close(); - } -} - -/** - * A StreamSubscription that pipes data through a sink. - * - * The constructor of this class takes a [_SinkMapper] which maps from - * [EventSink] to [EventSink]. The input to the mapper is the output of - * the transformation. The returned sink is the transformation's input. - */ -class _SinkTransformerStreamSubscription - extends _BufferingStreamSubscription { - /// The transformer's input sink. - late EventSink _transformerSink; - - /// The subscription to the input stream. - StreamSubscription? _subscription; - - _SinkTransformerStreamSubscription( - Stream source, - _SinkMapper mapper, - void onData(T data)?, - Function? onError, - void onDone()?, - bool cancelOnError) - // We set the adapter's target only when the user is allowed to send data. - : super(onData, onError, onDone, cancelOnError) { - _transformerSink = mapper(_EventSinkWrapper(this)); - _subscription = - source.listen(_handleData, onError: _handleError, onDone: _handleDone); - } - - // _EventSink interface. - - /** - * Adds an event to this subscriptions. - * - * Contrary to normal [_BufferingStreamSubscription]s we may receive - * events when the stream is already closed. Report them as state - * error. - */ - void _add(T data) { - if (_isClosed) { - throw StateError("Stream is already closed"); - } - super._add(data); - } - - /** - * Adds an error event to this subscriptions. - * - * Contrary to normal [_BufferingStreamSubscription]s we may receive - * events when the stream is already closed. Report them as state - * error. - */ - void _addError(Object error, StackTrace stackTrace) { - if (_isClosed) { - throw new StateError("Stream is already closed"); - } - super._addError(error, stackTrace); - } - - /** - * Adds a close event to this subscriptions. - * - * Contrary to normal [_BufferingStreamSubscription]s we may receive - * events when the stream is already closed. Report them as state - * error. - */ - void _close() { - if (_isClosed) { - throw new StateError("Stream is already closed"); - } - super._close(); - } - - // _BufferingStreamSubscription hooks. - - void _onPause() { - _subscription?.pause(); - } - - void _onResume() { - _subscription?.resume(); - } - - Future? _onCancel() { - var subscription = _subscription; - if (subscription != null) { - _subscription = null; - return subscription.cancel(); - } - return null; - } - - void _handleData(S data) { - try { - _transformerSink.add(data); - } catch (e, s) { - _addError(e, s); - } - } - - void _handleError(Object error, StackTrace stackTrace) { - try { - _transformerSink.addError(error, stackTrace); - } catch (e, s) { - if (identical(e, error)) { - _addError(error, stackTrace); - } else { - _addError(e, s); - } - } - } - - void _handleDone() { - try { - _subscription = null; - _transformerSink.close(); - } catch (e, s) { - _addError(e, s); - } - } -} - -typedef EventSink _SinkMapper(EventSink output); - -/** - * A StreamTransformer for Sink-mappers. - * - * A Sink-mapper takes an [EventSink] (its output) and returns another - * EventSink (its input). - * - * Note that this class can be `const`. - */ -class _StreamSinkTransformer extends StreamTransformerBase { - final _SinkMapper _sinkMapper; - const _StreamSinkTransformer(this._sinkMapper); - - Stream bind(Stream stream) => - new _BoundSinkStream(stream, _sinkMapper); -} - -/** - * The result of binding a StreamTransformer for Sink-mappers. - * - * It contains the bound Stream and the sink-mapper. Only when the user starts - * listening to this stream is the sink-mapper invoked. The result is used - * to create a StreamSubscription that transforms events. - */ -class _BoundSinkStream extends Stream { - final _SinkMapper _sinkMapper; - final Stream _stream; - - bool get isBroadcast => _stream.isBroadcast; - - _BoundSinkStream(this._stream, this._sinkMapper); - - StreamSubscription listen(void onData(T event)?, - {Function? onError, void onDone()?, bool? cancelOnError}) { - StreamSubscription subscription = - _SinkTransformerStreamSubscription(_stream, _sinkMapper, onData, - onError, onDone, cancelOnError ?? false); - return subscription; - } -} - -/// Data-handler coming from [StreamTransformer.fromHandlers]. -typedef void _TransformDataHandler(S data, EventSink sink); - -/// Error-handler coming from [StreamTransformer.fromHandlers]. -typedef void _TransformErrorHandler( - Object error, StackTrace stackTrace, EventSink sink); - -/// Done-handler coming from [StreamTransformer.fromHandlers]. -typedef void _TransformDoneHandler(EventSink sink); - -/** - * Wraps handlers (from [StreamTransformer.fromHandlers]) into an `EventSink`. - * - * This way we can reuse the code from [_StreamSinkTransformer]. - */ -class _HandlerEventSink implements EventSink { - final _TransformDataHandler? _handleData; - final _TransformErrorHandler? _handleError; - final _TransformDoneHandler? _handleDone; - - /// The output sink where the handlers should send their data into. - /// Set to `null` when closed. - EventSink? _sink; - - _HandlerEventSink(this._handleData, this._handleError, this._handleDone, - EventSink this._sink); - - void add(S data) { - var sink = _sink; - if (sink == null) { - throw StateError("Sink is closed"); - } - var handleData = _handleData; - if (handleData != null) { - handleData(data, sink); - } else { - sink.add(data as T); - } - } - - void addError(Object error, [StackTrace? stackTrace]) { - // TODO(40614): Remove once non-nullability is sound. - ArgumentError.checkNotNull(error, "error"); - var sink = _sink; - if (sink == null) { - throw StateError("Sink is closed"); - } - var handleError = _handleError; - stackTrace ??= AsyncError.defaultStackTrace(error); - if (handleError != null) { - handleError(error, stackTrace, sink); - } else { - sink.addError(error, stackTrace); - } - } - - void close() { - var sink = _sink; - if (sink == null) return; - _sink = null; - var handleDone = _handleDone; - if (handleDone != null) { - handleDone(sink); - } else { - sink.close(); - } - } -} - -/** - * A StreamTransformer that transformers events with the given handlers. - * - * Note that this transformer can only be used once. - */ -class _StreamHandlerTransformer extends _StreamSinkTransformer { - _StreamHandlerTransformer( - {void handleData(S data, EventSink sink)?, - void handleError(Object error, StackTrace stackTrace, EventSink sink)?, - void handleDone(EventSink sink)?}) - : super((EventSink outputSink) { - return new _HandlerEventSink( - handleData, handleError, handleDone, outputSink); - }); - - Stream bind(Stream stream) { - return super.bind(stream); - } -} - -/** - * A StreamTransformer that overrides [StreamTransformer.bind] with a callback. - */ -class _StreamBindTransformer extends StreamTransformerBase { - final Stream Function(Stream) _bind; - _StreamBindTransformer(this._bind); - - Stream bind(Stream stream) => _bind(stream); -} - -/// A closure mapping a stream and cancelOnError to a StreamSubscription. -typedef StreamSubscription _SubscriptionTransformer( - Stream stream, bool cancelOnError); - -/** - * A [StreamTransformer] that minimizes the number of additional classes. - * - * Instead of implementing three classes: a [StreamTransformer], a [Stream] - * (as the result of a `bind` call) and a [StreamSubscription] (which does the - * actual work), this class only requires a function that is invoked when the - * last bit (the subscription) of the transformer-workflow is needed. - * - * The given transformer function maps from Stream and cancelOnError to a - * `StreamSubscription`. As such it can also act on `cancel` events, making it - * fully general. - */ -class _StreamSubscriptionTransformer extends StreamTransformerBase { - final _SubscriptionTransformer _onListen; - - const _StreamSubscriptionTransformer(this._onListen); - - Stream bind(Stream stream) => - new _BoundSubscriptionStream(stream, _onListen); -} - -/** - * A stream transformed by a [_StreamSubscriptionTransformer]. - * - * When this stream is listened to it invokes the [_onListen] function with - * the stored [_stream]. Usually the transformer starts listening at this - * moment. - */ -class _BoundSubscriptionStream extends Stream { - final _SubscriptionTransformer _onListen; - final Stream _stream; - - bool get isBroadcast => _stream.isBroadcast; - - _BoundSubscriptionStream(this._stream, this._onListen); - - StreamSubscription listen(void onData(T event)?, - {Function? onError, void onDone()?, bool? cancelOnError}) { - StreamSubscription result = _onListen(_stream, cancelOnError ?? false); - result.onData(onData); - result.onError(onError); - result.onDone(onDone); - return result; - } -} diff --git a/sdk_nnbd/lib/async/timer.dart b/sdk_nnbd/lib/async/timer.dart deleted file mode 100644 index e0ef4471fb6..00000000000 --- a/sdk_nnbd/lib/async/timer.dart +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright (c) 2012, 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. - -part of dart.async; - -/** - * A count-down timer that can be configured to fire once or repeatedly. - * - * The timer counts down from the specified duration to 0. - * When the timer reaches 0, the timer invokes the specified callback function. - * Use a periodic timer to repeatedly count down the same interval. - * - * A negative duration is treated the same as a duration of 0. - * If the duration is statically known to be 0, consider using [run]. - * - * Frequently the duration is either a constant or computed as in the - * following example (taking advantage of the multiplication operator of - * the [Duration] class): - * ```dart - * const timeout = const Duration(seconds: 3); - * const ms = const Duration(milliseconds: 1); - * - * startTimeout([int milliseconds]) { - * var duration = milliseconds == null ? timeout : ms * milliseconds; - * return new Timer(duration, handleTimeout); - * } - * ... - * void handleTimeout() { // callback function - * ... - * } - * ``` - * Note: If Dart code using Timer is compiled to JavaScript, the finest - * granularity available in the browser is 4 milliseconds. - * - * See [Stopwatch] for measuring elapsed time. - */ -abstract class Timer { - /** - * Creates a new timer. - * - * The [callback] function is invoked after the given [duration]. - * - */ - factory Timer(Duration duration, void Function() callback) { - if (Zone.current == Zone.root) { - // No need to bind the callback. We know that the root's timer will - // be invoked in the root zone. - return Zone.current.createTimer(duration, callback); - } - return Zone.current - .createTimer(duration, Zone.current.bindCallbackGuarded(callback)); - } - - /** - * Creates a new repeating timer. - * - * The [callback] is invoked repeatedly with [duration] intervals until - * canceled with the [cancel] function. - * - * The exact timing depends on the underlying timer implementation. - * No more than `n` callbacks will be made in `duration * n` time, - * but the time between two consecutive callbacks - * can be shorter and longer than `duration`. - * - * In particular, an implementation may schedule the next callback, e.g., - * a `duration` after either when the previous callback ended, - * when the previous callback started, or when the previous callback was - * scheduled for - even if the actual callback was delayed. - * - * [duration] must a non-negative [Duration]. - */ - factory Timer.periodic(Duration duration, void callback(Timer timer)) { - if (Zone.current == Zone.root) { - // No need to bind the callback. We know that the root's timer will - // be invoked in the root zone. - return Zone.current.createPeriodicTimer(duration, callback); - } - var boundCallback = Zone.current.bindUnaryCallbackGuarded(callback); - return Zone.current.createPeriodicTimer(duration, boundCallback); - } - - /** - * Runs the given [callback] asynchronously as soon as possible. - * - * This function is equivalent to `new Timer(Duration.zero, callback)`. - */ - static void run(void Function() callback) { - new Timer(Duration.zero, callback); - } - - /** - * Cancels the timer. - * - * Once a [Timer] has been canceled, the callback function will not be called - * by the timer. Calling [cancel] more than once on a [Timer] is allowed, and - * will have no further effect. - */ - void cancel(); - - /** - * The number of durations preceding the most recent timer event. - * - * The value starts at zero and is incremented each time a timer event - * occurs, so each callback will see a larger value than the previous one. - * - * If a periodic timer with a non-zero duration is delayed too much, - * so more than one tick should have happened, - * all but the last tick in the past are considered "missed", - * and no callback is invoked for them. - * The [tick] count reflects the number of durations that have passed and - * not the number of callback invocations that have happened. - */ - int get tick; - - /** - * Returns whether the timer is still active. - * - * A non-periodic timer is active if the callback has not been executed, - * and the timer has not been canceled. - * - * A periodic timer is active if it has not been canceled. - */ - bool get isActive; - - external static Timer _createTimer( - Duration duration, void Function() callback); - external static Timer _createPeriodicTimer( - Duration duration, void callback(Timer timer)); -} diff --git a/sdk_nnbd/lib/async/zone.dart b/sdk_nnbd/lib/async/zone.dart deleted file mode 100644 index b4e3994cbcc..00000000000 --- a/sdk_nnbd/lib/async/zone.dart +++ /dev/null @@ -1,1630 +0,0 @@ -// Copyright (c) 2013, 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. - -part of dart.async; - -typedef R ZoneCallback(); -typedef R ZoneUnaryCallback(T arg); -typedef R ZoneBinaryCallback(T1 arg1, T2 arg2); - -typedef HandleUncaughtErrorHandler = void Function(Zone self, - ZoneDelegate parent, Zone zone, Object error, StackTrace stackTrace); -typedef RunHandler = R Function( - Zone self, ZoneDelegate parent, Zone zone, R Function() f); -typedef RunUnaryHandler = R Function( - Zone self, ZoneDelegate parent, Zone zone, R Function(T arg) f, T arg); -typedef RunBinaryHandler = R Function(Zone self, ZoneDelegate parent, - Zone zone, R Function(T1 arg1, T2 arg2) f, T1 arg1, T2 arg2); -typedef RegisterCallbackHandler = ZoneCallback Function( - Zone self, ZoneDelegate parent, Zone zone, R Function() f); -typedef RegisterUnaryCallbackHandler = ZoneUnaryCallback Function( - Zone self, ZoneDelegate parent, Zone zone, R Function(T arg) f); -typedef RegisterBinaryCallbackHandler - = ZoneBinaryCallback Function(Zone self, - ZoneDelegate parent, Zone zone, R Function(T1 arg1, T2 arg2) f); -typedef AsyncError? ErrorCallbackHandler(Zone self, ZoneDelegate parent, - Zone zone, Object error, StackTrace? stackTrace); -typedef void ScheduleMicrotaskHandler( - Zone self, ZoneDelegate parent, Zone zone, void f()); -typedef Timer CreateTimerHandler( - Zone self, ZoneDelegate parent, Zone zone, Duration duration, void f()); -typedef Timer CreatePeriodicTimerHandler(Zone self, ZoneDelegate parent, - Zone zone, Duration period, void f(Timer timer)); -typedef void PrintHandler( - Zone self, ZoneDelegate parent, Zone zone, String line); -typedef Zone ForkHandler(Zone self, ZoneDelegate parent, Zone zone, - ZoneSpecification? specification, Map? zoneValues); - -/** Pair of error and stack trace. Returned by [Zone.errorCallback]. */ -class AsyncError implements Error { - final Object error; - final StackTrace stackTrace; - - AsyncError(this.error, StackTrace? stackTrace) - : stackTrace = stackTrace ?? defaultStackTrace(error) { - // TODO(40614): Remove once non-nullability is sound. - ArgumentError.checkNotNull(error, "error"); - } - - /// A default stack trace for an error. - /// - /// If [error] is an [Error] and it has an [Error.stackTrace], - /// that stack trace is returned. - /// If not, the [StackTrace.empty] default stack trace is returned. - static StackTrace defaultStackTrace(Object error) { - if (error is Error) { - var stackTrace = error.stackTrace; - if (stackTrace != null) return stackTrace; - } - return StackTrace.empty; - } - - String toString() => '$error'; -} - -class _ZoneFunction { - final _Zone zone; - final T function; - const _ZoneFunction(this.zone, this.function); -} - -class _RunNullaryZoneFunction { - final _Zone zone; - final RunHandler function; - const _RunNullaryZoneFunction(this.zone, this.function); -} - -class _RunUnaryZoneFunction { - final _Zone zone; - final RunUnaryHandler function; - const _RunUnaryZoneFunction(this.zone, this.function); -} - -class _RunBinaryZoneFunction { - final _Zone zone; - final RunBinaryHandler function; - const _RunBinaryZoneFunction(this.zone, this.function); -} - -class _RegisterNullaryZoneFunction { - final _Zone zone; - final RegisterCallbackHandler function; - const _RegisterNullaryZoneFunction(this.zone, this.function); -} - -class _RegisterUnaryZoneFunction { - final _Zone zone; - final RegisterUnaryCallbackHandler function; - const _RegisterUnaryZoneFunction(this.zone, this.function); -} - -class _RegisterBinaryZoneFunction { - final _Zone zone; - final RegisterBinaryCallbackHandler function; - const _RegisterBinaryZoneFunction(this.zone, this.function); -} - -/** - * This class provides the specification for a forked zone. - * - * When forking a new zone (see [Zone.fork]) one can override the default - * behavior of the zone by providing callbacks. These callbacks must be - * given in an instance of this class. - * - * Handlers have the same signature as the same-named methods on [Zone] but - * receive three additional arguments: - * - * 1. the zone the handlers are attached to (the "self" zone). - * 2. a [ZoneDelegate] to the parent zone. - * 3. the zone that first received the request (before the request was - * bubbled up). - * - * Handlers can either stop propagation the request (by simply not calling the - * parent handler), or forward to the parent zone, potentially modifying the - * arguments on the way. - */ -abstract class ZoneSpecification { - /** - * Creates a specification with the provided handlers. - */ - const factory ZoneSpecification( - {HandleUncaughtErrorHandler? handleUncaughtError, - RunHandler? run, - RunUnaryHandler? runUnary, - RunBinaryHandler? runBinary, - RegisterCallbackHandler? registerCallback, - RegisterUnaryCallbackHandler? registerUnaryCallback, - RegisterBinaryCallbackHandler? registerBinaryCallback, - ErrorCallbackHandler? errorCallback, - ScheduleMicrotaskHandler? scheduleMicrotask, - CreateTimerHandler? createTimer, - CreatePeriodicTimerHandler? createPeriodicTimer, - PrintHandler? print, - ForkHandler? fork}) = _ZoneSpecification; - - /** - * Creates a specification from [other] with the provided handlers overriding - * the ones in [other]. - */ - factory ZoneSpecification.from(ZoneSpecification other, - {HandleUncaughtErrorHandler? handleUncaughtError, - RunHandler? run, - RunUnaryHandler? runUnary, - RunBinaryHandler? runBinary, - RegisterCallbackHandler? registerCallback, - RegisterUnaryCallbackHandler? registerUnaryCallback, - RegisterBinaryCallbackHandler? registerBinaryCallback, - ErrorCallbackHandler? errorCallback, - ScheduleMicrotaskHandler? scheduleMicrotask, - CreateTimerHandler? createTimer, - CreatePeriodicTimerHandler? createPeriodicTimer, - PrintHandler? print, - ForkHandler? fork}) { - return new ZoneSpecification( - handleUncaughtError: handleUncaughtError ?? other.handleUncaughtError, - run: run ?? other.run, - runUnary: runUnary ?? other.runUnary, - runBinary: runBinary ?? other.runBinary, - registerCallback: registerCallback ?? other.registerCallback, - registerUnaryCallback: - registerUnaryCallback ?? other.registerUnaryCallback, - registerBinaryCallback: - registerBinaryCallback ?? other.registerBinaryCallback, - errorCallback: errorCallback ?? other.errorCallback, - scheduleMicrotask: scheduleMicrotask ?? other.scheduleMicrotask, - createTimer: createTimer ?? other.createTimer, - createPeriodicTimer: createPeriodicTimer ?? other.createPeriodicTimer, - print: print ?? other.print, - fork: fork ?? other.fork); - } - - HandleUncaughtErrorHandler? get handleUncaughtError; - RunHandler? get run; - RunUnaryHandler? get runUnary; - RunBinaryHandler? get runBinary; - RegisterCallbackHandler? get registerCallback; - RegisterUnaryCallbackHandler? get registerUnaryCallback; - RegisterBinaryCallbackHandler? get registerBinaryCallback; - ErrorCallbackHandler? get errorCallback; - ScheduleMicrotaskHandler? get scheduleMicrotask; - CreateTimerHandler? get createTimer; - CreatePeriodicTimerHandler? get createPeriodicTimer; - PrintHandler? get print; - ForkHandler? get fork; -} - -/** - * Internal [ZoneSpecification] class. - * - * The implementation wants to rely on the fact that the getters cannot change - * dynamically. We thus require users to go through the redirecting - * [ZoneSpecification] constructor which instantiates this class. - */ -class _ZoneSpecification implements ZoneSpecification { - const _ZoneSpecification( - {this.handleUncaughtError, - this.run, - this.runUnary, - this.runBinary, - this.registerCallback, - this.registerUnaryCallback, - this.registerBinaryCallback, - this.errorCallback, - this.scheduleMicrotask, - this.createTimer, - this.createPeriodicTimer, - this.print, - this.fork}); - - final HandleUncaughtErrorHandler? handleUncaughtError; - final RunHandler? run; - final RunUnaryHandler? runUnary; - final RunBinaryHandler? runBinary; - final RegisterCallbackHandler? registerCallback; - final RegisterUnaryCallbackHandler? registerUnaryCallback; - final RegisterBinaryCallbackHandler? registerBinaryCallback; - final ErrorCallbackHandler? errorCallback; - final ScheduleMicrotaskHandler? scheduleMicrotask; - final CreateTimerHandler? createTimer; - final CreatePeriodicTimerHandler? createPeriodicTimer; - final PrintHandler? print; - final ForkHandler? fork; -} - -/** - * An adapted view of the parent zone. - * - * This class allows the implementation of a zone method to invoke methods on - * the parent zone while retaining knowledge of the originating zone. - * - * Custom zones (created through [Zone.fork] or [runZoned]) can provide - * implementations of most methods of zones. This is similar to overriding - * methods on [Zone], except that this mechanism doesn't require subclassing. - * - * A custom zone function (provided through a [ZoneSpecification]) typically - * records or wraps its parameters and then delegates the operation to its - * parent zone using the provided [ZoneDelegate]. - * - * While zones have access to their parent zone (through [Zone.parent]) it is - * recommended to call the methods on the provided parent delegate for two - * reasons: - * 1. the delegate methods take an additional `zone` argument which is the - * zone the action has been initiated in. - * 2. delegate calls are more efficient, since the implementation knows how - * to skip zones that would just delegate to their parents. - */ -abstract class ZoneDelegate { - void handleUncaughtError(Zone zone, Object error, StackTrace stackTrace); - R run(Zone zone, R f()); - R runUnary(Zone zone, R f(T arg), T arg); - R runBinary(Zone zone, R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2); - ZoneCallback registerCallback(Zone zone, R f()); - ZoneUnaryCallback registerUnaryCallback(Zone zone, R f(T arg)); - ZoneBinaryCallback registerBinaryCallback( - Zone zone, R f(T1 arg1, T2 arg2)); - AsyncError? errorCallback(Zone zone, Object error, StackTrace? stackTrace); - void scheduleMicrotask(Zone zone, void f()); - Timer createTimer(Zone zone, Duration duration, void f()); - Timer createPeriodicTimer(Zone zone, Duration period, void f(Timer timer)); - void print(Zone zone, String line); - Zone fork(Zone zone, ZoneSpecification? specification, Map? zoneValues); -} - -/** - * A zone represents an environment that remains stable across asynchronous - * calls. - * - * Code is always executed in the context of a zone, available as - * [Zone.current]. The initial `main` function runs in the context of the - * default zone ([Zone.root]). Code can be run in a different zone using either - * [runZoned], to create a new zone, or [Zone.run] to run code in the context of - * an existing zone likely created using [Zone.fork]. - * - * Developers can create a new zone that overrides some of the functionality of - * an existing zone. For example, custom zones can replace of modify the - * behavior of `print`, timers, microtasks or how uncaught errors are handled. - * - * The [Zone] class is not subclassable, but users can provide custom zones by - * forking an existing zone (usually [Zone.current]) with a [ZoneSpecification]. - * This is similar to creating a new class that extends the base `Zone` class - * and that overrides some methods, except without actually creating a new - * class. Instead the overriding methods are provided as functions that - * explicitly take the equivalent of their own class, the "super" class and the - * `this` object as parameters. - * - * Asynchronous callbacks always run in the context of the zone where they were - * scheduled. This is implemented using two steps: - * 1. the callback is first registered using one of [registerCallback], - * [registerUnaryCallback], or [registerBinaryCallback]. This allows the zone - * to record that a callback exists and potentially modify it (by returning a - * different callback). The code doing the registration (e.g., `Future.then`) - * also remembers the current zone so that it can later run the callback in - * that zone. - * 2. At a later point the registered callback is run in the remembered zone. - * - * This is all handled internally by the platform code and most users don't need - * to worry about it. However, developers of new asynchronous operations, - * provided by the underlying system or through native extensions, must follow - * the protocol to be zone compatible. - * - * For convenience, zones provide [bindCallback] (and the corresponding - * [bindUnaryCallback] and [bindBinaryCallback]) to make it easier to respect - * the zone contract: these functions first invoke the corresponding `register` - * functions and then wrap the returned function so that it runs in the current - * zone when it is later asynchronously invoked. - * - * Similarly, zones provide [bindCallbackGuarded] (and the corresponding - * [bindUnaryCallbackGuarded] and [bindBinaryCallbackGuarded]), when the - * callback should be invoked through [Zone.runGuarded]. - */ -abstract class Zone { - // Private constructor so that it is not possible instantiate a Zone class. - Zone._(); - - /** - * The root zone. - * - * All isolate entry functions (`main` or spawned functions) start running in - * the root zone (that is, [Zone.current] is identical to [Zone.root] when the - * entry function is called). If no custom zone is created, the rest of the - * program always runs in the root zone. - * - * The root zone implements the default behavior of all zone operations. - * Many methods, like [registerCallback] do the bare minimum required of the - * function, and are only provided as a hook for custom zones. Others, like - * [scheduleMicrotask], interact with the underlying system to implement the - * desired behavior. - */ - static const Zone root = _rootZone; - - /** The currently running zone. */ - static _Zone _current = _rootZone; - - /** The zone that is currently active. */ - static Zone get current => _current; - - /** - * Handles uncaught asynchronous errors. - * - * There are two kind of asynchronous errors that are handled by this - * function: - * 1. Uncaught errors that were thrown in asynchronous callbacks, for example, - * a `throw` in the function passed to [Timer.run]. - * 2. Asynchronous errors that are pushed through [Future] and [Stream] - * chains, but for which no child registered an error handler. - * Most asynchronous classes, like [Future] or [Stream] push errors to their - * listeners. Errors are propagated this way until either a listener handles - * the error (for example with [Future.catchError]), or no listener is - * available anymore. In the latter case, futures and streams invoke the - * zone's [handleUncaughtError]. - * - * By default, when handled by the root zone, uncaught asynchronous errors are - * treated like uncaught synchronous exceptions. - */ - void handleUncaughtError(Object error, StackTrace stackTrace); - - /** - * The parent zone of the this zone. - * - * Is `null` if `this` is the [root] zone. - * - * Zones are created by [fork] on an existing zone, or by [runZoned] which - * forks the [current] zone. The new zone's parent zone is the zone it was - * forked from. - */ - Zone? get parent; - - /** - * The error zone is the one that is responsible for dealing with uncaught - * errors. - * - * This is the closest parent zone of this zone that provides a - * [handleUncaughtError] method. - * - * Asynchronous errors never cross zone boundaries between zones with - * different error handlers. - * - * Example: - * ``` - * import 'dart:async'; - * - * main() { - * var future; - * runZoned(() { - * // The asynchronous error is caught by the custom zone which prints - * // 'asynchronous error'. - * future = Future.error("asynchronous error"); - * }, onError: (e) { print(e); }); // Creates a zone with an error handler. - * // The following `catchError` handler is never invoked, because the - * // custom zone created by the call to `runZoned` provides an - * // error handler. - * future.catchError((e) { throw "is never reached"; }); - * } - * ``` - * - * Note that errors cannot enter a child zone with a different error handler - * either: - * ``` - * import 'dart:async'; - * - * main() { - * runZoned(() { - * // The following asynchronous error is *not* caught by the `catchError` - * // in the nested zone, since errors are not to cross zone boundaries - * // with different error handlers. - * // Instead the error is handled by the current error handler, - * // printing "Caught by outer zone: asynchronous error". - * var future = Future.error("asynchronous error"); - * runZoned(() { - * future.catchError((e) { throw "is never reached"; }); - * }, onError: (e) { throw "is never reached"; }); - * }, onError: (e) { print("Caught by outer zone: $e"); }); - * } - * ``` - */ - Zone get errorZone; - - /** - * Returns true if `this` and [otherZone] are in the same error zone. - * - * Two zones are in the same error zone if they have the same [errorZone]. - */ - bool inSameErrorZone(Zone otherZone); - - /** - * Creates a new zone as a child of `this`. - * - * The new zone uses the closures in the given [specification] to override - * the current's zone behavior. All specification entries that are `null` - * inherit the behavior from the parent zone (`this`). - * - * The new zone inherits the stored values (accessed through [operator []]) - * of this zone and updates them with values from [zoneValues], which either - * adds new values or overrides existing ones. - * - * Note that the fork operation is interceptible. A zone can thus change - * the zone specification (or zone values), giving the forking zone full - * control over the child zone. - */ - Zone fork( - {ZoneSpecification? specification, Map? zoneValues}); - - /** - * Executes [action] in this zone. - * - * By default (as implemented in the [root] zone), runs [action] - * with [current] set to this zone. - * - * If [action] throws, the synchronous exception is not caught by the zone's - * error handler. Use [runGuarded] to achieve that. - * - * Since the root zone is the only zone that can modify the value of - * [current], custom zones intercepting run should always delegate to their - * parent zone. They may take actions before and after the call. - */ - R run(R action()); - - /** - * Executes the given [action] with [argument] in this zone. - * - * As [run] except that [action] is called with one [argument] instead of - * none. - */ - R runUnary(R action(T argument), T argument); - - /** - * Executes the given [action] with [argument1] and [argument2] in this - * zone. - * - * As [run] except that [action] is called with two arguments instead of none. - */ - R runBinary( - R action(T1 argument1, T2 argument2), T1 argument1, T2 argument2); - - /** - * Executes the given [action] in this zone and catches synchronous - * errors. - * - * This function is equivalent to: - * ``` - * try { - * this.run(action); - * } catch (e, s) { - * this.handleUncaughtError(e, s); - * } - * ``` - * - * See [run]. - */ - void runGuarded(void action()); - - /** - * Executes the given [action] with [argument] in this zone and - * catches synchronous errors. - * - * See [runGuarded]. - */ - void runUnaryGuarded(void action(T argument), T argument); - - /** - * Executes the given [action] with [argument1] and [argument2] in this - * zone and catches synchronous errors. - * - * See [runGuarded]. - */ - void runBinaryGuarded( - void action(T1 argument1, T2 argument2), T1 argument1, T2 argument2); - - /** - * Registers the given callback in this zone. - * - * When implementing an asynchronous primitive that uses callbacks, the - * callback must be registered using [registerCallback] at the point where the - * user provides the callback. This allows zones to record other information - * that they need at the same time, perhaps even wrapping the callback, so - * that the callback is prepared when it is later run in the same zones - * (using [run]). For example, a zone may decide - * to store the stack trace (at the time of the registration) with the - * callback. - * - * Returns the callback that should be used in place of the provided - * [callback]. Frequently zones simply return the original callback. - * - * Custom zones may intercept this operation. The default implementation in - * [Zone.root] returns the original callback unchanged. - */ - ZoneCallback registerCallback(R callback()); - - /** - * Registers the given callback in this zone. - * - * Similar to [registerCallback] but with a unary callback. - */ - ZoneUnaryCallback registerUnaryCallback(R callback(T arg)); - - /** - * Registers the given callback in this zone. - * - * Similar to [registerCallback] but with a unary callback. - */ - ZoneBinaryCallback registerBinaryCallback( - R callback(T1 arg1, T2 arg2)); - - /** - * Registers the provided [callback] and returns a function that will - * execute in this zone. - * - * Equivalent to: - * - * ZoneCallback registered = this.registerCallback(callback); - * return () => this.run(registered); - * - */ - ZoneCallback bindCallback(R callback()); - - /** - * Registers the provided [callback] and returns a function that will - * execute in this zone. - * - * Equivalent to: - * - * ZoneCallback registered = this.registerUnaryCallback(callback); - * return (arg) => thin.runUnary(registered, arg); - */ - ZoneUnaryCallback bindUnaryCallback(R callback(T argument)); - - /** - * Registers the provided [callback] and returns a function that will - * execute in this zone. - * - * Equivalent to: - * - * ZoneCallback registered = registerBinaryCallback(callback); - * return (arg1, arg2) => thin.runBinary(registered, arg1, arg2); - */ - ZoneBinaryCallback bindBinaryCallback( - R callback(T1 argument1, T2 argument2)); - - /** - * Registers the provided [callback] and returns a function that will - * execute in this zone. - * - * When the function executes, errors are caught and treated as uncaught - * errors. - * - * Equivalent to: - * - * ZoneCallback registered = this.registerCallback(callback); - * return () => this.runGuarded(registered); - * - */ - void Function() bindCallbackGuarded(void Function() callback); - - /** - * Registers the provided [callback] and returns a function that will - * execute in this zone. - * - * When the function executes, errors are caught and treated as uncaught - * errors. - * - * Equivalent to: - * - * ZoneCallback registered = this.registerUnaryCallback(callback); - * return (arg) => this.runUnaryGuarded(registered, arg); - */ - void Function(T) bindUnaryCallbackGuarded(void callback(T argument)); - - /** - * Registers the provided [callback] and returns a function that will - * execute in this zone. - * - * Equivalent to: - * - * ZoneCallback registered = registerBinaryCallback(callback); - * return (arg1, arg2) => this.runBinaryGuarded(registered, arg1, arg2); - */ - void Function(T1, T2) bindBinaryCallbackGuarded( - void callback(T1 argument1, T2 argument2)); - - /** - * Intercepts errors when added programmatically to a `Future` or `Stream`. - * - * When calling [Completer.completeError], [StreamController.addError], - * or some [Future] constructors, the current zone is allowed to intercept - * and replace the error. - * - * Future constructors invoke this function when the error is received - * directly, for example with [Future.error], or when the error is caught - * synchronously, for example with [Future.sync]. - * - * There is no guarantee that an error is only sent through [errorCallback] - * once. Libraries that use intermediate controllers or completers might - * end up invoking [errorCallback] multiple times. - * - * Returns `null` if no replacement is desired. Otherwise returns an instance - * of [AsyncError] holding the new pair of error and stack trace. - * - * Although not recommended, the returned instance may have its `error` member - * ([AsyncError.error]) be equal to `null` in which case the error should be - * replaced by a [NullThrownError]. - * - * Custom zones may intercept this operation. - * - * Implementations of a new asynchronous primitive that converts synchronous - * errors to asynchronous errors rarely need to invoke [errorCallback], since - * errors are usually reported through future completers or stream - * controllers. - */ - AsyncError? errorCallback(Object error, StackTrace? stackTrace); - - /** - * Runs [callback] asynchronously in this zone. - * - * The global `scheduleMicrotask` delegates to the current zone's - * [scheduleMicrotask]. The root zone's implementation interacts with the - * underlying system to schedule the given callback as a microtask. - * - * Custom zones may intercept this operation (for example to wrap the given - * [callback]). - */ - void scheduleMicrotask(void Function() callback); - - /** - * Creates a Timer where the callback is executed in this zone. - */ - Timer createTimer(Duration duration, void Function() callback); - - /** - * Creates a periodic Timer where the callback is executed in this zone. - */ - Timer createPeriodicTimer(Duration period, void callback(Timer timer)); - - /** - * Prints the given [line]. - * - * The global `print` function delegates to the current zone's [print] - * function which makes it possible to intercept printing. - * - * Example: - * ``` - * import 'dart:async'; - * - * main() { - * runZoned(() { - * // Ends up printing: "Intercepted: in zone". - * print("in zone"); - * }, zoneSpecification: new ZoneSpecification( - * print: (Zone self, ZoneDelegate parent, Zone zone, String line) { - * parent.print(zone, "Intercepted: $line"); - * })); - * } - * ``` - */ - void print(String line); - - /** - * Call to enter the Zone. - * - * The previous current zone is returned. - */ - static _Zone _enter(_Zone zone) { - assert(!identical(zone, _current)); - _Zone previous = _current; - _current = zone; - return previous; - } - - /** - * Call to leave the Zone. - * - * The previous Zone must be provided as `previous`. - */ - static void _leave(_Zone previous) { - assert(previous != null); - Zone._current = previous; - } - - /** - * Retrieves the zone-value associated with [key]. - * - * If this zone does not contain the value looks up the same key in the - * parent zone. If the [key] is not found returns `null`. - * - * Any object can be used as key, as long as it has compatible `operator ==` - * and `hashCode` implementations. - * By controlling access to the key, a zone can grant or deny access to the - * zone value. - */ - dynamic operator [](Object? key); -} - -class _ZoneDelegate implements ZoneDelegate { - final _Zone _delegationTarget; - - _ZoneDelegate(this._delegationTarget); - - void handleUncaughtError(Zone zone, Object error, StackTrace stackTrace) { - var implementation = _delegationTarget._handleUncaughtError; - _Zone implZone = implementation.zone; - HandleUncaughtErrorHandler handler = implementation.function; - return handler(implZone, implZone._parentDelegate, zone, error, stackTrace); - } - - R run(Zone zone, R f()) { - var implementation = _delegationTarget._run; - _Zone implZone = implementation.zone; - var handler = implementation.function as RunHandler; - return handler(implZone, implZone._parentDelegate, zone, f); - } - - R runUnary(Zone zone, R f(T arg), T arg) { - var implementation = _delegationTarget._runUnary; - _Zone implZone = implementation.zone; - var handler = implementation.function as RunUnaryHandler; - return handler(implZone, implZone._parentDelegate, zone, f, arg); - } - - R runBinary(Zone zone, R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) { - var implementation = _delegationTarget._runBinary; - _Zone implZone = implementation.zone; - var handler = implementation.function as RunBinaryHandler; - return handler(implZone, implZone._parentDelegate, zone, f, arg1, arg2); - } - - ZoneCallback registerCallback(Zone zone, R f()) { - var implementation = _delegationTarget._registerCallback; - _Zone implZone = implementation.zone; - var handler = implementation.function as RegisterCallbackHandler; - return handler(implZone, implZone._parentDelegate, zone, f); - } - - ZoneUnaryCallback registerUnaryCallback(Zone zone, R f(T arg)) { - var implementation = _delegationTarget._registerUnaryCallback; - _Zone implZone = implementation.zone; - var handler = implementation.function as RegisterUnaryCallbackHandler; - return handler(implZone, implZone._parentDelegate, zone, f); - } - - ZoneBinaryCallback registerBinaryCallback( - Zone zone, R f(T1 arg1, T2 arg2)) { - var implementation = _delegationTarget._registerBinaryCallback; - _Zone implZone = implementation.zone; - var handler = implementation.function as RegisterBinaryCallbackHandler; - return handler(implZone, implZone._parentDelegate, zone, f); - } - - AsyncError? errorCallback(Zone zone, Object error, StackTrace? stackTrace) { - // TODO(40614): Remove once non-nullability is sound. - ArgumentError.checkNotNull(error, "error"); - var implementation = _delegationTarget._errorCallback; - _Zone implZone = implementation.zone; - if (identical(implZone, _rootZone)) return null; - ErrorCallbackHandler handler = implementation.function; - return handler(implZone, implZone._parentDelegate, zone, error, stackTrace); - } - - void scheduleMicrotask(Zone zone, f()) { - var implementation = _delegationTarget._scheduleMicrotask; - _Zone implZone = implementation.zone; - ScheduleMicrotaskHandler handler = implementation.function; - handler(implZone, implZone._parentDelegate, zone, f); - } - - Timer createTimer(Zone zone, Duration duration, void f()) { - var implementation = _delegationTarget._createTimer; - _Zone implZone = implementation.zone; - CreateTimerHandler handler = implementation.function; - return handler(implZone, implZone._parentDelegate, zone, duration, f); - } - - Timer createPeriodicTimer(Zone zone, Duration period, void f(Timer timer)) { - var implementation = _delegationTarget._createPeriodicTimer; - _Zone implZone = implementation.zone; - CreatePeriodicTimerHandler handler = implementation.function; - return handler(implZone, implZone._parentDelegate, zone, period, f); - } - - void print(Zone zone, String line) { - var implementation = _delegationTarget._print; - _Zone implZone = implementation.zone; - PrintHandler handler = implementation.function; - handler(implZone, implZone._parentDelegate, zone, line); - } - - Zone fork(Zone zone, ZoneSpecification? specification, - Map? zoneValues) { - var implementation = _delegationTarget._fork; - _Zone implZone = implementation.zone; - ForkHandler handler = implementation.function; - return handler( - implZone, implZone._parentDelegate, zone, specification, zoneValues); - } -} - -/** - * Base class for Zone implementations. - */ -abstract class _Zone implements Zone { - const _Zone(); - - // TODO(floitsch): the types of the `_ZoneFunction`s should have a type for - // all fields. - _RunNullaryZoneFunction get _run; - _RunUnaryZoneFunction get _runUnary; - _RunBinaryZoneFunction get _runBinary; - _RegisterNullaryZoneFunction get _registerCallback; - _RegisterUnaryZoneFunction get _registerUnaryCallback; - _RegisterBinaryZoneFunction get _registerBinaryCallback; - _ZoneFunction get _errorCallback; - _ZoneFunction get _scheduleMicrotask; - _ZoneFunction get _createTimer; - _ZoneFunction get _createPeriodicTimer; - _ZoneFunction get _print; - _ZoneFunction get _fork; - _ZoneFunction get _handleUncaughtError; - // Parent zone. Only `null` for the root zone. - _Zone? get parent; - ZoneDelegate get _delegate; - ZoneDelegate get _parentDelegate; - Map get _map; - - bool inSameErrorZone(Zone otherZone) { - return identical(this, otherZone) || - identical(errorZone, otherZone.errorZone); - } -} - -class _CustomZone extends _Zone { - // The actual zone and implementation of each of these - // inheritable zone functions. - // TODO(floitsch): the types of the `_ZoneFunction`s should have a type for - // all fields, but we can't use generic function types as type arguments. - _RunNullaryZoneFunction _run; - _RunUnaryZoneFunction _runUnary; - _RunBinaryZoneFunction _runBinary; - _RegisterNullaryZoneFunction _registerCallback; - _RegisterUnaryZoneFunction _registerUnaryCallback; - _RegisterBinaryZoneFunction _registerBinaryCallback; - _ZoneFunction _errorCallback; - _ZoneFunction _scheduleMicrotask; - _ZoneFunction _createTimer; - _ZoneFunction _createPeriodicTimer; - _ZoneFunction _print; - _ZoneFunction _fork; - _ZoneFunction _handleUncaughtError; - - // A cached delegate to this zone. - ZoneDelegate? _delegateCache; - - /// The parent zone. - final _Zone parent; - - /// The zone's scoped value declaration map. - /// - /// This is always a [HashMap]. - final Map _map; - - ZoneDelegate get _delegate => _delegateCache ??= _ZoneDelegate(this); - ZoneDelegate get _parentDelegate => parent._delegate; - - _CustomZone(this.parent, ZoneSpecification specification, this._map) - : _run = parent._run, - _runUnary = parent._runUnary, - _runBinary = parent._runBinary, - _registerCallback = parent._registerCallback, - _registerUnaryCallback = parent._registerUnaryCallback, - _registerBinaryCallback = parent._registerBinaryCallback, - _errorCallback = parent._errorCallback, - _scheduleMicrotask = parent._scheduleMicrotask, - _createTimer = parent._createTimer, - _createPeriodicTimer = parent._createPeriodicTimer, - _print = parent._print, - _fork = parent._fork, - _handleUncaughtError = parent._handleUncaughtError { - // The root zone will have implementations of all parts of the - // specification, so it will never try to access the (null) parent. - // All other zones have a non-null parent. - var run = specification.run; - if (run != null) { - _run = _RunNullaryZoneFunction(this, run); - } - var runUnary = specification.runUnary; - if (runUnary != null) { - _runUnary = _RunUnaryZoneFunction(this, runUnary); - } - var runBinary = specification.runBinary; - if (runBinary != null) { - _runBinary = _RunBinaryZoneFunction(this, runBinary); - } - var registerCallback = specification.registerCallback; - if (registerCallback != null) { - _registerCallback = _RegisterNullaryZoneFunction(this, registerCallback); - } - var registerUnaryCallback = specification.registerUnaryCallback; - if (registerUnaryCallback != null) { - _registerUnaryCallback = - _RegisterUnaryZoneFunction(this, registerUnaryCallback); - } - var registerBinaryCallback = specification.registerBinaryCallback; - if (registerBinaryCallback != null) { - _registerBinaryCallback = - _RegisterBinaryZoneFunction(this, registerBinaryCallback); - } - var errorCallback = specification.errorCallback; - if (errorCallback != null) { - _errorCallback = _ZoneFunction(this, errorCallback); - } - var scheduleMicrotask = specification.scheduleMicrotask; - if (scheduleMicrotask != null) { - _scheduleMicrotask = - _ZoneFunction(this, scheduleMicrotask); - } - var createTimer = specification.createTimer; - if (createTimer != null) { - _createTimer = _ZoneFunction(this, createTimer); - } - var createPeriodicTimer = specification.createPeriodicTimer; - if (createPeriodicTimer != null) { - _createPeriodicTimer = - _ZoneFunction(this, createPeriodicTimer); - } - var print = specification.print; - if (print != null) { - _print = _ZoneFunction(this, print); - } - var fork = specification.fork; - if (fork != null) { - _fork = _ZoneFunction(this, fork); - } - var handleUncaughtError = specification.handleUncaughtError; - if (handleUncaughtError != null) { - _handleUncaughtError = - _ZoneFunction(this, handleUncaughtError); - } - } - - /** - * The closest error-handling zone. - * - * Returns `this` if `this` has an error-handler. Otherwise returns the - * parent's error-zone. - */ - Zone get errorZone => _handleUncaughtError.zone; - - void runGuarded(void f()) { - try { - run(f); - } catch (e, s) { - handleUncaughtError(e, s); - } - } - - void runUnaryGuarded(void f(T arg), T arg) { - try { - runUnary(f, arg); - } catch (e, s) { - handleUncaughtError(e, s); - } - } - - void runBinaryGuarded(void f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) { - try { - runBinary(f, arg1, arg2); - } catch (e, s) { - handleUncaughtError(e, s); - } - } - - ZoneCallback bindCallback(R f()) { - var registered = registerCallback(f); - return () => this.run(registered); - } - - ZoneUnaryCallback bindUnaryCallback(R f(T arg)) { - var registered = registerUnaryCallback(f); - return (arg) => this.runUnary(registered, arg); - } - - ZoneBinaryCallback bindBinaryCallback( - R f(T1 arg1, T2 arg2)) { - var registered = registerBinaryCallback(f); - return (arg1, arg2) => this.runBinary(registered, arg1, arg2); - } - - void Function() bindCallbackGuarded(void f()) { - var registered = registerCallback(f); - return () => this.runGuarded(registered); - } - - void Function(T) bindUnaryCallbackGuarded(void f(T arg)) { - var registered = registerUnaryCallback(f); - return (arg) => this.runUnaryGuarded(registered, arg); - } - - void Function(T1, T2) bindBinaryCallbackGuarded( - void f(T1 arg1, T2 arg2)) { - var registered = registerBinaryCallback(f); - return (arg1, arg2) => this.runBinaryGuarded(registered, arg1, arg2); - } - - dynamic operator [](Object? key) { - var result = _map[key]; - if (result != null || _map.containsKey(key)) return result; - // If we are not the root zone, look up in the parent zone. - if (parent != null) { - // We do not optimize for repeatedly looking up a key which isn't - // there. That would require storing the key and keeping it alive. - // Copying the key/value from the parent does not keep any new values - // alive. - var value = parent[key]; - if (value != null) { - _map[key] = value; - } - return value; - } - assert(this == _rootZone); - return null; - } - - // Methods that can be customized by the zone specification. - - void handleUncaughtError(Object error, StackTrace stackTrace) { - var implementation = this._handleUncaughtError; - ZoneDelegate parentDelegate = implementation.zone._parentDelegate; - HandleUncaughtErrorHandler handler = implementation.function; - return handler( - implementation.zone, parentDelegate, this, error, stackTrace); - } - - Zone fork( - {ZoneSpecification? specification, Map? zoneValues}) { - var implementation = this._fork; - ZoneDelegate parentDelegate = implementation.zone._parentDelegate; - ForkHandler handler = implementation.function; - return handler( - implementation.zone, parentDelegate, this, specification, zoneValues); - } - - R run(R f()) { - var implementation = this._run; - ZoneDelegate parentDelegate = implementation.zone._parentDelegate; - var handler = implementation.function as RunHandler; - return handler(implementation.zone, parentDelegate, this, f); - } - - R runUnary(R f(T arg), T arg) { - var implementation = this._runUnary; - ZoneDelegate parentDelegate = implementation.zone._parentDelegate; - var handler = implementation.function as RunUnaryHandler; - return handler(implementation.zone, parentDelegate, this, f, arg); - } - - R runBinary(R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) { - var implementation = this._runBinary; - ZoneDelegate parentDelegate = implementation.zone._parentDelegate; - var handler = implementation.function as RunBinaryHandler; - return handler(implementation.zone, parentDelegate, this, f, arg1, arg2); - } - - ZoneCallback registerCallback(R callback()) { - var implementation = this._registerCallback; - ZoneDelegate parentDelegate = implementation.zone._parentDelegate; - var handler = implementation.function as RegisterCallbackHandler; - return handler(implementation.zone, parentDelegate, this, callback); - } - - ZoneUnaryCallback registerUnaryCallback(R callback(T arg)) { - var implementation = this._registerUnaryCallback; - ZoneDelegate parentDelegate = implementation.zone._parentDelegate; - var handler = implementation.function as RegisterUnaryCallbackHandler; - return handler(implementation.zone, parentDelegate, this, callback); - } - - ZoneBinaryCallback registerBinaryCallback( - R callback(T1 arg1, T2 arg2)) { - var implementation = this._registerBinaryCallback; - ZoneDelegate parentDelegate = implementation.zone._parentDelegate; - var handler = implementation.function as RegisterBinaryCallbackHandler; - return handler(implementation.zone, parentDelegate, this, callback); - } - - AsyncError? errorCallback(Object error, StackTrace? stackTrace) { - // TODO(40614): Remove once non-nullability is sound. - ArgumentError.checkNotNull(error, "error"); - var implementation = this._errorCallback; - final _Zone implementationZone = implementation.zone; - if (identical(implementationZone, _rootZone)) return null; - final ZoneDelegate parentDelegate = implementationZone._parentDelegate; - ErrorCallbackHandler handler = implementation.function; - return handler(implementationZone, parentDelegate, this, error, stackTrace); - } - - void scheduleMicrotask(void f()) { - var implementation = this._scheduleMicrotask; - ZoneDelegate parentDelegate = implementation.zone._parentDelegate; - ScheduleMicrotaskHandler handler = implementation.function; - return handler(implementation.zone, parentDelegate, this, f); - } - - Timer createTimer(Duration duration, void f()) { - var implementation = this._createTimer; - ZoneDelegate parentDelegate = implementation.zone._parentDelegate; - CreateTimerHandler handler = implementation.function; - return handler(implementation.zone, parentDelegate, this, duration, f); - } - - Timer createPeriodicTimer(Duration duration, void f(Timer timer)) { - var implementation = this._createPeriodicTimer; - ZoneDelegate parentDelegate = implementation.zone._parentDelegate; - CreatePeriodicTimerHandler handler = implementation.function; - return handler(implementation.zone, parentDelegate, this, duration, f); - } - - void print(String line) { - var implementation = this._print; - ZoneDelegate parentDelegate = implementation.zone._parentDelegate; - PrintHandler handler = implementation.function; - return handler(implementation.zone, parentDelegate, this, line); - } -} - -void _rootHandleUncaughtError(Zone? self, ZoneDelegate? parent, Zone zone, - Object error, StackTrace stackTrace) { - _schedulePriorityAsyncCallback(() { - _rethrow(error, stackTrace); - }); -} - -external void _rethrow(Object error, StackTrace stackTrace); - -R _rootRun(Zone? self, ZoneDelegate? parent, Zone zone, R f()) { - if (identical(Zone._current, zone)) return f(); - - if (zone is! _Zone) { - throw ArgumentError.value(zone, "zone", "Can only run in platform zones"); - } - - _Zone old = Zone._enter(zone); - try { - return f(); - } finally { - Zone._leave(old); - } -} - -R _rootRunUnary( - Zone? self, ZoneDelegate? parent, Zone zone, R f(T arg), T arg) { - if (identical(Zone._current, zone)) return f(arg); - - if (zone is! _Zone) { - throw ArgumentError.value(zone, "zone", "Can only run in platform zones"); - } - - _Zone old = Zone._enter(zone); - try { - return f(arg); - } finally { - Zone._leave(old); - } -} - -R _rootRunBinary(Zone? self, ZoneDelegate? parent, Zone zone, - R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) { - if (identical(Zone._current, zone)) return f(arg1, arg2); - - if (zone is! _Zone) { - throw ArgumentError.value(zone, "zone", "Can only run in platform zones"); - } - - _Zone old = Zone._enter(zone); - try { - return f(arg1, arg2); - } finally { - Zone._leave(old); - } -} - -ZoneCallback _rootRegisterCallback( - Zone self, ZoneDelegate parent, Zone zone, R f()) { - return f; -} - -ZoneUnaryCallback _rootRegisterUnaryCallback( - Zone self, ZoneDelegate parent, Zone zone, R f(T arg)) { - return f; -} - -ZoneBinaryCallback _rootRegisterBinaryCallback( - Zone self, ZoneDelegate parent, Zone zone, R f(T1 arg1, T2 arg2)) { - return f; -} - -AsyncError? _rootErrorCallback(Zone self, ZoneDelegate parent, Zone zone, - Object error, StackTrace? stackTrace) => - null; - -void _rootScheduleMicrotask( - Zone? self, ZoneDelegate? parent, Zone zone, void f()) { - if (!identical(_rootZone, zone)) { - bool hasErrorHandler = !_rootZone.inSameErrorZone(zone); - if (hasErrorHandler) { - f = zone.bindCallbackGuarded(f); - } else { - f = zone.bindCallback(f); - } - } - _scheduleAsyncCallback(f); -} - -Timer _rootCreateTimer(Zone self, ZoneDelegate parent, Zone zone, - Duration duration, void Function() callback) { - if (!identical(_rootZone, zone)) { - callback = zone.bindCallback(callback); - } - return Timer._createTimer(duration, callback); -} - -Timer _rootCreatePeriodicTimer(Zone self, ZoneDelegate parent, Zone zone, - Duration duration, void callback(Timer timer)) { - if (!identical(_rootZone, zone)) { - callback = zone.bindUnaryCallback(callback); - } - return Timer._createPeriodicTimer(duration, callback); -} - -void _rootPrint(Zone self, ZoneDelegate parent, Zone zone, String line) { - printToConsole(line); -} - -void _printToZone(String line) { - Zone.current.print(line); -} - -Zone _rootFork(Zone? self, ZoneDelegate? parent, Zone zone, - ZoneSpecification? specification, Map? zoneValues) { - if (zone is! _Zone) { - throw ArgumentError.value(zone, "zone", "Can only fork a platform zone"); - } - // TODO(floitsch): it would be nice if we could get rid of this hack. - // Change the static zoneOrDirectPrint function to go through zones - // from now on. - printToZone = _printToZone; - - if (specification == null) { - specification = const ZoneSpecification(); - } else if (specification is! _ZoneSpecification) { - specification = ZoneSpecification.from(specification); - } - Map valueMap; - if (zoneValues == null) { - valueMap = zone._map; - } else { - valueMap = HashMap.from(zoneValues); - } - if (specification == null) - throw "unreachable"; // TODO(lrn): Remove when type promotion works. - return _CustomZone(zone, specification, valueMap); -} - -class _RootZone extends _Zone { - const _RootZone(); - - _RunNullaryZoneFunction get _run => - const _RunNullaryZoneFunction(_rootZone, _rootRun); - _RunUnaryZoneFunction get _runUnary => - const _RunUnaryZoneFunction(_rootZone, _rootRunUnary); - _RunBinaryZoneFunction get _runBinary => - const _RunBinaryZoneFunction(_rootZone, _rootRunBinary); - _RegisterNullaryZoneFunction get _registerCallback => - const _RegisterNullaryZoneFunction(_rootZone, _rootRegisterCallback); - _RegisterUnaryZoneFunction get _registerUnaryCallback => - const _RegisterUnaryZoneFunction(_rootZone, _rootRegisterUnaryCallback); - _RegisterBinaryZoneFunction get _registerBinaryCallback => - const _RegisterBinaryZoneFunction(_rootZone, _rootRegisterBinaryCallback); - _ZoneFunction get _errorCallback => - const _ZoneFunction(_rootZone, _rootErrorCallback); - _ZoneFunction get _scheduleMicrotask => - const _ZoneFunction( - _rootZone, _rootScheduleMicrotask); - _ZoneFunction get _createTimer => - const _ZoneFunction(_rootZone, _rootCreateTimer); - _ZoneFunction get _createPeriodicTimer => - const _ZoneFunction( - _rootZone, _rootCreatePeriodicTimer); - _ZoneFunction get _print => - const _ZoneFunction(_rootZone, _rootPrint); - _ZoneFunction get _fork => - const _ZoneFunction(_rootZone, _rootFork); - _ZoneFunction get _handleUncaughtError => - const _ZoneFunction( - _rootZone, _rootHandleUncaughtError); - - // The parent zone. - _Zone? get parent => null; - - /// The zone's scoped value declaration map. - /// - /// This is always a [HashMap]. - Map get _map => _rootMap; - - static final _rootMap = HashMap(); - - static ZoneDelegate? _rootDelegate; - - ZoneDelegate get _delegate => _rootDelegate ??= new _ZoneDelegate(this); - // It's a lie, but the root zone never uses the parent delegate. - ZoneDelegate get _parentDelegate => _delegate; - - /** - * The closest error-handling zone. - * - * Returns `this` if `this` has an error-handler. Otherwise returns the - * parent's error-zone. - */ - Zone get errorZone => this; - - // Zone interface. - - void runGuarded(void f()) { - try { - if (identical(_rootZone, Zone._current)) { - f(); - return; - } - _rootRun(null, null, this, f); - } catch (e, s) { - handleUncaughtError(e, s); - } - } - - void runUnaryGuarded(void f(T arg), T arg) { - try { - if (identical(_rootZone, Zone._current)) { - f(arg); - return; - } - _rootRunUnary(null, null, this, f, arg); - } catch (e, s) { - handleUncaughtError(e, s); - } - } - - void runBinaryGuarded(void f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) { - try { - if (identical(_rootZone, Zone._current)) { - f(arg1, arg2); - return; - } - _rootRunBinary(null, null, this, f, arg1, arg2); - } catch (e, s) { - handleUncaughtError(e, s); - } - } - - ZoneCallback bindCallback(R f()) { - return () => this.run(f); - } - - ZoneUnaryCallback bindUnaryCallback(R f(T arg)) { - return (arg) => this.runUnary(f, arg); - } - - ZoneBinaryCallback bindBinaryCallback( - R f(T1 arg1, T2 arg2)) { - return (arg1, arg2) => this.runBinary(f, arg1, arg2); - } - - void Function() bindCallbackGuarded(void f()) { - return () => this.runGuarded(f); - } - - void Function(T) bindUnaryCallbackGuarded(void f(T arg)) { - return (arg) => this.runUnaryGuarded(f, arg); - } - - void Function(T1, T2) bindBinaryCallbackGuarded( - void f(T1 arg1, T2 arg2)) { - return (arg1, arg2) => this.runBinaryGuarded(f, arg1, arg2); - } - - dynamic operator [](Object? key) => null; - - // Methods that can be customized by the zone specification. - - void handleUncaughtError(Object error, StackTrace stackTrace) { - _rootHandleUncaughtError(null, null, this, error, stackTrace); - } - - Zone fork( - {ZoneSpecification? specification, Map? zoneValues}) { - return _rootFork(null, null, this, specification, zoneValues); - } - - R run(R f()) { - if (identical(Zone._current, _rootZone)) return f(); - return _rootRun(null, null, this, f); - } - - R runUnary(R f(T arg), T arg) { - if (identical(Zone._current, _rootZone)) return f(arg); - return _rootRunUnary(null, null, this, f, arg); - } - - R runBinary(R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) { - if (identical(Zone._current, _rootZone)) return f(arg1, arg2); - return _rootRunBinary(null, null, this, f, arg1, arg2); - } - - ZoneCallback registerCallback(R f()) => f; - - ZoneUnaryCallback registerUnaryCallback(R f(T arg)) => f; - - ZoneBinaryCallback registerBinaryCallback( - R f(T1 arg1, T2 arg2)) => - f; - - AsyncError? errorCallback(Object error, StackTrace? stackTrace) => null; - - void scheduleMicrotask(void f()) { - _rootScheduleMicrotask(null, null, this, f); - } - - Timer createTimer(Duration duration, void f()) { - return Timer._createTimer(duration, f); - } - - Timer createPeriodicTimer(Duration duration, void f(Timer timer)) { - return Timer._createPeriodicTimer(duration, f); - } - - void print(String line) { - printToConsole(line); - } -} - -const _Zone _rootZone = const _RootZone(); - -/** - * Runs [body] in its own zone. - * - * Creates a new zone using [Zone.fork] based on [zoneSpecification] and - * [zoneValues], then runs [body] in that zone and returns the result. - * - * If [onError] is provided, it must have one of the types - * * `void Function(Object)` - * * `void Function(Object, StackTrace)` - * and the [onError] handler is used *both* to handle asynchronous errors - * by overriding [ZoneSpecification.handleUncaughtError] in [zoneSpecification], - * if any, *and* to handle errors thrown synchronously by the call to [body]. - * - * If an error occurs synchronously in [body], - * then throwing in the [onError] handler - * makes the call to `runZone` throw that error, - * and otherwise the call to `runZoned` attempt to return `null`. - * - * If the zone specification has a `handleUncaughtError` value or the [onError] - * parameter is provided, the zone becomes an error-zone. - * - * Errors will never cross error-zone boundaries by themselves. - * Errors that try to cross error-zone boundaries are considered uncaught in - * their originating error zone. - * - * var future = new Future.value(499); - * runZoned(() { - * var future2 = future.then((_) { throw "error in first error-zone"; }); - * runZoned(() { - * var future3 = future2.catchError((e) { print("Never reached!"); }); - * }, onError: (e, s) { print("unused error handler"); }); - * }, onError: (e, s) { print("catches error of first error-zone."); }); - * - * Example: - * - * runZoned(() { - * new Future(() { throw "asynchronous error"; }); - * }, onError: (e, s) => print(e)); // Will print "asynchronous error". - * - * It is possible to manually pass an error from one error zone to another - * by re-throwing it in the new zone. If [onError] throws, that error will - * occur in the original zone where [runZoned] was called. - */ -R runZoned(R body(), - {Map? zoneValues, - ZoneSpecification? zoneSpecification, - @Deprecated("Use runZonedGuarded instead") Function? onError}) { - ArgumentError.checkNotNull(body, "body"); - if (onError != null) { - // TODO: Remove this when code have been migrated off using [onError]. - if (onError is! void Function(Object, StackTrace)) { - if (onError is void Function(Object)) { - var originalOnError = onError; - onError = (Object error, StackTrace stack) => originalOnError(error); - } else { - throw ArgumentError.value(onError, "onError", - "Must be Function(Object) or Function(Object, StackTrace)"); - } - } - return runZonedGuarded(body, onError, - zoneSpecification: zoneSpecification, zoneValues: zoneValues) as R; - } - return _runZoned(body, zoneValues, zoneSpecification); -} - -/** - * Runs [body] in its own error zone. - * - * Creates a new zone using [Zone.fork] based on [zoneSpecification] and - * [zoneValues], then runs [body] in that zone and returns the result. - * - * The [onError] function is used *both* to handle asynchronous errors - * by overriding [ZoneSpecification.handleUncaughtError] in [zoneSpecification], - * if any, *and* to handle errors thrown synchronously by the call to [body]. - * - * If an error occurs synchronously in [body], - * then throwing in the [onError] handler - * makes the call to `runZonedGuarded` throw that error, - * and otherwise the call to `runZonedGuarded` returns `null`. - * - * The zone will always be an error-zone. - * - * Errors will never cross error-zone boundaries by themselves. - * Errors that try to cross error-zone boundaries are considered uncaught in - * their originating error zone. - * ```dart - * var future = Future.value(499); - * runZonedGuarded(() { - * var future2 = future.then((_) { throw "error in first error-zone"; }); - * runZonedGuarded(() { - * var future3 = future2.catchError((e) { print("Never reached!"); }); - * }, (e, s) { print("unused error handler"); }); - * }, (e, s) { print("catches error of first error-zone."); }); - * ``` - * Example: - * ```dart - * runZonedGuarded(() { - * new Future(() { throw "asynchronous error"; }); - * }, (e, s) => print(e)); // Will print "asynchronous error". - * ``` - * It is possible to manually pass an error from one error zone to another - * by re-throwing it in the new zone. If [onError] throws, that error will - * occur in the original zone where [runZoned] was called. - */ -@Since("2.8") -R? runZonedGuarded(R body(), void onError(Object error, StackTrace stack), - {Map? zoneValues, ZoneSpecification? zoneSpecification}) { - ArgumentError.checkNotNull(body, "body"); - ArgumentError.checkNotNull(onError, "onError"); - _Zone parentZone = Zone._current; - HandleUncaughtErrorHandler errorHandler = (Zone self, ZoneDelegate parent, - Zone zone, Object error, StackTrace stackTrace) { - try { - parentZone.runBinary(onError, error, stackTrace); - } catch (e, s) { - if (identical(e, error)) { - parent.handleUncaughtError(zone, error, stackTrace); - } else { - parent.handleUncaughtError(zone, e, s); - } - } - }; - if (zoneSpecification == null) { - zoneSpecification = - new ZoneSpecification(handleUncaughtError: errorHandler); - } else { - zoneSpecification = ZoneSpecification.from(zoneSpecification, - handleUncaughtError: errorHandler); - } - try { - return _runZoned(body, zoneValues, zoneSpecification); - } catch (error, stackTrace) { - onError(error, stackTrace); - } - return null; -} - -/// Runs [body] in a new zone based on [zoneValues] and [specification]. -R _runZoned(R body(), Map? zoneValues, - ZoneSpecification? specification) => - Zone.current - .fork(specification: specification, zoneValues: zoneValues) - .run(body); diff --git a/sdk_nnbd/lib/cli/cli.dart b/sdk_nnbd/lib/cli/cli.dart deleted file mode 100644 index 9c19c3a3252..00000000000 --- a/sdk_nnbd/lib/cli/cli.dart +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) 2017, 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. - -/// {@category VM} -library dart.cli; - -import 'dart:async'; -import 'dart:math'; - -part 'wait_for.dart'; diff --git a/sdk_nnbd/lib/cli/cli_sources.gni b/sdk_nnbd/lib/cli/cli_sources.gni deleted file mode 100644 index e90e1de8d87..00000000000 --- a/sdk_nnbd/lib/cli/cli_sources.gni +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright (c) 2017, 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. - -cli_sdk_sources = [ - "cli.dart", - - # The above file needs to be first if additional parts are added to the lib. - "wait_for.dart", -] diff --git a/sdk_nnbd/lib/cli/wait_for.dart b/sdk_nnbd/lib/cli/wait_for.dart deleted file mode 100644 index 35cb307ea93..00000000000 --- a/sdk_nnbd/lib/cli/wait_for.dart +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright (c) 2017, 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. - -part of dart.cli; - -/** - * Synchronously blocks the calling isolate to wait for asynchronous events to - * complete. - * - * If the [timeout] parameter is supplied, [waitForEvent] will return after - * the specified timeout even if no events have occurred. - * - * This call does the following: - * - suspends the current execution stack, - * - runs the microtask queue until it is empty, - * - waits until the message queue is not empty, - * - handles messages on the message queue, plus their associated microtasks, - * until the message queue is empty, - * - resumes the original stack. - * - * This function breaks the usual promise offered by Dart semantics that - * message handlers and microtasks run to completion before the next message - * handler or microtask begins to run. Of particular note is that use of this - * function in a finally block will allow microtasks and message handlers to - * run before all finally blocks for an exception have completed, possibly - * breaking invariants in your program. - * - * This function will synchronously throw the first unhandled exception it - * encounters in running the microtasks and message handlers as though the - * throwing microtask or message handler was the only Dart invocation on the - * stack. That is, unhandled exceptions in a microtask or message handler will - * skip over stacks suspended in a call to [waitForEvent]. - * - * Calls to this function may be nested. Earlier invocations will not - * be able to complete until subsequent ones do. Messages that arrive after - * a subsequent invocation are "consumed" by that invocation, and do not - * unblock an earlier invocation. Please be aware that nesting calls to - * [waitForEvent] can lead to deadlock when subsequent calls block to wait for - * a condition that is only satisfied after an earlier call returns. - * - * Please note that this call is only available in the standalone command-line - * Dart VM. Further, because it suspends the current execution stack until the - * message queue is empty, even when running in the standalone command-line VM - * there exists a risk that the current execution stack will be starved. - */ -external void _waitForEvent(int timeoutMillis); - -@pragma("vm:entry-point") -void Function(int) _getWaitForEvent() => _waitForEvent; - -// This should be set from C++ code by the embedder to wire up waitFor() to the -// native implementation. In the standalone VM this is set to _waitForEvent() -// above. If it is null, calling waitFor() will throw an UnsupportedError. -@pragma("vm:entry-point") -void Function(int)? _waitForEventClosure; - -class _WaitForUtils { - static void waitForEvent({Duration? timeout}) { - final closure = _waitForEventClosure; - if (closure == null) { - throw new UnsupportedError("waitFor is not supported by this embedder"); - } - closure(timeout == null ? 0 : max(1, timeout.inMilliseconds)); - } -} - -/** - * Suspends the stack, runs microtasks, and handles incoming events until - * [future] completes. - * - * WARNING: EXPERIMENTAL. USE AT YOUR OWN RISK. - * - * This call does the following: - * - While [future] is not completed: - * - suspends the current execution stack, - * - runs the microtask queue until it is empty, - * - waits until the message queue is not empty, - * - handles messages on the message queue, plus their associated microtasks, - * until the message queue is empty, - * - resumes the original stack. - * - * This function breaks the usual promise offered by Dart semantics that - * message handlers and microtasks run to completion before the next message - * handler or microtask begins to run. Of particular note is that use of this - * function in a finally block will allow microtasks and message handlers to - * run before all finally blocks for an exception have completed, possibly - * breaking invariants in your program. - * - * Use of this function should be considered a last resort when it is not - * possible to convert a Dart program entirely to an asynchronous style using - * `async` and `await`. - * - * If the [Future] completes normally, its result is returned. If the [Future] - * completes with an error, the error and stack trace are wrapped in an - * [AsyncError] and thrown. If a microtask or message handler run during this - * call results in an unhandled exception, that exception will be propagated - * as though the microtask or message handler was the only Dart invocation on - * the stack. That is, unhandled exceptions in a microtask or message handler - * will skip over stacks suspended in a call to [waitFor]. - * - * If the optional `timeout` parameter is passed, [waitFor] throws a - * [TimeoutException] if the [Future] is not completed within the specified - * period. - * - * Calls to [waitFor] may be nested. Earlier invocations will not complete - * until subsequent ones do, but the completion of a subsequent invocation will - * cause the previous invocation to wake up and check its [Future] for - * completion. - * - * Please be aware that nesting calls to [waitFor] can lead to deadlock if - * subsequent calls block waiting for a condition that is only satisfied when - * an earlier call returns. - */ -T waitFor(Future future, {Duration? timeout}) { - late T result; - bool futureCompleted = false; - Object? error; - StackTrace? stacktrace; - future.then((T r) { - futureCompleted = true; - result = r; - }, onError: (e, st) { - error = e; - stacktrace = st; - }); - - late Stopwatch s; - if (timeout != null) { - s = new Stopwatch()..start(); - } - Timer.run(() {}); // Enusre there is at least one message. - while (!futureCompleted && (error == null)) { - Duration? remaining; - if (timeout != null) { - if (s.elapsed >= timeout) { - throw new TimeoutException("waitFor() timed out", timeout); - } - remaining = timeout - s.elapsed; - } - _WaitForUtils.waitForEvent(timeout: remaining); - } - if (timeout != null) { - s.stop(); - } - Timer.run(() {}); // Ensure that previous calls to waitFor are woken up. - - if (error != null) { - throw new AsyncError(error!, stacktrace); - } - - return result; -} diff --git a/sdk_nnbd/lib/collection/collection.dart b/sdk_nnbd/lib/collection/collection.dart deleted file mode 100644 index b050a485e4c..00000000000 --- a/sdk_nnbd/lib/collection/collection.dart +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) 2012, 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. - -/// Classes and utilities that supplement the collection support in dart:core. -/// -/// To use this library in your code: -/// -/// import 'dart:collection'; -/// -/// {@category Core} -library dart.collection; - -import 'dart:_internal' hide Symbol; -import 'dart:math' show Random; // Used by ListMixin.shuffle. - -part 'collections.dart'; -part 'hash_map.dart'; -part 'hash_set.dart'; -part 'iterable.dart'; -part 'iterator.dart'; -part 'linked_hash_map.dart'; -part 'linked_hash_set.dart'; -part 'linked_list.dart'; -part 'list.dart'; -part 'maps.dart'; -part 'queue.dart'; -part 'set.dart'; -part 'splay_tree.dart'; diff --git a/sdk_nnbd/lib/collection/collection_sources.gni b/sdk_nnbd/lib/collection/collection_sources.gni deleted file mode 100644 index 3f2f19ec5a9..00000000000 --- a/sdk_nnbd/lib/collection/collection_sources.gni +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright (c) 2017, 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. - -# This file contains all sources for the dart:collection library. -collection_sdk_sources = [ - "collection.dart", - - # The above file needs to be first as it lists the parts below. - "collections.dart", - "hash_map.dart", - "hash_set.dart", - "iterable.dart", - "iterator.dart", - "linked_hash_map.dart", - "linked_hash_set.dart", - "linked_list.dart", - "list.dart", - "maps.dart", - "queue.dart", - "set.dart", - "splay_tree.dart", -] diff --git a/sdk_nnbd/lib/collection/collections.dart b/sdk_nnbd/lib/collection/collections.dart deleted file mode 100644 index 9b43996f638..00000000000 --- a/sdk_nnbd/lib/collection/collections.dart +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) 2013, 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. - -part of dart.collection; - -/// An unmodifiable [List] view of another List. -/// -/// The source of the elements may be a [List] or any [Iterable] with -/// efficient [Iterable.length] and [Iterable.elementAt]. -class UnmodifiableListView extends UnmodifiableListBase { - final Iterable _source; - - /// Creates an unmodifiable list backed by [source]. - /// - /// The [source] of the elements may be a [List] or any [Iterable] with - /// efficient [Iterable.length] and [Iterable.elementAt]. - UnmodifiableListView(Iterable source) : _source = source; - - List cast() => UnmodifiableListView(_source.cast()); - int get length => _source.length; - - E operator [](int index) => _source.elementAt(index); -} diff --git a/sdk_nnbd/lib/collection/hash_map.dart b/sdk_nnbd/lib/collection/hash_map.dart deleted file mode 100644 index 3990cd2eb02..00000000000 --- a/sdk_nnbd/lib/collection/hash_map.dart +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright (c) 2013, 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. - -part of dart.collection; - -/// Default function for equality comparison in customized HashMaps. -bool _defaultEquals(Object? a, Object? b) => a == b; - -/// Default function for hash-code computation in customized HashMaps. -int _defaultHashCode(Object? a) => a.hashCode; - -/// Type of custom equality function. -typedef _Equality = bool Function(K a, K b); - -/// Type of custom hash code function. -typedef _Hasher = int Function(K object); - -/// A hash-table based implementation of [Map]. -/// -/// The keys of a `HashMap` must have consistent [Object.==] -/// and [Object.hashCode] implementations. This means that the `==` operator -/// must define a stable equivalence relation on the keys (reflexive, -/// symmetric, transitive, and consistent over time), and that `hashCode` -/// must be the same for objects that are considered equal by `==`. -/// -/// The map allows `null` as a key. -/// -/// Iterating the map's keys, values or entries (through [forEach]) -/// may happen in any order. -/// The iteration order only changes when the map is modified. -/// Values are iterated in the same order as their associated keys, -/// so iterating the [keys] and [values] in parallel -/// will give matching key and value pairs. -abstract class HashMap implements Map { - /// Creates an unordered hash-table based [Map]. - /// - /// The created map is not ordered in any way. When iterating the keys or - /// values, the iteration order is unspecified except that it will stay the - /// same as long as the map isn't changed. - /// - /// If [equals] is provided, it is used to compare the keys in the table with - /// new keys. If [equals] is omitted, the key's own [Object.==] is used - /// instead. - /// - /// Similar, if [hashCode] is provided, it is used to produce a hash value - /// for keys in order to place them in the hash table. If it is omitted, the - /// key's own [Object.hashCode] is used. - /// - /// If using methods like [operator []], [remove] and [containsKey] together - /// with a custom equality and hashcode, an extra `isValidKey` function - /// can be supplied. This function is called before calling [equals] or - /// [hashCode] with an argument that may not be a [K] instance, and if the - /// call returns false, the key is assumed to not be in the set. - /// The [isValidKey] function defaults to just testing if the object is a - /// [K] instance. - /// - /// Example: - /// - /// new HashMap(equals: (int a, int b) => (b - a) % 5 == 0, - /// hashCode: (int e) => e % 5) - /// - /// This example map does not need an `isValidKey` function to be passed. - /// The default function accepts only `int` values, which can safely be - /// passed to both the `equals` and `hashCode` functions. - /// - /// If neither `equals`, `hashCode`, nor `isValidKey` is provided, - /// the default `isValidKey` instead accepts all keys. - /// The default equality and hashcode operations are assumed to work on all - /// objects. - /// - /// Likewise, if `equals` is [identical], `hashCode` is [identityHashCode] - /// and `isValidKey` is omitted, the resulting map is identity based, - /// and the `isValidKey` defaults to accepting all keys. - /// Such a map can be created directly using [HashMap.identity]. - /// - /// The used `equals` and `hashCode` method should always be consistent, - /// so that if `equals(a, b)` then `hashCode(a) == hashCode(b)`. The hash - /// of an object, or what it compares equal to, should not change while the - /// object is a key in the map. If it does change, the result is - /// unpredictable. - /// - /// If you supply one of [equals] and [hashCode], - /// you should generally also to supply the other. - external factory HashMap( - {bool Function(K, K)? equals, - int Function(K)? hashCode, - bool Function(dynamic)? isValidKey}); - - /// Creates an unordered identity-based map. - /// - /// Effectively a shorthand for: - /// - /// new HashMap(equals: identical, - /// hashCode: identityHashCode) - external factory HashMap.identity(); - - /// Creates a [HashMap] that contains all key/value pairs of [other]. - /// - /// The keys must all be instances of [K] and the values of [V]. - /// The [other] map itself can have any type. - factory HashMap.from(Map other) { - HashMap result = HashMap(); - other.forEach((dynamic k, dynamic v) { - result[k as K] = v as V; - }); - return result; - } - - /// Creates a [HashMap] that contains all key/value pairs of [other]. - factory HashMap.of(Map other) => HashMap()..addAll(other); - - /// Creates a [HashMap] where the keys and values are computed from the - /// [iterable]. - /// - /// For each element of the [iterable] this constructor computes a key/value - /// pair, by applying [key] and [value] respectively. - /// - /// The keys of the key/value pairs do not need to be unique. The last - /// occurrence of a key will simply overwrite any previous value. - /// - /// If no values are specified for [key] and [value] the default is the - /// identity function. - factory HashMap.fromIterable(Iterable iterable, - {K Function(dynamic element)? key, V Function(dynamic element)? value}) { - HashMap map = HashMap(); - MapBase._fillMapWithMappedIterable(map, iterable, key, value); - return map; - } - - /// Creates a [HashMap] associating the given [keys] to [values]. - /// - /// This constructor iterates over [keys] and [values] and maps each element - /// of [keys] to the corresponding element of [values]. - /// - /// If [keys] contains the same object multiple times, the last occurrence - /// overwrites the previous value. - /// - /// It is an error if the two [Iterable]s don't have the same length. - factory HashMap.fromIterables(Iterable keys, Iterable values) { - HashMap map = HashMap(); - MapBase._fillMapWithIterables(map, keys, values); - return map; - } - - /// Creates a [HashMap] containing the entries of [entries]. - /// - /// Returns a new `HashMap` where all entries of [entries] - /// have been added in iteration order. - /// - /// If multiple [entries] have the same key, - /// later occurrences overwrite the earlier ones. - @Since("2.1") - factory HashMap.fromEntries(Iterable> entries) => - HashMap()..addEntries(entries); -} diff --git a/sdk_nnbd/lib/collection/hash_set.dart b/sdk_nnbd/lib/collection/hash_set.dart deleted file mode 100644 index 6ebb04e6330..00000000000 --- a/sdk_nnbd/lib/collection/hash_set.dart +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright (c) 2013, 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. - -part of dart.collection; - -/// An unordered hash-table based [Set] implementation. -/// -/// The elements of a `HashSet` must have consistent equality -/// and hashCode implementations. This means that the equals operation -/// must define a stable equivalence relation on the elements (reflexive, -/// symmetric, transitive, and consistent over time), and that the hashCode -/// must consistent with equality, so that the same for objects that are -/// considered equal. -/// -/// The set allows `null` as an element. -/// -/// Most simple operations on `HashSet` are done in (potentially amortized) -/// constant time: [add], [contains], [remove], and [length], provided the hash -/// codes of objects are well distributed. -/// -/// The iteration order of the set is not specified and depends on -/// the hashcodes of the provided elements. However, the order is stable: -/// multiple iterations over the same set produce the same order, as long as -/// the set is not modified. -abstract class HashSet implements Set { - /// Create a hash set using the provided [equals] as equality. - /// - /// The provided [equals] must define a stable equivalence relation, and - /// [hashCode] must be consistent with [equals]. If the [equals] or [hashCode] - /// methods won't work on all objects, but only on some instances of E, the - /// [isValidKey] predicate can be used to restrict the keys that the functions - /// are applied to. - /// Any key for which [isValidKey] returns false is automatically assumed - /// to not be in the set when asking `contains`. - /// - /// If [equals] or [hashCode] are omitted, the set uses - /// the elements' intrinsic [Object.==] and [Object.hashCode]. - /// - /// If you supply one of [equals] and [hashCode], - /// you should generally also to supply the other. - /// - /// If the supplied `equals` or `hashCode` functions won't work on all [E] - /// objects, and the map will be used in a setting where a non-`E` object - /// is passed to, e.g., `contains`, then the [isValidKey] function should - /// also be supplied. - /// - /// If [isValidKey] is omitted, it defaults to testing if the object is an - /// [E] instance. That means that: - /// - /// new HashSet(equals: (int e1, int e2) => (e1 - e2) % 5 == 0, - /// hashCode: (int e) => e % 5) - /// - /// does not need an `isValidKey` argument, because it defaults to only - /// accepting `int` values which are accepted by both `equals` and `hashCode`. - /// - /// If neither `equals`, `hashCode`, nor `isValidKey` is provided, - /// the default `isValidKey` instead accepts all values. - /// The default equality and hashcode operations are assumed to work on all - /// objects. - /// - /// Likewise, if `equals` is [identical], `hashCode` is [identityHashCode] - /// and `isValidKey` is omitted, the resulting set is identity based, - /// and the `isValidKey` defaults to accepting all keys. - /// Such a map can be created directly using [HashSet.identity]. - external factory HashSet( - {bool Function(E, E)? equals, - int Function(E)? hashCode, - bool Function(dynamic)? isValidKey}); - - /// Creates an unordered identity-based set. - /// - /// Effectively a shorthand for: - /// - /// new HashSet(equals: identical, - /// hashCode: identityHashCode) - external factory HashSet.identity(); - - /// Create a hash set containing all [elements]. - /// - /// Creates a hash set as by `HashSet()` and adds all given [elements] - /// to the set. The elements are added in order. If [elements] contains - /// two entries that are equal, but not identical, then the first one is - /// the one in the resulting set. - /// - /// All the [elements] should be instances of [E]. - /// The `elements` iterable itself may have any element type, so this - /// constructor can be used to down-cast a `Set`, for example as: - /// ```dart - /// Set superSet = ...; - /// Set subSet = - /// HashSet.from(superSet.whereType()); - /// ``` - factory HashSet.from(Iterable elements) { - HashSet result = HashSet(); - for (final e in elements) { - result.add(e as E); - } - return result; - } - - /// Create a hash set containing all [elements]. - /// - /// Creates a hash set as by `new HashSet()` and adds all given [elements] - /// to the set. The elements are added in order. If [elements] contains - /// two entries that are equal, but not identical, then the first one is - /// the one in the resulting set. - factory HashSet.of(Iterable elements) => HashSet()..addAll(elements); - - /// Provides an iterator that iterates over the elements of this set. - /// - /// The order of iteration is unspecified, - /// but consistent between changes to the set. - Iterator get iterator; -} diff --git a/sdk_nnbd/lib/collection/iterable.dart b/sdk_nnbd/lib/collection/iterable.dart deleted file mode 100644 index 17f84a2a25f..00000000000 --- a/sdk_nnbd/lib/collection/iterable.dart +++ /dev/null @@ -1,400 +0,0 @@ -// Copyright (c) 2012, 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. - -part of dart.collection; - -/// This [Iterable] mixin implements all [Iterable] members except `iterator`. -/// -/// All other methods are implemented in terms of `iterator`. -abstract class IterableMixin implements Iterable { - // This class has methods copied verbatim into: - // - IterableBase - // - SetMixin - // If changing a method here, also change the other copies. - - Iterable cast() => Iterable.castFrom(this); - Iterable map(T f(E element)) => MappedIterable(this, f); - - Iterable where(bool f(E element)) => WhereIterable(this, f); - - Iterable whereType() => WhereTypeIterable(this); - - Iterable expand(Iterable f(E element)) => - ExpandIterable(this, f); - - Iterable followedBy(Iterable other) { - // Type workaround because IterableMixin doesn't promote - // to EfficientLengthIterable. - Iterable self = this; - if (self is EfficientLengthIterable) { - return FollowedByIterable.firstEfficient(self, other); - } - return FollowedByIterable(this, other); - } - - bool contains(Object? element) { - for (E e in this) { - if (e == element) return true; - } - return false; - } - - void forEach(void f(E element)) { - for (E element in this) f(element); - } - - E reduce(E combine(E value, E element)) { - Iterator iterator = this.iterator; - if (!iterator.moveNext()) { - throw IterableElementError.noElement(); - } - E value = iterator.current; - while (iterator.moveNext()) { - value = combine(value, iterator.current); - } - return value; - } - - T fold(T initialValue, T combine(T previousValue, E element)) { - var value = initialValue; - for (E element in this) value = combine(value, element); - return value; - } - - bool every(bool f(E element)) { - for (E element in this) { - if (!f(element)) return false; - } - return true; - } - - String join([String separator = ""]) { - Iterator iterator = this.iterator; - if (!iterator.moveNext()) return ""; - StringBuffer buffer = StringBuffer(); - if (separator == null || separator == "") { - do { - buffer.write("${iterator.current}"); - } while (iterator.moveNext()); - } else { - buffer.write("${iterator.current}"); - while (iterator.moveNext()) { - buffer.write(separator); - buffer.write("${iterator.current}"); - } - } - return buffer.toString(); - } - - bool any(bool test(E element)) { - for (E element in this) { - if (test(element)) return true; - } - return false; - } - - List toList({bool growable = true}) => - List.from(this, growable: growable); - - Set toSet() => Set.from(this); - - int get length { - assert(this is! EfficientLengthIterable); - int count = 0; - Iterator it = iterator; - while (it.moveNext()) { - count++; - } - return count; - } - - bool get isEmpty => !iterator.moveNext(); - - bool get isNotEmpty => !isEmpty; - - Iterable take(int count) { - return TakeIterable(this, count); - } - - Iterable takeWhile(bool test(E value)) { - return TakeWhileIterable(this, test); - } - - Iterable skip(int count) { - return SkipIterable(this, count); - } - - Iterable skipWhile(bool test(E value)) { - return SkipWhileIterable(this, test); - } - - E get first { - Iterator it = iterator; - if (!it.moveNext()) { - throw IterableElementError.noElement(); - } - return it.current; - } - - E get last { - Iterator it = iterator; - if (!it.moveNext()) { - throw IterableElementError.noElement(); - } - E result; - do { - result = it.current; - } while (it.moveNext()); - return result; - } - - E get single { - Iterator it = iterator; - if (!it.moveNext()) throw IterableElementError.noElement(); - E result = it.current; - if (it.moveNext()) throw IterableElementError.tooMany(); - return result; - } - - E firstWhere(bool test(E value), {E Function()? orElse}) { - for (E element in this) { - if (test(element)) return element; - } - if (orElse != null) return orElse(); - throw IterableElementError.noElement(); - } - - E lastWhere(bool test(E value), {E Function()? orElse}) { - late E result; - bool foundMatching = false; - for (E element in this) { - if (test(element)) { - result = element; - foundMatching = true; - } - } - if (foundMatching) return result; - if (orElse != null) return orElse(); - throw IterableElementError.noElement(); - } - - E singleWhere(bool test(E element), {E Function()? orElse}) { - late E result; - bool foundMatching = false; - for (E element in this) { - if (test(element)) { - if (foundMatching) { - throw IterableElementError.tooMany(); - } - result = element; - foundMatching = true; - } - } - if (foundMatching) return result; - if (orElse != null) return orElse(); - throw IterableElementError.noElement(); - } - - E elementAt(int index) { - ArgumentError.checkNotNull(index, "index"); - RangeError.checkNotNegative(index, "index"); - int elementIndex = 0; - for (E element in this) { - if (index == elementIndex) return element; - elementIndex++; - } - throw RangeError.index(index, this, "index", null, elementIndex); - } - - String toString() => IterableBase.iterableToShortString(this, '(', ')'); -} - -/// Base class for implementing [Iterable]. -/// -/// This class implements all methods of [Iterable], except [Iterable.iterator], -/// in terms of `iterator`. -abstract class IterableBase extends Iterable { - const IterableBase(); - - /// Convert an `Iterable` to a string like [IterableBase.toString]. - /// - /// Allows using other delimiters than '(' and ')'. - /// - /// Handles circular references where converting one of the elements - /// to a string ends up converting [iterable] to a string again. - static String iterableToShortString(Iterable iterable, - [String leftDelimiter = '(', String rightDelimiter = ')']) { - if (_isToStringVisiting(iterable)) { - if (leftDelimiter == "(" && rightDelimiter == ")") { - // Avoid creating a new string in the "common" case. - return "(...)"; - } - return "$leftDelimiter...$rightDelimiter"; - } - List parts = []; - _toStringVisiting.add(iterable); - try { - _iterablePartsToStrings(iterable, parts); - } finally { - assert(identical(_toStringVisiting.last, iterable)); - _toStringVisiting.removeLast(); - } - return (StringBuffer(leftDelimiter) - ..writeAll(parts, ", ") - ..write(rightDelimiter)) - .toString(); - } - - /// Converts an `Iterable` to a string. - /// - /// Converts each elements to a string, and separates the results by ", ". - /// Then wraps the result in [leftDelimiter] and [rightDelimiter]. - /// - /// Unlike [iterableToShortString], this conversion doesn't omit any - /// elements or puts any limit on the size of the result. - /// - /// Handles circular references where converting one of the elements - /// to a string ends up converting [iterable] to a string again. - static String iterableToFullString(Iterable iterable, - [String leftDelimiter = '(', String rightDelimiter = ')']) { - if (_isToStringVisiting(iterable)) { - return "$leftDelimiter...$rightDelimiter"; - } - StringBuffer buffer = StringBuffer(leftDelimiter); - _toStringVisiting.add(iterable); - try { - buffer.writeAll(iterable, ", "); - } finally { - assert(identical(_toStringVisiting.last, iterable)); - _toStringVisiting.removeLast(); - } - buffer.write(rightDelimiter); - return buffer.toString(); - } -} - -/// A collection used to identify cyclic lists during toString() calls. -final List _toStringVisiting = []; - -/// Check if we are currently visiting `o` in a toString call. -bool _isToStringVisiting(Object o) { - for (int i = 0; i < _toStringVisiting.length; i++) { - if (identical(o, _toStringVisiting[i])) return true; - } - return false; -} - -/// Convert elements of [iterable] to strings and store them in [parts]. -void _iterablePartsToStrings(Iterable iterable, List parts) { - /* - * This is the complicated part of [iterableToShortString]. - * It is extracted as a separate function to avoid having too much code - * inside the try/finally. - */ - /// Try to stay below this many characters. - const int lengthLimit = 80; - - /// Always at least this many elements at the start. - const int headCount = 3; - - /// Always at least this many elements at the end. - const int tailCount = 2; - - /// Stop iterating after this many elements. Iterables can be infinite. - const int maxCount = 100; - // Per entry length overhead. It's for ", " for all after the first entry, - // and for "(" and ")" for the initial entry. By pure luck, that's the same - // number. - const int overhead = 2; - const int ellipsisSize = 3; // "...".length. - - int length = 0; - int count = 0; - Iterator it = iterable.iterator; - // Initial run of elements, at least headCount, and then continue until - // passing at most lengthLimit characters. - while (length < lengthLimit || count < headCount) { - if (!it.moveNext()) return; - String next = "${it.current}"; - parts.add(next); - length += next.length + overhead; - count++; - } - - String penultimateString; - String ultimateString; - - // Find last two elements. One or more of them may already be in the - // parts array. Include their length in `length`. - if (!it.moveNext()) { - if (count <= headCount + tailCount) return; - ultimateString = parts.removeLast(); - penultimateString = parts.removeLast(); - } else { - Object? penultimate = it.current; - count++; - if (!it.moveNext()) { - if (count <= headCount + 1) { - parts.add("$penultimate"); - return; - } - ultimateString = "$penultimate"; - penultimateString = parts.removeLast(); - length += ultimateString.length + overhead; - } else { - Object? ultimate = it.current; - count++; - // Then keep looping, keeping the last two elements in variables. - assert(count < maxCount); - while (it.moveNext()) { - penultimate = ultimate; - ultimate = it.current; - count++; - if (count > maxCount) { - // If we haven't found the end before maxCount, give up. - // This cannot happen in the code above because each entry - // increases length by at least two, so there is no way to - // visit more than ~40 elements before this loop. - - // Remove any surplus elements until length, including ", ...)", - // is at most lengthLimit. - while (length > lengthLimit - ellipsisSize - overhead && - count > headCount) { - length -= parts.removeLast().length + overhead; - count--; - } - parts.add("..."); - return; - } - } - penultimateString = "$penultimate"; - ultimateString = "$ultimate"; - length += ultimateString.length + penultimateString.length + 2 * overhead; - } - } - - // If there is a gap between the initial run and the last two, - // prepare to add an ellipsis. - String? elision; - if (count > parts.length + tailCount) { - elision = "..."; - length += ellipsisSize + overhead; - } - - // If the last two elements were very long, and we have more than - // headCount elements in the initial run, drop some to make room for - // the last two. - while (length > lengthLimit && parts.length > headCount) { - length -= parts.removeLast().length + overhead; - if (elision == null) { - elision = "..."; - length += ellipsisSize + overhead; - } - } - if (elision != null) { - parts.add(elision); - } - parts.add(penultimateString); - parts.add(ultimateString); -} diff --git a/sdk_nnbd/lib/collection/iterator.dart b/sdk_nnbd/lib/collection/iterator.dart deleted file mode 100644 index 671f0eea005..00000000000 --- a/sdk_nnbd/lib/collection/iterator.dart +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) 2012, 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. - -part of dart.collection; - -/// The [HasNextIterator] class wraps an [Iterator] and provides methods to -/// iterate over an object using `hasNext` and `next`. -/// -/// An [HasNextIterator] does not implement the [Iterator] interface. -class HasNextIterator { - static const int _HAS_NEXT_AND_NEXT_IN_CURRENT = 0; - static const int _NO_NEXT = 1; - static const int _NOT_MOVED_YET = 2; - - Iterator _iterator; - int _state = _NOT_MOVED_YET; - - HasNextIterator(this._iterator); - - bool get hasNext { - if (_state == _NOT_MOVED_YET) _move(); - return _state == _HAS_NEXT_AND_NEXT_IN_CURRENT; - } - - E next() { - // Call to hasNext is necessary to make sure we are positioned at the first - // element when we start iterating. - if (!hasNext) throw StateError("No more elements"); - assert(_state == _HAS_NEXT_AND_NEXT_IN_CURRENT); - E result = _iterator.current; - _move(); - return result; - } - - void _move() { - if (_iterator.moveNext()) { - _state = _HAS_NEXT_AND_NEXT_IN_CURRENT; - } else { - _state = _NO_NEXT; - } - } -} diff --git a/sdk_nnbd/lib/collection/linked_hash_map.dart b/sdk_nnbd/lib/collection/linked_hash_map.dart deleted file mode 100644 index 9dfdb997dc4..00000000000 --- a/sdk_nnbd/lib/collection/linked_hash_map.dart +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright (c) 2013, 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. - -part of dart.collection; - -/// A hash-table based implementation of [Map]. -/// -/// The insertion order of keys is remembered, -/// and keys are iterated in the order they were inserted into the map. -/// Values are iterated in their corresponding key's order. -/// Changing a key's value, when the key is already in the map, -/// does not change the iteration order, -/// but removing the key and adding it again -/// will make it be last in the iteration order. -/// -/// The keys of a `LinkedHashMap` must have consistent [Object.==] -/// and [Object.hashCode] implementations. This means that the `==` operator -/// must define a stable equivalence relation on the keys (reflexive, -/// symmetric, transitive, and consistent over time), and that `hashCode` -/// must be the same for objects that are considered equal by `==`. -/// -/// The map allows `null` as a key. -abstract class LinkedHashMap implements Map { - /// Creates an insertion-ordered hash-table based [Map]. - /// - /// If [equals] is provided, it is used to compare the keys in the table with - /// new keys. If [equals] is omitted, the key's own [Object.==] is used - /// instead. - /// - /// Similar, if [hashCode] is provided, it is used to produce a hash value - /// for keys in order to place them in the hash table. If it is omitted, the - /// key's own [Object.hashCode] is used. - /// - /// If using methods like [operator []], [remove] and [containsKey] together - /// with a custom equality and hashcode, an extra `isValidKey` function - /// can be supplied. This function is called before calling [equals] or - /// [hashCode] with an argument that may not be a [K] instance, and if the - /// call returns false, the key is assumed to not be in the set. - /// The [isValidKey] function defaults to just testing if the object is a - /// [K] instance. - /// - /// Example: - /// - /// new LinkedHashMap(equals: (int a, int b) => (b - a) % 5 == 0, - /// hashCode: (int e) => e % 5) - /// - /// This example map does not need an `isValidKey` function to be passed. - /// The default function accepts only `int` values, which can safely be - /// passed to both the `equals` and `hashCode` functions. - /// - /// If neither `equals`, `hashCode`, nor `isValidKey` is provided, - /// the default `isValidKey` instead accepts all keys. - /// The default equality and hashcode operations are assumed to work on all - /// objects. - /// - /// Likewise, if `equals` is [identical], `hashCode` is [identityHashCode] - /// and `isValidKey` is omitted, the resulting map is identity based, - /// and the `isValidKey` defaults to accepting all keys. - /// Such a map can be created directly using [LinkedHashMap.identity]. - /// - /// The used `equals` and `hashCode` method should always be consistent, - /// so that if `equals(a, b)` then `hashCode(a) == hashCode(b)`. The hash - /// of an object, or what it compares equal to, should not change while the - /// object is in the table. If it does change, the result is unpredictable. - /// - /// If you supply one of [equals] and [hashCode], - /// you should generally also to supply the other. - external factory LinkedHashMap( - {bool Function(K, K)? equals, - int Function(K)? hashCode, - bool Function(dynamic)? isValidKey}); - - /// Creates an insertion-ordered identity-based map. - /// - /// Effectively a shorthand for: - /// - /// new LinkedHashMap(equals: identical, - /// hashCode: identityHashCode) - external factory LinkedHashMap.identity(); - - /// Creates a [LinkedHashMap] that contains all key value pairs of [other]. - /// - /// The keys must all be instances of [K] and the values to [V]. - /// The [other] map itself can have any type. - factory LinkedHashMap.from(Map other) { - LinkedHashMap result = LinkedHashMap(); - other.forEach((dynamic k, dynamic v) { - result[k as K] = v as V; - }); - return result; - } - - /// Creates a [LinkedHashMap] that contains all key value pairs of [other]. - factory LinkedHashMap.of(Map other) => - LinkedHashMap()..addAll(other); - - /// Creates a [LinkedHashMap] where the keys and values are computed from the - /// [iterable]. - /// - /// For each element of the [iterable] this constructor computes a key/value - /// pair, by applying [key] and [value] respectively. - /// - /// The keys of the key/value pairs do not need to be unique. The last - /// occurrence of a key will simply overwrite any previous value. - /// - /// If no values are specified for [key] and [value] the default is the - /// identity function. - factory LinkedHashMap.fromIterable(Iterable iterable, - {K Function(dynamic element)? key, V Function(dynamic element)? value}) { - LinkedHashMap map = LinkedHashMap(); - MapBase._fillMapWithMappedIterable(map, iterable, key, value); - return map; - } - - /// Creates a [LinkedHashMap] associating the given [keys] to [values]. - /// - /// This constructor iterates over [keys] and [values] and maps each element of - /// [keys] to the corresponding element of [values]. - /// - /// If [keys] contains the same object multiple times, the last occurrence - /// overwrites the previous value. - /// - /// It is an error if the two [Iterable]s don't have the same length. - factory LinkedHashMap.fromIterables(Iterable keys, Iterable values) { - LinkedHashMap map = LinkedHashMap(); - MapBase._fillMapWithIterables(map, keys, values); - return map; - } - - /// Creates a [LinkedHashMap] containing the entries of [entries]. - /// - /// Returns a new `LinkedHashMap` where all entries of [entries] - /// have been added in iteration order. - /// - /// If multiple [entries] have the same key, - /// later occurrences overwrite the earlier ones. - @Since("2.1") - factory LinkedHashMap.fromEntries(Iterable> entries) => - LinkedHashMap()..addEntries(entries); -} diff --git a/sdk_nnbd/lib/collection/linked_hash_set.dart b/sdk_nnbd/lib/collection/linked_hash_set.dart deleted file mode 100644 index c4f68188d2d..00000000000 --- a/sdk_nnbd/lib/collection/linked_hash_set.dart +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright (c) 2013, 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. - -part of dart.collection; - -/// A [LinkedHashSet] is a hash-table based [Set] implementation. -/// -/// The `LinkedHashSet` also keep track of the order that elements were inserted -/// in, and iteration happens in first-to-last insertion order. -/// -/// The elements of a `LinkedHashSet` must have consistent [Object.==] -/// and [Object.hashCode] implementations. This means that the `==` operator -/// must define a stable equivalence relation on the elements (reflexive, -/// symmetric, transitive, and consistent over time), and that `hashCode` -/// must be the same for objects that are considered equal by `==`. -/// -/// The set allows `null` as an element. -/// -/// Iteration of elements is done in element insertion order. -/// An element that was added after another will occur later in the iteration. -/// Adding an element that is already in the set -/// does not change its position in the iteration order, -/// but removing an element and adding it again, -/// will make it the last element of an iteration. -/// -/// Most simple operations on `HashSet` are done in (potentially amortized) -/// constant time: [add], [contains], [remove], and [length], provided the hash -/// codes of objects are well distributed.. -abstract class LinkedHashSet implements Set { - /// Create an insertion-ordered hash set using the provided - /// [equals] and [hashCode]. - /// - /// The provided [equals] must define a stable equivalence relation, and - /// [hashCode] must be consistent with [equals]. If the [equals] or [hashCode] - /// methods won't work on all objects, but only on some instances of E, the - /// [isValidKey] predicate can be used to restrict the keys that the functions - /// are applied to. - /// Any key for which [isValidKey] returns false is automatically assumed - /// to not be in the set when asking `contains`. - /// - /// If [equals] or [hashCode] are omitted, the set uses - /// the elements' intrinsic [Object.==] and [Object.hashCode], - /// and [isValidKey] is ignored since these operations are assumed - /// to work on all objects. - /// - /// If you supply one of [equals] and [hashCode], - /// you should generally also to supply the other. - /// - /// If the supplied `equals` or `hashCode` functions won't work on all [E] - /// objects, and the map will be used in a setting where a non-`E` object - /// is passed to, e.g., `contains`, then the [isValidKey] function should - /// also be supplied. - /// - /// If [isValidKey] is omitted, it defaults to testing if the object is an - /// [E] instance. That means that: - /// - /// new LinkedHashSet(equals: (int e1, int e2) => (e1 - e2) % 5 == 0, - /// hashCode: (int e) => e % 5) - /// - /// does not need an `isValidKey` argument, because it defaults to only - /// accepting `int` values which are accepted by both `equals` and `hashCode`. - /// - /// If neither `equals`, `hashCode`, nor `isValidKey` is provided, - /// the default `isValidKey` instead accepts all values. - /// The default equality and hashcode operations are assumed to work on all - /// objects. - /// - /// Likewise, if `equals` is [identical], `hashCode` is [identityHashCode] - /// and `isValidKey` is omitted, the resulting set is identity based, - /// and the `isValidKey` defaults to accepting all keys. - /// Such a map can be created directly using [LinkedHashSet.identity]. - external factory LinkedHashSet( - {bool Function(E, E)? equals, - int Function(E)? hashCode, - bool Function(dynamic)? isValidKey}); - - /// Creates an insertion-ordered identity-based set. - /// - /// Effectively a shorthand for: - /// - /// new LinkedHashSet(equals: identical, - /// hashCode: identityHashCode) - external factory LinkedHashSet.identity(); - - /// Create a linked hash set containing all [elements]. - /// - /// Creates a linked hash set as by `new LinkedHashSet()` and adds each - /// element of `elements` to this set in the order they are iterated. - /// - /// All the [elements] should be instances of [E]. - /// The `elements` iterable itself may have any element type, - /// so this constructor can be used to down-cast a `Set`, for example as: - /// - /// Set superSet = ...; - /// Iterable tmp = superSet.where((e) => e is SubType); - /// Set subSet = new LinkedHashSet.from(tmp); - factory LinkedHashSet.from(Iterable elements) { - LinkedHashSet result = LinkedHashSet(); - for (final element in elements) { - result.add(element as E); - } - return result; - } - - /// Create a linked hash set from [elements]. - /// - /// Creates a linked hash set as by `new LinkedHashSet()` and adds each - /// element of `elements` to this set in the order they are iterated. - factory LinkedHashSet.of(Iterable elements) => - LinkedHashSet()..addAll(elements); - - /// Executes a function on each element of the set. - /// - /// The elements are iterated in insertion order. - void forEach(void action(E element)); - - /// Provides an iterator that iterates over the elements in insertion order. - Iterator get iterator; -} diff --git a/sdk_nnbd/lib/collection/linked_list.dart b/sdk_nnbd/lib/collection/linked_list.dart deleted file mode 100644 index 843eedde6a8..00000000000 --- a/sdk_nnbd/lib/collection/linked_list.dart +++ /dev/null @@ -1,266 +0,0 @@ -// Copyright (c) 2013, 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. - -part of dart.collection; - -/// A specialized double-linked list of elements that extends [LinkedListEntry]. -/// -/// This is not a generic data structure. It only accepts elements that extend -/// the [LinkedListEntry] class. See the [Queue] implementations for generic -/// collections that allow constant time adding and removing at the ends. -/// -/// This is not a [List] implementation. Despite its name, this class does not -/// implement the [List] interface. It does not allow constant time lookup by -/// index. -/// -/// Because the elements themselves contain the links of this linked list, -/// each element can be in only one list at a time. To add an element to another -/// list, it must first be removed from its current list (if any). -/// -/// In return, each element knows its own place in the linked list, as well as -/// which list it is in. This allows constant time -/// [LinkedListEntry.insertAfter], [LinkedListEntry.insertBefore] and -/// [LinkedListEntry.unlink] operations when all you have is the element. -/// -/// A `LinkedList` also allows constant time adding and removing at either end, -/// and a constant time length getter. -class LinkedList> extends Iterable { - int _modificationCount = 0; - int _length = 0; - E? _first; - - /// Construct a new empty linked list. - LinkedList(); - - /// Add [entry] to the beginning of the linked list. - void addFirst(E entry) { - _insertBefore(_first, entry, updateFirst: true); - _first = entry; - } - - /// Add [entry] to the end of the linked list. - void add(E entry) { - _insertBefore(_first, entry, updateFirst: false); - } - - /// Add [entries] to the end of the linked list. - void addAll(Iterable entries) { - entries.forEach(add); - } - - /// Remove [entry] from the linked list. - /// - /// Returns false and does nothing if [entry] is not in this linked list. - /// - /// This is equivalent to calling `entry.unlink()` if the entry is in this - /// list. - bool remove(E entry) { - if (entry._list != this) return false; - _unlink(entry); // Unlink will decrement length. - return true; - } - - Iterator get iterator => _LinkedListIterator(this); - - int get length => _length; - - /// Remove all elements from this linked list. - void clear() { - _modificationCount++; - if (isEmpty) return; - - E next = _first!; - do { - E entry = next; - next = entry._next!; - entry._next = entry._previous = entry._list = null; - } while (!identical(next, _first)); - - _first = null; - _length = 0; - } - - E get first { - if (isEmpty) { - throw StateError('No such element'); - } - return _first!; - } - - E get last { - if (isEmpty) { - throw StateError('No such element'); - } - return _first!._previous!; - } - - E get single { - if (isEmpty) { - throw StateError('No such element'); - } - if (_length > 1) { - throw StateError('Too many elements'); - } - return _first!; - } - - /// Call [action] with each entry in this linked list. - /// - /// It's an error if [action] modifies the linked list. - void forEach(void action(E entry)) { - int modificationCount = _modificationCount; - if (isEmpty) return; - - E current = _first!; - do { - action(current); - if (modificationCount != _modificationCount) { - throw ConcurrentModificationError(this); - } - current = current._next!; - } while (!identical(current, _first)); - } - - bool get isEmpty => _length == 0; - - /// Inserts [newEntry] as last entry of the list. - /// - /// If [updateFirst] is true and [entry] is the first entry in the list, - /// updates the [_first] field to point to the [newEntry] as first entry. - void _insertBefore(E? entry, E newEntry, {required bool updateFirst}) { - if (newEntry.list != null) { - throw StateError('LinkedListEntry is already in a LinkedList'); - } - _modificationCount++; - - newEntry._list = this; - if (isEmpty) { - assert(entry == null); - newEntry._previous = newEntry._next = newEntry; - _first = newEntry; - _length++; - return; - } - E predecessor = entry!._previous!; - E successor = entry; - newEntry._previous = predecessor; - newEntry._next = successor; - predecessor._next = newEntry; - successor._previous = newEntry; - if (updateFirst && identical(entry, _first)) { - _first = newEntry; - } - _length++; - } - - void _unlink(E entry) { - _modificationCount++; - entry._next!._previous = entry._previous; - E? next = entry._previous!._next = entry._next; - _length--; - entry._list = entry._next = entry._previous = null; - if (isEmpty) { - _first = null; - } else if (identical(entry, _first)) { - _first = next; - } - } -} - -class _LinkedListIterator> implements Iterator { - final LinkedList _list; - final int _modificationCount; - E? _current; - E? _next; - bool _visitedFirst; - - _LinkedListIterator(LinkedList list) - : _list = list, - _modificationCount = list._modificationCount, - _next = list._first, - _visitedFirst = false; - - E get current { - final cur = _current; - return (cur != null) ? cur : cur as E; - } - - bool moveNext() { - if (_modificationCount != _list._modificationCount) { - throw ConcurrentModificationError(this); - } - if (_list.isEmpty || (_visitedFirst && identical(_next, _list.first))) { - _current = null; - return false; - } - _visitedFirst = true; - _current = _next; - _next = _next!._next; - return true; - } -} - -/// An object that can be an element in a [LinkedList]. -/// -/// All elements of a `LinkedList` must extend this class. -/// The class provides the internal links that link elements together -/// in the `LinkedList`, and a reference to the linked list itself -/// that an element is currently part of. -/// -/// An entry can be in at most one linked list at a time. -/// While an entry is in a linked list, the [list] property points to that -/// linked list, and otherwise the `list` property is `null`. -/// -/// When created, an entry is not in any linked list. -abstract class LinkedListEntry> { - LinkedList? _list; - E? _next; - E? _previous; - - /// Get the linked list containing this element. - /// - /// Returns `null` if this entry is not currently in any list. - LinkedList? get list => _list; - - /// Unlink the element from its linked list. - /// - /// The entry must currently be in a linked list when this method is called. - void unlink() { - _list!._unlink(this as E); - } - - /// Return the successor of this element in its linked list. - /// - /// Returns `null` if there is no successor in the linked list, or if this - /// entry is not currently in any list. - E? get next { - if (_list == null || identical(_list!.first, _next)) return null; - return _next; - } - - /// Return the predecessor of this element in its linked list. - /// - /// Returns `null` if there is no predecessor in the linked list, or if this - /// entry is not currently in any list. - E? get previous { - if (_list == null || identical(this, _list!.first)) return null; - return _previous; - } - - /// Insert an element after this element in this element's linked list. - /// - /// This entry must be in a linked list when this method is called. - /// The [entry] must not be in a linked list. - void insertAfter(E entry) { - _list!._insertBefore(_next, entry, updateFirst: false); - } - - /// Insert an element before this element in this element's linked list. - /// - /// This entry must be in a linked list when this method is called. - /// The [entry] must not be in a linked list. - void insertBefore(E entry) { - _list!._insertBefore(this as E, entry, updateFirst: true); - } -} diff --git a/sdk_nnbd/lib/collection/list.dart b/sdk_nnbd/lib/collection/list.dart deleted file mode 100644 index fdf2f8ad991..00000000000 --- a/sdk_nnbd/lib/collection/list.dart +++ /dev/null @@ -1,569 +0,0 @@ -// Copyright (c) 2013, 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. - -part of dart.collection; - -/// Abstract implementation of a list. -/// -/// `ListBase` can be used as a base class for implementing the `List` -/// interface. -/// -/// All operations are defined in terms of `length`, `operator[]`, -/// `operator[]=` and `length=`, which need to be implemented. -/// -/// *NOTICE*: Forwarding just these four operations to a normal growable [List] -/// (as created by `[]`) will give very bad performance for `add` and -/// `addAll` operations of `ListBase`. These operations are implemented by -/// increasing the length of the list by one for each `add` operation, and -/// repeatedly increasing the length of a growable list is not efficient. -/// To avoid this, either override 'add' and 'addAll' to also forward directly -/// to the growable list, or, preferably, use `DelegatingList` from -/// "package:collection/collection.dart" instead. -abstract class ListBase extends Object with ListMixin { - /// Converts a [List] to a [String]. - /// - /// Converts [list] to a string by converting each element to a string (by - /// calling [Object.toString]), joining them with ", ", and wrapping the - /// result in "[" and "]". - /// - /// Handles circular references where converting one of the elements - /// to a string ends up converting [list] to a string again. - static String listToString(List list) => - IterableBase.iterableToFullString(list, '[', ']'); -} - -/// Base implementation of a [List] class. -/// -/// `ListMixin` can be used as a mixin to make a class implement -/// the `List` interface. -/// -/// This implements all read operations using only the `length` and -/// `operator[]` members. It implements write operations using those and -/// `length=` and `operator[]=` -/// -/// *NOTICE*: Forwarding just these four operations to a normal growable [List] -/// (as created by `[]`) will give very bad performance for `add` and -/// `addAll` operations of `ListBase`. These operations are implemented by -/// increasing the length of the list by one for each `add` operation, and -/// repeatedly increasing the length of a growable list is not efficient. -/// To avoid this, either override 'add' and 'addAll' to also forward directly -/// to the growable list, or, if possible, use `DelegatingList` from -/// "package:collection/collection.dart" instead. -abstract class ListMixin implements List { - // Iterable interface. - // TODO(lrn): When we get composable mixins, reuse IterableMixin instead - // of redaclating everything. - Iterator get iterator => ListIterator(this); - - E elementAt(int index) => this[index]; - - Iterable followedBy(Iterable other) => - FollowedByIterable.firstEfficient(this, other); - - void forEach(void action(E element)) { - int length = this.length; - for (int i = 0; i < length; i++) { - action(this[i]); - if (length != this.length) { - throw ConcurrentModificationError(this); - } - } - } - - @pragma("vm:prefer-inline") - bool get isEmpty => length == 0; - - bool get isNotEmpty => !isEmpty; - - E get first { - if (length == 0) throw IterableElementError.noElement(); - return this[0]; - } - - void set first(E value) { - if (length == 0) throw IterableElementError.noElement(); - this[0] = value; - } - - E get last { - if (length == 0) throw IterableElementError.noElement(); - return this[length - 1]; - } - - void set last(E value) { - if (length == 0) throw IterableElementError.noElement(); - this[length - 1] = value; - } - - E get single { - if (length == 0) throw IterableElementError.noElement(); - if (length > 1) throw IterableElementError.tooMany(); - return this[0]; - } - - bool contains(Object? element) { - int length = this.length; - for (int i = 0; i < length; i++) { - if (this[i] == element) return true; - if (length != this.length) { - throw ConcurrentModificationError(this); - } - } - return false; - } - - bool every(bool test(E element)) { - int length = this.length; - for (int i = 0; i < length; i++) { - if (!test(this[i])) return false; - if (length != this.length) { - throw ConcurrentModificationError(this); - } - } - return true; - } - - bool any(bool test(E element)) { - int length = this.length; - for (int i = 0; i < length; i++) { - if (test(this[i])) return true; - if (length != this.length) { - throw ConcurrentModificationError(this); - } - } - return false; - } - - E firstWhere(bool test(E element), {E Function()? orElse}) { - int length = this.length; - for (int i = 0; i < length; i++) { - E element = this[i]; - if (test(element)) return element; - if (length != this.length) { - throw ConcurrentModificationError(this); - } - } - if (orElse != null) return orElse(); - throw IterableElementError.noElement(); - } - - E lastWhere(bool test(E element), {E Function()? orElse}) { - int length = this.length; - for (int i = length - 1; i >= 0; i--) { - E element = this[i]; - if (test(element)) return element; - if (length != this.length) { - throw ConcurrentModificationError(this); - } - } - if (orElse != null) return orElse(); - throw IterableElementError.noElement(); - } - - E singleWhere(bool test(E element), {E Function()? orElse}) { - int length = this.length; - late E match; - bool matchFound = false; - for (int i = 0; i < length; i++) { - E element = this[i]; - if (test(element)) { - if (matchFound) { - throw IterableElementError.tooMany(); - } - matchFound = true; - match = element; - } - if (length != this.length) { - throw ConcurrentModificationError(this); - } - } - if (matchFound) return match; - if (orElse != null) return orElse(); - throw IterableElementError.noElement(); - } - - String join([String separator = ""]) { - if (length == 0) return ""; - StringBuffer buffer = StringBuffer()..writeAll(this, separator); - return buffer.toString(); - } - - Iterable where(bool test(E element)) => WhereIterable(this, test); - - Iterable whereType() => WhereTypeIterable(this); - - Iterable map(T f(E element)) => MappedListIterable(this, f); - - Iterable expand(Iterable f(E element)) => - ExpandIterable(this, f); - - E reduce(E combine(E previousValue, E element)) { - int length = this.length; - if (length == 0) throw IterableElementError.noElement(); - E value = this[0]; - for (int i = 1; i < length; i++) { - value = combine(value, this[i]); - if (length != this.length) { - throw ConcurrentModificationError(this); - } - } - return value; - } - - T fold(T initialValue, T combine(T previousValue, E element)) { - var value = initialValue; - int length = this.length; - for (int i = 0; i < length; i++) { - value = combine(value, this[i]); - if (length != this.length) { - throw ConcurrentModificationError(this); - } - } - return value; - } - - Iterable skip(int count) => SubListIterable(this, count, null); - - Iterable skipWhile(bool test(E element)) { - return SkipWhileIterable(this, test); - } - - Iterable take(int count) => SubListIterable(this, 0, count); - - Iterable takeWhile(bool test(E element)) { - return TakeWhileIterable(this, test); - } - - List toList({bool growable = true}) { - if (this.isEmpty) return List.empty(growable: growable); - var first = this[0]; - var result = List.filled(this.length, first, growable: growable); - for (int i = 1; i < this.length; i++) { - result[i] = this[i]; - } - return result; - } - - Set toSet() { - Set result = Set(); - for (int i = 0; i < length; i++) { - result.add(this[i]); - } - return result; - } - - // List interface. - void add(E element) { - this[this.length++] = element; - } - - void addAll(Iterable iterable) { - int i = this.length; - for (E element in iterable) { - assert(this.length == i || (throw ConcurrentModificationError(this))); - add(element); - i++; - } - } - - bool remove(Object? element) { - for (int i = 0; i < this.length; i++) { - if (this[i] == element) { - this._closeGap(i, i + 1); - return true; - } - } - return false; - } - - /// Removes elements from the list starting at [start] up to but not including - /// [end]. Arguments are pre-validated. - void _closeGap(int start, int end) { - int length = this.length; - assert(0 <= start); - assert(start < end); - assert(end <= length); - int size = end - start; - for (int i = end; i < length; i++) { - this[i - size] = this[i]; - } - this.length = length - size; - } - - void removeWhere(bool test(E element)) { - _filter(test, false); - } - - void retainWhere(bool test(E element)) { - _filter(test, true); - } - - void _filter(bool test(E element), bool retainMatching) { - List retained = []; - int length = this.length; - for (int i = 0; i < length; i++) { - var element = this[i]; - if (test(element) == retainMatching) { - retained.add(element); - } - if (length != this.length) { - throw ConcurrentModificationError(this); - } - } - if (retained.length != this.length) { - this.setRange(0, retained.length, retained); - this.length = retained.length; - } - } - - void clear() { - this.length = 0; - } - - List cast() => List.castFrom(this); - E removeLast() { - if (length == 0) { - throw IterableElementError.noElement(); - } - E result = this[length - 1]; - length--; - return result; - } - - void sort([int Function(E a, E b)? compare]) { - Sort.sort(this, compare ?? _compareAny); - } - - static int _compareAny(dynamic a, dynamic b) { - return Comparable.compare(a as Comparable, b as Comparable); - } - - void shuffle([Random? random]) { - random ??= Random(); - if (random == null) throw "!"; // TODO(38493): The `??=` should promote. - - int length = this.length; - while (length > 1) { - int pos = random.nextInt(length); - length -= 1; - var tmp = this[length]; - this[length] = this[pos]; - this[pos] = tmp; - } - } - - Map asMap() { - return ListMapView(this); - } - - List operator +(List other) => [...this, ...other]; - - List sublist(int start, [int? end]) { - int listLength = this.length; - end ??= listLength; - if (end == null) throw "!"; // TODO(38493): The `??=` should promote. - - RangeError.checkValidRange(start, end, listLength); - return List.from(getRange(start, end)); - } - - Iterable getRange(int start, int end) { - RangeError.checkValidRange(start, end, this.length); - return SubListIterable(this, start, end); - } - - void removeRange(int start, int end) { - RangeError.checkValidRange(start, end, this.length); - if (end > start) { - _closeGap(start, end); - } - } - - void fillRange(int start, int end, [E? fill]) { - // Hoist the case to fail eagerly if the user provides an invalid `null` - // value (or omits it) when E is a non-nullable type. - E value = fill as E; - RangeError.checkValidRange(start, end, this.length); - for (int i = start; i < end; i++) { - this[i] = value; - } - } - - void setRange(int start, int end, Iterable iterable, [int skipCount = 0]) { - RangeError.checkValidRange(start, end, this.length); - int length = end - start; - if (length == 0) return; - RangeError.checkNotNegative(skipCount, "skipCount"); - - List otherList; - int otherStart; - // TODO(floitsch): Make this accept more. - if (iterable is List) { - otherList = iterable; - otherStart = skipCount; - } else { - otherList = iterable.skip(skipCount).toList(growable: false); - otherStart = 0; - } - if (otherStart + length > otherList.length) { - throw IterableElementError.tooFew(); - } - if (otherStart < start) { - // Copy backwards to ensure correct copy if [from] is this. - for (int i = length - 1; i >= 0; i--) { - this[start + i] = otherList[otherStart + i]; - } - } else { - for (int i = 0; i < length; i++) { - this[start + i] = otherList[otherStart + i]; - } - } - } - - void replaceRange(int start, int end, Iterable newContents) { - RangeError.checkValidRange(start, end, this.length); - if (start == this.length) { - addAll(newContents); - return; - } - if (newContents is! EfficientLengthIterable) { - newContents = newContents.toList(); - } - int removeLength = end - start; - int insertLength = newContents.length; - if (removeLength >= insertLength) { - int insertEnd = start + insertLength; - this.setRange(start, insertEnd, newContents); - if (removeLength > insertLength) { - _closeGap(insertEnd, end); - } - } else if (end == this.length) { - int i = start; - for (E element in newContents) { - if (i < end) { - this[i] = element; - } else { - add(element); - } - i++; - } - } else { - int delta = insertLength - removeLength; - int oldLength = this.length; - int insertEnd = start + insertLength; // aka. end + delta. - for (int i = oldLength - delta; i < oldLength; ++i) { - add(this[i > 0 ? i : 0]); - } - if (insertEnd < oldLength) { - this.setRange(insertEnd, oldLength, this, end); - } - this.setRange(start, insertEnd, newContents); - } - } - - int indexOf(Object? element, [int start = 0]) { - if (start < 0) start = 0; - for (int i = start; i < this.length; i++) { - if (this[i] == element) return i; - } - return -1; - } - - int indexWhere(bool test(E element), [int start = 0]) { - if (start < 0) start = 0; - for (int i = start; i < this.length; i++) { - if (test(this[i])) return i; - } - return -1; - } - - int lastIndexOf(Object? element, [int? start]) { - if (start == null || start >= this.length) start = this.length - 1; - - // TODO(38493): The previous line should promote. - if (start == null) throw "!"; - - for (int i = start; i >= 0; i--) { - if (this[i] == element) return i; - } - return -1; - } - - int lastIndexWhere(bool test(E element), [int? start]) { - if (start == null || start >= this.length) start = this.length - 1; - - // TODO(38493): The previous line should promote. - if (start == null) throw "!"; - - for (int i = start; i >= 0; i--) { - if (test(this[i])) return i; - } - return -1; - } - - void insert(int index, E element) { - ArgumentError.checkNotNull(index, "index"); - RangeError.checkValueInInterval(index, 0, length, "index"); - if (index == this.length) { - add(element); - return; - } - this.length++; - setRange(index + 1, this.length, this, index); - this[index] = element; - } - - E removeAt(int index) { - E result = this[index]; - _closeGap(index, index + 1); - return result; - } - - void insertAll(int index, Iterable iterable) { - RangeError.checkValueInInterval(index, 0, length, "index"); - if (index == length) { - addAll(iterable); - return; - } - if (iterable is! EfficientLengthIterable || identical(iterable, this)) { - iterable = iterable.toList(); - } - int insertionLength = iterable.length; - if (insertionLength == 0) { - return; - } - // There might be errors after the length change, in which case the list - // will end up being modified but the operation not complete. Unless we - // always go through a "toList" we can't really avoid that. - int oldLength = length; - for (int i = oldLength - insertionLength; i < oldLength; ++i) { - add(this[i > 0 ? i : 0]); - } - if (iterable.length != insertionLength) { - // If the iterable's length is linked to this list's length somehow, - // we can't insert one in the other. - this.length -= insertionLength; - throw ConcurrentModificationError(iterable); - } - int oldCopyStart = index + insertionLength; - if (oldCopyStart < oldLength) { - setRange(oldCopyStart, oldLength, this, index); - } - setAll(index, iterable); - } - - void setAll(int index, Iterable iterable) { - if (iterable is List) { - setRange(index, index + iterable.length, iterable); - } else { - for (E element in iterable) { - this[index++] = element; - } - } - } - - Iterable get reversed => ReversedListIterable(this); - - String toString() => IterableBase.iterableToFullString(this, '[', ']'); -} diff --git a/sdk_nnbd/lib/collection/maps.dart b/sdk_nnbd/lib/collection/maps.dart deleted file mode 100644 index 85a3155a889..00000000000 --- a/sdk_nnbd/lib/collection/maps.dart +++ /dev/null @@ -1,388 +0,0 @@ -// Copyright (c) 2012, 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. - -part of dart.collection; - -/// Base class for implementing a [Map]. -/// -/// This class has a basic implementation of all but five of the members of -/// [Map]. -/// A basic `Map` class can be implemented by extending this class and -/// implementing `keys`, `operator[]`, `operator[]=`, `remove` and `clear`. -/// The remaining operations are implemented in terms of these five. -/// -/// The `keys` iterable should have efficient [Iterable.length] and -/// [Iterable.contains] operations, and it should catch concurrent modifications -/// of the keys while iterating. -/// -/// A more efficient implementation is usually possible by overriding -/// some of the other members as well. -abstract class MapBase extends MapMixin { - static String mapToString(Map m) { - // Reuses the list in IterableBase for detecting toString cycles. - if (_isToStringVisiting(m)) { - return '{...}'; - } - - var result = StringBuffer(); - try { - _toStringVisiting.add(m); - result.write('{'); - bool first = true; - m.forEach((Object? k, Object? v) { - if (!first) { - result.write(', '); - } - first = false; - result.write(k); - result.write(': '); - result.write(v); - }); - result.write('}'); - } finally { - assert(identical(_toStringVisiting.last, m)); - _toStringVisiting.removeLast(); - } - - return result.toString(); - } - - static Object? _id(Object? x) => x; - - /// Fills a [Map] with key/value pairs computed from [iterable]. - /// - /// This method is used by [Map] classes in the named constructor - /// `fromIterable`. - static void _fillMapWithMappedIterable( - Map map, - Iterable iterable, - Object? Function(Object? element)? key, - Object? Function(Object? element)? value) { - key ??= _id; - value ??= _id; - - if (key == null) throw "!"; // TODO(38493): The `??=` should promote. - if (value == null) throw "!"; // TODO(38493): The `??=` should promote. - - for (var element in iterable) { - map[key(element)] = value(element); - } - } - - /// Fills a map by associating the [keys] to [values]. - /// - /// This method is used by [Map] classes in the named constructor - /// `fromIterables`. - static void _fillMapWithIterables(Map map, - Iterable keys, Iterable values) { - Iterator keyIterator = keys.iterator; - Iterator valueIterator = values.iterator; - - bool hasNextKey = keyIterator.moveNext(); - bool hasNextValue = valueIterator.moveNext(); - - while (hasNextKey && hasNextValue) { - map[keyIterator.current] = valueIterator.current; - hasNextKey = keyIterator.moveNext(); - hasNextValue = valueIterator.moveNext(); - } - - if (hasNextKey || hasNextValue) { - throw ArgumentError("Iterables do not have same length."); - } - } -} - -/// Mixin implementing a [Map]. -/// -/// This mixin has a basic implementation of all but five of the members of -/// [Map]. -/// A basic `Map` class can be implemented by mixin in this class and -/// implementing `keys`, `operator[]`, `operator[]=`, `remove` and `clear`. -/// The remaining operations are implemented in terms of these five. -/// -/// The `keys` iterable should have efficient [Iterable.length] and -/// [Iterable.contains] operations, and it should catch concurrent modifications -/// of the keys while iterating. -/// -/// A more efficient implementation is usually possible by overriding -/// some of the other members as well. -abstract class MapMixin implements Map { - Iterable get keys; - V? operator [](Object? key); - operator []=(K key, V value); - V? remove(Object? key); - // The `clear` operation should not be based on `remove`. - // It should clear the map even if some keys are not equal to themselves. - void clear(); - - Map cast() => Map.castFrom(this); - void forEach(void action(K key, V value)) { - for (K key in keys) { - action(key, this[key] as V); - } - } - - void addAll(Map other) { - for (K key in other.keys) { - this[key] = other[key] as V; - } - } - - bool containsValue(Object? value) { - for (K key in keys) { - if (this[key] == value) return true; - } - return false; - } - - V putIfAbsent(K key, V ifAbsent()) { - if (containsKey(key)) { - return this[key] as V; - } - return this[key] = ifAbsent(); - } - - V update(K key, V update(V value), {V Function()? ifAbsent}) { - if (this.containsKey(key)) { - return this[key] = update(this[key] as V); - } - if (ifAbsent != null) { - return this[key] = ifAbsent(); - } - throw ArgumentError.value(key, "key", "Key not in map."); - } - - void updateAll(V update(K key, V value)) { - for (var key in this.keys) { - this[key] = update(key, this[key] as V); - } - } - - Iterable> get entries { - return keys.map((K key) => MapEntry(key, this[key] as V)); - } - - Map map(MapEntry transform(K key, V value)) { - var result = {}; - for (var key in this.keys) { - var entry = transform(key, this[key] as V); - result[entry.key] = entry.value; - } - return result; - } - - void addEntries(Iterable> newEntries) { - for (var entry in newEntries) { - this[entry.key] = entry.value; - } - } - - void removeWhere(bool test(K key, V value)) { - var keysToRemove = []; - for (var key in keys) { - if (test(key, this[key] as V)) keysToRemove.add(key); - } - for (var key in keysToRemove) { - this.remove(key); - } - } - - bool containsKey(Object? key) => keys.contains(key); - int get length => keys.length; - bool get isEmpty => keys.isEmpty; - bool get isNotEmpty => keys.isNotEmpty; - Iterable get values => _MapBaseValueIterable(this); - String toString() => MapBase.mapToString(this); -} - -/// Basic implementation of an unmodifiable [Map]. -/// -/// This class has a basic implementation of all but two of the members of -/// an umodifiable [Map]. -/// A simple unmodifiable `Map` class can be implemented by extending this -/// class and implementing `keys` and `operator[]`. -/// -/// Modifying operations throw when used. -/// The remaining non-modifying operations are implemented in terms of `keys` -/// and `operator[]`. -/// -/// The `keys` iterable should have efficient [Iterable.length] and -/// [Iterable.contains] operations, and it should catch concurrent modifications -/// of the keys while iterating. -/// -/// A more efficient implementation is usually possible by overriding -/// some of the other members as well. -abstract class UnmodifiableMapBase = MapBase - with _UnmodifiableMapMixin; - -/// Implementation of [Map.values] based on the map and its [Map.keys] iterable. -/// -/// Iterable that iterates over the values of a `Map`. -/// It accesses the values by iterating over the keys of the map, and using the -/// map's `operator[]` to lookup the keys. -class _MapBaseValueIterable extends EfficientLengthIterable { - final Map _map; - _MapBaseValueIterable(this._map); - - int get length => _map.length; - bool get isEmpty => _map.isEmpty; - bool get isNotEmpty => _map.isNotEmpty; - V get first => _map[_map.keys.first] as V; - V get single => _map[_map.keys.single] as V; - V get last => _map[_map.keys.last] as V; - - Iterator get iterator => _MapBaseValueIterator(_map); -} - -/// Iterator created by [_MapBaseValueIterable]. -/// -/// Iterates over the values of a map by iterating its keys and lookup up the -/// values. -class _MapBaseValueIterator implements Iterator { - final Iterator _keys; - final Map _map; - V? _current; - - _MapBaseValueIterator(Map map) - : _map = map, - _keys = map.keys.iterator; - - bool moveNext() { - if (_keys.moveNext()) { - _current = _map[_keys.current]; - return true; - } - _current = null; - return false; - } - - V get current { - final cur = _current; - return (cur != null) ? cur : cur as V; - } -} - -/// Mixin that overrides mutating map operations with implementations that -/// throw. -abstract class _UnmodifiableMapMixin implements Map { - /// This operation is not supported by an unmodifiable map. - void operator []=(K key, V value) { - throw UnsupportedError("Cannot modify unmodifiable map"); - } - - /// This operation is not supported by an unmodifiable map. - void addAll(Map other) { - throw UnsupportedError("Cannot modify unmodifiable map"); - } - - /// This operation is not supported by an unmodifiable map. - void addEntries(Iterable> entries) { - throw UnsupportedError("Cannot modify unmodifiable map"); - } - - /// This operation is not supported by an unmodifiable map. - void clear() { - throw UnsupportedError("Cannot modify unmodifiable map"); - } - - /// This operation is not supported by an unmodifiable map. - V remove(Object? key) { - throw UnsupportedError("Cannot modify unmodifiable map"); - } - - /// This operation is not supported by an unmodifiable map. - void removeWhere(bool test(K key, V value)) { - throw UnsupportedError("Cannot modify unmodifiable map"); - } - - /// This operation is not supported by an unmodifiable map. - V putIfAbsent(K key, V ifAbsent()) { - throw UnsupportedError("Cannot modify unmodifiable map"); - } - - /// This operation is not supported by an unmodifiable map. - V update(K key, V update(V value), {V Function()? ifAbsent}) { - throw UnsupportedError("Cannot modify unmodifiable map"); - } - - /// This operation is not supported by an unmodifiable map. - void updateAll(V update(K key, V value)) { - throw UnsupportedError("Cannot modify unmodifiable map"); - } -} - -/// Wrapper around a class that implements [Map] that only exposes `Map` -/// members. -/// -/// A simple wrapper that delegates all `Map` members to the map provided in the -/// constructor. -/// -/// Base for delegating map implementations like [UnmodifiableMapView]. -class MapView implements Map { - final Map _map; - const MapView(Map map) : _map = map; - - Map cast() => _map.cast(); - V? operator [](Object? key) => _map[key]; - void operator []=(K key, V value) { - _map[key] = value; - } - - void addAll(Map other) { - _map.addAll(other); - } - - void clear() { - _map.clear(); - } - - V putIfAbsent(K key, V ifAbsent()) => _map.putIfAbsent(key, ifAbsent); - bool containsKey(Object? key) => _map.containsKey(key); - bool containsValue(Object? value) => _map.containsValue(value); - void forEach(void action(K key, V value)) { - _map.forEach(action); - } - - bool get isEmpty => _map.isEmpty; - bool get isNotEmpty => _map.isNotEmpty; - int get length => _map.length; - Iterable get keys => _map.keys; - V? remove(Object? key) => _map.remove(key); - String toString() => _map.toString(); - Iterable get values => _map.values; - - Iterable> get entries => _map.entries; - - void addEntries(Iterable> entries) { - _map.addEntries(entries); - } - - Map map(MapEntry transform(K key, V value)) => - _map.map(transform); - - V update(K key, V update(V value), {V Function()? ifAbsent}) => - _map.update(key, update, ifAbsent: ifAbsent); - - void updateAll(V update(K key, V value)) { - _map.updateAll(update); - } - - void removeWhere(bool test(K key, V value)) { - _map.removeWhere(test); - } -} - -/// View of a [Map] that disallow modifying the map. -/// -/// A wrapper around a `Map` that forwards all members to the map provided in -/// the constructor, except for operations that modify the map. -/// Modifying operations throw instead. -class UnmodifiableMapView extends MapView - with _UnmodifiableMapMixin { - UnmodifiableMapView(Map map) : super(map); - - Map cast() => - UnmodifiableMapView(_map.cast()); -} diff --git a/sdk_nnbd/lib/collection/queue.dart b/sdk_nnbd/lib/collection/queue.dart deleted file mode 100644 index 26abbfe0f01..00000000000 --- a/sdk_nnbd/lib/collection/queue.dart +++ /dev/null @@ -1,919 +0,0 @@ -// Copyright (c) 2011, 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. - -part of dart.collection; - -/// A [Queue] is a collection that can be manipulated at both ends. One -/// can iterate over the elements of a queue through [forEach] or with -/// an [Iterator]. -/// -/// It is generally not allowed to modify the queue (add or remove entries) -/// while an operation on the queue is being performed, for example during a -/// call to [forEach]. -/// Modifying the queue while it is being iterated will most likely break the -/// iteration. -/// This goes both for using the [iterator] directly, or for iterating an -/// `Iterable` returned by a method like [map] or [where]. -abstract class Queue implements EfficientLengthIterable { - /// Creates a queue. - factory Queue() = ListQueue; - - /// Creates a queue containing all [elements]. - /// - /// The element order in the queue is as if the elements were added using - /// [addLast] in the order provided by [elements.iterator]. - /// - /// All the [elements] should be instances of [E]. - /// The `elements` iterable itself may have any element type, so this - /// constructor can be used to down-cast a `Queue`, for example as: - /// ```dart - /// Queue superQueue = ...; - /// Queue subQueue = - /// new Queue.from(superQueue.whereType()); - /// ``` - factory Queue.from(Iterable elements) = ListQueue.from; - - /// Creates a queue from [elements]. - /// - /// The element order in the queue is as if the elements were added using - /// [addLast] in the order provided by [elements.iterator]. - factory Queue.of(Iterable elements) = ListQueue.of; - - /// Adapts [source] to be a `Queue`. - /// - /// Any time the queue would produce an element that is not a [T], - /// the element access will throw. - /// - /// Any time a [T] value is attempted stored into the adapted queue, - /// the store will throw unless the value is also an instance of [S]. - /// - /// If all accessed elements of [source] are actually instances of [T], - /// and if all elements stored into the returned queue are actually instance - /// of [S], - /// then the returned queue can be used as a `Queue`. - static Queue castFrom(Queue source) => CastQueue(source); - - /// Provides a view of this queue as a queue of [R] instances, if necessary. - /// - /// If this queue contains only instances of [R], all read operations - /// will work correctly. If any operation tries to access an element - /// that is not an instance of [R], the access will throw instead. - /// - /// Elements added to the queue (e.g., by using [addFirst] or [addAll]) - /// must be instance of [R] to be valid arguments to the adding function, - /// and they must be instances of [E] as well to be accepted by - /// this queue as well. - Queue cast(); - - /// Removes and returns the first element of this queue. - /// - /// The queue must not be empty when this method is called. - E removeFirst(); - - /// Removes and returns the last element of the queue. - /// - /// The queue must not be empty when this method is called. - E removeLast(); - - /// Adds [value] at the beginning of the queue. - void addFirst(E value); - - /// Adds [value] at the end of the queue. - void addLast(E value); - - /// Adds [value] at the end of the queue. - void add(E value); - - /// Remove a single instance of [value] from the queue. - /// - /// Returns `true` if a value was removed, or `false` if the queue - /// contained no element equal to [value]. - bool remove(Object? value); - - /// Adds all elements of [iterable] at the end of the queue. The - /// length of the queue is extended by the length of [iterable]. - void addAll(Iterable iterable); - - /// Removes all elements matched by [test] from the queue. - /// - /// The `test` function must not throw or modify the queue. - void removeWhere(bool test(E element)); - - /// Removes all elements not matched by [test] from the queue. - /// - /// The `test` function must not throw or modify the queue. - void retainWhere(bool test(E element)); - - /// Removes all elements in the queue. The size of the queue becomes zero. - void clear(); -} - -class _DoubleLink> { - Link? _previousLink; - Link? _nextLink; - - void _link(Link? previous, Link? next) { - _nextLink = next; - _previousLink = previous; - if (previous != null) previous._nextLink = this as Link; - if (next != null) next._previousLink = this as Link; - } - - void _unlink() { - if (_previousLink != null) _previousLink!._nextLink = _nextLink; - if (_nextLink != null) _nextLink!._previousLink = _previousLink; - _nextLink = null; - _previousLink = null; - } -} - -/// An entry in a doubly linked list. It contains a pointer to the next -/// entry, the previous entry, and the boxed element. -class DoubleLinkedQueueEntry extends _DoubleLink> { - // TODO(rnystrom): This needs to be nullable because the subclass - // _DoubleLinkedQueueSentinel does not have an element. A cleaner solution is - // probably to refactor the class hierarchy so that _DoubleLinkedQueueSentinel - // does not inherit an element field. - E? _element; - - /// The element in the queue. - E get element => _element as E; - set element(E element) { - _element = element; - } - - DoubleLinkedQueueEntry(this._element); - - /// Appends the given [e] as entry just after this entry. - void append(E e) { - DoubleLinkedQueueEntry(e)._link(this, _nextLink); - } - - /// Prepends the given [e] as entry just before this entry. - void prepend(E e) { - DoubleLinkedQueueEntry(e)._link(_previousLink, this); - } - - E remove() { - _unlink(); - return element; - } - - /// Returns the previous entry or `null` if there is none. - DoubleLinkedQueueEntry? previousEntry() => _previousLink; - - /// Returns the next entry or `null` if there is none. - DoubleLinkedQueueEntry? nextEntry() => _nextLink; -} - -/// Interface for the link classes used by [DoubleLinkedQueue]. -/// -/// Both the [_DoubleLinkedQueueElement] and [_DoubleLinkedQueueSentinel] -/// implement this interface. -/// The entry contains a link back to the queue, so calling `append` -/// or `prepend` can correctly update the element count. -abstract class _DoubleLinkedQueueEntry extends DoubleLinkedQueueEntry { - DoubleLinkedQueue? _queue; - _DoubleLinkedQueueEntry(E? element, this._queue) : super(element); - - DoubleLinkedQueueEntry? _asNonSentinelEntry(); - - void _append(E e) { - _DoubleLinkedQueueElement(e, _queue)._link(this, _nextLink); - } - - void _prepend(E e) { - _DoubleLinkedQueueElement(e, _queue)._link(_previousLink, this); - } - - E _remove(); - - E get _element => super._element as E; - - DoubleLinkedQueueEntry? nextEntry() { - _DoubleLinkedQueueEntry entry = _nextLink as _DoubleLinkedQueueEntry; - return entry._asNonSentinelEntry(); - } - - DoubleLinkedQueueEntry? previousEntry() { - _DoubleLinkedQueueEntry entry = - _previousLink as _DoubleLinkedQueueEntry; - return entry._asNonSentinelEntry(); - } -} - -/// The actual entry type used by the [DoubleLinkedQueue]. -/// -/// The entry contains a reference to the queue, allowing -/// [append]/[prepend] to update the list length. -class _DoubleLinkedQueueElement extends _DoubleLinkedQueueEntry { - _DoubleLinkedQueueElement(E element, DoubleLinkedQueue? queue) - : super(element, queue); - - void append(E e) { - _append(e); - if (_queue != null) _queue!._elementCount++; - } - - void prepend(E e) { - _prepend(e); - if (_queue != null) _queue!._elementCount++; - } - - E _remove() { - _queue = null; - _unlink(); - return element; - } - - E remove() { - if (_queue != null) _queue!._elementCount--; - return _remove(); - } - - _DoubleLinkedQueueElement? _asNonSentinelEntry() { - return this; - } -} - -/// A sentinel in a double linked list is used to manipulate the list -/// at both ends. -/// A double linked list has exactly one sentinel, -/// which is the only entry when the list is constructed. -/// Initially, a sentinel has its next and previous entry point to itself. -/// A sentinel does not box any user element. -class _DoubleLinkedQueueSentinel extends _DoubleLinkedQueueEntry { - _DoubleLinkedQueueSentinel(DoubleLinkedQueue queue) : super(null, queue) { - _previousLink = this; - _nextLink = this; - } - - DoubleLinkedQueueEntry? _asNonSentinelEntry() { - return null; - } - - /// Hit by, e.g., [DoubleLinkedQueue.removeFirst] if the queue is empty. - E _remove() { - throw IterableElementError.noElement(); - } - - /// Hit by, e.g., [DoubleLinkedQueue.first] if the queue is empty. - E get _element { - throw IterableElementError.noElement(); - } -} - -/// A [Queue] implementation based on a double-linked list. -/// -/// Allows constant time add, remove-at-ends and peek operations. -class DoubleLinkedQueue extends Iterable implements Queue { - late _DoubleLinkedQueueSentinel _sentinel = - _DoubleLinkedQueueSentinel(this); - - int _elementCount = 0; - - DoubleLinkedQueue(); - - /// Creates a double-linked queue containing all [elements]. - /// - /// The element order in the queue is as if the elements were added using - /// [addLast] in the order provided by [elements.iterator]. - /// - /// All the [elements] should be instances of [E]. - /// The `elements` iterable itself may have any element type, so this - /// constructor can be used to down-cast a `Queue`, for example as: - /// ```dart - /// Queue superQueue = ...; - /// Queue subQueue = - /// new DoubleLinkedQueue.from(superQueue.whereType()); - /// ``` - factory DoubleLinkedQueue.from(Iterable elements) { - DoubleLinkedQueue list = DoubleLinkedQueue(); - for (final e in elements) { - list.addLast(e as E); - } - return list; - } - - /// Creates a double-linked queue from [elements]. - /// - /// The element order in the queue is as if the elements were added using - /// [addLast] in the order provided by [elements.iterator]. - factory DoubleLinkedQueue.of(Iterable elements) => - DoubleLinkedQueue()..addAll(elements); - - Queue cast() => Queue.castFrom(this); - int get length => _elementCount; - - void addLast(E value) { - _sentinel._prepend(value); - _elementCount++; - } - - void addFirst(E value) { - _sentinel._append(value); - _elementCount++; - } - - void add(E value) { - _sentinel._prepend(value); - _elementCount++; - } - - void addAll(Iterable iterable) { - for (final E value in iterable) { - _sentinel._prepend(value); - _elementCount++; - } - } - - E removeLast() { - _DoubleLinkedQueueEntry lastEntry = - _sentinel._previousLink as _DoubleLinkedQueueEntry; - E result = lastEntry._remove(); - _elementCount--; - return result; - } - - E removeFirst() { - _DoubleLinkedQueueEntry firstEntry = - _sentinel._nextLink as _DoubleLinkedQueueEntry; - E result = firstEntry._remove(); - _elementCount--; - return result; - } - - bool remove(Object? o) { - _DoubleLinkedQueueEntry entry = - _sentinel._nextLink as _DoubleLinkedQueueEntry; - while (!identical(entry, _sentinel)) { - bool equals = (entry._element == o); - if (!identical(this, entry._queue)) { - // Entry must still be in the queue. - throw ConcurrentModificationError(this); - } - if (equals) { - entry._remove(); - _elementCount--; - return true; - } - entry = entry._nextLink as _DoubleLinkedQueueEntry; - } - return false; - } - - void _filter(bool test(E element), bool removeMatching) { - _DoubleLinkedQueueEntry entry = - _sentinel._nextLink as _DoubleLinkedQueueEntry; - while (!identical(entry, _sentinel)) { - bool matches = test(entry._element); - if (!identical(this, entry._queue)) { - // Entry must still be in the queue. - throw ConcurrentModificationError(this); - } - DoubleLinkedQueueEntry next = entry._nextLink!; // Cannot be null. - if (identical(removeMatching, matches)) { - entry._remove(); - _elementCount--; - } - entry = next as _DoubleLinkedQueueEntry; - } - } - - void removeWhere(bool test(E element)) { - _filter(test, true); - } - - void retainWhere(bool test(E element)) { - _filter(test, false); - } - - E get first { - DoubleLinkedQueueEntry firstEntry = _sentinel._nextLink!; - return firstEntry._element as E; - } - - E get last { - DoubleLinkedQueueEntry lastEntry = _sentinel._previousLink!; - return lastEntry._element as E; - } - - E get single { - // Note that this throws correctly if the queue is empty - // because reading the element of the sentinel throws. - if (identical(_sentinel._nextLink, _sentinel._previousLink)) { - DoubleLinkedQueueEntry entry = _sentinel._nextLink!; - return entry._element as E; - } - throw IterableElementError.tooMany(); - } - - /// The entry object of the first element in the queue. - /// - /// Each element of the queue has an associated [DoubleLinkedQueueEntry]. - /// - /// Returns the entry object corresponding to the first element of the queue, - /// or `null` if the queue is empty. - /// - /// The entry objects can also be accessed using [lastEntry], - /// and they can be iterated using [DoubleLinkedQueueEntry.nextEntry] and - /// [DoubleLinkedQueueEntry.previousEntry]. - DoubleLinkedQueueEntry? firstEntry() { - return _sentinel.nextEntry(); - } - - /// The entry object of the last element in the queue. - /// - /// Each element of the queue has an associated [DoubleLinkedQueueEntry]. - /// - /// Returns the entry object corresponding to the last element of the queue, - /// or `null` if the queue is empty. - /// - /// The entry objects can also be accessed using [firstEntry], - /// and they can be iterated using [DoubleLinkedQueueEntry.nextEntry] and - /// [DoubleLinkedQueueEntry.previousEntry]. - DoubleLinkedQueueEntry? lastEntry() { - return _sentinel.previousEntry(); - } - - bool get isEmpty { - return (identical(_sentinel._nextLink, _sentinel)); - } - - void clear() { - _sentinel._nextLink = _sentinel; - _sentinel._previousLink = _sentinel; - _elementCount = 0; - } - - /// Calls [action] for each entry object of this double-linked queue. - /// - /// Each element of the queue has an associated [DoubleLinkedQueueEntry]. - /// This method iterates the entry objects from first to last and calls - /// [action] with each object in turn. - /// - /// The entry objects can also be accessed using [firstEntry] and [lastEntry], - /// and iterated using [DoubleLinkedQueueEntry.nextEntry()] and - /// [DoubleLinkedQueueEntry.previousEntry()]. - /// - /// The [action] function can use methods on [DoubleLinkedQueueEntry] to - /// remove the entry or it can insert elements before or after then entry. - /// If the current entry is removed, iteration continues with the entry that - /// was following the current entry when [action] was called. Any elements - /// inserted after the current element before it is removed will not be - /// visited by the iteration. - void forEachEntry(void action(DoubleLinkedQueueEntry element)) { - _DoubleLinkedQueueEntry entry = - _sentinel._nextLink as _DoubleLinkedQueueEntry; - while (!identical(entry, _sentinel)) { - _DoubleLinkedQueueElement element = - entry as _DoubleLinkedQueueElement; - _DoubleLinkedQueueEntry next = - element._nextLink as _DoubleLinkedQueueEntry; - // Remember both entry and entry._nextLink. - // If someone calls `element.remove()` we continue from `next`. - // Otherwise we use the value of entry._nextLink which may have been - // updated. - action(element); - if (identical(this, entry._queue)) { - next = entry._nextLink as _DoubleLinkedQueueEntry; - } else if (!identical(this, next._queue)) { - throw ConcurrentModificationError(this); - } - entry = next; - } - } - - _DoubleLinkedQueueIterator get iterator { - return _DoubleLinkedQueueIterator(_sentinel); - } - - String toString() => IterableBase.iterableToFullString(this, '{', '}'); -} - -class _DoubleLinkedQueueIterator implements Iterator { - _DoubleLinkedQueueSentinel? _sentinel; - DoubleLinkedQueueEntry? _nextEntry; - E? _current; - - _DoubleLinkedQueueIterator(_DoubleLinkedQueueSentinel sentinel) - : _sentinel = sentinel, - _nextEntry = sentinel._nextLink; - - bool moveNext() { - if (identical(_nextEntry, _sentinel)) { - _current = null; - _nextEntry = null; - _sentinel = null; - return false; - } - _DoubleLinkedQueueEntry elementEntry = - _nextEntry as _DoubleLinkedQueueEntry; - if (!identical(_sentinel!._queue, elementEntry._queue)) { - throw ConcurrentModificationError(_sentinel!._queue); - } - _current = elementEntry._element; - _nextEntry = elementEntry._nextLink; - return true; - } - - E get current { - final cur = _current; - return (cur != null) ? cur : cur as E; - } -} - -/// List based [Queue]. -/// -/// Keeps a cyclic buffer of elements, and grows to a larger buffer when -/// it fills up. This guarantees constant time peek and remove operations, and -/// amortized constant time add operations. -/// -/// The structure is efficient for any queue or stack usage. -class ListQueue extends ListIterable implements Queue { - static const int _INITIAL_CAPACITY = 8; - List _table; - int _head; - int _tail; - int _modificationCount = 0; - - /// Create an empty queue. - /// - /// If [initialCapacity] is given, prepare the queue for at least that many - /// elements. - ListQueue([int? initialCapacity]) - : _head = 0, - _tail = 0, - _table = List.filled(_calculateCapacity(initialCapacity), null); - - static int _calculateCapacity(int? initialCapacity) { - if (initialCapacity == null || initialCapacity < _INITIAL_CAPACITY) { - return _INITIAL_CAPACITY; - } else if (!_isPowerOf2(initialCapacity)) { - return _nextPowerOf2(initialCapacity); - } - assert(_isPowerOf2(initialCapacity)); - return initialCapacity; - } - - /// Create a `ListQueue` containing all [elements]. - /// - /// The elements are added to the queue, as by [addLast], in the order given - /// by `elements.iterator`. - /// - /// All the [elements] should be instances of [E]. - /// The `elements` iterable itself may have any element type, so this - /// constructor can be used to down-cast a `Queue`, for example as: - /// ```dart - /// Queue superQueue = ...; - /// Queue subQueue = - /// new ListQueue.from(superQueue.whereType()); - /// ``` - factory ListQueue.from(Iterable elements) { - if (elements is List) { - int length = elements.length; - ListQueue queue = ListQueue(length + 1); - assert(queue._table.length > length); - for (int i = 0; i < length; i++) { - queue._table[i] = elements[i] as E; - } - queue._tail = length; - return queue; - } else { - int capacity = _INITIAL_CAPACITY; - if (elements is EfficientLengthIterable) { - capacity = elements.length; - } - ListQueue result = ListQueue(capacity); - for (final element in elements) { - result.addLast(element as E); - } - return result; - } - } - - /// Create a `ListQueue` from [elements]. - /// - /// The elements are added to the queue, as by [addLast], in the order given - /// by `elements.iterator`. - factory ListQueue.of(Iterable elements) => - ListQueue()..addAll(elements); - - // Iterable interface. - - Queue cast() => Queue.castFrom(this); - Iterator get iterator => _ListQueueIterator(this); - - void forEach(void f(E element)) { - int modificationCount = _modificationCount; - for (int i = _head; i != _tail; i = (i + 1) & (_table.length - 1)) { - f(_table[i] as E); - _checkModification(modificationCount); - } - } - - bool get isEmpty => _head == _tail; - - int get length => (_tail - _head) & (_table.length - 1); - - E get first { - if (_head == _tail) throw IterableElementError.noElement(); - return _table[_head] as E; - } - - E get last { - if (_head == _tail) throw IterableElementError.noElement(); - return _table[(_tail - 1) & (_table.length - 1)] as E; - } - - E get single { - if (_head == _tail) throw IterableElementError.noElement(); - if (length > 1) throw IterableElementError.tooMany(); - return _table[_head] as E; - } - - E elementAt(int index) { - RangeError.checkValidIndex(index, this); - return _table[(_head + index) & (_table.length - 1)] as E; - } - - List toList({bool growable = true}) { - int mask = _table.length - 1; - int length = (_tail - _head) & mask; - if (length == 0) return List.empty(growable: growable); - - var list = List.filled(length, first, growable: growable); - for (int i = 0; i < length; i++) { - list[i] = _table[(_head + i) & mask] as E; - } - return list; - } - - // Collection interface. - - void add(E value) { - _add(value); - } - - void addAll(Iterable elements) { - if (elements is List) { - List list = elements; - int addCount = list.length; - int length = this.length; - if (length + addCount >= _table.length) { - _preGrow(length + addCount); - // After preGrow, all elements are at the start of the list. - _table.setRange(length, length + addCount, list, 0); - _tail += addCount; - } else { - // Adding addCount elements won't reach _head. - int endSpace = _table.length - _tail; - if (addCount < endSpace) { - _table.setRange(_tail, _tail + addCount, list, 0); - _tail += addCount; - } else { - int preSpace = addCount - endSpace; - _table.setRange(_tail, _tail + endSpace, list, 0); - _table.setRange(0, preSpace, list, endSpace); - _tail = preSpace; - } - } - _modificationCount++; - } else { - for (E element in elements) _add(element); - } - } - - bool remove(Object? value) { - for (int i = _head; i != _tail; i = (i + 1) & (_table.length - 1)) { - E? element = _table[i]; - if (element == value) { - _remove(i); - _modificationCount++; - return true; - } - } - return false; - } - - void _filterWhere(bool test(E element), bool removeMatching) { - int modificationCount = _modificationCount; - int i = _head; - while (i != _tail) { - E element = _table[i] as E; - bool remove = identical(removeMatching, test(element)); - _checkModification(modificationCount); - if (remove) { - i = _remove(i); - modificationCount = ++_modificationCount; - } else { - i = (i + 1) & (_table.length - 1); - } - } - } - - /// Remove all elements matched by [test]. - /// - /// This method is inefficient since it works by repeatedly removing single - /// elements, each of which can take linear time. - void removeWhere(bool test(E element)) { - _filterWhere(test, true); - } - - /// Remove all elements not matched by [test]. - /// - /// This method is inefficient since it works by repeatedly removing single - /// elements, each of which can take linear time. - void retainWhere(bool test(E element)) { - _filterWhere(test, false); - } - - void clear() { - if (_head != _tail) { - for (int i = _head; i != _tail; i = (i + 1) & (_table.length - 1)) { - _table[i] = null; - } - _head = _tail = 0; - _modificationCount++; - } - } - - String toString() => IterableBase.iterableToFullString(this, "{", "}"); - - // Queue interface. - - void addLast(E value) { - _add(value); - } - - void addFirst(E value) { - _head = (_head - 1) & (_table.length - 1); - _table[_head] = value; - if (_head == _tail) _grow(); - _modificationCount++; - } - - E removeFirst() { - if (_head == _tail) throw IterableElementError.noElement(); - _modificationCount++; - E result = _table[_head] as E; - _table[_head] = null; - _head = (_head + 1) & (_table.length - 1); - return result; - } - - E removeLast() { - if (_head == _tail) throw IterableElementError.noElement(); - _modificationCount++; - _tail = (_tail - 1) & (_table.length - 1); - E result = _table[_tail] as E; - _table[_tail] = null; - return result; - } - - // Internal helper functions. - - /// Whether [number] is a power of two. - /// - /// Only works for positive numbers. - static bool _isPowerOf2(int number) => (number & (number - 1)) == 0; - - /// Rounds [number] up to the nearest power of 2. - /// - /// If [number] is a power of 2 already, it is returned. - /// - /// Only works for positive numbers. - static int _nextPowerOf2(int number) { - assert(number > 0); - number = (number << 1) - 1; - for (;;) { - int nextNumber = number & (number - 1); - if (nextNumber == 0) return number; - number = nextNumber; - } - } - - /// Check if the queue has been modified during iteration. - void _checkModification(int expectedModificationCount) { - if (expectedModificationCount != _modificationCount) { - throw ConcurrentModificationError(this); - } - } - - /// Adds element at end of queue. Used by both [add] and [addAll]. - void _add(E element) { - _table[_tail] = element; - _tail = (_tail + 1) & (_table.length - 1); - if (_head == _tail) _grow(); - _modificationCount++; - } - - /// Removes the element at [offset] into [_table]. - /// - /// Removal is performed by linearly moving elements either before or after - /// [offset] by one position. - /// - /// Returns the new offset of the following element. This may be the same - /// offset or the following offset depending on how elements are moved - /// to fill the hole. - int _remove(int offset) { - int mask = _table.length - 1; - int startDistance = (offset - _head) & mask; - int endDistance = (_tail - offset) & mask; - if (startDistance < endDistance) { - // Closest to start. - int i = offset; - while (i != _head) { - int prevOffset = (i - 1) & mask; - _table[i] = _table[prevOffset]; - i = prevOffset; - } - _table[_head] = null; - _head = (_head + 1) & mask; - return (offset + 1) & mask; - } else { - _tail = (_tail - 1) & mask; - int i = offset; - while (i != _tail) { - int nextOffset = (i + 1) & mask; - _table[i] = _table[nextOffset]; - i = nextOffset; - } - _table[_tail] = null; - return offset; - } - } - - /// Grow the table when full. - void _grow() { - List newTable = List.filled(_table.length * 2, null); - int split = _table.length - _head; - newTable.setRange(0, split, _table, _head); - newTable.setRange(split, split + _head, _table, 0); - _head = 0; - _tail = _table.length; - _table = newTable; - } - - int _writeToList(List target) { - assert(target.length >= length); - if (_head <= _tail) { - int length = _tail - _head; - target.setRange(0, length, _table, _head); - return length; - } else { - int firstPartSize = _table.length - _head; - target.setRange(0, firstPartSize, _table, _head); - target.setRange(firstPartSize, firstPartSize + _tail, _table, 0); - return _tail + firstPartSize; - } - } - - /// Grows the table even if it is not full. - void _preGrow(int newElementCount) { - assert(newElementCount >= length); - - // Add some extra room to ensure that there's room for more elements after - // expansion. - newElementCount += newElementCount >> 1; - int newCapacity = _nextPowerOf2(newElementCount); - List newTable = List.filled(newCapacity, null); - _tail = _writeToList(newTable); - _table = newTable; - _head = 0; - } -} - -/// Iterator for a [ListQueue]. -/// -/// Considers any add or remove operation a concurrent modification. -class _ListQueueIterator implements Iterator { - final ListQueue _queue; - final int _end; - final int _modificationCount; - int _position; - E? _current; - - _ListQueueIterator(ListQueue queue) - : _queue = queue, - _end = queue._tail, - _modificationCount = queue._modificationCount, - _position = queue._head; - - E get current { - final cur = _current; - return (cur != null) ? cur : cur as E; - } - - bool moveNext() { - _queue._checkModification(_modificationCount); - if (_position == _end) { - _current = null; - return false; - } - _current = _queue._table[_position]; - _position = (_position + 1) & (_queue._table.length - 1); - return true; - } -} diff --git a/sdk_nnbd/lib/collection/set.dart b/sdk_nnbd/lib/collection/set.dart deleted file mode 100644 index 1eb74919824..00000000000 --- a/sdk_nnbd/lib/collection/set.dart +++ /dev/null @@ -1,626 +0,0 @@ -// Copyright (c) 2014, 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. - -/// Base implementations of [Set]. -part of dart.collection; - -/// Mixin implementation of [Set]. -/// -/// This class provides a base implementation of a `Set` that depends only -/// on the abstract members: [add], [contains], [lookup], [remove], -/// [iterator], [length] and [toSet]. -/// -/// Some of the methods assume that `toSet` creates a modifiable set. -/// If using this mixin for an unmodifiable set, -/// where `toSet` should return an unmodifiable set, -/// it's necessary to reimplement -/// [retainAll], [union], [intersection] and [difference]. -/// -/// Implementations of `Set` using this mixin should consider also implementing -/// `clear` in constant time. The default implementation works by removing every -/// element. -abstract class SetMixin implements Set { - // This class reimplements all of [IterableMixin]. - // If/when Dart mixins get more powerful, we should just create a single - // Mixin class from IterableMixin and the new methods of this class. - - bool add(E value); - - bool contains(Object? element); - - E? lookup(Object? element); - - bool remove(Object? value); - - Iterator get iterator; - - Set toSet(); - - int get length; - - bool get isEmpty => length == 0; - - bool get isNotEmpty => length != 0; - - Set cast() => Set.castFrom(this); - Iterable followedBy(Iterable other) => - FollowedByIterable.firstEfficient(this, other); - - Iterable whereType() => WhereTypeIterable(this); - - void clear() { - removeAll(toList()); - } - - void addAll(Iterable elements) { - for (E element in elements) add(element); - } - - void removeAll(Iterable elements) { - for (Object? element in elements) remove(element); - } - - void retainAll(Iterable elements) { - // Create a copy of the set, remove all of elements from the copy, - // then remove all remaining elements in copy from this. - Set toRemove = toSet(); - for (Object? o in elements) { - toRemove.remove(o); - } - removeAll(toRemove); - } - - void removeWhere(bool test(E element)) { - List toRemove = []; - for (E element in this) { - if (test(element)) toRemove.add(element); - } - removeAll(toRemove); - } - - void retainWhere(bool test(E element)) { - List toRemove = []; - for (E element in this) { - if (!test(element)) toRemove.add(element); - } - removeAll(toRemove); - } - - bool containsAll(Iterable other) { - for (var o in other) { - if (!contains(o)) return false; - } - return true; - } - - Set union(Set other) { - return toSet()..addAll(other); - } - - Set intersection(Set other) { - Set result = toSet(); - for (E element in this) { - if (!other.contains(element)) result.remove(element); - } - return result; - } - - Set difference(Set other) { - Set result = toSet(); - for (E element in this) { - if (other.contains(element)) result.remove(element); - } - return result; - } - - List toList({bool growable = true}) => - List.of(this, growable: growable); - - Iterable map(T f(E element)) => - EfficientLengthMappedIterable(this, f); - - E get single { - if (length > 1) throw IterableElementError.tooMany(); - Iterator it = iterator; - if (!it.moveNext()) throw IterableElementError.noElement(); - E result = it.current; - return result; - } - - String toString() => IterableBase.iterableToFullString(this, '{', '}'); - - // Copied from IterableMixin. - // Should be inherited if we had multi-level mixins. - - Iterable where(bool f(E element)) => WhereIterable(this, f); - - Iterable expand(Iterable f(E element)) => - ExpandIterable(this, f); - - void forEach(void f(E element)) { - for (E element in this) f(element); - } - - E reduce(E combine(E value, E element)) { - Iterator iterator = this.iterator; - if (!iterator.moveNext()) { - throw IterableElementError.noElement(); - } - E value = iterator.current; - while (iterator.moveNext()) { - value = combine(value, iterator.current); - } - return value; - } - - T fold(T initialValue, T combine(T previousValue, E element)) { - var value = initialValue; - for (E element in this) value = combine(value, element); - return value; - } - - bool every(bool f(E element)) { - for (E element in this) { - if (!f(element)) return false; - } - return true; - } - - String join([String separator = ""]) { - Iterator iterator = this.iterator; - if (!iterator.moveNext()) return ""; - StringBuffer buffer = StringBuffer(); - if (separator == null || separator == "") { - do { - buffer.write(iterator.current); - } while (iterator.moveNext()); - } else { - buffer.write(iterator.current); - while (iterator.moveNext()) { - buffer.write(separator); - buffer.write(iterator.current); - } - } - return buffer.toString(); - } - - bool any(bool test(E element)) { - for (E element in this) { - if (test(element)) return true; - } - return false; - } - - Iterable take(int n) { - return TakeIterable(this, n); - } - - Iterable takeWhile(bool test(E value)) { - return TakeWhileIterable(this, test); - } - - Iterable skip(int n) { - return SkipIterable(this, n); - } - - Iterable skipWhile(bool test(E value)) { - return SkipWhileIterable(this, test); - } - - E get first { - Iterator it = iterator; - if (!it.moveNext()) { - throw IterableElementError.noElement(); - } - return it.current; - } - - E get last { - Iterator it = iterator; - if (!it.moveNext()) { - throw IterableElementError.noElement(); - } - E result; - do { - result = it.current; - } while (it.moveNext()); - return result; - } - - E firstWhere(bool test(E value), {E Function()? orElse}) { - for (E element in this) { - if (test(element)) return element; - } - if (orElse != null) return orElse(); - throw IterableElementError.noElement(); - } - - E lastWhere(bool test(E value), {E Function()? orElse}) { - late E result; - bool foundMatching = false; - for (E element in this) { - if (test(element)) { - result = element; - foundMatching = true; - } - } - if (foundMatching) return result; - if (orElse != null) return orElse(); - throw IterableElementError.noElement(); - } - - E singleWhere(bool test(E value), {E Function()? orElse}) { - late E result; - bool foundMatching = false; - for (E element in this) { - if (test(element)) { - if (foundMatching) { - throw IterableElementError.tooMany(); - } - result = element; - foundMatching = true; - } - } - if (foundMatching) return result; - if (orElse != null) return orElse(); - throw IterableElementError.noElement(); - } - - E elementAt(int index) { - ArgumentError.checkNotNull(index, "index"); - RangeError.checkNotNegative(index, "index"); - int elementIndex = 0; - for (E element in this) { - if (index == elementIndex) return element; - elementIndex++; - } - throw RangeError.index(index, this, "index", null, elementIndex); - } -} - -/// Base implementation of [Set]. -/// -/// This class provides a base implementation of a `Set` that depends only -/// on the abstract members: [add], [contains], [lookup], [remove], -/// [iterator], [length] and [toSet]. -/// -/// Some of the methods assume that `toSet` creates a modifiable set. -/// If using this base class for an unmodifiable set, -/// where `toSet` should return an unmodifiable set, -/// it's necessary to reimplement -/// [retainAll], [union], [intersection] and [difference]. -/// -/// Implementations of `Set` using this base should consider also implementing -/// `clear` in constant time. The default implementation works by removing every -/// element. -abstract class SetBase extends Object with SetMixin { - /// Converts a [Set] to a [String]. - /// - /// Converts [set] to a string by converting each element to a string (by - /// calling [Object.toString]), joining them with ", ", and wrapping the - /// result in "{" and "}". - /// - /// Handles circular references where converting one of the elements - /// to a string ends up converting [set] to a string again. - static String setToString(Set set) => - IterableBase.iterableToFullString(set, '{', '}'); -} - -/// Common internal implementation of some [Set] methods. -// TODO(35548): Make this mix-in SetMixin, by adding `with SetMixin` -// and removing the copied members below, -// when analyzer supports const constructors for mixin applications. -abstract class _SetBase implements Set { - // The following two methods override the ones in SetBase. - // It's possible to be more efficient if we have a way to create an empty - // set of the correct type. - const _SetBase(); - - Set _newSet(); - - Set _newSimilarSet(); - - Set cast() => Set.castFrom(this, newSet: _newSimilarSet); - - Set difference(Set other) { - Set result = _newSet(); - for (var element in this) { - if (!other.contains(element)) result.add(element); - } - return result; - } - - Set intersection(Set other) { - Set result = _newSet(); - for (var element in this) { - if (other.contains(element)) result.add(element); - } - return result; - } - - // Subclasses can optimize this further. - Set toSet() => _newSet()..addAll(this); - - /// TODO(35548): Remove the following declarations again when the analyzer - /// supports mixins with const constructors, and mix in `SetMixin` instead. - - bool get isEmpty => length == 0; - - bool get isNotEmpty => length != 0; - - Iterable followedBy(Iterable other) => - FollowedByIterable.firstEfficient(this, other); - - Iterable whereType() => WhereTypeIterable(this); - - void clear() { - removeAll(toList()); - } - - void addAll(Iterable elements) { - for (E element in elements) add(element); - } - - void removeAll(Iterable elements) { - for (Object? element in elements) remove(element); - } - - void retainAll(Iterable elements) { - // Create a copy of the set, remove all of elements from the copy, - // then remove all remaining elements in copy from this. - Set toRemove = toSet(); - for (Object? o in elements) { - toRemove.remove(o); - } - removeAll(toRemove); - } - - void removeWhere(bool test(E element)) { - List toRemove = []; - for (E element in this) { - if (test(element)) toRemove.add(element); - } - removeAll(toRemove); - } - - void retainWhere(bool test(E element)) { - List toRemove = []; - for (E element in this) { - if (!test(element)) toRemove.add(element); - } - removeAll(toRemove); - } - - bool containsAll(Iterable other) { - for (Object? o in other) { - if (!contains(o)) return false; - } - return true; - } - - Set union(Set other) { - return toSet()..addAll(other); - } - - List toList({bool growable = true}) => - List.of(this, growable: growable); - - Iterable map(T f(E element)) => - EfficientLengthMappedIterable(this, f); - - E get single { - if (length > 1) throw IterableElementError.tooMany(); - Iterator it = iterator; - if (!it.moveNext()) throw IterableElementError.noElement(); - E result = it.current; - return result; - } - - String toString() => IterableBase.iterableToFullString(this, '{', '}'); - - Iterable where(bool f(E element)) => WhereIterable(this, f); - - Iterable expand(Iterable f(E element)) => - ExpandIterable(this, f); - - void forEach(void f(E element)) { - for (E element in this) f(element); - } - - E reduce(E combine(E value, E element)) { - Iterator iterator = this.iterator; - if (!iterator.moveNext()) { - throw IterableElementError.noElement(); - } - E value = iterator.current; - while (iterator.moveNext()) { - value = combine(value, iterator.current); - } - return value; - } - - T fold(T initialValue, T combine(T previousValue, E element)) { - var value = initialValue; - for (E element in this) value = combine(value, element); - return value; - } - - bool every(bool f(E element)) { - for (E element in this) { - if (!f(element)) return false; - } - return true; - } - - String join([String separator = ""]) { - Iterator iterator = this.iterator; - if (!iterator.moveNext()) return ""; - StringBuffer buffer = StringBuffer(); - if (separator == null || separator == "") { - do { - buffer.write(iterator.current); - } while (iterator.moveNext()); - } else { - buffer.write(iterator.current); - while (iterator.moveNext()) { - buffer.write(separator); - buffer.write(iterator.current); - } - } - return buffer.toString(); - } - - bool any(bool test(E element)) { - for (E element in this) { - if (test(element)) return true; - } - return false; - } - - Iterable take(int n) { - return TakeIterable(this, n); - } - - Iterable takeWhile(bool test(E value)) { - return TakeWhileIterable(this, test); - } - - Iterable skip(int n) { - return SkipIterable(this, n); - } - - Iterable skipWhile(bool test(E value)) { - return SkipWhileIterable(this, test); - } - - E get first { - Iterator it = iterator; - if (!it.moveNext()) { - throw IterableElementError.noElement(); - } - return it.current; - } - - E get last { - Iterator it = iterator; - if (!it.moveNext()) { - throw IterableElementError.noElement(); - } - E result; - do { - result = it.current; - } while (it.moveNext()); - return result; - } - - E firstWhere(bool test(E value), {E Function()? orElse}) { - for (E element in this) { - if (test(element)) return element; - } - if (orElse != null) return orElse(); - throw IterableElementError.noElement(); - } - - E lastWhere(bool test(E value), {E Function()? orElse}) { - late E result; - bool foundMatching = false; - for (E element in this) { - if (test(element)) { - result = element; - foundMatching = true; - } - } - if (foundMatching) return result; - if (orElse != null) return orElse(); - throw IterableElementError.noElement(); - } - - E singleWhere(bool test(E value), {E Function()? orElse}) { - late E result; - bool foundMatching = false; - for (E element in this) { - if (test(element)) { - if (foundMatching) { - throw IterableElementError.tooMany(); - } - result = element; - foundMatching = true; - } - } - if (foundMatching) return result; - if (orElse != null) return orElse(); - throw IterableElementError.noElement(); - } - - E elementAt(int index) { - ArgumentError.checkNotNull(index, "index"); - RangeError.checkNotNegative(index, "index"); - int elementIndex = 0; - for (E element in this) { - if (index == elementIndex) return element; - elementIndex++; - } - throw RangeError.index(index, this, "index", null, elementIndex); - } -} - -/// Class used to implement const sets. -class _UnmodifiableSet extends _SetBase { - final Map _map; - - const _UnmodifiableSet(this._map); - - Set _newSet() => LinkedHashSet(); - - Set _newSimilarSet() => LinkedHashSet(); - - // Lookups use map methods. - - bool contains(Object? element) => _map.containsKey(element); - - Iterator get iterator => _map.keys.iterator; - - int get length => _map.length; - - E? lookup(Object? element) { - for (var key in _map.keys) { - if (key == element) return key; - } - return null; - } - - // Mutating methods throw. - - bool add(E value) { - throw UnsupportedError("Cannot change unmodifiable set"); - } - - void clear() { - throw UnsupportedError("Cannot change unmodifiable set"); - } - - void addAll(Iterable elements) { - throw UnsupportedError("Cannot change unmodifiable set"); - } - - void removeAll(Iterable elements) { - throw UnsupportedError("Cannot change unmodifiable set"); - } - - void retainAll(Iterable elements) { - throw UnsupportedError("Cannot change unmodifiable set"); - } - - void removeWhere(bool test(E element)) { - throw UnsupportedError("Cannot change unmodifiable set"); - } - - void retainWhere(bool test(E element)) { - throw UnsupportedError("Cannot change unmodifiable set"); - } - - bool remove(Object? value) { - throw UnsupportedError("Cannot change unmodifiable set"); - } -} diff --git a/sdk_nnbd/lib/collection/splay_tree.dart b/sdk_nnbd/lib/collection/splay_tree.dart deleted file mode 100644 index a019b645e87..00000000000 --- a/sdk_nnbd/lib/collection/splay_tree.dart +++ /dev/null @@ -1,918 +0,0 @@ -// Copyright (c) 2012, 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. - -part of dart.collection; - -typedef _Predicate = bool Function(T value); - -/// A node in a splay tree. It holds the sorting key and the left -/// and right children in the tree. -class _SplayTreeNode> { - final K key; - - Node? left; - Node? right; - - _SplayTreeNode(this.key); -} - -/// A node in a splay tree based set. -class _SplayTreeSetNode extends _SplayTreeNode> { - _SplayTreeSetNode(K key) : super(key); -} - -/// A node in a splay tree based map. -/// -/// A [_SplayTreeNode] that also contains a value -class _SplayTreeMapNode - extends _SplayTreeNode> { - V value; - _SplayTreeMapNode(K key, this.value) : super(key); -} - -/// A splay tree is a self-balancing binary search tree. -/// -/// It has the additional property that recently accessed elements -/// are quick to access again. -/// It performs basic operations such as insertion, look-up and -/// removal, in O(log(n)) amortized time. -abstract class _SplayTree> { - // The root node of the splay tree. It will contain either the last - // element inserted or the last element looked up. - Node? get _root; - set _root(Node? newValue); - - // Number of elements in the splay tree. - int _count = 0; - - /// Counter incremented whenever the keys in the map changes. - /// - /// Used to detect concurrent modifications. - int _modificationCount = 0; - - /// Counter incremented whenever the tree structure changes. - /// - /// Used to detect that an in-place traversal cannot use - /// cached information that relies on the tree structure. - int _splayCount = 0; - - /// The comparator that is used for this splay tree. - Comparator get _compare; - - /// The predicate to determine that a given object is a valid key. - _Predicate get _validKey; - - /// Perform the splay operation for the given key. Moves the node with - /// the given key to the top of the tree. If no node has the given - /// key, the last node on the search path is moved to the top of the - /// tree. This is the simplified top-down splaying algorithm from: - /// "Self-adjusting Binary Search Trees" by Sleator and Tarjan. - /// - /// Returns the result of comparing the new root of the tree to [key]. - /// Returns -1 if the table is empty. - int _splay(K key) { - if (_root == null) return -1; - - // The right and newTreeRight variables start out null, and are set - // after the first move left. The right node is the destination - // for subsequent left rebalances, and newTreeRight holds the left - // child of the final tree. The newTreeRight variable is set at most - // once, after the first move left, and is null iff right is null. - // The left and newTreeLeft variables play the corresponding role for - // right rebalances. - Node? right; - Node? newTreeRight; - Node? left; - Node? newTreeLeft; - var current = _root!; - // Hoist the field read out of the loop. - var compare = _compare; - int comp; - while (true) { - comp = compare(current.key, key); - if (comp > 0) { - var currentLeft = current.left; - if (currentLeft == null) break; - comp = compare(currentLeft.key, key); - if (comp > 0) { - // Rotate right. - current.left = currentLeft.right; - currentLeft.right = current; - current = currentLeft; - currentLeft = current.left; - if (currentLeft == null) break; - } - // Link right. - if (right == null) { - // First left rebalance, store the eventual right child - newTreeRight = current; - } else { - right.left = current; - } - right = current; - current = currentLeft; - } else if (comp < 0) { - var currentRight = current.right; - if (currentRight == null) break; - comp = compare(currentRight.key, key); - if (comp < 0) { - // Rotate left. - current.right = currentRight.left; - currentRight.left = current; - current = currentRight; - currentRight = current.right; - if (currentRight == null) break; - } - // Link left. - if (left == null) { - // First right rebalance, store the eventual left child - newTreeLeft = current; - } else { - left.right = current; - } - left = current; - current = currentRight; - } else { - break; - } - } - // Assemble. - if (left != null) { - left.right = current.left; - current.left = newTreeLeft; - } - if (right != null) { - right.left = current.right; - current.right = newTreeRight; - } - _root = current; - - _splayCount++; - return comp; - } - - // Emulates splaying with a key that is smaller than any in the subtree - // anchored at [node]. - // and that node is returned. It should replace the reference to [node] - // in any parent tree or root pointer. - Node _splayMin(Node node) { - var current = node; - var nextLeft = current.left; - while (nextLeft != null) { - var left = nextLeft; - current.left = left.right; - left.right = current; - current = left; - nextLeft = current.left; - } - return current; - } - - // Emulates splaying with a key that is greater than any in the subtree - // anchored at [node]. - // After this, the largest element in the tree is the root of the subtree, - // and that node is returned. It should replace the reference to [node] - // in any parent tree or root pointer. - Node _splayMax(Node node) { - var current = node; - var nextRight = current.right; - while (nextRight != null) { - var right = nextRight; - current.right = right.left; - right.left = current; - current = right; - nextRight = current.right; - } - return current; - } - - Node? _remove(K key) { - if (_root == null) return null; - int comp = _splay(key); - if (comp != 0) return null; - var root = _root!; - var result = root; - var left = root.left; - _count--; - // assert(_count >= 0); - if (left == null) { - _root = root.right; - } else { - var right = root.right; - // Splay to make sure that the new root has an empty right child. - root = _splayMax(left); - - // Insert the original right child as the right child of the new - // root. - root.right = right; - _root = root; - } - _modificationCount++; - return result; - } - - /// Adds a new root node with the given [key] or [value]. - /// - /// The [comp] value is the result of comparing the existing root's key - /// with key. - void _addNewRoot(Node node, int comp) { - _count++; - _modificationCount++; - var root = _root; - if (root == null) { - _root = node; - return; - } - // assert(_count >= 0); - if (comp < 0) { - node.left = root; - node.right = root.right; - root.right = null; - } else { - node.right = root; - node.left = root.left; - root.left = null; - } - _root = node; - } - - Node? get _first { - var root = _root; - if (root == null) return null; - _root = _splayMin(root); - return _root; - } - - Node? get _last { - var root = _root; - if (root == null) return null; - _root = _splayMax(root); - return _root; - } - - void _clear() { - _root = null; - _count = 0; - _modificationCount++; - } -} - -int _dynamicCompare(dynamic a, dynamic b) => Comparable.compare(a, b); - -Comparator _defaultCompare() { - // If K <: Comparable, then we can just use Comparable.compare - // with no casts. - Object compare = Comparable.compare; - if (compare is Comparator) { - return compare; - } - // Otherwise wrap and cast the arguments on each call. - return _dynamicCompare; -} - -/// A [Map] of objects that can be ordered relative to each other. -/// -/// The map is based on a self-balancing binary tree. It allows most operations -/// in amortized logarithmic time. -/// -/// Keys of the map are compared using the `compare` function passed in -/// the constructor, both for ordering and for equality. -/// If the map contains only the key `a`, then `map.containsKey(b)` -/// will return `true` if and only if `compare(a, b) == 0`, -/// and the value of `a == b` is not even checked. -/// If the compare function is omitted, the objects are assumed to be -/// [Comparable], and are compared using their [Comparable.compareTo] method. -/// Non-comparable objects (including `null`) will not work as keys -/// in that case. -/// -/// To allow calling [operator []], [remove] or [containsKey] with objects -/// that are not supported by the `compare` function, an extra `isValidKey` -/// predicate function can be supplied. This function is tested before -/// using the `compare` function on an argument value that may not be a [K] -/// value. If omitted, the `isValidKey` function defaults to testing if the -/// value is a [K]. -class SplayTreeMap extends _SplayTree> - with MapMixin { - _SplayTreeMapNode? _root; - - Comparator _compare; - _Predicate _validKey; - - SplayTreeMap( - [int Function(K key1, K key2)? compare, - bool Function(dynamic potentialKey)? isValidKey]) - : _compare = compare ?? _defaultCompare(), - _validKey = isValidKey ?? ((dynamic v) => v is K); - - /// Creates a [SplayTreeMap] that contains all key/value pairs of [other]. - /// - /// The keys must all be instances of [K] and the values of [V]. - /// The [other] map itself can have any type. - factory SplayTreeMap.from(Map other, - [int Function(K key1, K key2)? compare, - bool Function(dynamic potentialKey)? isValidKey]) { - if (other is Map) { - return SplayTreeMap.of(other, compare, isValidKey); - } - SplayTreeMap result = SplayTreeMap(compare, isValidKey); - other.forEach((dynamic k, dynamic v) { - result[k] = v; - }); - return result; - } - - /// Creates a [SplayTreeMap] that contains all key/value pairs of [other]. - factory SplayTreeMap.of(Map other, - [int Function(K key1, K key2)? compare, - bool Function(dynamic potentialKey)? isValidKey]) => - SplayTreeMap(compare, isValidKey)..addAll(other); - - /// Creates a [SplayTreeMap] where the keys and values are computed from the - /// [iterable]. - /// - /// For each element of the [iterable] this constructor computes a key/value - /// pair, by applying [key] and [value] respectively. - /// - /// The keys of the key/value pairs do not need to be unique. The last - /// occurrence of a key will simply overwrite any previous value. - /// - /// If no functions are specified for [key] and [value] the default is to - /// use the iterable value itself. - factory SplayTreeMap.fromIterable(Iterable iterable, - {K Function(dynamic element)? key, - V Function(dynamic element)? value, - int Function(K key1, K key2)? compare, - bool Function(dynamic potentialKey)? isValidKey}) { - SplayTreeMap map = SplayTreeMap(compare, isValidKey); - MapBase._fillMapWithMappedIterable(map, iterable, key, value); - return map; - } - - /// Creates a [SplayTreeMap] associating the given [keys] to [values]. - /// - /// This constructor iterates over [keys] and [values] and maps each element - /// of [keys] to the corresponding element of [values]. - /// - /// If [keys] contains the same object multiple times, the last occurrence - /// overwrites the previous value. - /// - /// It is an error if the two [Iterable]s don't have the same length. - factory SplayTreeMap.fromIterables(Iterable keys, Iterable values, - [int Function(K key1, K key2)? compare, - bool Function(dynamic potentialKey)? isValidKey]) { - SplayTreeMap map = SplayTreeMap(compare, isValidKey); - MapBase._fillMapWithIterables(map, keys, values); - return map; - } - - V? operator [](Object? key) { - if (!_validKey(key)) return null; - if (_root != null) { - int comp = _splay(key as dynamic); - if (comp == 0) { - return _root!.value; - } - } - return null; - } - - V? remove(Object? key) { - if (!_validKey(key)) return null; - _SplayTreeMapNode? mapRoot = _remove(key as dynamic); - if (mapRoot != null) return mapRoot.value; - return null; - } - - void operator []=(K key, V value) { - if (key == null) throw ArgumentError(key); - // Splay on the key to move the last node on the search path for - // the key to the root of the tree. - int comp = _splay(key); - if (comp == 0) { - _root!.value = value; - return; - } - _addNewRoot(_SplayTreeMapNode(key, value), comp); - } - - V putIfAbsent(K key, V ifAbsent()) { - if (key == null) throw ArgumentError(key); - int comp = _splay(key); - if (comp == 0) { - return _root!.value; - } - int modificationCount = _modificationCount; - int splayCount = _splayCount; - V value = ifAbsent(); - if (modificationCount != _modificationCount) { - throw ConcurrentModificationError(this); - } - if (splayCount != _splayCount) { - comp = _splay(key); - // Key is still not there, otherwise _modificationCount would be changed. - assert(comp != 0); - } - _addNewRoot(_SplayTreeMapNode(key, value), comp); - return value; - } - - void addAll(Map other) { - other.forEach((K key, V value) { - this[key] = value; - }); - } - - bool get isEmpty { - return (_root == null); - } - - bool get isNotEmpty => !isEmpty; - - void forEach(void f(K key, V value)) { - Iterator<_SplayTreeMapNode> nodes = - _SplayTreeNodeIterator>(this); - while (nodes.moveNext()) { - _SplayTreeMapNode node = nodes.current; - f(node.key, node.value); - } - } - - int get length { - return _count; - } - - void clear() { - _clear(); - } - - bool containsKey(Object? key) { - return _validKey(key) && _splay(key as dynamic) == 0; - } - - bool containsValue(Object? value) { - int initialSplayCount = _splayCount; - bool visit(_SplayTreeMapNode? node) { - while (node != null) { - if (node.value == value) return true; - if (initialSplayCount != _splayCount) { - throw ConcurrentModificationError(this); - } - if (node.right != null && visit(node.right)) { - return true; - } - node = node.left; - } - return false; - } - - return visit(_root); - } - - Iterable get keys => - _SplayTreeKeyIterable>(this); - - Iterable get values => _SplayTreeValueIterable(this); - - /// Get the first key in the map. Returns `null` if the map is empty. - K? firstKey() { - if (_root == null) return null; - return _first!.key; - } - - /// Get the last key in the map. Returns `null` if the map is empty. - K? lastKey() { - if (_root == null) return null; - return _last!.key; - } - - /// Get the last key in the map that is strictly smaller than [key]. Returns - /// `null` if no key was not found. - K? lastKeyBefore(K key) { - if (key == null) throw ArgumentError(key); - if (_root == null) return null; - int comp = _splay(key); - if (comp < 0) return _root!.key; - _SplayTreeMapNode? node = _root!.left; - if (node == null) return null; - var nodeRight = node.right; - while (nodeRight != null) { - node = nodeRight; - nodeRight = node.right; - } - return node!.key; - } - - /// Get the first key in the map that is strictly larger than [key]. Returns - /// `null` if no key was not found. - K? firstKeyAfter(K key) { - if (key == null) throw ArgumentError(key); - if (_root == null) return null; - int comp = _splay(key); - if (comp > 0) return _root!.key; - _SplayTreeMapNode? node = _root!.right; - if (node == null) return null; - var nodeLeft = node.left; - while (nodeLeft != null) { - node = nodeLeft; - nodeLeft = node.left; - } - return node!.key; - } -} - -abstract class _SplayTreeIterator, T> - implements Iterator { - final _SplayTree _tree; - - /// Worklist of nodes to visit. - /// - /// These nodes have been passed over on the way down in a - /// depth-first left-to-right traversal. Visiting each node, - /// and their right subtrees will visit the remainder of - /// the nodes of a full traversal. - /// - /// Only valid as long as the original tree isn't reordered. - final List _workList = []; - - /// Original modification counter of [_tree]. - /// - /// Incremented on [_tree] when a key is added or removed. - /// If it changes, iteration is aborted. - /// - /// Not final because some iterators may modify the tree knowingly, - /// and they update the modification count in that case. - int _modificationCount; - - /// Count of splay operations on [_tree] when [_workList] was built. - /// - /// If the splay count on [_tree] increases, [_workList] becomes invalid. - int _splayCount; - - /// Current node. - Node? _currentNode; - - _SplayTreeIterator(_SplayTree tree) - : _tree = tree, - _modificationCount = tree._modificationCount, - _splayCount = tree._splayCount { - _findLeftMostDescendent(tree._root); - } - - _SplayTreeIterator.startAt(_SplayTree tree, K startKey) - : _tree = tree, - _modificationCount = tree._modificationCount, - _splayCount = -1 { - if (tree._root == null) return; - int compare = tree._splay(startKey); - _splayCount = tree._splayCount; - if (compare < 0) { - // Don't include the root, start at the next element after the root. - _findLeftMostDescendent(tree._root!.right); - } else { - _workList.add(tree._root!); - } - } - - T get current { - var node = _currentNode; - if (node == null) return null as T; - return _getValue(node); - } - - void _findLeftMostDescendent(Node? node) { - while (node != null) { - _workList.add(node); - node = node.left; - } - } - - /// Called when the tree structure of the tree has changed. - /// - /// This can be caused by a splay operation. - /// If the key-set changes, iteration is aborted before getting - /// here, so we know that the keys are the same as before, it's - /// only the tree that has been reordered. - void _rebuildWorkList(Node currentNode) { - assert(_workList.isNotEmpty); - _workList.clear(); - _tree._splay(currentNode.key); - _findLeftMostDescendent(_tree._root!.right); - assert(_workList.isNotEmpty); - } - - bool moveNext() { - if (_modificationCount != _tree._modificationCount) { - throw ConcurrentModificationError(_tree); - } - // Picks the next element in the worklist as current. - // Updates the worklist with the left-most path of the current node's - // right-hand child. - // If the worklist is no longer valid (after a splay), it is rebuild - // from scratch. - if (_workList.isEmpty) { - _currentNode = null; - return false; - } - if (_tree._splayCount != _splayCount && _currentNode != null) { - _rebuildWorkList(_currentNode!); - } - _currentNode = _workList.removeLast(); - _findLeftMostDescendent(_currentNode!.right); - return true; - } - - T _getValue(Node node); -} - -class _SplayTreeKeyIterable> - extends EfficientLengthIterable { - _SplayTree _tree; - _SplayTreeKeyIterable(this._tree); - int get length => _tree._count; - bool get isEmpty => _tree._count == 0; - Iterator get iterator => _SplayTreeKeyIterator(_tree); - - Set toSet() { - SplayTreeSet set = SplayTreeSet(_tree._compare, _tree._validKey); - set._count = _tree._count; - set._root = set._copyNode(_tree._root); - return set; - } -} - -class _SplayTreeValueIterable extends EfficientLengthIterable { - SplayTreeMap _map; - _SplayTreeValueIterable(this._map); - int get length => _map._count; - bool get isEmpty => _map._count == 0; - Iterator get iterator => _SplayTreeValueIterator(_map); -} - -class _SplayTreeKeyIterator> - extends _SplayTreeIterator { - _SplayTreeKeyIterator(_SplayTree map) : super(map); - K _getValue(Node node) => node.key; -} - -class _SplayTreeValueIterator - extends _SplayTreeIterator, V> { - _SplayTreeValueIterator(SplayTreeMap map) : super(map); - V _getValue(_SplayTreeMapNode node) => node.value; -} - -class _SplayTreeNodeIterator> - extends _SplayTreeIterator { - _SplayTreeNodeIterator(_SplayTree tree) : super(tree); - _SplayTreeNodeIterator.startAt(_SplayTree tree, K startKey) - : super.startAt(tree, startKey); - Node _getValue(Node node) => node; -} - -/// A [Set] of objects that can be ordered relative to each other. -/// -/// The set is based on a self-balancing binary tree. It allows most operations -/// in amortized logarithmic time. -/// -/// Elements of the set are compared using the `compare` function passed in -/// the constructor, both for ordering and for equality. -/// If the set contains only an object `a`, then `set.contains(b)` -/// will return `true` if and only if `compare(a, b) == 0`, -/// and the value of `a == b` is not even checked. -/// If the compare function is omitted, the objects are assumed to be -/// [Comparable], and are compared using their [Comparable.compareTo] method. -/// Non-comparable objects (including `null`) will not work as an element -/// in that case. -class SplayTreeSet extends _SplayTree> - with IterableMixin, SetMixin { - _SplayTreeSetNode? _root; - - Comparator _compare; - _Predicate _validKey; - - /// Create a new [SplayTreeSet] with the given compare function. - /// - /// If the [compare] function is omitted, it defaults to [Comparable.compare], - /// and the elements must be comparable. - /// - /// A provided `compare` function may not work on all objects. It may not even - /// work on all `E` instances. - /// - /// For operations that add elements to the set, the user is supposed to not - /// pass in objects that doesn't work with the compare function. - /// - /// The methods [contains], [remove], [lookup], [removeAll] or [retainAll] - /// are typed to accept any object(s), and the [isValidKey] test can used to - /// filter those objects before handing them to the `compare` function. - /// - /// If [isValidKey] is provided, only values satisfying `isValidKey(other)` - /// are compared using the `compare` method in the methods mentioned above. - /// If the `isValidKey` function returns false for an object, it is assumed to - /// not be in the set. - /// - /// If omitted, the `isValidKey` function defaults to checking against the - /// type parameter: `other is E`. - SplayTreeSet( - [int Function(E key1, E key2)? compare, - bool Function(dynamic potentialKey)? isValidKey]) - : _compare = compare ?? _defaultCompare(), - _validKey = isValidKey ?? ((dynamic v) => v is E); - - /// Creates a [SplayTreeSet] that contains all [elements]. - /// - /// The set works as if created by `new SplayTreeSet(compare, isValidKey)`. - /// - /// All the [elements] should be instances of [E] and valid arguments to - /// [compare]. - /// The `elements` iterable itself may have any element type, so this - /// constructor can be used to down-cast a `Set`, for example as: - /// ```dart - /// Set superSet = ...; - /// Set subSet = - /// new SplayTreeSet.from(superSet.whereType()); - /// ``` - factory SplayTreeSet.from(Iterable elements, - [int Function(E key1, E key2)? compare, - bool Function(dynamic potentialKey)? isValidKey]) { - if (elements is Iterable) { - return SplayTreeSet.of(elements, compare, isValidKey); - } - SplayTreeSet result = SplayTreeSet(compare, isValidKey); - for (var element in elements) { - result.add(element as dynamic); - } - return result; - } - - /// Creates a [SplayTreeSet] from [elements]. - /// - /// The set works as if created by `new SplayTreeSet(compare, isValidKey)`. - /// - /// All the [elements] should be valid as arguments to the [compare] function. - factory SplayTreeSet.of(Iterable elements, - [int Function(E key1, E key2)? compare, - bool Function(dynamic potentialKey)? isValidKey]) => - SplayTreeSet(compare, isValidKey)..addAll(elements); - - Set _newSet() => - SplayTreeSet((T a, T b) => _compare(a as E, b as E), _validKey); - - Set cast() => Set.castFrom(this, newSet: _newSet); - - // From Iterable. - - Iterator get iterator => - _SplayTreeKeyIterator>(this); - - int get length => _count; - bool get isEmpty => _root == null; - bool get isNotEmpty => _root != null; - - E get first { - if (_count == 0) throw IterableElementError.noElement(); - return _first!.key; - } - - E get last { - if (_count == 0) throw IterableElementError.noElement(); - return _last!.key; - } - - E get single { - if (_count == 0) throw IterableElementError.noElement(); - if (_count > 1) throw IterableElementError.tooMany(); - return _root!.key; - } - - // From Set. - bool contains(Object? element) { - return _validKey(element) && _splay(element as E) == 0; - } - - bool add(E element) { - int compare = _splay(element); - if (compare == 0) return false; - _addNewRoot(_SplayTreeSetNode(element), compare); - return true; - } - - bool remove(Object? object) { - if (!_validKey(object)) return false; - return _remove(object as E) != null; - } - - void addAll(Iterable elements) { - for (E element in elements) { - int compare = _splay(element); - if (compare != 0) { - _addNewRoot(_SplayTreeSetNode(element), compare); - } - } - } - - void removeAll(Iterable elements) { - for (Object? element in elements) { - if (_validKey(element)) _remove(element as E); - } - } - - void retainAll(Iterable elements) { - // Build a set with the same sense of equality as this set. - SplayTreeSet retainSet = SplayTreeSet(_compare, _validKey); - int modificationCount = _modificationCount; - for (Object? object in elements) { - if (modificationCount != _modificationCount) { - // The iterator should not have side effects. - throw ConcurrentModificationError(this); - } - // Equivalent to this.contains(object). - if (_validKey(object) && _splay(object as E) == 0) { - retainSet.add(_root!.key); - } - } - // Take over the elements from the retained set, if it differs. - if (retainSet._count != _count) { - _root = retainSet._root; - _count = retainSet._count; - _modificationCount++; - } - } - - E? lookup(Object? object) { - if (!_validKey(object)) return null; - int comp = _splay(object as E); - if (comp != 0) return null; - return _root!.key; - } - - Set intersection(Set other) { - Set result = SplayTreeSet(_compare, _validKey); - for (E element in this) { - if (other.contains(element)) result.add(element); - } - return result; - } - - Set difference(Set other) { - Set result = SplayTreeSet(_compare, _validKey); - for (E element in this) { - if (!other.contains(element)) result.add(element); - } - return result; - } - - Set union(Set other) { - return _clone()..addAll(other); - } - - SplayTreeSet _clone() { - var set = SplayTreeSet(_compare, _validKey); - set._count = _count; - set._root = _copyNode<_SplayTreeSetNode>(_root); - return set; - } - - // Copies the structure of a SplayTree into a new similar structure. - // Works on _SplayTreeMapNode as well, but only copies the keys, - _SplayTreeSetNode? _copyNode>( - Node? node) { - if (node == null) return null; - // Given a source node and a destination node, copy the left - // and right subtrees of the source node into the destination node. - // The left subtree is copied recursively, but the right spine - // of every subtree is copied iteratively. - void copyChildren(Node node, _SplayTreeSetNode dest) { - Node? left; - Node? right; - do { - left = node.left; - right = node.right; - if (left != null) { - var newLeft = _SplayTreeSetNode(left.key); - dest.left = newLeft; - // Recursively copy the left tree. - copyChildren(left, newLeft); - } - if (right != null) { - var newRight = _SplayTreeSetNode(right.key); - dest.right = newRight; - // Set node and dest to copy the right tree iteratively. - node = right; - dest = newRight; - } - } while (right != null); - } - - var result = _SplayTreeSetNode(node.key); - copyChildren(node, result); - return result; - } - - void clear() { - _clear(); - } - - Set toSet() => _clone(); - - String toString() => IterableBase.iterableToFullString(this, '{', '}'); -} diff --git a/sdk_nnbd/lib/convert/ascii.dart b/sdk_nnbd/lib/convert/ascii.dart deleted file mode 100644 index 9d980162e8a..00000000000 --- a/sdk_nnbd/lib/convert/ascii.dart +++ /dev/null @@ -1,291 +0,0 @@ -// Copyright (c) 2013, 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. - -part of dart.convert; - -/// An instance of the default implementation of the [AsciiCodec]. -/// -/// This instance provides a convenient access to the most common ASCII -/// use cases. -/// -/// Examples: -/// ```dart -/// var encoded = ascii.encode("This is ASCII!"); -/// var decoded = ascii.decode([0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, -/// 0x20, 0x41, 0x53, 0x43, 0x49, 0x49, 0x21]); -/// ``` -const AsciiCodec ascii = AsciiCodec(); - -const int _asciiMask = 0x7F; - -/// An [AsciiCodec] allows encoding strings as ASCII bytes -/// and decoding ASCII bytes to strings. -class AsciiCodec extends Encoding { - final bool _allowInvalid; - - /// Instantiates a new [AsciiCodec]. - /// - /// If [allowInvalid] is true, the [decode] method and the converter - /// returned by [decoder] will default to allowing invalid values. - /// If allowing invalid values, the values will be decoded into the Unicode - /// Replacement character (U+FFFD). If not, an exception will be thrown. - /// Calls to the [decode] method can choose to override this default. - /// - /// Encoders will not accept invalid (non ASCII) characters. - const AsciiCodec({bool allowInvalid = false}) : _allowInvalid = allowInvalid; - - /// The name of this codec, "us-ascii". - String get name => "us-ascii"; - - Uint8List encode(String source) => encoder.convert(source); - - /// Decodes the ASCII [bytes] (a list of unsigned 7-bit integers) to the - /// corresponding string. - /// - /// If [bytes] contains values that are not in the range 0 .. 127, the decoder - /// will eventually throw a [FormatException]. - /// - /// If [allowInvalid] is not provided, it defaults to the value used to create - /// this [AsciiCodec]. - String decode(List bytes, {bool? allowInvalid}) { - if (allowInvalid ?? _allowInvalid) { - return const AsciiDecoder(allowInvalid: true).convert(bytes); - } else { - return const AsciiDecoder(allowInvalid: false).convert(bytes); - } - } - - AsciiEncoder get encoder => const AsciiEncoder(); - - AsciiDecoder get decoder => _allowInvalid - ? const AsciiDecoder(allowInvalid: true) - : const AsciiDecoder(allowInvalid: false); -} - -// Superclass for [AsciiEncoder] and [Latin1Encoder]. -// Generalizes common operations that only differ by a mask; -class _UnicodeSubsetEncoder extends Converter> { - final int _subsetMask; - - const _UnicodeSubsetEncoder(this._subsetMask); - - /// Converts the [String] into a list of its code units. - /// - /// If [start] and [end] are provided, only the substring - /// `string.substring(start, end)` is used as input to the conversion. - Uint8List convert(String string, [int start = 0, int? end]) { - var stringLength = string.length; - end = RangeError.checkValidRange(start, end, stringLength); - // TODO(38725): Remove workaround when assignment promotion is implemented - if (end == null) { - throw RangeError("Invalid range"); - } - var length = end - start; - var result = Uint8List(length); - for (var i = 0; i < length; i++) { - var codeUnit = string.codeUnitAt(start + i); - if ((codeUnit & ~_subsetMask) != 0) { - throw ArgumentError.value( - string, "string", "Contains invalid characters."); - } - result[i] = codeUnit; - } - return result; - } - - /// Starts a chunked conversion. - /// - /// The converter works more efficiently if the given [sink] is a - /// [ByteConversionSink]. - StringConversionSink startChunkedConversion(Sink> sink) { - return _UnicodeSubsetEncoderSink(_subsetMask, - sink is ByteConversionSink ? sink : ByteConversionSink.from(sink)); - } - - // Override the base-class' bind, to provide a better type. - Stream> bind(Stream stream) => super.bind(stream); -} - -/// This class converts strings of only ASCII characters to bytes. -class AsciiEncoder extends _UnicodeSubsetEncoder { - const AsciiEncoder() : super(_asciiMask); -} - -/// This class encodes chunked strings to bytes (unsigned 8-bit -/// integers). -class _UnicodeSubsetEncoderSink extends StringConversionSinkBase { - final ByteConversionSink _sink; - final int _subsetMask; - - _UnicodeSubsetEncoderSink(this._subsetMask, this._sink); - - void close() { - _sink.close(); - } - - void addSlice(String source, int start, int end, bool isLast) { - RangeError.checkValidRange(start, end, source.length); - for (var i = start; i < end; i++) { - var codeUnit = source.codeUnitAt(i); - if ((codeUnit & ~_subsetMask) != 0) { - throw ArgumentError( - "Source contains invalid character with code point: $codeUnit."); - } - } - _sink.add(source.codeUnits.sublist(start, end)); - if (isLast) { - close(); - } - } -} - -/// This class converts Latin-1 bytes (lists of unsigned 8-bit integers) -/// to a string. -abstract class _UnicodeSubsetDecoder extends Converter, String> { - final bool _allowInvalid; - final int _subsetMask; - - /// Instantiates a new decoder. - /// - /// The [_allowInvalid] argument defines how [convert] deals - /// with invalid bytes. - /// - /// The [_subsetMask] argument is a bit mask used to define the subset - /// of Unicode being decoded. Use [_LATIN1_MASK] for Latin-1 (8-bit) or - /// [_asciiMask] for ASCII (7-bit). - /// - /// If [_allowInvalid] is `true`, [convert] replaces invalid bytes with the - /// Unicode Replacement character `U+FFFD` (�). - /// Otherwise it throws a [FormatException]. - const _UnicodeSubsetDecoder(this._allowInvalid, this._subsetMask); - - /// Converts the [bytes] (a list of unsigned 7- or 8-bit integers) to the - /// corresponding string. - /// - /// If [start] and [end] are provided, only the sub-list of bytes from - /// `start` to `end` (`end` not inclusive) is used as input to the conversion. - String convert(List bytes, [int start = 0, int? end]) { - end = RangeError.checkValidRange(start, end, bytes.length); - // TODO(38725): Remove workaround when assignment promotion is implemented - if (end == null) { - throw RangeError("Invalid range"); - } - for (var i = start; i < end; i++) { - var byte = bytes[i]; - if ((byte & ~_subsetMask) != 0) { - if (!_allowInvalid) { - throw FormatException("Invalid value in input: $byte"); - } - return _convertInvalid(bytes, start, end); - } - } - return String.fromCharCodes(bytes, start, end); - } - - String _convertInvalid(List bytes, int start, int end) { - var buffer = StringBuffer(); - for (var i = start; i < end; i++) { - var value = bytes[i]; - if ((value & ~_subsetMask) != 0) value = 0xFFFD; - buffer.writeCharCode(value); - } - return buffer.toString(); - } - - /// Starts a chunked conversion. - /// - /// The converter works more efficiently if the given [sink] is a - /// [StringConversionSink]. - ByteConversionSink startChunkedConversion(Sink sink); - - // Override the base-class's bind, to provide a better type. - Stream bind(Stream> stream) => super.bind(stream); -} - -class AsciiDecoder extends _UnicodeSubsetDecoder { - const AsciiDecoder({bool allowInvalid = false}) - : super(allowInvalid, _asciiMask); - - /// Starts a chunked conversion. - /// - /// The converter works more efficiently if the given [sink] is a - /// [StringConversionSink]. - ByteConversionSink startChunkedConversion(Sink sink) { - StringConversionSink stringSink; - if (sink is StringConversionSink) { - stringSink = sink; - } else { - stringSink = StringConversionSink.from(sink); - } - // TODO(lrn): Use asUtf16Sink when it becomes available. It - // works just as well, is likely to have less decoding overhead, - // and make adding U+FFFD easier. - // At that time, merge this with _Latin1DecoderSink; - if (_allowInvalid) { - return _ErrorHandlingAsciiDecoderSink(stringSink.asUtf8Sink(false)); - } else { - return _SimpleAsciiDecoderSink(stringSink); - } - } -} - -class _ErrorHandlingAsciiDecoderSink extends ByteConversionSinkBase { - ByteConversionSink _utf8Sink; - _ErrorHandlingAsciiDecoderSink(this._utf8Sink); - - void close() { - _utf8Sink.close(); - } - - void add(List source) { - addSlice(source, 0, source.length, false); - } - - void addSlice(List source, int start, int end, bool isLast) { - RangeError.checkValidRange(start, end, source.length); - for (var i = start; i < end; i++) { - if ((source[i] & ~_asciiMask) != 0) { - if (i > start) _utf8Sink.addSlice(source, start, i, false); - // Add UTF-8 encoding of U+FFFD. - _utf8Sink.add(const [0xEF, 0xBF, 0xBD]); - start = i + 1; - } - } - if (start < end) { - _utf8Sink.addSlice(source, start, end, isLast); - } else if (isLast) { - close(); - } - } -} - -class _SimpleAsciiDecoderSink extends ByteConversionSinkBase { - Sink _sink; - _SimpleAsciiDecoderSink(this._sink); - - void close() { - _sink.close(); - } - - void add(List source) { - for (var i = 0; i < source.length; i++) { - if ((source[i] & ~_asciiMask) != 0) { - throw FormatException("Source contains non-ASCII bytes."); - } - } - _sink.add(String.fromCharCodes(source)); - } - - void addSlice(List source, int start, int end, bool isLast) { - final length = source.length; - RangeError.checkValidRange(start, end, length); - if (start < end) { - if (start != 0 || end != length) { - source = source.sublist(start, end); - } - add(source); - } - if (isLast) close(); - } -} diff --git a/sdk_nnbd/lib/convert/base64.dart b/sdk_nnbd/lib/convert/base64.dart deleted file mode 100644 index 0955ca1e60d..00000000000 --- a/sdk_nnbd/lib/convert/base64.dart +++ /dev/null @@ -1,870 +0,0 @@ -// 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. - -part of dart.convert; - -/// A [base64](https://tools.ietf.org/html/rfc4648) encoder and decoder. -/// -/// It encodes using the default base64 alphabet, -/// decodes using both the base64 and base64url alphabets, -/// does not allow invalid characters and requires padding. -/// -/// Examples: -/// -/// var encoded = base64.encode([0x62, 0x6c, 0xc3, 0xa5, 0x62, 0xc3, 0xa6, -/// 0x72, 0x67, 0x72, 0xc3, 0xb8, 0x64]); -/// var decoded = base64.decode("YmzDpWLDpnJncsO4ZAo="); -/// -/// The top-level [base64Encode] and [base64Decode] functions may be used -/// instead if a local variable shadows the [base64] constant. -const Base64Codec base64 = Base64Codec(); - -/// A [base64url](https://tools.ietf.org/html/rfc4648) encoder and decoder. -/// -/// It encodes and decodes using the base64url alphabet, -/// decodes using both the base64 and base64url alphabets, -/// does not allow invalid characters and requires padding. -/// -/// Examples: -/// -/// var encoded = base64Url.encode([0x62, 0x6c, 0xc3, 0xa5, 0x62, 0xc3, 0xa6, -/// 0x72, 0x67, 0x72, 0xc3, 0xb8, 0x64]); -/// var decoded = base64Url.decode("YmzDpWLDpnJncsO4ZAo="); -const Base64Codec base64Url = Base64Codec.urlSafe(); - -/// Encodes [bytes] using [base64](https://tools.ietf.org/html/rfc4648) encoding. -/// -/// Shorthand for `base64.encode(bytes)`. Useful if a local variable shadows the global -/// [base64] constant. -String base64Encode(List bytes) => base64.encode(bytes); - -/// Encodes [bytes] using [base64url](https://tools.ietf.org/html/rfc4648) encoding. -/// -/// Shorthand for `base64url.encode(bytes)`. -String base64UrlEncode(List bytes) => base64Url.encode(bytes); - -/// Decodes [base64](https://tools.ietf.org/html/rfc4648) or [base64url](https://tools.ietf.org/html/rfc4648) encoded bytes. -/// -/// Shorthand for `base64.decode(bytes)`. Useful if a local variable shadows the -/// global [base64] constant. -Uint8List base64Decode(String source) => base64.decode(source); - -// Constants used in more than one class. -const int _paddingChar = 0x3d; // '='. - -/// A [base64](https://tools.ietf.org/html/rfc4648) encoder and decoder. -/// -/// A [Base64Codec] allows base64 encoding bytes into ASCII strings and -/// decoding valid encodings back to bytes. -/// -/// This implementation only handles the simplest RFC 4648 base64 and base64url -/// encodings. -/// It does not allow invalid characters when decoding and it requires, -/// and generates, padding so that the input is always a multiple of four -/// characters. -class Base64Codec extends Codec, String> { - final Base64Encoder _encoder; - const Base64Codec() : _encoder = const Base64Encoder(); - const Base64Codec.urlSafe() : _encoder = const Base64Encoder.urlSafe(); - - Base64Encoder get encoder => _encoder; - - Base64Decoder get decoder => const Base64Decoder(); - - /// Decodes [encoded]. - /// - /// The input is decoded as if by `decoder.convert`. - /// - /// The returned [Uint8List] contains exactly the decoded bytes, - /// so the [Uint8List.length] is precisely the number of decoded bytes. - /// The [Uint8List.buffer] may be larger than the decoded bytes. - Uint8List decode(String encoded) => decoder.convert(encoded); - - /// Validates and normalizes the base64 encoded data in [source]. - /// - /// Only acts on the substring from [start] to [end], with [end] - /// defaulting to the end of the string. - /// - /// Normalization will: - /// * Unescape any `%`-escapes. - /// * Only allow valid characters (`A`-`Z`, `a`-`z`, `0`-`9`, `/` and `+`). - /// * Normalize a `_` or `-` character to `/` or `+`. - /// * Validate that existing padding (trailing `=` characters) is correct. - /// * If no padding exists, add correct padding if necessary and possible. - /// * Validate that the length is correct (a multiple of four). - String normalize(String source, [int start = 0, int? end]) { - end = RangeError.checkValidRange(start, end, source.length); - // TODO(38725): Remove workaround when assignment promotion is implemented - if (end == null) { - throw RangeError("Invalid range"); - } - const percent = 0x25; - const equals = 0x3d; - StringBuffer? buffer; - var sliceStart = start; - var alphabet = _Base64Encoder._base64Alphabet; - var inverseAlphabet = _Base64Decoder._inverseAlphabet; - var firstPadding = -1; - var firstPaddingSourceIndex = -1; - var paddingCount = 0; - for (var i = start; i < end;) { - var sliceEnd = i; - var char = source.codeUnitAt(i++); - var originalChar = char; - // Normalize char, keep originalChar to see if it matches the source. - if (char == percent) { - if (i + 2 <= end) { - char = parseHexByte(source, i); // May be negative. - i += 2; - // We know that %25 isn't valid, but our table considers it - // a potential padding start, so skip the checks. - if (char == percent) char = -1; - } else { - // An invalid HEX escape (too short). - // Just skip past the handling and reach the throw below. - char = -1; - } - } - // If char is negative here, hex-decoding failed in some way. - if (0 <= char && char <= 127) { - var value = inverseAlphabet[char]; - if (value >= 0) { - char = alphabet.codeUnitAt(value); - if (char == originalChar) continue; - } else if (value == _Base64Decoder._padding) { - // We have ruled out percent, so char is '='. - if (firstPadding < 0) { - // Mark position in normalized output where padding occurs. - firstPadding = (buffer?.length ?? 0) + (sliceEnd - sliceStart); - firstPaddingSourceIndex = sliceEnd; - } - paddingCount++; - // It could have been an escaped equals (%3D). - if (originalChar == equals) continue; - } - if (value != _Base64Decoder._invalid) { - (buffer ??= StringBuffer()) - ..write(source.substring(sliceStart, sliceEnd)) - ..writeCharCode(char); - sliceStart = i; - continue; - } - } - throw FormatException("Invalid base64 data", source, sliceEnd); - } - if (buffer != null) { - buffer.write(source.substring(sliceStart, end)); - if (firstPadding >= 0) { - // There was padding in the source. Check that it is valid: - // * result length a multiple of four - // * one or two padding characters at the end. - _checkPadding(source, firstPaddingSourceIndex, end, firstPadding, - paddingCount, buffer.length); - } else { - // Length of last chunk (1-4 chars) in the encoding. - var endLength = ((buffer.length - 1) % 4) + 1; - if (endLength == 1) { - // The data must have length 0, 2 or 3 modulo 4. - throw FormatException("Invalid base64 encoding length ", source, end); - } - while (endLength < 4) { - buffer.write("="); - endLength++; - } - } - return source.replaceRange(start, end, buffer.toString()); - } - // Original was already normalized, only check padding. - var length = end - start; - if (firstPadding >= 0) { - _checkPadding(source, firstPaddingSourceIndex, end, firstPadding, - paddingCount, length); - } else { - // No padding given, so add some if needed it. - var endLength = length % 4; - if (endLength == 1) { - // The data must have length 0, 2 or 3 modulo 4. - throw FormatException("Invalid base64 encoding length ", source, end); - } - if (endLength > 1) { - // There is no "insertAt" on String, but this works as well. - source = source.replaceRange(end, end, (endLength == 2) ? "==" : "="); - } - } - return source; - } - - static void _checkPadding(String source, int sourceIndex, int sourceEnd, - int firstPadding, int paddingCount, int length) { - if (length % 4 != 0) { - throw FormatException( - "Invalid base64 padding, padded length must be multiple of four, " - "is $length", - source, - sourceEnd); - } - if (firstPadding + paddingCount != length) { - throw FormatException( - "Invalid base64 padding, '=' not at the end", source, sourceIndex); - } - if (paddingCount > 2) { - throw FormatException( - "Invalid base64 padding, more than two '=' characters", - source, - sourceIndex); - } - } -} - -// ------------------------------------------------------------------------ -// Encoder -// ------------------------------------------------------------------------ - -/// Base64 and base64url encoding converter. -/// -/// Encodes lists of bytes using base64 or base64url encoding. -/// -/// The results are ASCII strings using a restricted alphabet. -class Base64Encoder extends Converter, String> { - final bool _urlSafe; - - const Base64Encoder() : _urlSafe = false; - const Base64Encoder.urlSafe() : _urlSafe = true; - - String convert(List input) { - if (input.isEmpty) return ""; - var encoder = _Base64Encoder(_urlSafe); - var buffer = encoder.encode(input, 0, input.length, true)!; - return String.fromCharCodes(buffer); - } - - ByteConversionSink startChunkedConversion(Sink sink) { - if (sink is StringConversionSink) { - return _Utf8Base64EncoderSink(sink.asUtf8Sink(false), _urlSafe); - } - return _AsciiBase64EncoderSink(sink, _urlSafe); - } -} - -/// Helper class for encoding bytes to base64. -class _Base64Encoder { - /// The RFC 4648 base64 encoding alphabet. - static const String _base64Alphabet = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - - /// The RFC 4648 base64url encoding alphabet. - static const String _base64UrlAlphabet = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; - - /// Shift-count to extract the values stored in [_state]. - static const int _valueShift = 2; - - /// Mask to extract the count value stored in [_state]. - static const int _countMask = 3; - - static const int _sixBitMask = 0x3F; - - /// Intermediate state between chunks. - /// - /// Encoding handles three bytes at a time. - /// If fewer than three bytes has been seen, this value encodes - /// the number of bytes seen (0, 1 or 2) and their values. - int _state = 0; - - /// Alphabet used for encoding. - final String _alphabet; - - _Base64Encoder(bool urlSafe) - : _alphabet = urlSafe ? _base64UrlAlphabet : _base64Alphabet; - - /// Encode count and bits into a value to be stored in [_state]. - static int _encodeState(int count, int bits) { - assert(count <= _countMask); - return bits << _valueShift | count; - } - - /// Extract bits from encoded state. - static int _stateBits(int state) => state >> _valueShift; - - /// Extract count from encoded state. - static int _stateCount(int state) => state & _countMask; - - /// Create a [Uint8List] with the provided length. - Uint8List createBuffer(int bufferLength) => Uint8List(bufferLength); - - /// Encode [bytes] from [start] to [end] and the bits in [_state]. - /// - /// Returns a [Uint8List] of the ASCII codes of the encoded data. - /// - /// If the input, including left over [_state] from earlier encodings, - /// are not a multiple of three bytes, then the partial state is stored - /// back into [_state]. - /// If [isLast] is true, partial state is encoded in the output instead, - /// with the necessary padding. - /// - /// Returns `null` if there is no output. - Uint8List? encode(List bytes, int start, int end, bool isLast) { - assert(0 <= start); - assert(start <= end); - assert(end <= bytes.length); - var length = end - start; - - var count = _stateCount(_state); - var byteCount = (count + length); - var fullChunks = byteCount ~/ 3; - var partialChunkLength = byteCount - fullChunks * 3; - var bufferLength = fullChunks * 4; - if (isLast && partialChunkLength > 0) { - bufferLength += 4; // Room for padding. - } - var output = createBuffer(bufferLength); - _state = - encodeChunk(_alphabet, bytes, start, end, isLast, output, 0, _state); - if (bufferLength > 0) return output; - // If the input plus the data in state is still less than three bytes, - // there may not be any output. - return null; - } - - static int encodeChunk(String alphabet, List bytes, int start, int end, - bool isLast, Uint8List output, int outputIndex, int state) { - var bits = _stateBits(state); - // Count number of missing bytes in three-byte chunk. - var expectedChars = 3 - _stateCount(state); - - // The input must be a list of bytes (integers in the range 0..255). - // The value of `byteOr` will be the bitwise or of all the values in - // `bytes` and a later check will validate that they were all valid bytes. - var byteOr = 0; - for (var i = start; i < end; i++) { - var byte = bytes[i]; - byteOr |= byte; - bits = ((bits << 8) | byte) & 0xFFFFFF; // Never store more than 24 bits. - expectedChars--; - if (expectedChars == 0) { - output[outputIndex++] = alphabet.codeUnitAt((bits >> 18) & _sixBitMask); - output[outputIndex++] = alphabet.codeUnitAt((bits >> 12) & _sixBitMask); - output[outputIndex++] = alphabet.codeUnitAt((bits >> 6) & _sixBitMask); - output[outputIndex++] = alphabet.codeUnitAt(bits & _sixBitMask); - expectedChars = 3; - bits = 0; - } - } - if (byteOr >= 0 && byteOr <= 255) { - if (isLast && expectedChars < 3) { - writeFinalChunk(alphabet, output, outputIndex, 3 - expectedChars, bits); - return 0; - } - return _encodeState(3 - expectedChars, bits); - } - - // There was an invalid byte value somewhere in the input - find it! - var i = start; - while (i < end) { - var byte = bytes[i]; - if (byte < 0 || byte > 255) break; - i++; - } - throw ArgumentError.value( - bytes, "Not a byte value at index $i: 0x${bytes[i].toRadixString(16)}"); - } - - /// Writes a final encoded four-character chunk. - /// - /// Only used when the [_state] contains a partial (1 or 2 byte) - /// input. - static void writeFinalChunk( - String alphabet, Uint8List output, int outputIndex, int count, int bits) { - assert(count > 0); - if (count == 1) { - output[outputIndex++] = alphabet.codeUnitAt((bits >> 2) & _sixBitMask); - output[outputIndex++] = alphabet.codeUnitAt((bits << 4) & _sixBitMask); - output[outputIndex++] = _paddingChar; - output[outputIndex++] = _paddingChar; - } else { - assert(count == 2); - output[outputIndex++] = alphabet.codeUnitAt((bits >> 10) & _sixBitMask); - output[outputIndex++] = alphabet.codeUnitAt((bits >> 4) & _sixBitMask); - output[outputIndex++] = alphabet.codeUnitAt((bits << 2) & _sixBitMask); - output[outputIndex++] = _paddingChar; - } - } -} - -class _BufferCachingBase64Encoder extends _Base64Encoder { - /// Reused buffer. - /// - /// When the buffer isn't released to the sink, only used to create another - /// value (a string), the buffer can be reused between chunks. - Uint8List? bufferCache; - - _BufferCachingBase64Encoder(bool urlSafe) : super(urlSafe); - - Uint8List createBuffer(int bufferLength) { - Uint8List? buffer = bufferCache; - if (buffer == null || buffer.length < bufferLength) { - bufferCache = buffer = Uint8List(bufferLength); - } - // TODO(38725): Remove workaround when assignment promotion is implemented - if (buffer == null) { - throw "unreachable"; - } - // Return a view of the buffer, so it has the requested length. - return Uint8List.view(buffer.buffer, buffer.offsetInBytes, bufferLength); - } -} - -abstract class _Base64EncoderSink extends ByteConversionSinkBase { - void add(List source) { - _add(source, 0, source.length, false); - } - - void close() { - _add(const [], 0, 0, true); - } - - void addSlice(List source, int start, int end, bool isLast) { - if (end == null) throw ArgumentError.notNull("end"); - RangeError.checkValidRange(start, end, source.length); - _add(source, start, end, isLast); - } - - void _add(List source, int start, int end, bool isLast); -} - -class _AsciiBase64EncoderSink extends _Base64EncoderSink { - final Sink _sink; - final _Base64Encoder _encoder; - - _AsciiBase64EncoderSink(this._sink, bool urlSafe) - : _encoder = _BufferCachingBase64Encoder(urlSafe); - - void _add(List source, int start, int end, bool isLast) { - var buffer = _encoder.encode(source, start, end, isLast); - if (buffer != null) { - var string = String.fromCharCodes(buffer); - _sink.add(string); - } - if (isLast) { - _sink.close(); - } - } -} - -class _Utf8Base64EncoderSink extends _Base64EncoderSink { - final ByteConversionSink _sink; - final _Base64Encoder _encoder; - - _Utf8Base64EncoderSink(this._sink, bool urlSafe) - : _encoder = _Base64Encoder(urlSafe); - - void _add(List source, int start, int end, bool isLast) { - var buffer = _encoder.encode(source, start, end, isLast); - if (buffer != null) { - _sink.addSlice(buffer, 0, buffer.length, isLast); - } - } -} - -// ------------------------------------------------------------------------ -// Decoder -// ------------------------------------------------------------------------ - -/// Decoder for base64 encoded data. -/// -/// This decoder accepts both base64 and base64url ("url-safe") encodings. -/// -/// The encoding is required to be properly padded. -class Base64Decoder extends Converter> { - const Base64Decoder(); - - /// Decodes the characters of [input] from [start] to [end] as base64. - /// - /// If [start] is omitted, it defaults to the start of [input]. - /// If [end] is omitted, it defaults to the end of [input]. - /// - /// The returned [Uint8List] contains exactly the decoded bytes, - /// so the [Uint8List.length] is precisely the number of decoded bytes. - /// The [Uint8List.buffer] may be larger than the decoded bytes. - Uint8List convert(String input, [int start = 0, int? end]) { - end = RangeError.checkValidRange(start, end, input.length); - // TODO(38725): Remove workaround when assignment promotion is implemented - if (end == null) { - throw RangeError("Invalid range"); - } - if (start == end) return Uint8List(0); - var decoder = _Base64Decoder(); - var buffer = decoder.decode(input, start, end)!; - decoder.close(input, end); - return buffer; - } - - StringConversionSink startChunkedConversion(Sink> sink) { - return _Base64DecoderSink(sink); - } -} - -/// Helper class implementing base64 decoding with intermediate state. -class _Base64Decoder { - /// Shift-count to extract the values stored in [_state]. - static const int _valueShift = 2; - - /// Mask to extract the count value stored in [_state]. - static const int _countMask = 3; - - /// Invalid character in decoding table. - static const int _invalid = -2; - - /// Padding character in decoding table. - static const int _padding = -1; - - // Shorthands to make the table more readable. - static const int __ = _invalid; - static const int _p = _padding; - - /// Mapping from ASCII characters to their index in the base64 alphabet. - /// - /// Uses [_invalid] for invalid indices and [_padding] for the padding - /// character. - /// - /// Accepts the "URL-safe" alphabet as well (`-` and `_` are the - /// 62nd and 63rd alphabet characters), and considers `%` a padding - /// character, which must then be followed by `3D`, the percent-escape - /// for `=`. - static final List _inverseAlphabet = Int8List.fromList([ - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // - __, __, __, __, __, _p, __, __, __, __, __, 62, __, 62, __, 63, // - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, __, __, __, _p, __, __, // - __, 00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, // - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, __, __, __, __, 63, // - __, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, // - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, __, __, __, __, __, // - ]); - - // Character constants. - static const int _char_percent = 0x25; // '%'. - static const int _char_3 = 0x33; // '3'. - static const int _char_d = 0x64; // 'd'. - - /// Maintains the intermediate state of a partly-decoded input. - /// - /// Base64 is decoded in chunks of four characters. If a chunk does not - /// contain a full block, the decoded bits (six per character) of the - /// available characters are stored in [_state] until the next call to - /// [_decode] or [_close]. - /// - /// If no padding has been seen, the value is - /// `numberOfCharactersSeen | (decodedBits << 2)` - /// where `numberOfCharactersSeen` is between 0 and 3 and decoded bits - /// contains six bits per seen character. - /// - /// If padding has been seen the value is negative. It's the bitwise negation - /// of the number of remaining allowed padding characters (always ~0 or ~1). - /// - /// A state of `0` or `~0` are valid places to end decoding, all other values - /// mean that a four-character block has not been completed. - int _state = 0; - - /// Encodes [count] and [bits] as a value to be stored in [_state]. - static int _encodeCharacterState(int count, int bits) { - assert(count == (count & _countMask)); - return (bits << _valueShift | count); - } - - /// Extracts count from a [_state] value. - static int _stateCount(int state) { - assert(state >= 0); - return state & _countMask; - } - - /// Extracts value bits from a [_state] value. - static int _stateBits(int state) { - assert(state >= 0); - return state >> _valueShift; - } - - /// Encodes a number of expected padding characters to be stored in [_state]. - static int _encodePaddingState(int expectedPadding) { - assert(expectedPadding >= 0); - assert(expectedPadding <= 5); - return -expectedPadding - 1; // ~expectedPadding adapted to dart2js. - } - - /// Extracts expected padding character count from a [_state] value. - static int _statePadding(int state) { - assert(state < 0); - return -state - 1; // ~state adapted to dart2js. - } - - static bool _hasSeenPadding(int state) => state < 0; - - /// Decodes [input] from [start] to [end]. - /// - /// Returns a [Uint8List] with the decoded bytes. - /// If a previous call had an incomplete four-character block, the bits from - /// those are included in decoding - Uint8List? decode(String input, int start, int end) { - assert(0 <= start); - assert(start <= end); - assert(end <= input.length); - if (_hasSeenPadding(_state)) { - _state = _checkPadding(input, start, end, _state); - return null; - } - if (start == end) return Uint8List(0); - var buffer = _allocateBuffer(input, start, end, _state); - _state = decodeChunk(input, start, end, buffer, 0, _state); - return buffer; - } - - /// Checks that [_state] represents a valid decoding. - void close(String? input, int? end) { - if (_state < _encodePaddingState(0)) { - throw FormatException("Missing padding character", input, end); - } - if (_state > 0) { - throw FormatException( - "Invalid length, must be multiple of four", input, end); - } - _state = _encodePaddingState(0); - } - - /// Decodes [input] from [start] to [end]. - /// - /// Includes the state returned by a previous call in the decoding. - /// Writes the decoding to [output] at [outIndex], and there must - /// be room in the output. - static int decodeChunk(String input, int start, int end, Uint8List output, - int outIndex, int state) { - assert(!_hasSeenPadding(state)); - const asciiMask = 127; - const asciiMax = 127; - const eightBitMask = 0xFF; - const bitsPerCharacter = 6; - - var bits = _stateBits(state); - var count = _stateCount(state); - // String contents should be all ASCII. - // Instead of checking for each character, we collect the bitwise-or of - // all the characters in `charOr` and later validate that all characters - // were ASCII. - var charOr = 0; - final inverseAlphabet = _Base64Decoder._inverseAlphabet; - for (var i = start; i < end; i++) { - var char = input.codeUnitAt(i); - charOr |= char; - var code = inverseAlphabet[char & asciiMask]; - if (code >= 0) { - bits = ((bits << bitsPerCharacter) | code) & 0xFFFFFF; - count = (count + 1) & 3; - if (count == 0) { - assert(outIndex + 3 <= output.length); - output[outIndex++] = (bits >> 16) & eightBitMask; - output[outIndex++] = (bits >> 8) & eightBitMask; - output[outIndex++] = bits & eightBitMask; - bits = 0; - } - continue; - } else if (code == _padding && count > 1) { - if (charOr < 0 || charOr > asciiMax) break; - if (count == 3) { - if ((bits & 0x03) != 0) { - throw FormatException("Invalid encoding before padding", input, i); - } - output[outIndex++] = bits >> 10; - output[outIndex++] = bits >> 2; - } else { - if ((bits & 0x0F) != 0) { - throw FormatException("Invalid encoding before padding", input, i); - } - output[outIndex++] = bits >> 4; - } - // Expected padding is the number of expected padding characters, - // where `=` counts as three and `%3D` counts as one per character. - // - // Expect either zero or one padding depending on count (2 or 3), - // plus two more characters if the code was `%` (a partial padding). - var expectedPadding = (3 - count) * 3; - if (char == _char_percent) expectedPadding += 2; - state = _encodePaddingState(expectedPadding); - return _checkPadding(input, i + 1, end, state); - } - throw FormatException("Invalid character", input, i); - } - if (charOr >= 0 && charOr <= asciiMax) { - return _encodeCharacterState(count, bits); - } - // There is an invalid (non-ASCII) character in the input. - int i; - for (i = start; i < end; i++) { - var char = input.codeUnitAt(i); - if (char < 0 || char > asciiMax) break; - } - throw FormatException("Invalid character", input, i); - } - - static Uint8List _emptyBuffer = Uint8List(0); - - /// Allocates a buffer with room for the decoding of a substring of [input]. - /// - /// Includes room for the characters in [state], and handles padding correctly. - static Uint8List _allocateBuffer( - String input, int start, int end, int state) { - assert(state >= 0); - var paddingStart = _trimPaddingChars(input, start, end); - var length = _stateCount(state) + (paddingStart - start); - // Three bytes per full four bytes in the input. - var bufferLength = (length >> 2) * 3; - // If padding was seen, then this is the last chunk, and the final partial - // chunk should be decoded too. - var remainderLength = length & 3; - if (remainderLength != 0 && paddingStart < end) { - bufferLength += remainderLength - 1; - } - if (bufferLength > 0) return Uint8List(bufferLength); - // If the input plus state is less than four characters, and it's not - // at the end of input, no buffer is needed. - return _emptyBuffer; - } - - /// Returns the position of the start of padding at the end of the input. - /// - /// Returns the end of input if there is no padding. - /// - /// This is used to ensure that the decoding buffer has the exact size - /// it needs when input is valid, and at least enough bytes to reach the error - /// when input is invalid. - /// - /// Never count more than two padding sequences since any more than that - /// will raise an error anyway, and we only care about being precise for - /// successful conversions. - static int _trimPaddingChars(String input, int start, int end) { - // This may count '%=' as two paddings. That's ok, it will err later, - // but the buffer will be large enough to reach the error. - var padding = 0; - var index = end; - var newEnd = end; - while (index > start && padding < 2) { - index--; - var char = input.codeUnitAt(index); - if (char == _paddingChar) { - padding++; - newEnd = index; - continue; - } - if ((char | 0x20) == _char_d) { - if (index == start) break; - index--; - char = input.codeUnitAt(index); - } - if (char == _char_3) { - if (index == start) break; - index--; - char = input.codeUnitAt(index); - } - if (char == _char_percent) { - padding++; - newEnd = index; - continue; - } - break; - } - return newEnd; - } - - /// Check that the remainder of the string is valid padding. - /// - /// Valid padding is a correct number (0, 1 or 2) of `=` characters - /// or `%3D` sequences depending on the number of preceding base64 characters. - /// The [state] parameter encodes which padding continuations are allowed - /// as the number of expected characters. That number is the number of - /// expected padding characters times 3 minus the number of padding characters - /// seen so far, where `=` counts as 3 counts as three characters, - /// and the padding sequence `%3D` counts as one character per character. - /// - /// The number of missing characters is always between 0 and 5 because we - /// only call this function after having seen at least one `=` or `%` - /// character. - /// If the number of missing characters is not 3 or 0, we have seen (at least) - /// a `%` character and expects the rest of the `%3D` sequence, and a `=` is - /// not allowed. When missing 3 characters, either `=` or `%` is allowed. - /// - /// When the value is 0, no more padding (or any other character) is allowed. - static int _checkPadding(String input, int start, int end, int state) { - assert(_hasSeenPadding(state)); - if (start == end) return state; - var expectedPadding = _statePadding(state); - assert(expectedPadding >= 0); - assert(expectedPadding < 6); - while (expectedPadding > 0) { - var char = input.codeUnitAt(start); - if (expectedPadding == 3) { - if (char == _paddingChar) { - expectedPadding -= 3; - start++; - break; - } - if (char == _char_percent) { - expectedPadding--; - start++; - if (start == end) break; - char = input.codeUnitAt(start); - } else { - break; - } - } - // Partial padding means we have seen part of a "%3D" escape. - var expectedPartialPadding = expectedPadding; - if (expectedPartialPadding > 3) expectedPartialPadding -= 3; - if (expectedPartialPadding == 2) { - // Expects '3' - if (char != _char_3) break; - start++; - expectedPadding--; - if (start == end) break; - char = input.codeUnitAt(start); - } - // Expects 'D' or 'd'. - if ((char | 0x20) != _char_d) break; - start++; - expectedPadding--; - if (start == end) break; - } - if (start != end) { - throw FormatException("Invalid padding character", input, start); - } - return _encodePaddingState(expectedPadding); - } -} - -class _Base64DecoderSink extends StringConversionSinkBase { - /// Output sink - final Sink> _sink; - final _Base64Decoder _decoder = _Base64Decoder(); - - _Base64DecoderSink(this._sink); - - void add(String string) { - if (string.isEmpty) return; - var buffer = _decoder.decode(string, 0, string.length); - if (buffer != null) _sink.add(buffer); - } - - void close() { - _decoder.close(null, null); - _sink.close(); - } - - void addSlice(String string, int start, int end, bool isLast) { - RangeError.checkValidRange(start, end, string.length); - if (start == end) return; - var buffer = _decoder.decode(string, start, end); - if (buffer != null) _sink.add(buffer); - if (isLast) { - _decoder.close(string, end); - _sink.close(); - } - } -} diff --git a/sdk_nnbd/lib/convert/byte_conversion.dart b/sdk_nnbd/lib/convert/byte_conversion.dart deleted file mode 100644 index 3d52d78ee1c..00000000000 --- a/sdk_nnbd/lib/convert/byte_conversion.dart +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright (c) 2013, 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. - -part of dart.convert; - -/// The [ByteConversionSink] provides an interface for converters to -/// efficiently transmit byte data. -/// -/// Instead of limiting the interface to one non-chunked list of bytes it -/// accepts its input in chunks (themselves being lists of bytes). -/// -/// This abstract class will likely get more methods over time. Implementers are -/// urged to extend or mix in [ByteConversionSinkBase] to ensure that their -/// class covers the newly added methods. -abstract class ByteConversionSink extends ChunkedConversionSink> { - ByteConversionSink(); - factory ByteConversionSink.withCallback( - void callback(List accumulated)) = _ByteCallbackSink; - factory ByteConversionSink.from(Sink> sink) = _ByteAdapterSink; - - /// Adds the next [chunk] to `this`. - /// - /// Adds the bytes defined by [start] and [end]-exclusive to `this`. - /// - /// If [isLast] is `true` closes `this`. - /// - /// Contrary to `add` the given [chunk] must not be held onto. Once the method - /// returns, it is safe to overwrite the data in it. - void addSlice(List chunk, int start, int end, bool isLast); - - // TODO(floitsch): add more methods: - // - iterateBytes. -} - -/// This class provides a base-class for converters that need to accept byte -/// inputs. -abstract class ByteConversionSinkBase extends ByteConversionSink { - void add(List chunk); - void close(); - - void addSlice(List chunk, int start, int end, bool isLast) { - add(chunk.sublist(start, end)); - if (isLast) close(); - } -} - -/// This class adapts a simple [Sink] to a [ByteConversionSink]. -/// -/// All additional methods of the [ByteConversionSink] (compared to the -/// ChunkedConversionSink) are redirected to the `add` method. -class _ByteAdapterSink extends ByteConversionSinkBase { - final Sink> _sink; - - _ByteAdapterSink(this._sink); - - void add(List chunk) { - _sink.add(chunk); - } - - void close() { - _sink.close(); - } -} - -/// This class accumulates all chunks into one list of bytes -/// and invokes a callback when the sink is closed. -/// -/// This class can be used to terminate a chunked conversion. -class _ByteCallbackSink extends ByteConversionSinkBase { - static const _INITIAL_BUFFER_SIZE = 1024; - - final void Function(List) _callback; - List _buffer = Uint8List(_INITIAL_BUFFER_SIZE); - int _bufferIndex = 0; - - _ByteCallbackSink(void callback(List accumulated)) - : _callback = callback; - - void add(Iterable chunk) { - var freeCount = _buffer.length - _bufferIndex; - if (chunk.length > freeCount) { - // Grow the buffer. - var oldLength = _buffer.length; - var newLength = _roundToPowerOf2(chunk.length + oldLength) * 2; - var grown = Uint8List(newLength); - grown.setRange(0, _buffer.length, _buffer); - _buffer = grown; - } - _buffer.setRange(_bufferIndex, _bufferIndex + chunk.length, chunk); - _bufferIndex += chunk.length; - } - - static int _roundToPowerOf2(int v) { - assert(v > 0); - v--; - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - v++; - return v; - } - - void close() { - _callback(_buffer.sublist(0, _bufferIndex)); - } -} diff --git a/sdk_nnbd/lib/convert/chunked_conversion.dart b/sdk_nnbd/lib/convert/chunked_conversion.dart deleted file mode 100644 index d2c24f00f5a..00000000000 --- a/sdk_nnbd/lib/convert/chunked_conversion.dart +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (c) 2013, 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. - -part of dart.convert; - -/// A [ChunkedConversionSink] is used to transmit data more efficiently between -/// two converters during chunked conversions. -/// -/// The basic `ChunkedConversionSink` is just a [Sink], and converters should -/// work with a plain `Sink`, but may work more efficiently with certain -/// specialized types of `ChunkedConversionSink`. -/// -/// It is recommended that implementations of `ChunkedConversionSink` extend -/// this class, to inherit any further methods that may be added to the class. -abstract class ChunkedConversionSink implements Sink { - ChunkedConversionSink(); - factory ChunkedConversionSink.withCallback( - void callback(List accumulated)) = _SimpleCallbackSink; - - /// Adds chunked data to this sink. - /// - /// This method is also used when converters are used as [StreamTransformer]s. - void add(T chunk); - - /// Closes the sink. - /// - /// This signals the end of the chunked conversion. This method is called - /// when converters are used as [StreamTransformer]'s. - void close(); -} - -/// This class accumulates all chunks and invokes a callback with a list of -/// the chunks when the sink is closed. -/// -/// This class can be used to terminate a chunked conversion. -class _SimpleCallbackSink extends ChunkedConversionSink { - final void Function(List) _callback; - final List _accumulated = []; - - _SimpleCallbackSink(this._callback); - - void add(T chunk) { - _accumulated.add(chunk); - } - - void close() { - _callback(_accumulated); - } -} - -/// This class implements the logic for a chunked conversion as a -/// stream transformer. -/// -/// It is used as strategy in the [EventTransformStream]. -/// -/// It also implements the [ChunkedConversionSink] interface so that it -/// can be used as output sink in a chunked conversion. -class _ConverterStreamEventSink implements EventSink { - /// The output sink for the converter. - final EventSink _eventSink; - - /// The input sink for new data. All data that is received with - /// [handleData] is added into this sink. - final Sink _chunkedSink; - - _ConverterStreamEventSink(Converter converter, EventSink sink) - : _eventSink = sink, - _chunkedSink = converter.startChunkedConversion(sink); - - void add(S o) { - _chunkedSink.add(o); - } - - void addError(Object error, [StackTrace? stackTrace]) { - // TODO(40614): Remove once non-nullability is sound. - ArgumentError.checkNotNull(error, "error"); - _eventSink.addError(error, stackTrace); - } - - void close() { - _chunkedSink.close(); - } -} diff --git a/sdk_nnbd/lib/convert/codec.dart b/sdk_nnbd/lib/convert/codec.dart deleted file mode 100644 index 38e4a3c32aa..00000000000 --- a/sdk_nnbd/lib/convert/codec.dart +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (c) 2013, 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. - -part of dart.convert; - -/// A [Codec] encodes and (if supported) decodes data. -/// -/// Codecs can be fused. For example fusing [json] and [utf8] produces -/// an encoder that can convert Json objects directly to bytes, or can decode -/// bytes directly to json objects. -/// -/// Fused codecs generally attempt to optimize the operations and can be faster -/// than executing each step of an encoding separately. -abstract class Codec { - const Codec(); - - /// Encodes [input]. - /// - /// The input is encoded as if by `encoder.convert`. - T encode(S input) => encoder.convert(input); - - /// Decodes [encoded] data. - /// - /// The input is decoded as if by `decoder.convert`. - S decode(T encoded) => decoder.convert(encoded); - - /// Returns the encoder from [S] to [T]. - /// - /// It may be stateful and should not be reused. - Converter get encoder; - - /// Returns the decoder of `this`, converting from [T] to [S]. - /// - /// It may be stateful and should not be reused. - Converter get decoder; - - /// Fuses `this` with `other`. - /// - /// When encoding, the resulting codec encodes with `this` before - /// encoding with [other]. - /// - /// When decoding, the resulting codec decodes with [other] before decoding - /// with `this`. - /// - /// In some cases one needs to use the [inverted] codecs to be able to fuse - /// them correctly. That is, the output type of `this` ([T]) must match the - /// input type of the second codec [other]. - /// - /// Examples: - /// ```dart - /// final jsonToBytes = json.fuse(utf8); - /// List bytes = jsonToBytes.encode(["json-object"]); - /// var decoded = jsonToBytes.decode(bytes); - /// assert(decoded is List && decoded[0] == "json-object"); - /// - /// var inverted = json.inverted; - /// var jsonIdentity = json.fuse(inverted); - /// var jsonObject = jsonIdentity.encode(["1", 2]); - /// assert(jsonObject is List && jsonObject[0] == "1" && jsonObject[1] == 2); - /// ``` - // TODO(floitsch): use better example with line-splitter once that one is - // in this library. - Codec fuse(Codec other) { - return _FusedCodec(this, other); - } - - /// Inverts `this`. - /// - /// The [encoder] and [decoder] of the resulting codec are swapped. - Codec get inverted => _InvertedCodec(this); -} - -/// Fuses the given codecs. -/// -/// In the non-chunked conversion simply invokes the non-chunked conversions in -/// sequence. -class _FusedCodec extends Codec { - final Codec _first; - final Codec _second; - - Converter get encoder => _first.encoder.fuse(_second.encoder); - Converter get decoder => _second.decoder.fuse(_first.decoder); - - _FusedCodec(this._first, this._second); -} - -class _InvertedCodec extends Codec { - final Codec _codec; - - _InvertedCodec(Codec codec) : _codec = codec; - - Converter get encoder => _codec.decoder; - Converter get decoder => _codec.encoder; - - Codec get inverted => _codec; -} diff --git a/sdk_nnbd/lib/convert/convert.dart b/sdk_nnbd/lib/convert/convert.dart deleted file mode 100644 index 61737822b68..00000000000 --- a/sdk_nnbd/lib/convert/convert.dart +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) 2013, 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. - -/// -/// Encoders and decoders for converting between different data representations, -/// including JSON and UTF-8. -/// -/// In addition to converters for common data representations, this library -/// provides support for implementing converters in a way which makes them easy to -/// chain and to use with streams. -/// -/// To use this library in your code: -/// -/// import 'dart:convert'; -/// -/// Two commonly used converters are the top-level instances of -/// [JsonCodec] and [Utf8Codec], named [json] and [utf8], respectively. -/// -/// JSON is a simple text format for representing -/// structured objects and collections. -/// The JSON encoder/decoder transforms between strings and -/// object structures, such as lists and maps, using the JSON format. -/// -/// UTF-8 is a common variable-width encoding that can represent -/// every character in the Unicode character set. -/// The UTF-8 encoder/decoder transforms between Strings and bytes. -/// -/// Converters are often used with streams -/// to transform the data that comes through the stream -/// as it becomes available. -/// The following code uses two converters. -/// The first is a UTF-8 decoder, which converts the data from bytes to UTF-8 -/// as it's read from a file, -/// The second is an instance of [LineSplitter], -/// which splits the data on newline boundaries. -/// -/// var lineNumber = 1; -/// var stream = File('quotes.txt').openRead(); -/// -/// stream.transform(utf8.decoder) -/// .transform(const LineSplitter()) -/// .listen((line) { -/// if (showLineNumbers) { -/// stdout.write('${lineNumber++} '); -/// } -/// stdout.writeln(line); -/// }); -/// -/// See the documentation for the [Codec] and [Converter] classes -/// for information about creating your own converters. -/// -/// {@category Core} -library dart.convert; - -import 'dart:async'; -import 'dart:typed_data'; -import 'dart:_internal' show CastConverter, parseHexByte; - -part 'ascii.dart'; -part 'base64.dart'; -part 'byte_conversion.dart'; -part 'chunked_conversion.dart'; -part 'codec.dart'; -part 'converter.dart'; -part 'encoding.dart'; -part 'html_escape.dart'; -part 'json.dart'; -part 'latin1.dart'; -part 'line_splitter.dart'; -part 'string_conversion.dart'; -part 'utf.dart'; diff --git a/sdk_nnbd/lib/convert/convert_sources.gni b/sdk_nnbd/lib/convert/convert_sources.gni deleted file mode 100644 index ad7964978e6..00000000000 --- a/sdk_nnbd/lib/convert/convert_sources.gni +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright (c) 2017, 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. - -# This file contains all sources for the dart:convert library. -convert_sdk_sources = [ - "convert.dart", - - # The above file needs to be first as it lists the parts below. - "ascii.dart", - "base64.dart", - "byte_conversion.dart", - "chunked_conversion.dart", - "codec.dart", - "converter.dart", - "encoding.dart", - "html_escape.dart", - "json.dart", - "latin1.dart", - "line_splitter.dart", - "string_conversion.dart", - "utf.dart", -] diff --git a/sdk_nnbd/lib/convert/converter.dart b/sdk_nnbd/lib/convert/converter.dart deleted file mode 100644 index 21679333660..00000000000 --- a/sdk_nnbd/lib/convert/converter.dart +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) 2013, 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. - -part of dart.convert; - -/// A [Converter] converts data from one representation into another. -/// -/// It is recommended that implementations of `Converter` extend this class, -/// to inherit any further methods that may be added to the class. -abstract class Converter extends StreamTransformerBase { - const Converter(); - - /// Adapts [source] to be a `Converter`. - /// - /// This allows [source] to be used at the new type, but at run-time it - /// must satisfy the requirements of both the new type and its original type. - /// - /// Conversion input must be both [SS] and [TS] and the output created by - /// [source] for those input must be both [ST] and [TT]. - static Converter castFrom(Converter source) => - CastConverter(source); - - /// Converts [input] and returns the result of the conversion. - T convert(S input); - - /// Fuses `this` with [other]. - /// - /// Encoding with the resulting converter is equivalent to converting with - /// `this` before converting with `other`. - Converter fuse(Converter other) { - return _FusedConverter(this, other); - } - - /// Starts a chunked conversion. - /// - /// The returned sink serves as input for the long-running conversion. The - /// given [sink] serves as output. - Sink startChunkedConversion(Sink sink) { - throw UnsupportedError( - "This converter does not support chunked conversions: $this"); - } - - Stream bind(Stream stream) { - return Stream.eventTransformed( - stream, (EventSink sink) => _ConverterStreamEventSink(this, sink)); - } - - /// Provides a `Converter` view of this stream transformer. - /// - /// The resulting transformer will check at run-time that all conversion - /// inputs are actually instances of [S], - /// and it will check that all conversion output produced by this converter - /// are actually instances of [RT]. - Converter cast() => Converter.castFrom(this); -} - -/// Fuses two converters. -/// -/// For a non-chunked conversion converts the input in sequence. -class _FusedConverter extends Converter { - final Converter _first; - final Converter _second; - - _FusedConverter(this._first, this._second); - - T convert(S input) => _second.convert(_first.convert(input)); - - Sink startChunkedConversion(Sink sink) { - return _first.startChunkedConversion(_second.startChunkedConversion(sink)); - } -} diff --git a/sdk_nnbd/lib/convert/encoding.dart b/sdk_nnbd/lib/convert/encoding.dart deleted file mode 100644 index b9238a8d67b..00000000000 --- a/sdk_nnbd/lib/convert/encoding.dart +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (c) 2013, 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. - -part of dart.convert; - -/// Open-ended Encoding enum. -abstract class Encoding extends Codec> { - const Encoding(); - - /// Returns the encoder from `String` to `List`. - /// - /// It may be stateful and should not be reused. - Converter> get encoder; - - /// Returns the decoder of `this`, converting from `List` to `String`. - /// - /// It may be stateful and should not be reused. - Converter, String> get decoder; - - Future decodeStream(Stream> byteStream) { - return decoder - .bind(byteStream) - .fold(StringBuffer(), - (StringBuffer buffer, String string) => buffer..write(string)) - .then((StringBuffer buffer) => buffer.toString()); - } - - /// Name of the encoding. - /// - /// If the encoding is standardized, this is the lower-case version of one of - /// the IANA official names for the character set (see - /// http://www.iana.org/assignments/character-sets/character-sets.xml) - String get name; - - // All aliases (in lowercase) of supported encoding from - // http://www.iana.org/assignments/character-sets/character-sets.xml. - static final Map _nameToEncoding = { - // ISO_8859-1:1987. - "iso_8859-1:1987": latin1, - "iso-ir-100": latin1, - "iso_8859-1": latin1, - "iso-8859-1": latin1, - "latin1": latin1, - "l1": latin1, - "ibm819": latin1, - "cp819": latin1, - "csisolatin1": latin1, - - // US-ASCII. - "iso-ir-6": ascii, - "ansi_x3.4-1968": ascii, - "ansi_x3.4-1986": ascii, - "iso_646.irv:1991": ascii, - "iso646-us": ascii, - "us-ascii": ascii, - "us": ascii, - "ibm367": ascii, - "cp367": ascii, - "csascii": ascii, - "ascii": ascii, // This is not in the IANA official names. - - // UTF-8. - "csutf8": utf8, - "utf-8": utf8 - }; - - /// Gets an [Encoding] object from the name of the character set - /// name. The names used are the IANA official names for the - /// character set (see - /// http://www.iana.org/assignments/character-sets/character-sets.xml). - /// - /// The [name] passed is case insensitive. - /// - /// If character set is not supported `null` is returned. - static Encoding? getByName(String? name) { - if (name == null) return null; - return _nameToEncoding[name.toLowerCase()]; - } -} diff --git a/sdk_nnbd/lib/convert/html_escape.dart b/sdk_nnbd/lib/convert/html_escape.dart deleted file mode 100644 index 317e6c194bc..00000000000 --- a/sdk_nnbd/lib/convert/html_escape.dart +++ /dev/null @@ -1,228 +0,0 @@ -// Copyright (c) 2013, 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. - -part of dart.convert; - -/// A `String` converter that converts characters to HTML entities. -/// -/// This is intended to sanitize text before inserting the text into an HTML -/// document. Characters that are meaningful in HTML are converted to -/// HTML entities (like `&` for `&`). -/// -/// The general converter escapes all characters that are meaningful in HTML -/// attributes or normal element context. Elements with special content types -/// (like CSS or JavaScript) may need a more specialized escaping that -/// understands that content type. -/// -/// If the context where the text will be inserted is known in more detail, -/// it's possible to omit escaping some characters (like quotes when not -/// inside an attribute value). -/// -/// The escaped text should only be used inside quoted HTML attributes values -/// or as text content of a normal element. Using the escaped text inside a -/// tag, but not inside a quoted attribute value, is still dangerous. -const HtmlEscape htmlEscape = HtmlEscape(); - -/// HTML escape modes. -/// -/// Allows specifying a mode for HTML escaping that depend on the context -/// where the escaped result is going to be used. -/// The relevant contexts are: -/// -/// * as text content of an HTML element. -/// * as value of a (single- or double-) quoted attribute value. -/// -/// All modes require escaping of `&` (ampersand) characters, and may -/// enable escaping of more characters. -/// -/// Custom escape modes can be created using the [HtmlEscapeMode.HtmlEscapeMode] -/// constructor. -class HtmlEscapeMode { - final String _name; - - /// Whether to escape '<' and '>'. - final bool escapeLtGt; - - /// Whether to escape '"' (quote). - final bool escapeQuot; - - /// Whether to escape "'" (apostrophe). - final bool escapeApos; - - /// Whether to escape "/" (forward slash, solidus). - /// - /// Escaping a slash is recommended to avoid cross-site scripting attacks by - /// [the Open Web Application Security Project](https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet#RULE_.231_-_HTML_Escape_Before_Inserting_Untrusted_Data_into_HTML_Element_Content) - final bool escapeSlash; - - /// Default escaping mode which escape all characters. - /// - /// The result of such an escaping is usable both in element content and - /// in any attribute value. - /// - /// The escaping only works for elements with normal HTML content, - /// and not for, for example, script or style element content, - /// which require escapes matching their particular content syntax. - static const HtmlEscapeMode unknown = - HtmlEscapeMode._('unknown', true, true, true, true); - - /// Escaping mode for text going into double-quoted HTML attribute values. - /// - /// The result should not be used as the content of an unquoted - /// or single-quoted attribute value. - /// - /// Escapes double quotes (`"`) but not single quotes (`'`), - /// and escapes `<` and `>` characters because they are not allowed - /// in strict XHTML attributes - static const HtmlEscapeMode attribute = - HtmlEscapeMode._('attribute', true, true, false, false); - - /// Escaping mode for text going into single-quoted HTML attribute values. - /// - /// The result should not be used as the content of an unquoted - /// or double-quoted attribute value. - /// - /// Escapes single quotes (`'`) but not double quotes (`"`), - /// and escapes `<` and `>` characters because they are not allowed - /// in strict XHTML attributes - static const HtmlEscapeMode sqAttribute = - HtmlEscapeMode._('attribute', true, false, true, false); - - /// Escaping mode for text going into HTML element content. - /// - /// The escaping only works for elements with normal HTML content, - /// and not for, for example, script or style element content, - /// which require escapes matching their particular content syntax. - /// - /// Escapes `<` and `>` characters. - static const HtmlEscapeMode element = - HtmlEscapeMode._('element', true, false, false, false); - - const HtmlEscapeMode._(this._name, this.escapeLtGt, this.escapeQuot, - this.escapeApos, this.escapeSlash); - - /// Create a custom escaping mode. - /// - /// All modes escape `&`. - /// The mode can further be set to escape `<` and `>` ([escapeLtGt]), - /// `"` ([escapeQuot]), `'` ([escapeApos]), and/or `/` ([escapeSlash]). - const HtmlEscapeMode( - {String name = "custom", - this.escapeLtGt = false, - this.escapeQuot = false, - this.escapeApos = false, - this.escapeSlash = false}) - : _name = name; - - String toString() => _name; -} - -/// Converter which escapes characters with special meaning in HTML. -/// -/// The converter finds characters that are significant in HTML source and -/// replaces them with corresponding HTML entities. -/// -/// The characters that need escaping in HTML are: -/// -/// * `&` (ampersand) always need to be escaped. -/// * `<` (less than) and '>' (greater than) when inside an element. -/// * `"` (quote) when inside a double-quoted attribute value. -/// * `'` (apostrophe) when inside a single-quoted attribute value. -/// Apostrophe is escaped as `'` instead of `'` since -/// not all browsers understand `'`. -/// * `/` (slash) is recommended to be escaped because it may be used -/// to terminate an element in some HTML dialects. -/// -/// Escaping `>` (greater than) isn't necessary, but the result is often -/// found to be easier to read if greater-than is also escaped whenever -/// less-than is. -class HtmlEscape extends Converter { - /// The [HtmlEscapeMode] used by the converter. - final HtmlEscapeMode mode; - - /// Create converter that escapes HTML characters. - /// - /// If [mode] is provided as either [HtmlEscapeMode.attribute] or - /// [HtmlEscapeMode.element], only the corresponding subset of HTML - /// characters are escaped. - /// The default is to escape all HTML characters. - const HtmlEscape([this.mode = HtmlEscapeMode.unknown]); - - String convert(String text) { - var val = _convert(text, 0, text.length); - return val == null ? text : val; - } - - /// Converts the substring of text from start to end. - /// - /// Returns `null` if no changes were necessary, otherwise returns - /// the converted string. - String? _convert(String text, int start, int end) { - StringBuffer? result; - for (var i = start; i < end; i++) { - var ch = text[i]; - String? replacement; - switch (ch) { - case '&': - replacement = '&'; - break; - case '"': - if (mode.escapeQuot) replacement = '"'; - break; - case "'": - if (mode.escapeApos) replacement = '''; - break; - case '<': - if (mode.escapeLtGt) replacement = '<'; - break; - case '>': - if (mode.escapeLtGt) replacement = '>'; - break; - case '/': - if (mode.escapeSlash) replacement = '/'; - break; - } - if (replacement != null) { - result ??= StringBuffer(); - // TODO(38725): Remove workaround when assignment promotion is - // implemented - if (result == null) { - throw "unreachable"; - } - if (i > start) result.write(text.substring(start, i)); - result.write(replacement); - start = i + 1; - } - } - if (result == null) return null; - if (end > start) result.write(text.substring(start, end)); - return result.toString(); - } - - StringConversionSink startChunkedConversion(Sink sink) { - return _HtmlEscapeSink(this, - sink is StringConversionSink ? sink : StringConversionSink.from(sink)); - } -} - -class _HtmlEscapeSink extends StringConversionSinkBase { - final HtmlEscape _escape; - final StringConversionSink _sink; - - _HtmlEscapeSink(this._escape, this._sink); - - void addSlice(String chunk, int start, int end, bool isLast) { - var val = _escape._convert(chunk, start, end); - if (val == null) { - _sink.addSlice(chunk, start, end, isLast); - } else { - _sink.add(val); - if (isLast) _sink.close(); - } - } - - void close() { - _sink.close(); - } -} diff --git a/sdk_nnbd/lib/convert/json.dart b/sdk_nnbd/lib/convert/json.dart deleted file mode 100644 index 6d897a09416..00000000000 --- a/sdk_nnbd/lib/convert/json.dart +++ /dev/null @@ -1,1088 +0,0 @@ -// Copyright (c) 2013, 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. - -part of dart.convert; - -/// Error thrown by JSON serialization if an object cannot be serialized. -/// -/// The [unsupportedObject] field holds that object that failed to be serialized. -/// -/// If an object isn't directly serializable, the serializer calls the `toJson` -/// method on the object. If that call fails, the error will be stored in the -/// [cause] field. If the call returns an object that isn't directly -/// serializable, the [cause] is null. -class JsonUnsupportedObjectError extends Error { - /// The object that could not be serialized. - final Object? unsupportedObject; - - /// The exception thrown when trying to convert the object. - final Object? cause; - - /// The partial result of the conversion, up until the error happened. - /// - /// May be null. - final String? partialResult; - - JsonUnsupportedObjectError(this.unsupportedObject, - {this.cause, this.partialResult}); - - String toString() { - var safeString = Error.safeToString(unsupportedObject); - String prefix; - if (cause != null) { - prefix = "Converting object to an encodable object failed:"; - } else { - prefix = "Converting object did not return an encodable object:"; - } - return "$prefix $safeString"; - } -} - -/// Reports that an object could not be stringified due to cyclic references. -/// -/// An object that references itself cannot be serialized by -/// [JsonCodec.encode]/[JsonEncoder.convert]. -/// When the cycle is detected, a [JsonCyclicError] is thrown. -class JsonCyclicError extends JsonUnsupportedObjectError { - /// The first object that was detected as part of a cycle. - JsonCyclicError(Object? object) : super(object); - String toString() => "Cyclic error in JSON stringify"; -} - -/// An instance of the default implementation of the [JsonCodec]. -/// -/// This instance provides a convenient access to the most common JSON -/// use cases. -/// -/// Examples: -/// -/// var encoded = json.encode([1, 2, { "a": null }]); -/// var decoded = json.decode('["foo", { "bar": 499 }]'); -/// -/// The top-level [jsonEncode] and [jsonDecode] functions may be used instead if -/// a local variable shadows the [json] constant. -const JsonCodec json = JsonCodec(); - -/// Converts [value] to a JSON string. -/// -/// If value contains objects that are not directly encodable to a JSON -/// string (a value that is not a number, boolean, string, null, list or a map -/// with string keys), the [toEncodable] function is used to convert it to an -/// object that must be directly encodable. -/// -/// If [toEncodable] is omitted, it defaults to a function that returns the -/// result of calling `.toJson()` on the unencodable object. -/// -/// Shorthand for `json.encode`. Useful if a local variable shadows the global -/// [json] constant. -String jsonEncode(Object? object, - {Object? toEncodable(Object? nonEncodable)?}) => - json.encode(object, toEncodable: toEncodable); - -/// Parses the string and returns the resulting Json object. -/// -/// The optional [reviver] function is called once for each object or list -/// property that has been parsed during decoding. The `key` argument is either -/// the integer list index for a list property, the string map key for object -/// properties, or `null` for the final result. -/// -/// The default [reviver] (when not provided) is the identity function. -/// -/// Shorthand for `json.decode`. Useful if a local variable shadows the global -/// [json] constant. -dynamic jsonDecode(String source, - {Object? reviver(Object? key, Object? value)?}) => - json.decode(source, reviver: reviver); - -/// A [JsonCodec] encodes JSON objects to strings and decodes strings to -/// JSON objects. -/// -/// Examples: -/// -/// var encoded = json.encode([1, 2, { "a": null }]); -/// var decoded = json.decode('["foo", { "bar": 499 }]'); -class JsonCodec extends Codec { - final Object? Function(Object? key, Object? value)? _reviver; - final Object? Function(dynamic)? _toEncodable; - - /// Creates a `JsonCodec` with the given reviver and encoding function. - /// - /// The [reviver] function is called during decoding. It is invoked once for - /// each object or list property that has been parsed. - /// The `key` argument is either the integer list index for a list property, - /// the string map key for object properties, or `null` for the final result. - /// - /// If [reviver] is omitted, it defaults to returning the value argument. - /// - /// The [toEncodable] function is used during encoding. It is invoked for - /// values that are not directly encodable to a string (a value that is not a - /// number, boolean, string, null, list or a map with string keys). The - /// function must return an object that is directly encodable. The elements of - /// a returned list and values of a returned map do not need to be directly - /// encodable, and if they aren't, `toEncodable` will be used on them as well. - /// Please notice that it is possible to cause an infinite recursive regress - /// in this way, by effectively creating an infinite data structure through - /// repeated call to `toEncodable`. - /// - /// If [toEncodable] is omitted, it defaults to a function that returns the - /// result of calling `.toJson()` on the unencodable object. - const JsonCodec( - {Object? reviver(Object? key, Object? value)?, - Object? toEncodable(dynamic object)?}) - : _reviver = reviver, - _toEncodable = toEncodable; - - /// Creates a `JsonCodec` with the given reviver. - /// - /// The [reviver] function is called once for each object or list property - /// that has been parsed during decoding. The `key` argument is either the - /// integer list index for a list property, the string map key for object - /// properties, or `null` for the final result. - JsonCodec.withReviver(dynamic reviver(Object? key, Object? value)) - : this(reviver: reviver); - - /// Parses the string and returns the resulting Json object. - /// - /// The optional [reviver] function is called once for each object or list - /// property that has been parsed during decoding. The `key` argument is either - /// the integer list index for a list property, the string map key for object - /// properties, or `null` for the final result. - /// - /// The default [reviver] (when not provided) is the identity function. - dynamic decode(String source, - {Object? reviver(Object? key, Object? value)?}) { - reviver ??= _reviver; - if (reviver == null) return decoder.convert(source); - return JsonDecoder(reviver).convert(source); - } - - /// Converts [value] to a JSON string. - /// - /// If value contains objects that are not directly encodable to a JSON - /// string (a value that is not a number, boolean, string, null, list or a map - /// with string keys), the [toEncodable] function is used to convert it to an - /// object that must be directly encodable. - /// - /// If [toEncodable] is omitted, it defaults to a function that returns the - /// result of calling `.toJson()` on the unencodable object. - String encode(Object? value, {Object? toEncodable(dynamic object)?}) { - toEncodable ??= _toEncodable; - if (toEncodable == null) return encoder.convert(value); - return JsonEncoder(toEncodable).convert(value); - } - - JsonEncoder get encoder { - if (_toEncodable == null) return const JsonEncoder(); - return JsonEncoder(_toEncodable); - } - - JsonDecoder get decoder { - if (_reviver == null) return const JsonDecoder(); - return JsonDecoder(_reviver); - } -} - -/// This class converts JSON objects to strings. -class JsonEncoder extends Converter { - /// The string used for indention. - /// - /// When generating multi-line output, this string is inserted once at the - /// beginning of each indented line for each level of indentation. - /// - /// If `null`, the output is encoded as a single line. - final String? indent; - - /// Function called on non-encodable objects to return a replacement - /// encodable object that will be encoded in the orignal's place. - final Object? Function(dynamic)? _toEncodable; - - /// Creates a JSON encoder. - /// - /// The JSON encoder handles numbers, strings, booleans, null, lists and - /// maps with string keys directly. - /// - /// Any other object is attempted converted by [toEncodable] to an - /// object that is of one of the convertible types. - /// - /// If [toEncodable] is omitted, it defaults to calling `.toJson()` on - /// the object. - const JsonEncoder([Object? toEncodable(dynamic object)?]) - : indent = null, - _toEncodable = toEncodable; - - /// Creates a JSON encoder that creates multi-line JSON. - /// - /// The encoding of elements of lists and maps are indented and put on separate - /// lines. The [indent] string is prepended to these elements, once for each - /// level of indentation. - /// - /// If [indent] is `null`, the output is encoded as a single line. - /// - /// The JSON encoder handles numbers, strings, booleans, null, lists and - /// maps with string keys directly. - /// - /// Any other object is attempted converted by [toEncodable] to an - /// object that is of one of the convertible types. - /// - /// If [toEncodable] is omitted, it defaults to calling `.toJson()` on - /// the object. - const JsonEncoder.withIndent(this.indent, - [Object? toEncodable(dynamic object)?]) - : _toEncodable = toEncodable; - - /// Converts [object] to a JSON [String]. - /// - /// Directly serializable values are [num], [String], [bool], and [Null], as - /// well as some [List] and [Map] values. For [List], the elements must all be - /// serializable. For [Map], the keys must be [String] and the values must be - /// serializable. - /// - /// If a value of any other type is attempted to be serialized, the - /// `toEncodable` function provided in the constructor is called with the value - /// as argument. The result, which must be a directly serializable value, is - /// serialized instead of the original value. - /// - /// If the conversion throws, or returns a value that is not directly - /// serializable, a [JsonUnsupportedObjectError] exception is thrown. - /// If the call throws, the error is caught and stored in the - /// [JsonUnsupportedObjectError]'s [:cause:] field. - /// - /// If a [List] or [Map] contains a reference to itself, directly or through - /// other lists or maps, it cannot be serialized and a [JsonCyclicError] is - /// thrown. - /// - /// [object] should not change during serialization. - /// - /// If an object is serialized more than once, [convert] may cache the text - /// for it. In other words, if the content of an object changes after it is - /// first serialized, the new values may not be reflected in the result. - String convert(Object? object) => - _JsonStringStringifier.stringify(object, _toEncodable, indent); - - /// Starts a chunked conversion. - /// - /// The converter works more efficiently if the given [sink] is a - /// [StringConversionSink]. - /// - /// Returns a chunked-conversion sink that accepts at most one object. It is - /// an error to invoke `add` more than once on the returned sink. - ChunkedConversionSink startChunkedConversion(Sink sink) { - if (sink is _Utf8EncoderSink) { - return _JsonUtf8EncoderSink( - sink._sink, - _toEncodable, - JsonUtf8Encoder._utf8Encode(indent), - JsonUtf8Encoder._defaultBufferSize); - } - return _JsonEncoderSink( - sink is StringConversionSink ? sink : StringConversionSink.from(sink), - _toEncodable, - indent); - } - - // Override the base class's bind, to provide a better type. - Stream bind(Stream stream) => super.bind(stream); - - Converter fuse(Converter other) { - if (other is Utf8Encoder) { - // The instance check guarantees that `T` is (a subtype of) List, - // but the static type system doesn't know that, and so we cast. - return JsonUtf8Encoder(indent, _toEncodable) as Converter; - } - return super.fuse(other); - } -} - -/// Encoder that encodes a single object as a UTF-8 encoded JSON string. -/// -/// This encoder works equivalently to first converting the object to -/// a JSON string, and then UTF-8 encoding the string, but without -/// creating an intermediate string. -class JsonUtf8Encoder extends Converter> { - /// Default buffer size used by the JSON-to-UTF-8 encoder. - static const int _defaultBufferSize = 256; - @deprecated - static const int DEFAULT_BUFFER_SIZE = _defaultBufferSize; - - /// Indentation used in pretty-print mode, `null` if not pretty. - final List? _indent; - - /// Function called with each un-encodable object encountered. - final Object? Function(dynamic)? _toEncodable; - - /// UTF-8 buffer size. - final int _bufferSize; - - /// Create converter. - /// - /// If [indent] is non-`null`, the converter attempts to "pretty-print" the - /// JSON, and uses `indent` as the indentation. Otherwise the result has no - /// whitespace outside of string literals. - /// If `indent` contains characters that are not valid JSON whitespace - /// characters, the result will not be valid JSON. JSON whitespace characters - /// are space (U+0020), tab (U+0009), line feed (U+000a) and carriage return - /// (U+000d) ([ECMA - /// 404](http://www.ecma-international.org/publications/standards/Ecma-404.htm)). - /// - /// The [bufferSize] is the size of the internal buffers used to collect - /// UTF-8 code units. - /// If using [startChunkedConversion], it will be the size of the chunks. - /// - /// The JSON encoder handles numbers, strings, booleans, null, lists and maps - /// directly. - /// - /// Any other object is attempted converted by [toEncodable] to an object that - /// is of one of the convertible types. - /// - /// If [toEncodable] is omitted, it defaults to calling `.toJson()` on the - /// object. - JsonUtf8Encoder( - [String? indent, dynamic toEncodable(dynamic object)?, int? bufferSize]) - : _indent = _utf8Encode(indent), - _toEncodable = toEncodable, - _bufferSize = bufferSize ?? _defaultBufferSize; - - static List? _utf8Encode(String? string) { - if (string == null) return null; - if (string.isEmpty) return Uint8List(0); - checkAscii: - { - for (var i = 0; i < string.length; i++) { - if (string.codeUnitAt(i) >= 0x80) break checkAscii; - } - return string.codeUnits; - } - return utf8.encode(string); - } - - /// Convert [object] into UTF-8 encoded JSON. - List convert(Object? object) { - var bytes = >[]; - // The `stringify` function always converts into chunks. - // Collect the chunks into the `bytes` list, then combine them afterwards. - void addChunk(Uint8List chunk, int start, int end) { - if (start > 0 || end < chunk.length) { - var length = end - start; - chunk = - Uint8List.view(chunk.buffer, chunk.offsetInBytes + start, length); - } - bytes.add(chunk); - } - - _JsonUtf8Stringifier.stringify( - object, _indent, _toEncodable, _bufferSize, addChunk); - if (bytes.length == 1) return bytes[0]; - var length = 0; - for (var i = 0; i < bytes.length; i++) { - length += bytes[i].length; - } - var result = Uint8List(length); - for (var i = 0, offset = 0; i < bytes.length; i++) { - var byteList = bytes[i]; - int end = offset + byteList.length; - result.setRange(offset, end, byteList); - offset = end; - } - return result; - } - - /// Start a chunked conversion. - /// - /// Only one object can be passed into the returned sink. - /// - /// The argument [sink] will receive byte lists in sizes depending on the - /// `bufferSize` passed to the constructor when creating this encoder. - ChunkedConversionSink startChunkedConversion(Sink> sink) { - ByteConversionSink byteSink; - if (sink is ByteConversionSink) { - byteSink = sink; - } else { - byteSink = ByteConversionSink.from(sink); - } - return _JsonUtf8EncoderSink(byteSink, _toEncodable, _indent, _bufferSize); - } - - // Override the base class's bind, to provide a better type. - Stream> bind(Stream stream) { - return super.bind(stream); - } -} - -/// Implements the chunked conversion from object to its JSON representation. -/// -/// The sink only accepts one value, but will produce output in a chunked way. -class _JsonEncoderSink extends ChunkedConversionSink { - final String? _indent; - final Object? Function(dynamic)? _toEncodable; - final StringConversionSink _sink; - bool _isDone = false; - - _JsonEncoderSink(this._sink, this._toEncodable, this._indent); - - /// Encodes the given object [o]. - /// - /// It is an error to invoke this method more than once on any instance. While - /// this makes the input effectively non-chunked the output will be generated - /// in a chunked way. - void add(Object? o) { - if (_isDone) { - throw StateError("Only one call to add allowed"); - } - _isDone = true; - var stringSink = _sink.asStringSink(); - _JsonStringStringifier.printOn(o, stringSink, _toEncodable, _indent); - stringSink.close(); - } - - void close() {/* do nothing */} -} - -/// Sink returned when starting a chunked conversion from object to bytes. -class _JsonUtf8EncoderSink extends ChunkedConversionSink { - /// The byte sink receiveing the encoded chunks. - final ByteConversionSink _sink; - final List? _indent; - final Object? Function(dynamic)? _toEncodable; - final int _bufferSize; - bool _isDone = false; - _JsonUtf8EncoderSink( - this._sink, this._toEncodable, this._indent, this._bufferSize); - - /// Callback called for each slice of result bytes. - void _addChunk(Uint8List chunk, int start, int end) { - _sink.addSlice(chunk, start, end, false); - } - - void add(Object? object) { - if (_isDone) { - throw StateError("Only one call to add allowed"); - } - _isDone = true; - _JsonUtf8Stringifier.stringify( - object, _indent, _toEncodable, _bufferSize, _addChunk); - _sink.close(); - } - - void close() { - if (!_isDone) { - _isDone = true; - _sink.close(); - } - } -} - -/// This class parses JSON strings and builds the corresponding objects. -/// -/// A JSON input must be the JSON encoding of a single JSON value, -/// which can be a list or map containing other values. -/// -/// When used as a [StreamTransformer], the input stream may emit -/// multiple strings. The concatenation of all of these strings must -/// be a valid JSON encoding of a single JSON value. -class JsonDecoder extends Converter { - final Object? Function(Object? key, Object? value)? _reviver; - - /// Constructs a new JsonDecoder. - /// - /// The [reviver] may be `null`. - const JsonDecoder([Object? reviver(Object? key, Object? value)?]) - : _reviver = reviver; - - /// Converts the given JSON-string [input] to its corresponding object. - /// - /// Parsed JSON values are of the types [num], [String], [bool], [Null], - /// [List]s of parsed JSON values or [Map]s from [String] to parsed JSON - /// values. - /// - /// If `this` was initialized with a reviver, then the parsing operation - /// invokes the reviver on every object or list property that has been parsed. - /// The arguments are the property name ([String]) or list index ([int]), and - /// the value is the parsed value. The return value of the reviver is used as - /// the value of that property instead the parsed value. - /// - /// Throws [FormatException] if the input is not valid JSON text. - dynamic convert(String input) => _parseJson(input, _reviver); - - /// Starts a conversion from a chunked JSON string to its corresponding object. - /// - /// The output [sink] receives exactly one decoded element through `add`. - external StringConversionSink startChunkedConversion(Sink sink); - - // Override the base class's bind, to provide a better type. - Stream bind(Stream stream) => super.bind(stream); -} - -// Internal optimized JSON parsing implementation. -external dynamic _parseJson(String source, reviver(key, value)?); - -// Implementation of encoder/stringifier. - -dynamic _defaultToEncodable(dynamic object) => object.toJson(); - -/// JSON encoder that traverses an object structure and writes JSON source. -/// -/// This is an abstract implementation that doesn't decide on the output -/// format, but writes the JSON through abstract methods like [writeString]. -abstract class _JsonStringifier { - // Character code constants. - static const int backspace = 0x08; - static const int tab = 0x09; - static const int newline = 0x0a; - static const int carriageReturn = 0x0d; - static const int formFeed = 0x0c; - static const int quote = 0x22; - static const int char_0 = 0x30; - static const int backslash = 0x5c; - static const int char_b = 0x62; - static const int char_d = 0x64; - static const int char_f = 0x66; - static const int char_n = 0x6e; - static const int char_r = 0x72; - static const int char_t = 0x74; - static const int char_u = 0x75; - static const int surrogateMin = 0xd800; - static const int surrogateMask = 0xfc00; - static const int surrogateLead = 0xd800; - static const int surrogateTrail = 0xdc00; - - /// List of objects currently being traversed. Used to detect cycles. - final List _seen = []; - - /// Function called for each un-encodable object encountered. - final Function(dynamic) _toEncodable; - - _JsonStringifier(dynamic toEncodable(dynamic o)?) - : _toEncodable = toEncodable ?? _defaultToEncodable; - - String? get _partialResult; - - /// Append a string to the JSON output. - void writeString(String characters); - - /// Append part of a string to the JSON output. - void writeStringSlice(String characters, int start, int end); - - /// Append a single character, given by its code point, to the JSON output. - void writeCharCode(int charCode); - - /// Write a number to the JSON output. - void writeNumber(num number); - - // ('0' + x) or ('a' + x - 10) - static int hexDigit(int x) => x < 10 ? 48 + x : 87 + x; - - /// Write, and suitably escape, a string's content as a JSON string literal. - void writeStringContent(String s) { - var offset = 0; - final length = s.length; - for (var i = 0; i < length; i++) { - var charCode = s.codeUnitAt(i); - if (charCode > backslash) { - if (charCode >= surrogateMin) { - // Possible surrogate. Check if it is unpaired. - if (((charCode & surrogateMask) == surrogateLead && - !(i + 1 < length && - (s.codeUnitAt(i + 1) & surrogateMask) == - surrogateTrail)) || - ((charCode & surrogateMask) == surrogateTrail && - !(i - 1 >= 0 && - (s.codeUnitAt(i - 1) & surrogateMask) == - surrogateLead))) { - // Lone surrogate. - if (i > offset) writeStringSlice(s, offset, i); - offset = i + 1; - writeCharCode(backslash); - writeCharCode(char_u); - writeCharCode(char_d); - writeCharCode(hexDigit((charCode >> 8) & 0xf)); - writeCharCode(hexDigit((charCode >> 4) & 0xf)); - writeCharCode(hexDigit(charCode & 0xf)); - } - } - continue; - } - if (charCode < 32) { - if (i > offset) writeStringSlice(s, offset, i); - offset = i + 1; - writeCharCode(backslash); - switch (charCode) { - case backspace: - writeCharCode(char_b); - break; - case tab: - writeCharCode(char_t); - break; - case newline: - writeCharCode(char_n); - break; - case formFeed: - writeCharCode(char_f); - break; - case carriageReturn: - writeCharCode(char_r); - break; - default: - writeCharCode(char_u); - writeCharCode(char_0); - writeCharCode(char_0); - writeCharCode(hexDigit((charCode >> 4) & 0xf)); - writeCharCode(hexDigit(charCode & 0xf)); - break; - } - } else if (charCode == quote || charCode == backslash) { - if (i > offset) writeStringSlice(s, offset, i); - offset = i + 1; - writeCharCode(backslash); - writeCharCode(charCode); - } - } - if (offset == 0) { - writeString(s); - } else if (offset < length) { - writeStringSlice(s, offset, length); - } - } - - /// Check if an encountered object is already being traversed. - /// - /// Records the object if it isn't already seen. Should have a matching call to - /// [_removeSeen] when the object is no longer being traversed. - void _checkCycle(Object? object) { - for (var i = 0; i < _seen.length; i++) { - if (identical(object, _seen[i])) { - throw JsonCyclicError(object); - } - } - _seen.add(object); - } - - /// Remove [object] from the list of currently traversed objects. - /// - /// Should be called in the opposite order of the matching [_checkCycle] - /// calls. - void _removeSeen(Object? object) { - assert(_seen.isNotEmpty); - assert(identical(_seen.last, object)); - _seen.removeLast(); - } - - /// Write an object. - /// - /// If [object] isn't directly encodable, the [_toEncodable] function gets one - /// chance to return a replacement which is encodable. - void writeObject(Object? object) { - // Tries stringifying object directly. If it's not a simple value, List or - // Map, call toJson() to get a custom representation and try serializing - // that. - if (writeJsonValue(object)) return; - _checkCycle(object); - try { - var customJson = _toEncodable(object); - if (!writeJsonValue(customJson)) { - throw JsonUnsupportedObjectError(object, partialResult: _partialResult); - } - _removeSeen(object); - } catch (e) { - throw JsonUnsupportedObjectError(object, - cause: e, partialResult: _partialResult); - } - } - - /// Serialize a [num], [String], [bool], [Null], [List] or [Map] value. - /// - /// Returns true if the value is one of these types, and false if not. - /// If a value is both a [List] and a [Map], it's serialized as a [List]. - bool writeJsonValue(Object? object) { - if (object is num) { - if (!object.isFinite) return false; - writeNumber(object); - return true; - } else if (identical(object, true)) { - writeString('true'); - return true; - } else if (identical(object, false)) { - writeString('false'); - return true; - } else if (object == null) { - writeString('null'); - return true; - } else if (object is String) { - writeString('"'); - writeStringContent(object); - writeString('"'); - return true; - } else if (object is List) { - _checkCycle(object); - writeList(object); - _removeSeen(object); - return true; - } else if (object is Map) { - _checkCycle(object); - // writeMap can fail if keys are not all strings. - var success = writeMap(object); - _removeSeen(object); - return success; - } else { - return false; - } - } - - /// Serialize a [List]. - void writeList(List list) { - writeString('['); - if (list.isNotEmpty) { - writeObject(list[0]); - for (var i = 1; i < list.length; i++) { - writeString(','); - writeObject(list[i]); - } - } - writeString(']'); - } - - /// Serialize a [Map]. - bool writeMap(Map map) { - if (map.isEmpty) { - writeString("{}"); - return true; - } - var keyValueList = List.filled(map.length * 2, null); - var i = 0; - var allStringKeys = true; - map.forEach((key, value) { - if (key is! String) { - allStringKeys = false; - } - keyValueList[i++] = key; - keyValueList[i++] = value; - }); - if (!allStringKeys) return false; - writeString('{'); - var separator = '"'; - for (var i = 0; i < keyValueList.length; i += 2) { - writeString(separator); - separator = ',"'; - writeStringContent(keyValueList[i] as String); - writeString('":'); - writeObject(keyValueList[i + 1]); - } - writeString('}'); - return true; - } -} - -/// A modification of [_JsonStringifier] which indents the contents of [List] and -/// [Map] objects using the specified indent value. -/// -/// Subclasses should implement [writeIndentation]. -abstract class _JsonPrettyPrintMixin implements _JsonStringifier { - int _indentLevel = 0; - - /// Add [indentLevel] indentations to the JSON output. - void writeIndentation(int indentLevel); - - void writeList(List list) { - if (list.isEmpty) { - writeString('[]'); - } else { - writeString('[\n'); - _indentLevel++; - writeIndentation(_indentLevel); - writeObject(list[0]); - for (var i = 1; i < list.length; i++) { - writeString(',\n'); - writeIndentation(_indentLevel); - writeObject(list[i]); - } - writeString('\n'); - _indentLevel--; - writeIndentation(_indentLevel); - writeString(']'); - } - } - - bool writeMap(Map map) { - if (map.isEmpty) { - writeString("{}"); - return true; - } - var keyValueList = List.filled(map.length * 2, null); - var i = 0; - var allStringKeys = true; - map.forEach((key, value) { - if (key is! String) { - allStringKeys = false; - } - keyValueList[i++] = key; - keyValueList[i++] = value; - }); - if (!allStringKeys) return false; - writeString('{\n'); - _indentLevel++; - var separator = ""; - for (var i = 0; i < keyValueList.length; i += 2) { - writeString(separator); - separator = ",\n"; - writeIndentation(_indentLevel); - writeString('"'); - writeStringContent(keyValueList[i] as String); - writeString('": '); - writeObject(keyValueList[i + 1]); - } - writeString('\n'); - _indentLevel--; - writeIndentation(_indentLevel); - writeString('}'); - return true; - } -} - -/// A specialization of [_JsonStringifier] that writes its JSON to a string. -class _JsonStringStringifier extends _JsonStringifier { - final StringSink _sink; - - _JsonStringStringifier( - this._sink, dynamic Function(dynamic object)? _toEncodable) - : super(_toEncodable); - - /// Convert object to a string. - /// - /// The [toEncodable] function is used to convert non-encodable objects - /// to encodable ones. - /// - /// If [indent] is not `null`, the resulting JSON will be "pretty-printed" - /// with newlines and indentation. The `indent` string is added as indentation - /// for each indentation level. It should only contain valid JSON whitespace - /// characters (space, tab, carriage return or line feed). - static String stringify( - Object? object, dynamic toEncodable(dynamic object)?, String? indent) { - var output = StringBuffer(); - printOn(object, output, toEncodable, indent); - return output.toString(); - } - - /// Convert object to a string, and write the result to the [output] sink. - /// - /// The result is written piecemally to the sink. - static void printOn(Object? object, StringSink output, - dynamic toEncodable(dynamic o)?, String? indent) { - _JsonStringifier stringifier; - if (indent == null) { - stringifier = _JsonStringStringifier(output, toEncodable); - } else { - stringifier = _JsonStringStringifierPretty(output, toEncodable, indent); - } - stringifier.writeObject(object); - } - - String? get _partialResult => _sink is StringBuffer ? _sink.toString() : null; - - void writeNumber(num number) { - _sink.write(number.toString()); - } - - void writeString(String string) { - _sink.write(string); - } - - void writeStringSlice(String string, int start, int end) { - _sink.write(string.substring(start, end)); - } - - void writeCharCode(int charCode) { - _sink.writeCharCode(charCode); - } -} - -class _JsonStringStringifierPretty extends _JsonStringStringifier - with _JsonPrettyPrintMixin { - final String _indent; - - _JsonStringStringifierPretty( - StringSink sink, dynamic toEncodable(dynamic o)?, this._indent) - : super(sink, toEncodable); - - void writeIndentation(int count) { - for (var i = 0; i < count; i++) writeString(_indent); - } -} - -/// Specialization of [_JsonStringifier] that writes the JSON as UTF-8. -/// -/// The JSON text is UTF-8 encoded and written to [Uint8List] buffers. -/// The buffers are then passed back to a user provided callback method. -class _JsonUtf8Stringifier extends _JsonStringifier { - final int bufferSize; - final void Function(Uint8List list, int start, int end) addChunk; - Uint8List buffer; - int index = 0; - - _JsonUtf8Stringifier( - dynamic toEncodable(dynamic o)?, this.bufferSize, this.addChunk) - : buffer = Uint8List(bufferSize), - super(toEncodable); - - /// Convert [object] to UTF-8 encoded JSON. - /// - /// Calls [addChunk] with slices of UTF-8 code units. - /// These will typically have size [bufferSize], but may be shorter. - /// The buffers are not reused, so the [addChunk] call may keep and reuse the - /// chunks. - /// - /// If [indent] is non-`null`, the result will be "pretty-printed" with extra - /// newlines and indentation, using [indent] as the indentation. - static void stringify( - Object? object, - List? indent, - dynamic toEncodable(dynamic o)?, - int bufferSize, - void addChunk(Uint8List chunk, int start, int end)) { - _JsonUtf8Stringifier stringifier; - if (indent != null) { - stringifier = - _JsonUtf8StringifierPretty(toEncodable, indent, bufferSize, addChunk); - } else { - stringifier = _JsonUtf8Stringifier(toEncodable, bufferSize, addChunk); - } - stringifier.writeObject(object); - stringifier.flush(); - } - - /// Must be called at the end to push the last chunk to the [addChunk] - /// callback. - void flush() { - if (index > 0) { - addChunk(buffer, 0, index); - } - buffer = Uint8List(0); - index = 0; - } - - String? get _partialResult => null; - - void writeNumber(num number) { - writeAsciiString(number.toString()); - } - - /// Write a string that is known to not have non-ASCII characters. - void writeAsciiString(String string) { - // TODO(lrn): Optimize by copying directly into buffer instead of going - // through writeCharCode; - for (var i = 0; i < string.length; i++) { - var char = string.codeUnitAt(i); - assert(char <= 0x7f); - writeByte(char); - } - } - - void writeString(String string) { - writeStringSlice(string, 0, string.length); - } - - void writeStringSlice(String string, int start, int end) { - // TODO(lrn): Optimize by copying directly into buffer instead of going - // through writeCharCode/writeByte. Assumption is the most characters - // in strings are plain ASCII. - for (var i = start; i < end; i++) { - var char = string.codeUnitAt(i); - if (char <= 0x7f) { - writeByte(char); - } else { - if ((char & 0xF800) == 0xD800) { - // Surrogate. - if (char < 0xDC00 && i + 1 < end) { - // Lead surrogate. - var nextChar = string.codeUnitAt(i + 1); - if ((nextChar & 0xFC00) == 0xDC00) { - // Tail surrogate. - char = 0x10000 + ((char & 0x3ff) << 10) + (nextChar & 0x3ff); - writeFourByteCharCode(char); - i++; - continue; - } - } - // Unpaired surrogate. - writeMultiByteCharCode(unicodeReplacementCharacterRune); - continue; - } - writeMultiByteCharCode(char); - } - } - } - - void writeCharCode(int charCode) { - if (charCode <= 0x7f) { - writeByte(charCode); - return; - } - writeMultiByteCharCode(charCode); - } - - void writeMultiByteCharCode(int charCode) { - if (charCode <= 0x7ff) { - writeByte(0xC0 | (charCode >> 6)); - writeByte(0x80 | (charCode & 0x3f)); - return; - } - if (charCode <= 0xffff) { - writeByte(0xE0 | (charCode >> 12)); - writeByte(0x80 | ((charCode >> 6) & 0x3f)); - writeByte(0x80 | (charCode & 0x3f)); - return; - } - writeFourByteCharCode(charCode); - } - - void writeFourByteCharCode(int charCode) { - assert(charCode <= 0x10ffff); - writeByte(0xF0 | (charCode >> 18)); - writeByte(0x80 | ((charCode >> 12) & 0x3f)); - writeByte(0x80 | ((charCode >> 6) & 0x3f)); - writeByte(0x80 | (charCode & 0x3f)); - } - - void writeByte(int byte) { - assert(byte <= 0xff); - if (index == buffer.length) { - addChunk(buffer, 0, index); - buffer = Uint8List(bufferSize); - index = 0; - } - buffer[index++] = byte; - } -} - -/// Pretty-printing version of [_JsonUtf8Stringifier]. -class _JsonUtf8StringifierPretty extends _JsonUtf8Stringifier - with _JsonPrettyPrintMixin { - final List indent; - _JsonUtf8StringifierPretty(dynamic toEncodable(dynamic o)?, this.indent, - int bufferSize, void addChunk(Uint8List buffer, int start, int end)) - : super(toEncodable, bufferSize, addChunk); - - void writeIndentation(int count) { - var indent = this.indent; - var indentLength = indent.length; - if (indentLength == 1) { - var char = indent[0]; - while (count > 0) { - writeByte(char); - count -= 1; - } - return; - } - while (count > 0) { - count--; - var end = index + indentLength; - if (end <= buffer.length) { - buffer.setRange(index, end, indent); - index = end; - } else { - for (var i = 0; i < indentLength; i++) { - writeByte(indent[i]); - } - } - } - } -} diff --git a/sdk_nnbd/lib/convert/latin1.dart b/sdk_nnbd/lib/convert/latin1.dart deleted file mode 100644 index f396682615b..00000000000 --- a/sdk_nnbd/lib/convert/latin1.dart +++ /dev/null @@ -1,181 +0,0 @@ -// Copyright (c) 2013, 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. - -part of dart.convert; - -/// An instance of the default implementation of the [Latin1Codec]. -/// -/// This instance provides a convenient access to the most common ISO Latin 1 -/// use cases. -/// -/// Examples: -/// ```dart -/// var encoded = latin1.encode("blåbærgrød"); -/// var decoded = latin1.decode([0x62, 0x6c, 0xe5, 0x62, 0xe6, -/// 0x72, 0x67, 0x72, 0xf8, 0x64]); -/// ``` -const Latin1Codec latin1 = Latin1Codec(); - -const int _latin1Mask = 0xFF; - -/// A [Latin1Codec] encodes strings to ISO Latin-1 (aka ISO-8859-1) bytes -/// and decodes Latin-1 bytes to strings. -class Latin1Codec extends Encoding { - final bool _allowInvalid; - - /// Instantiates a new [Latin1Codec]. - /// - /// If [allowInvalid] is true, the [decode] method and the converter - /// returned by [decoder] will default to allowing invalid values. Invalid - /// values are decoded into the Unicode Replacement character (U+FFFD). - /// Calls to the [decode] method can override this default. - /// - /// Encoders will not accept invalid (non Latin-1) characters. - const Latin1Codec({bool allowInvalid = false}) : _allowInvalid = allowInvalid; - - /// The name of this codec, "iso-8859-1". - String get name => "iso-8859-1"; - - Uint8List encode(String source) => encoder.convert(source); - - /// Decodes the Latin-1 [bytes] (a list of unsigned 8-bit integers) to the - /// corresponding string. - /// - /// If [bytes] contains values that are not in the range 0 .. 255, the decoder - /// will eventually throw a [FormatException]. - /// - /// If [allowInvalid] is not provided, it defaults to the value used to create - /// this [Latin1Codec]. - String decode(List bytes, {bool? allowInvalid}) { - if (allowInvalid ?? _allowInvalid) { - return const Latin1Decoder(allowInvalid: true).convert(bytes); - } else { - return const Latin1Decoder(allowInvalid: false).convert(bytes); - } - } - - Latin1Encoder get encoder => const Latin1Encoder(); - - Latin1Decoder get decoder => _allowInvalid - ? const Latin1Decoder(allowInvalid: true) - : const Latin1Decoder(allowInvalid: false); -} - -/// This class converts strings of only ISO Latin-1 characters to bytes. -class Latin1Encoder extends _UnicodeSubsetEncoder { - const Latin1Encoder() : super(_latin1Mask); -} - -/// This class converts Latin-1 bytes (lists of unsigned 8-bit integers) -/// to a string. -class Latin1Decoder extends _UnicodeSubsetDecoder { - /// Instantiates a new [Latin1Decoder]. - /// - /// The optional [allowInvalid] argument defines how [convert] deals - /// with invalid bytes. - /// - /// If it is `true`, [convert] replaces invalid bytes with the Unicode - /// Replacement character `U+FFFD` (�). - /// Otherwise it throws a [FormatException]. - const Latin1Decoder({bool allowInvalid = false}) - : super(allowInvalid, _latin1Mask); - - /// Starts a chunked conversion. - /// - /// The converter works more efficiently if the given [sink] is a - /// [StringConversionSink]. - ByteConversionSink startChunkedConversion(Sink sink) { - StringConversionSink stringSink; - if (sink is StringConversionSink) { - stringSink = sink; - } else { - stringSink = StringConversionSink.from(sink); - } - // TODO(lrn): Use stringSink.asUtf16Sink() if it becomes available. - if (!_allowInvalid) return _Latin1DecoderSink(stringSink); - return _Latin1AllowInvalidDecoderSink(stringSink); - } -} - -class _Latin1DecoderSink extends ByteConversionSinkBase { - StringConversionSink? _sink; - _Latin1DecoderSink(this._sink); - - void close() { - _sink!.close(); - _sink = null; - } - - void add(List source) { - addSlice(source, 0, source.length, false); - } - - void _addSliceToSink(List source, int start, int end, bool isLast) { - // If _sink was a UTF-16 conversion sink, just add the slice directly with - // _sink.addSlice(source, start, end, isLast). - // The code below is an moderately stupid workaround until a real - // solution can be made. - _sink!.add(String.fromCharCodes(source, start, end)); - if (isLast) close(); - } - - void addSlice(List source, int start, int end, bool isLast) { - RangeError.checkValidRange(start, end, source.length); - if (start == end) return; - if (source is! Uint8List) { - // List may contain value outside of the 0..255 range. If so, throw. - // Technically, we could excuse Uint8ClampedList as well, but it unlikely - // to be relevant. - _checkValidLatin1(source, start, end); - } - _addSliceToSink(source, start, end, isLast); - } - - static void _checkValidLatin1(List source, int start, int end) { - var mask = 0; - for (var i = start; i < end; i++) { - mask |= source[i]; - } - if (mask >= 0 && mask <= _latin1Mask) { - return; - } - _reportInvalidLatin1(source, start, end); // Always throws. - } - - static void _reportInvalidLatin1(List source, int start, int end) { - // Find the index of the first non-Latin-1 character code. - for (var i = start; i < end; i++) { - var char = source[i]; - if (char < 0 || char > _latin1Mask) { - throw FormatException( - "Source contains non-Latin-1 characters.", source, i); - } - } - // Unreachable - we only call the function if the loop above throws. - assert(false); - } -} - -class _Latin1AllowInvalidDecoderSink extends _Latin1DecoderSink { - _Latin1AllowInvalidDecoderSink(StringConversionSink sink) : super(sink); - - void addSlice(List source, int start, int end, bool isLast) { - RangeError.checkValidRange(start, end, source.length); - for (var i = start; i < end; i++) { - var char = source[i]; - if (char > _latin1Mask || char < 0) { - if (i > start) _addSliceToSink(source, start, i, false); - // Add UTF-8 encoding of U+FFFD. - _addSliceToSink(const [0xFFFD], 0, 1, false); - start = i + 1; - } - } - if (start < end) { - _addSliceToSink(source, start, end, isLast); - } - if (isLast) { - close(); - } - } -} diff --git a/sdk_nnbd/lib/convert/line_splitter.dart b/sdk_nnbd/lib/convert/line_splitter.dart deleted file mode 100644 index fa0be3f7fa4..00000000000 --- a/sdk_nnbd/lib/convert/line_splitter.dart +++ /dev/null @@ -1,177 +0,0 @@ -// Copyright (c) 2013, 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. - -part of dart.convert; - -// Character constants. -const int _LF = 10; -const int _CR = 13; - -/// A [StreamTransformer] that splits a [String] into individual lines. -/// -/// A line is terminated by either a CR (U+000D), a LF (U+000A), a -/// CR+LF sequence (DOS line ending), -/// and a final non-empty line can be ended by the end of the string. -/// -/// The returned lines do not contain the line terminators. - -class LineSplitter extends StreamTransformerBase { - const LineSplitter(); - - /// Split [lines] into individual lines. - /// - /// If [start] and [end] are provided, only split the contents of - /// `lines.substring(start, end)`. The [start] and [end] values must - /// specify a valid sub-range of [lines] - /// (`0 <= start <= end <= lines.length`). - static Iterable split(String lines, [int start = 0, int? end]) sync* { - end = RangeError.checkValidRange(start, end, lines.length); - // TODO(38725): Remove workaround when assignment promotion is implemented - if (end == null) { - throw RangeError("Invalid range"); - } - var sliceStart = start; - var char = 0; - for (var i = start; i < end; i++) { - var previousChar = char; - char = lines.codeUnitAt(i); - if (char != _CR) { - if (char != _LF) continue; - if (previousChar == _CR) { - sliceStart = i + 1; - continue; - } - } - yield lines.substring(sliceStart, i); - sliceStart = i + 1; - } - if (sliceStart < end) { - yield lines.substring(sliceStart, end); - } - } - - List convert(String data) { - var lines = []; - var end = data.length; - var sliceStart = 0; - var char = 0; - for (var i = 0; i < end; i++) { - var previousChar = char; - char = data.codeUnitAt(i); - if (char != _CR) { - if (char != _LF) continue; - if (previousChar == _CR) { - sliceStart = i + 1; - continue; - } - } - lines.add(data.substring(sliceStart, i)); - sliceStart = i + 1; - } - if (sliceStart < end) { - lines.add(data.substring(sliceStart, end)); - } - return lines; - } - - StringConversionSink startChunkedConversion(Sink sink) { - return _LineSplitterSink( - sink is StringConversionSink ? sink : StringConversionSink.from(sink)); - } - - Stream bind(Stream stream) { - return Stream.eventTransformed( - stream, (EventSink sink) => _LineSplitterEventSink(sink)); - } -} - -// TODO(floitsch): deal with utf8. -class _LineSplitterSink extends StringConversionSinkBase { - final StringConversionSink _sink; - - /// The carry-over from the previous chunk. - /// - /// If the previous slice ended in a line without a line terminator, - /// then the next slice may continue the line. - String? _carry; - - /// Whether to skip a leading LF character from the next slice. - /// - /// If the previous slice ended on a CR character, a following LF - /// would be part of the same line termination, and should be ignored. - /// - /// Only `true` when [_carry] is `null`. - bool _skipLeadingLF = false; - - _LineSplitterSink(this._sink); - - void addSlice(String chunk, int start, int end, bool isLast) { - end = RangeError.checkValidRange(start, end, chunk.length); - // If the chunk is empty, it's probably because it's the last one. - // Handle that here, so we know the range is non-empty below. - if (start >= end) { - if (isLast) close(); - return; - } - String? carry = _carry; - if (carry != null) { - assert(!_skipLeadingLF); - chunk = carry + chunk.substring(start, end); - start = 0; - end = chunk.length; - _carry = null; - } else if (_skipLeadingLF) { - if (chunk.codeUnitAt(start) == _LF) { - start += 1; - } - _skipLeadingLF = false; - } - _addLines(chunk, start, end); - if (isLast) close(); - } - - void close() { - if (_carry != null) { - _sink.add(_carry!); - _carry = null; - } - _sink.close(); - } - - void _addLines(String lines, int start, int end) { - var sliceStart = start; - var char = 0; - for (var i = start; i < end; i++) { - var previousChar = char; - char = lines.codeUnitAt(i); - if (char != _CR) { - if (char != _LF) continue; - if (previousChar == _CR) { - sliceStart = i + 1; - continue; - } - } - _sink.add(lines.substring(sliceStart, i)); - sliceStart = i + 1; - } - if (sliceStart < end) { - _carry = lines.substring(sliceStart, end); - } else { - _skipLeadingLF = (char == _CR); - } - } -} - -class _LineSplitterEventSink extends _LineSplitterSink - implements EventSink { - final EventSink _eventSink; - - _LineSplitterEventSink(EventSink eventSink) - : _eventSink = eventSink, - super(StringConversionSink.from(eventSink)); - - void addError(Object o, [StackTrace? stackTrace]) { - _eventSink.addError(o, stackTrace); - } -} diff --git a/sdk_nnbd/lib/convert/string_conversion.dart b/sdk_nnbd/lib/convert/string_conversion.dart deleted file mode 100644 index 2315330aaa9..00000000000 --- a/sdk_nnbd/lib/convert/string_conversion.dart +++ /dev/null @@ -1,323 +0,0 @@ -// Copyright (c) 2013, 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. - -part of dart.convert; - -/// This class provides an interface for converters to -/// efficiently transmit String data. -/// -/// Instead of limiting the interface to one non-chunked String it accepts -/// partial strings or can be transformed into a byte sink that -/// accepts UTF-8 code units. -/// -/// This abstract class will likely get more methods over time. Implementers are -/// urged to extend [StringConversionSinkBase] or to mix in -/// [StringConversionSinkMixin], to ensure that their class covers the newly -/// added methods. -abstract class StringConversionSink extends ChunkedConversionSink { - StringConversionSink(); - factory StringConversionSink.withCallback(void callback(String accumulated)) = - _StringCallbackSink; - factory StringConversionSink.from(Sink sink) = _StringAdapterSink; - - /// Creates a new instance wrapping the given [sink]. - /// - /// Every string that is added to the returned instance is forwarded to - /// the [sink]. The instance is allowed to buffer and is not required to - /// forward immediately. - factory StringConversionSink.fromStringSink(StringSink sink) = - _StringSinkConversionSink; - - /// Adds the next [chunk] to `this`. - /// - /// Adds the substring defined by [start] and [end]-exclusive to `this`. - /// - /// If [isLast] is `true` closes `this`. - void addSlice(String chunk, int start, int end, bool isLast); - - /// Returns `this` as a sink that accepts UTF-8 input. - /// - /// If used, this method must be the first and only call to `this`. It - /// invalidates `this`. All further operations must be performed on the result. - ByteConversionSink asUtf8Sink(bool allowMalformed); - // - asRuneSink - // - asCodeUnitsSink - - /// Returns `this` as a [ClosableStringSink]. - /// - /// If used, this method must be the first and only call to `this`. It - /// invalidates `this`. All further operations must be performed on the result. - ClosableStringSink asStringSink(); -} - -/// A [ClosableStringSink] extends the [StringSink] interface by adding a -/// `close` method. -abstract class ClosableStringSink extends StringSink { - /// Creates a new instance combining a [StringSink] [sink] and a callback - /// [onClose] which is invoked when the returned instance is closed. - factory ClosableStringSink.fromStringSink(StringSink sink, void onClose()) = - _ClosableStringSink; - - /// Closes `this` and flushes any outstanding data. - void close(); -} - -/// This class wraps an existing [StringSink] and invokes a -/// closure when [close] is invoked. -class _ClosableStringSink implements ClosableStringSink { - final void Function() _callback; - final StringSink _sink; - - _ClosableStringSink(this._sink, this._callback); - - void close() { - _callback(); - } - - void writeCharCode(int charCode) { - _sink.writeCharCode(charCode); - } - - void write(Object? o) { - _sink.write(o); - } - - void writeln([Object? o = ""]) { - _sink.writeln(o); - } - - void writeAll(Iterable objects, [String separator = ""]) { - _sink.writeAll(objects, separator); - } -} - -/// This class wraps an existing [StringConversionSink] and exposes a -/// [ClosableStringSink] interface. The wrapped sink only needs to implement -/// `add` and `close`. -// TODO(floitsch): make this class public? -class _StringConversionSinkAsStringSinkAdapter implements ClosableStringSink { - static const _MIN_STRING_SIZE = 16; - - final StringBuffer _buffer; - final StringConversionSink _chunkedSink; - - _StringConversionSinkAsStringSinkAdapter(this._chunkedSink) - : _buffer = StringBuffer(); - - void close() { - if (_buffer.isNotEmpty) _flush(); - _chunkedSink.close(); - } - - void writeCharCode(int charCode) { - _buffer.writeCharCode(charCode); - if (_buffer.length > _MIN_STRING_SIZE) _flush(); - } - - void write(Object? o) { - if (_buffer.isNotEmpty) _flush(); - _chunkedSink.add(o.toString()); - } - - void writeln([Object? o = ""]) { - _buffer.writeln(o); - if (_buffer.length > _MIN_STRING_SIZE) _flush(); - } - - void writeAll(Iterable objects, [String separator = ""]) { - if (_buffer.isNotEmpty) _flush(); - var iterator = objects.iterator; - if (!iterator.moveNext()) return; - if (separator.isEmpty) { - do { - _chunkedSink.add(iterator.current.toString()); - } while (iterator.moveNext()); - } else { - _chunkedSink.add(iterator.current.toString()); - while (iterator.moveNext()) { - write(separator); - _chunkedSink.add(iterator.current.toString()); - } - } - } - - void _flush() { - var accumulated = _buffer.toString(); - _buffer.clear(); - _chunkedSink.add(accumulated); - } -} - -/// This class provides a base-class for converters that need to accept String -/// inputs. -abstract class StringConversionSinkBase extends StringConversionSinkMixin {} - -/// This class provides a mixin for converters that need to accept String -/// inputs. -abstract class StringConversionSinkMixin implements StringConversionSink { - void addSlice(String str, int start, int end, bool isLast); - void close(); - - void add(String str) { - addSlice(str, 0, str.length, false); - } - - ByteConversionSink asUtf8Sink(bool allowMalformed) { - return _Utf8ConversionSink(this, allowMalformed); - } - - ClosableStringSink asStringSink() { - return _StringConversionSinkAsStringSinkAdapter(this); - } -} - -/// This class is a [StringConversionSink] that wraps a [StringSink]. -class _StringSinkConversionSink - extends StringConversionSinkBase { - final TStringSink _stringSink; - _StringSinkConversionSink(this._stringSink); - - void close() {} - - void addSlice(String str, int start, int end, bool isLast) { - if (start != 0 || end != str.length) { - for (var i = start; i < end; i++) { - _stringSink.writeCharCode(str.codeUnitAt(i)); - } - } else { - _stringSink.write(str); - } - if (isLast) close(); - } - - void add(String str) { - _stringSink.write(str); - } - - ByteConversionSink asUtf8Sink(bool allowMalformed) { - return _Utf8StringSinkAdapter(this, _stringSink, allowMalformed); - } - - ClosableStringSink asStringSink() { - return ClosableStringSink.fromStringSink(_stringSink, close); - } -} - -/// This class accumulates all chunks into one string -/// and invokes a callback when the sink is closed. -/// -/// This class can be used to terminate a chunked conversion. -class _StringCallbackSink extends _StringSinkConversionSink { - final void Function(String) _callback; - - _StringCallbackSink(this._callback) : super(StringBuffer()); - - void close() { - var accumulated = _stringSink.toString(); - _stringSink.clear(); - _callback(accumulated); - } - - ByteConversionSink asUtf8Sink(bool allowMalformed) { - return _Utf8StringSinkAdapter(this, _stringSink, allowMalformed); - } -} - -/// This class adapts a simple [ChunkedConversionSink] to a -/// [StringConversionSink]. -/// -/// All additional methods of the [StringConversionSink] (compared to the -/// ChunkedConversionSink) are redirected to the `add` method. -class _StringAdapterSink extends StringConversionSinkBase { - final Sink _sink; - - _StringAdapterSink(this._sink); - - void add(String str) { - _sink.add(str); - } - - void addSlice(String str, int start, int end, bool isLast) { - if (start == 0 && end == str.length) { - add(str); - } else { - add(str.substring(start, end)); - } - if (isLast) close(); - } - - void close() { - _sink.close(); - } -} - -/// Decodes UTF-8 code units and stores them in a [StringSink]. -/// -/// The `Sink` provided is closed when this sink is closed. -class _Utf8StringSinkAdapter extends ByteConversionSink { - final _Utf8Decoder _decoder; - final Sink _sink; - final StringSink _stringSink; - - _Utf8StringSinkAdapter(this._sink, this._stringSink, bool allowMalformed) - : _decoder = _Utf8Decoder(allowMalformed); - - void close() { - _decoder.flush(_stringSink); - _sink.close(); - } - - void add(List chunk) { - addSlice(chunk, 0, chunk.length, false); - } - - void addSlice( - List codeUnits, int startIndex, int endIndex, bool isLast) { - _stringSink.write(_decoder.convertChunked(codeUnits, startIndex, endIndex)); - if (isLast) close(); - } -} - -/// Decodes UTF-8 code units. -/// -/// Forwards the decoded strings to the given [StringConversionSink]. -// TODO(floitsch): make this class public? -class _Utf8ConversionSink extends ByteConversionSink { - final _Utf8Decoder _decoder; - final StringConversionSink _chunkedSink; - final StringBuffer _buffer; - _Utf8ConversionSink(StringConversionSink sink, bool allowMalformed) - : this._(sink, StringBuffer(), allowMalformed); - - _Utf8ConversionSink._( - this._chunkedSink, StringBuffer stringBuffer, bool allowMalformed) - : _decoder = _Utf8Decoder(allowMalformed), - _buffer = stringBuffer; - - void close() { - _decoder.flush(_buffer); - if (_buffer.isNotEmpty) { - var accumulated = _buffer.toString(); - _buffer.clear(); - _chunkedSink.addSlice(accumulated, 0, accumulated.length, true); - } else { - _chunkedSink.close(); - } - } - - void add(List chunk) { - addSlice(chunk, 0, chunk.length, false); - } - - void addSlice(List chunk, int startIndex, int endIndex, bool isLast) { - _buffer.write(_decoder.convertChunked(chunk, startIndex, endIndex)); - if (_buffer.isNotEmpty) { - var accumulated = _buffer.toString(); - _chunkedSink.addSlice(accumulated, 0, accumulated.length, isLast); - _buffer.clear(); - return; - } - if (isLast) close(); - } -} diff --git a/sdk_nnbd/lib/convert/utf.dart b/sdk_nnbd/lib/convert/utf.dart deleted file mode 100644 index c74f918cfb7..00000000000 --- a/sdk_nnbd/lib/convert/utf.dart +++ /dev/null @@ -1,691 +0,0 @@ -// Copyright (c) 2013, 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. - -part of dart.convert; - -/// The Unicode Replacement character `U+FFFD` (�). -const int unicodeReplacementCharacterRune = 0xFFFD; - -/// The Unicode Byte Order Marker (BOM) character `U+FEFF`. -const int unicodeBomCharacterRune = 0xFEFF; - -/// An instance of the default implementation of the [Utf8Codec]. -/// -/// This instance provides a convenient access to the most common UTF-8 -/// use cases. -/// -/// Examples: -/// -/// var encoded = utf8.encode("Îñţérñåţîöñåļîžåţîờñ"); -/// var decoded = utf8.decode([0x62, 0x6c, 0xc3, 0xa5, 0x62, 0xc3, 0xa6, -/// 0x72, 0x67, 0x72, 0xc3, 0xb8, 0x64]); -const Utf8Codec utf8 = Utf8Codec(); - -/// A [Utf8Codec] encodes strings to utf-8 code units (bytes) and decodes -/// UTF-8 code units to strings. -class Utf8Codec extends Encoding { - final bool _allowMalformed; - - /// Instantiates a new [Utf8Codec]. - /// - /// The optional [allowMalformed] argument defines how [decoder] (and [decode]) - /// deal with invalid or unterminated character sequences. - /// - /// If it is `true` (and not overridden at the method invocation) [decode] and - /// the [decoder] replace invalid (or unterminated) octet - /// sequences with the Unicode Replacement character `U+FFFD` (�). Otherwise - /// they throw a [FormatException]. - const Utf8Codec({bool allowMalformed = false}) - : _allowMalformed = allowMalformed; - - /// The name of this codec, "utf-8". - String get name => "utf-8"; - - /// Decodes the UTF-8 [codeUnits] (a list of unsigned 8-bit integers) to the - /// corresponding string. - /// - /// If the [codeUnits] start with the encoding of a - /// [unicodeBomCharacterRune], that character is discarded. - /// - /// If [allowMalformed] is `true` the decoder replaces invalid (or - /// unterminated) character sequences with the Unicode Replacement character - /// `U+FFFD` (�). Otherwise it throws a [FormatException]. - /// - /// If [allowMalformed] is not given, it defaults to the `allowMalformed` that - /// was used to instantiate `this`. - String decode(List codeUnits, {bool? allowMalformed}) { - // Switch between const objects to avoid allocation. - Utf8Decoder decoder = allowMalformed ?? _allowMalformed - ? const Utf8Decoder(allowMalformed: true) - : const Utf8Decoder(allowMalformed: false); - return decoder.convert(codeUnits); - } - - Utf8Encoder get encoder => const Utf8Encoder(); - Utf8Decoder get decoder { - // Switch between const objects to avoid allocation. - return _allowMalformed - ? const Utf8Decoder(allowMalformed: true) - : const Utf8Decoder(allowMalformed: false); - } -} - -/// This class converts strings to their UTF-8 code units (a list of -/// unsigned 8-bit integers). -class Utf8Encoder extends Converter> { - const Utf8Encoder(); - - /// Converts [string] to its UTF-8 code units (a list of - /// unsigned 8-bit integers). - /// - /// If [start] and [end] are provided, only the substring - /// `string.substring(start, end)` is converted. - /// - /// Any unpaired surrogate character (`U+D800`-`U+DFFF`) in the input string - /// is encoded as a Unicode Replacement character `U+FFFD` (�). - Uint8List convert(String string, [int start = 0, int? end]) { - var stringLength = string.length; - end = RangeError.checkValidRange(start, end, stringLength); - // TODO(38725): Remove workaround when assignment promotion is implemented - if (end == null) { - throw RangeError("Invalid range"); - } - var length = end - start; - if (length == 0) return Uint8List(0); - // Create a new encoder with a length that is guaranteed to be big enough. - // A single code unit uses at most 3 bytes, a surrogate pair at most 4. - var encoder = _Utf8Encoder.withBufferSize(length * 3); - var endPosition = encoder._fillBuffer(string, start, end); - assert(endPosition >= end - 1); - if (endPosition != end) { - // Encoding skipped the last code unit. - // That can only happen if the last code unit is a leadsurrogate. - // Force encoding of the lead surrogate by itself. - var lastCodeUnit = string.codeUnitAt(end - 1); - assert(_isLeadSurrogate(lastCodeUnit)); - // Write a replacement character to represent the unpaired surrogate. - encoder._writeReplacementCharacter(); - } - return encoder._buffer.sublist(0, encoder._bufferIndex); - } - - /// Starts a chunked conversion. - /// - /// The converter works more efficiently if the given [sink] is a - /// [ByteConversionSink]. - StringConversionSink startChunkedConversion(Sink> sink) { - return _Utf8EncoderSink( - sink is ByteConversionSink ? sink : ByteConversionSink.from(sink)); - } - - // Override the base-classes bind, to provide a better type. - Stream> bind(Stream stream) => super.bind(stream); -} - -/// This class encodes Strings to UTF-8 code units (unsigned 8 bit integers). -// TODO(floitsch): make this class public. -class _Utf8Encoder { - int _carry = 0; - int _bufferIndex = 0; - final Uint8List _buffer; - - static const _DEFAULT_BYTE_BUFFER_SIZE = 1024; - - _Utf8Encoder() : this.withBufferSize(_DEFAULT_BYTE_BUFFER_SIZE); - - _Utf8Encoder.withBufferSize(int bufferSize) - : _buffer = _createBuffer(bufferSize); - - /// Allow an implementation to pick the most efficient way of storing bytes. - static Uint8List _createBuffer(int size) => Uint8List(size); - - /// Write a replacement character (U+FFFD). Used for unpaired surrogates. - void _writeReplacementCharacter() { - _buffer[_bufferIndex++] = 0xEF; - _buffer[_bufferIndex++] = 0xBF; - _buffer[_bufferIndex++] = 0xBD; - } - - /// Tries to combine the given [leadingSurrogate] with the [nextCodeUnit] and - /// writes it to [_buffer]. - /// - /// Returns true if the [nextCodeUnit] was combined with the - /// [leadingSurrogate]. If it wasn't then nextCodeUnit was not a trailing - /// surrogate and has not been written yet. - /// - /// It is safe to pass 0 for [nextCodeUnit] in which case a replacement - /// character is written to represent the unpaired lead surrogate. - bool _writeSurrogate(int leadingSurrogate, int nextCodeUnit) { - if (_isTailSurrogate(nextCodeUnit)) { - var rune = _combineSurrogatePair(leadingSurrogate, nextCodeUnit); - // If the rune is encoded with 2 code-units then it must be encoded - // with 4 bytes in UTF-8. - assert(rune > _THREE_BYTE_LIMIT); - assert(rune <= _FOUR_BYTE_LIMIT); - _buffer[_bufferIndex++] = 0xF0 | (rune >> 18); - _buffer[_bufferIndex++] = 0x80 | ((rune >> 12) & 0x3f); - _buffer[_bufferIndex++] = 0x80 | ((rune >> 6) & 0x3f); - _buffer[_bufferIndex++] = 0x80 | (rune & 0x3f); - return true; - } else { - // Unpaired lead surrogate. - _writeReplacementCharacter(); - return false; - } - } - - /// Fills the [_buffer] with as many characters as possible. - /// - /// Does not encode any trailing lead-surrogate. This must be done by the - /// caller. - /// - /// Returns the position in the string. The returned index points to the - /// first code unit that hasn't been encoded. - int _fillBuffer(String str, int start, int end) { - if (start != end && _isLeadSurrogate(str.codeUnitAt(end - 1))) { - // Don't handle a trailing lead-surrogate in this loop. The caller has - // to deal with those. - end--; - } - int stringIndex; - for (stringIndex = start; stringIndex < end; stringIndex++) { - var codeUnit = str.codeUnitAt(stringIndex); - // ASCII has the same representation in UTF-8 and UTF-16. - if (codeUnit <= _ONE_BYTE_LIMIT) { - if (_bufferIndex >= _buffer.length) break; - _buffer[_bufferIndex++] = codeUnit; - } else if (_isLeadSurrogate(codeUnit)) { - if (_bufferIndex + 4 > _buffer.length) break; - // Note that it is safe to read the next code unit. We decremented - // [end] above when the last valid code unit was a leading surrogate. - var nextCodeUnit = str.codeUnitAt(stringIndex + 1); - var wasCombined = _writeSurrogate(codeUnit, nextCodeUnit); - if (wasCombined) stringIndex++; - } else if (_isTailSurrogate(codeUnit)) { - if (_bufferIndex + 3 > _buffer.length) break; - // Unpaired tail surrogate. - _writeReplacementCharacter(); - } else { - var rune = codeUnit; - if (rune <= _TWO_BYTE_LIMIT) { - if (_bufferIndex + 1 >= _buffer.length) break; - _buffer[_bufferIndex++] = 0xC0 | (rune >> 6); - _buffer[_bufferIndex++] = 0x80 | (rune & 0x3f); - } else { - assert(rune <= _THREE_BYTE_LIMIT); - if (_bufferIndex + 2 >= _buffer.length) break; - _buffer[_bufferIndex++] = 0xE0 | (rune >> 12); - _buffer[_bufferIndex++] = 0x80 | ((rune >> 6) & 0x3f); - _buffer[_bufferIndex++] = 0x80 | (rune & 0x3f); - } - } - } - return stringIndex; - } -} - -/// This class encodes chunked strings to UTF-8 code units (unsigned 8-bit -/// integers). -class _Utf8EncoderSink extends _Utf8Encoder with StringConversionSinkMixin { - final ByteConversionSink _sink; - - _Utf8EncoderSink(this._sink); - - void close() { - if (_carry != 0) { - // addSlice will call close again, but then the carry must be equal to 0. - addSlice("", 0, 0, true); - return; - } - _sink.close(); - } - - void addSlice(String str, int start, int end, bool isLast) { - _bufferIndex = 0; - - if (start == end && !isLast) { - return; - } - - if (_carry != 0) { - var nextCodeUnit = 0; - if (start != end) { - nextCodeUnit = str.codeUnitAt(start); - } else { - assert(isLast); - } - var wasCombined = _writeSurrogate(_carry, nextCodeUnit); - // Either we got a non-empty string, or we must not have been combined. - assert(!wasCombined || start != end); - if (wasCombined) start++; - _carry = 0; - } - do { - start = _fillBuffer(str, start, end); - var isLastSlice = isLast && (start == end); - if (start == end - 1 && _isLeadSurrogate(str.codeUnitAt(start))) { - if (isLast && _bufferIndex < _buffer.length - 3) { - // There is still space for the replacement character to represent - // the last incomplete surrogate. - _writeReplacementCharacter(); - } else { - // Otherwise store it in the carry. If isLast is true, then - // close will flush the last carry. - _carry = str.codeUnitAt(start); - } - start++; - } - _sink.addSlice(_buffer, 0, _bufferIndex, isLastSlice); - _bufferIndex = 0; - } while (start < end); - if (isLast) close(); - } - - // TODO(floitsch): implement asUtf8Sink. Sligthly complicated because it - // needs to deal with malformed input. -} - -/// This class converts UTF-8 code units (lists of unsigned 8-bit integers) -/// to a string. -class Utf8Decoder extends Converter, String> { - final bool _allowMalformed; - - /// Instantiates a new [Utf8Decoder]. - /// - /// The optional [allowMalformed] argument defines how [convert] deals - /// with invalid or unterminated character sequences. - /// - /// If it is `true` [convert] replaces invalid (or unterminated) character - /// sequences with the Unicode Replacement character `U+FFFD` (�). Otherwise - /// it throws a [FormatException]. - const Utf8Decoder({bool allowMalformed = false}) - : _allowMalformed = allowMalformed; - - /// Converts the UTF-8 [codeUnits] (a list of unsigned 8-bit integers) to the - /// corresponding string. - /// - /// Uses the code units from [start] to, but no including, [end]. - /// If [end] is omitted, it defaults to `codeUnits.length`. - /// - /// If the [codeUnits] start with the encoding of a - /// [unicodeBomCharacterRune], that character is discarded. - String convert(List codeUnits, [int start = 0, int? end]) { - // Allow the implementation to intercept and specialize based on the type - // of codeUnits. - var result = _convertIntercepted(_allowMalformed, codeUnits, start, end); - if (result != null) { - return result; - } - - return _Utf8Decoder(_allowMalformed).convertSingle(codeUnits, start, end); - } - - /// Starts a chunked conversion. - /// - /// The converter works more efficiently if the given [sink] is a - /// [StringConversionSink]. - ByteConversionSink startChunkedConversion(Sink sink) { - StringConversionSink stringSink; - if (sink is StringConversionSink) { - stringSink = sink; - } else { - stringSink = StringConversionSink.from(sink); - } - return stringSink.asUtf8Sink(_allowMalformed); - } - - // Override the base-classes bind, to provide a better type. - Stream bind(Stream> stream) => super.bind(stream); - - external Converter, T> fuse(Converter next); - - external static String? _convertIntercepted( - bool allowMalformed, List codeUnits, int start, int? end); -} - -// UTF-8 constants. -const int _ONE_BYTE_LIMIT = 0x7f; // 7 bits -const int _TWO_BYTE_LIMIT = 0x7ff; // 11 bits -const int _THREE_BYTE_LIMIT = 0xffff; // 16 bits -const int _FOUR_BYTE_LIMIT = 0x10ffff; // 21 bits, truncated to Unicode max. - -// UTF-16 constants. -const int _SURROGATE_TAG_MASK = 0xFC00; -const int _SURROGATE_VALUE_MASK = 0x3FF; -const int _LEAD_SURROGATE_MIN = 0xD800; -const int _TAIL_SURROGATE_MIN = 0xDC00; - -bool _isLeadSurrogate(int codeUnit) => - (codeUnit & _SURROGATE_TAG_MASK) == _LEAD_SURROGATE_MIN; -bool _isTailSurrogate(int codeUnit) => - (codeUnit & _SURROGATE_TAG_MASK) == _TAIL_SURROGATE_MIN; -int _combineSurrogatePair(int lead, int tail) => - 0x10000 + ((lead & _SURROGATE_VALUE_MASK) << 10) | - (tail & _SURROGATE_VALUE_MASK); - -class _Utf8Decoder { - /// Decode malformed UTF-8 as replacement characters (instead of throwing)? - final bool allowMalformed; - - /// Decoder DFA state. - int _state; - - /// Partially decoded character. Meaning depends on state. Not used when in - /// the initial/accept state. When in an error state, contains the index into - /// the input of the error. - int _charOrIndex = 0; - - // State machine for UTF-8 decoding, based on this decoder by Björn Höhrmann: - // https://bjoern.hoehrmann.de/utf-8/decoder/dfa/ - // - // One iteration in the state machine proceeds as: - // - // type = typeTable[byte]; - // char = (state != accept) - // ? (byte & 0x3F) | (char << 6) - // : byte & (shiftedByteMask >> type); - // state = transitionTable[state + type]; - // - // After each iteration, if state == accept, char is output as a character. - - // Mask to and on the type read from the table. - static const int typeMask = 0x1F; - // Mask shifted right by byte type to mask first byte of sequence. - static const int shiftedByteMask = 0xF0FE; - - // Byte types. - // 'A' = ASCII, 00-7F - // 'B' = 2-byte, C2-DF - // 'C' = 3-byte, E1-EC, EE - // 'D' = 3-byte (possibly surrogate), ED - // 'E' = Illegal, C0-C1, F5+ - // 'F' = Low extension, 80-8F - // 'G' = Mid extension, 90-9F - // 'H' = High extension, A0-BA, BC-BE - // 'I' = Second byte of BOM, BB - // 'J' = Third byte of BOM, BF - // 'K' = 3-byte (possibly overlong), E0 - // 'L' = First byte of BOM, EF - // 'M' = 4-byte (possibly out-of-range), F4 - // 'N' = 4-byte, F1-F3 - // 'O' = 4-byte (possibly overlong), F0 - static const String typeTable = "" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 00-1F - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 20-3F - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 40-5F - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 60-7F - "FFFFFFFFFFFFFFFFGGGGGGGGGGGGGGGG" // 80-9F - "HHHHHHHHHHHHHHHHHHHHHHHHHHHIHHHJ" // A0-BF - "EEBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" // C0-DF - "KCCCCCCCCCCCCDCLONNNMEEEEEEEEEEE" // E0-FF - ; - - // States (offsets into transition table). - static const int IA = 0x00; // Initial / Accept - static const int BB = 0x10; // Before BOM - static const int AB = 0x20; // After BOM - static const int X1 = 0x30; // Expecting one extension byte - static const int X2 = 0x3A; // Expecting two extension bytes - static const int X3 = 0x44; // Expecting three extension bytes - static const int TO = 0x4E; // Possibly overlong 3-byte - static const int TS = 0x58; // Possibly surrogate - static const int QO = 0x62; // Possibly overlong 4-byte - static const int QR = 0x6C; // Possibly out-of-range 4-byte - static const int B1 = 0x76; // One byte into BOM - static const int B2 = 0x80; // Two bytes into BOM - static const int E1 = 0x41; // Error: Missing extension byte - static const int E2 = 0x43; // Error: Unexpected extension byte - static const int E3 = 0x45; // Error: Invalid byte - static const int E4 = 0x47; // Error: Overlong encoding - static const int E5 = 0x49; // Error: Out of range - static const int E6 = 0x4B; // Error: Surrogate - static const int E7 = 0x4D; // Error: Unfinished - - // Character equivalents for states. - static const String _IA = '\u0000'; - static const String _BB = '\u0010'; - static const String _AB = '\u0020'; - static const String _X1 = '\u0030'; - static const String _X2 = '\u003A'; - static const String _X3 = '\u0044'; - static const String _TO = '\u004E'; - static const String _TS = '\u0058'; - static const String _QO = '\u0062'; - static const String _QR = '\u006C'; - static const String _B1 = '\u0076'; - static const String _B2 = '\u0080'; - static const String _E1 = '\u0041'; - static const String _E2 = '\u0043'; - static const String _E3 = '\u0045'; - static const String _E4 = '\u0047'; - static const String _E5 = '\u0049'; - static const String _E6 = '\u004B'; - static const String _E7 = '\u004D'; - - // Transition table of the state machine. Maps state and byte type - // to next state. - static const String transitionTable = " " - // A B C D E F G H I J K L M N O - "$_IA$_X1$_X2$_TS$_E3$_E2$_E2$_E2$_E2$_E2$_TO$_X2$_QR$_X3$_QO " // IA - "$_IA$_X1$_X2$_TS$_E3$_E2$_E2$_E2$_E2$_E2$_TO$_B1$_QR$_X3$_QO " // BB - "$_IA$_X1$_X2$_TS$_E3$_E2$_E2$_E2$_E2$_E2$_TO$_X2$_QR$_X3$_QO " // AB - "$_E1$_E1$_E1$_E1$_E1$_IA$_IA$_IA$_IA$_IA" // Overlap 5 E1s X1 - "$_E1$_E1$_E1$_E1$_E1$_X1$_X1$_X1$_X1$_X1" // Overlap 5 E1s X2 - "$_E1$_E1$_E1$_E1$_E1$_X2$_X2$_X2$_X2$_X2" // Overlap 5 E1s X3 - "$_E1$_E1$_E1$_E1$_E1$_E4$_E4$_X1$_X1$_X1" // Overlap 5 E1s TO - "$_E1$_E1$_E1$_E1$_E1$_X1$_X1$_E6$_E6$_E6" // Overlap 5 E1s TS - "$_E1$_E1$_E1$_E1$_E1$_E4$_X2$_X2$_X2$_X2" // Overlap 5 E1s QO - "$_E1$_E1$_E1$_E1$_E1$_X2$_E5$_E5$_E5$_E5" // Overlap 5 E1s QR - "$_E1$_E1$_E1$_E1$_E1$_X1$_X1$_X1$_B2$_X1" // Overlap 5 E1s B1 - "$_E1$_E1$_E1$_E1$_E1$_IA$_IA$_IA$_IA$_AB$_E1$_E1$_E1$_E1$_E1" // B2 - ; - - // Aliases for states. - static const int initial = IA; - static const int accept = IA; - static const int beforeBom = BB; - static const int afterBom = AB; - static const int errorMissingExtension = E1; - static const int errorUnexpectedExtension = E2; - static const int errorInvalid = E3; - static const int errorOverlong = E4; - static const int errorOutOfRange = E5; - static const int errorSurrogate = E6; - static const int errorUnfinished = E7; - - @pragma("vm:prefer-inline") - static bool isErrorState(int state) => (state & 1) != 0; - - static String errorDescription(int state) { - switch (state) { - case errorMissingExtension: - return "Missing extension byte"; - case errorUnexpectedExtension: - return "Unexpected extension byte"; - case errorInvalid: - return "Invalid UTF-8 byte"; - case errorOverlong: - return "Overlong encoding"; - case errorOutOfRange: - return "Out of unicode range"; - case errorSurrogate: - return "Encoded surrogate"; - case errorUnfinished: - return "Unfinished UTF-8 octet sequence"; - default: - return ""; - } - } - - external _Utf8Decoder(bool allowMalformed); - - external String convertSingle(List codeUnits, int start, int? maybeEnd); - - external String convertChunked(List codeUnits, int start, int? maybeEnd); - - String convertGeneral( - List codeUnits, int start, int? maybeEnd, bool single) { - int end = RangeError.checkValidRange(start, maybeEnd, codeUnits.length); - - if (start == end) return ""; - - // Have bytes as Uint8List. - Uint8List bytes; - int errorOffset; - if (codeUnits is Uint8List) { - bytes = codeUnits; - errorOffset = 0; - } else { - bytes = _makeUint8List(codeUnits, start, end); - errorOffset = start; - end -= start; - start = 0; - } - - String result = _convertRecursive(bytes, start, end, single); - if (isErrorState(_state)) { - String message = errorDescription(_state); - _state = initial; // Ready for more input. - throw FormatException(message, codeUnits, errorOffset + _charOrIndex); - } - return result; - } - - String _convertRecursive(Uint8List bytes, int start, int end, bool single) { - // Chunk long strings to avoid a pathological case of JS repeated string - // concatenation. - if (end - start > 1000) { - int mid = (start + end) ~/ 2; - String s1 = _convertRecursive(bytes, start, mid, false); - if (isErrorState(_state)) return s1; - String s2 = _convertRecursive(bytes, mid, end, single); - return s1 + s2; - } - return decodeGeneral(bytes, start, end, single); - } - - /// Flushes this decoder as if closed. - /// - /// This method throws if the input was partial and the decoder was - /// constructed with `allowMalformed` set to `false`. - void flush(StringSink sink) { - final int state = _state; - _state = initial; - if (state <= afterBom) { - return; - } - // Unfinished sequence. - if (allowMalformed) { - sink.writeCharCode(unicodeReplacementCharacterRune); - } else { - throw FormatException(errorDescription(errorUnfinished), null, null); - } - } - - String decodeGeneral(Uint8List bytes, int start, int end, bool single) { - final String typeTable = _Utf8Decoder.typeTable; - final String transitionTable = _Utf8Decoder.transitionTable; - int state = _state; - int char = _charOrIndex; - final StringBuffer buffer = StringBuffer(); - int i = start; - int byte = bytes[i++]; - loop: - while (true) { - multibyte: - while (true) { - int type = typeTable.codeUnitAt(byte) & typeMask; - char = (state <= afterBom) - ? byte & (shiftedByteMask >> type) - : (byte & 0x3F) | (char << 6); - state = transitionTable.codeUnitAt(state + type); - if (state == accept) { - buffer.writeCharCode(char); - if (i == end) break loop; - break multibyte; - } else if (isErrorState(state)) { - if (allowMalformed) { - switch (state) { - case errorInvalid: - case errorUnexpectedExtension: - // A single byte that can't start a sequence. - buffer.writeCharCode(unicodeReplacementCharacterRune); - break; - case errorMissingExtension: - // Unfinished sequence followed by a byte that can start a - // sequence. - buffer.writeCharCode(unicodeReplacementCharacterRune); - // Re-parse offending byte. - i -= 1; - break; - default: - // Unfinished sequence followed by a byte that can't start a - // sequence. - buffer.writeCharCode(unicodeReplacementCharacterRune); - buffer.writeCharCode(unicodeReplacementCharacterRune); - break; - } - state = initial; - } else { - _state = state; - _charOrIndex = i - 1; - return ""; - } - } - if (i == end) break loop; - byte = bytes[i++]; - } - - final int markStart = i; - byte = bytes[i++]; - if (byte < 128) { - int markEnd = end; - while (i < end) { - byte = bytes[i++]; - if (byte >= 128) { - markEnd = i - 1; - break; - } - } - assert(markStart < markEnd); - if (markEnd - markStart < 20) { - for (int m = markStart; m < markEnd; m++) { - buffer.writeCharCode(bytes[m]); - } - } else { - buffer.write(String.fromCharCodes(bytes, markStart, markEnd)); - } - if (markEnd == end) break loop; - } - } - - if (single && state > afterBom) { - // Unfinished sequence. - if (allowMalformed) { - buffer.writeCharCode(unicodeReplacementCharacterRune); - } else { - _state = errorUnfinished; - _charOrIndex = end; - return ""; - } - } - _state = state; - _charOrIndex = char; - return buffer.toString(); - } - - static Uint8List _makeUint8List(List codeUnits, int start, int end) { - final int length = end - start; - final Uint8List bytes = Uint8List(length); - for (int i = 0; i < length; i++) { - int b = codeUnits[start + i]; - if ((b & ~0xFF) != 0) { - // Replace invalid byte values by FF, which is also invalid. - b = 0xFF; - } - bytes[i] = b; - } - return bytes; - } -} diff --git a/sdk_nnbd/lib/core/annotations.dart b/sdk_nnbd/lib/core/annotations.dart deleted file mode 100644 index f4076833d99..00000000000 --- a/sdk_nnbd/lib/core/annotations.dart +++ /dev/null @@ -1,240 +0,0 @@ -// Copyright (c) 2013, 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. - -part of dart.core; - -/** - * The annotation `@Deprecated('migration')` marks a feature as deprecated. - * - * The annotation [deprecated] is a shorthand for deprecating until - * an unspecified "next release" without migration instructions. - * - * The intent of the `@Deprecated` annotation is to inform users of a feature - * that they should change their code, even if it is currently still working - * correctly. - * - * A deprecated feature is scheduled to be removed at a later time, possibly - * specified in [message]. A deprecated feature should not be used, code using - * it will break at some point in the future. If existing code is using the - * feature it should be rewritten to not use the deprecated feature. - * - * A deprecated feature should document how the same effect can be achieved in - * [message], so the programmer knows how to rewrite the code. - * - * The `@Deprecated` annotation applies to libraries, top-level declarations - * (variables, getters, setters, functions, classes and typedefs), - * class-level declarations (variables, getters, setters, methods, operators or - * constructors, whether static or not), named optional arguments and - * trailing optional positional parameters. - * - * Deprecation is transitive: - * - * - If a library is deprecated, so is every member of it. - * - If a class is deprecated, so is every member of it. - * - If a variable is deprecated, so are its implicit getter and setter. - * - * - * A tool that processes Dart source code may report when: - * - * - the code imports a deprecated library. - * - the code exports a deprecated library, or any deprecated member of - *  a non-deprecated library. - * - the code refers statically to a deprecated declaration. - * - the code dynamically uses a member of an object with a statically known - * type, where the member is deprecated on the static type of the object. - * - the code dynamically calls a method with an argument where the - * corresponding optional parameter is deprecated on the object's static type. - * - * - * If the deprecated use is inside a library, class or method which is itself - * deprecated, the tool should not bother the user about it. - * A deprecated feature is expected to use other deprecated features. - */ -class Deprecated { - /** - * Message provided to the user when they use the deprecated feature. - * - * The message should explain how to migrate away from the feature if an - * alternative is available, and when the deprecated feature is expected to be - * removed. - */ - final String message; - - /** - * Create a deprecation annotation which specifies the migration path and - * expiration of the annotated feature. - * - * The [message] argument should be readable by programmers, and should state - * an alternative feature (if available) as well as when an annotated feature - * is expected to be removed. - */ - const Deprecated(this.message); - - @Deprecated('Use `message` instead. Will be removed in Dart 3.0.0') - String get expires => message; - - String toString() => "Deprecated feature: $message"; -} - -/** - * Marks a feature as [Deprecated] until the next release. - */ -const Deprecated deprecated = Deprecated("next release"); - -class _Override { - const _Override(); -} - -/** - * The annotation `@override` marks an instance member as overriding a - * superclass member with the same name. - * - * The annotation applies to instance methods, getters and setters, and to - * instance fields, where it means that the implicit getter and setter of the - * field is marked as overriding, but the field itself is not. - * - * The intent of the `@override` notation is to catch situations where a - * superclass renames a member, and an independent subclass which used to - * override the member, could silently continue working using the - * superclass implementation. - * - * The editor, or a similar tool aimed at the programmer, may report if no - * declaration of an annotated member is inherited by the class from either a - * superclass or an interface. - * - * Use the `@override` annotation judiciously and only for methods where - * the superclass is not under the programmer's control, the superclass is in a - * different library or package, and it is not considered stable. - * In any case, the use of `@override` is optional. - * - * For example, the annotation is intentionally not used in the Dart platform - * libraries, since they only depend on themselves. - */ -const Object override = _Override(); - -/** - * An annotation class that was used during development of Dart 2. - * - * Should not be used any more. - */ -@deprecated -class Provisional { - String? get message => null; - const Provisional({String? message}); -} - -/** - * An annotation that was used during development of Dart 2. - * - * Should not be used any more. - */ -@deprecated -const Null provisional = null; - -class _Proxy { - const _Proxy(); -} - -/** - * This annotation is deprecated and will be removed in Dart 2. - * - * Dart 2 has a more restrictive type system than Dart 1, and it requires - * method access to be either through a known interface or by using - * dynamic invocations. The original intent of `@proxy` (to implement a class - * that isn't known statically, as documented at the end of this text), - * is not supported by Dart 2. - * To continue to perform dynamic invocations on an object, - * it should be accessed through a reference of type `dynamic`. - * - * The annotation `@proxy` marks a class as implementing members dynamically - * through `noSuchMethod`. - * - * The annotation applies to any class. It is inherited by subclasses from both - * superclass and interfaces. - * - * If a class is annotated with `@proxy`, or it implements any class that is - * annotated, then all member accesses are allowed on an object of that type. - * As such, it is not a static type warning to access any member of the object - * which is not implemented by the class, or to call a method with a different - * number of parameters than it is declared with. - * - * The annotation does not change which classes the annotated class implements, - * and does not prevent static warnings for assigning an object to a variable - * with a static type not implemented by the object. - * - * The suppression of warnings only affect static type warnings about - * member access. - * The runtime type of the object is unaffected. - * It is not considered to implement any special interfaces, - * so assigning it to a typed variable may fail in checked mode, - * and testing it with the `is` operator - * will only return true for types it actually implements or extends. - * Accessing a member which isn't implemented by the class - * will cause the `noSuchMethod` method to be called normally, - * the `@proxy` annotation merely states the intent to handle (some of) those - * `noSuchMethod` calls gracefully. - * - * A class that marked as `@proxy` should override the `noSuchMethod` - * declared on [Object]. - * - * The intent of the `@proxy` notation is to create objects that implement a - * type (or multiple types) that are not known at compile time. If the types - * are known at compile time, a class can be written that implements these - * types. - */ -@deprecated -const Object proxy = _Proxy(); - -/** - * A hint to tools. - * - * Tools that work with Dart programs may accept hints to guide their behavior - * as `pragma` annotations on declarations. - * Each tool decides which hints it accepts, what they mean, and whether and - * how they apply to sub-parts of the annotated entity. - * - * Tools that recognize pragma hints should pick a pragma prefix to identify - * the tool. They should recognize any hint with a [name] starting with their - * prefix followed by `:` as if it was intended for that tool. A hint with a - * prefix for another tool should be ignored (unless compatibility with that - * other tool is a goal). - * - * A tool may recognize unprefixed names as well, if they would recognize that - * name with their own prefix in front. - * - * If the hint can be parameterized, an extra [options] object can be added as well. - * - * For example: - * - * ```dart - * @pragma('Tool:pragma-name', [param1, param2, ...]) - * class Foo { } - * - * @pragma('OtherTool:other-pragma') - * void foo() { } - * ``` - * - * Here class Foo is annotated with a Tool specific pragma 'pragma-name' and - * function foo is annotated with a pragma 'other-pragma' specific to OtherTool. - * - */ -@pragma('vm:entry-point') -class pragma { - /** - * The name of the hint. - * - * A string that is recognized by one or more tools, or such a string prefixed - * by a tool identifier and a colon, which is only recognized by that - * particular tool. - */ - final String name; - - /** Optional extra data parameterizing the hint. */ - final Object? options; - - /** Creates a hint named [name] with optional [options]. */ - const factory pragma(String name, [Object? options]) = pragma._; - - const pragma._(this.name, [this.options]); -} diff --git a/sdk_nnbd/lib/core/bigint.dart b/sdk_nnbd/lib/core/bigint.dart deleted file mode 100644 index 94a9445ebca..00000000000 --- a/sdk_nnbd/lib/core/bigint.dart +++ /dev/null @@ -1,414 +0,0 @@ -// Copyright (c) 2017, 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. - -part of dart.core; - -/** - * An arbitrarily large integer. - */ -abstract class BigInt implements Comparable { - external static BigInt get zero; - external static BigInt get one; - external static BigInt get two; - - /** - * Parses [source] as a, possibly signed, integer literal and returns its - * value. - * - * The [source] must be a non-empty sequence of base-[radix] digits, - * optionally prefixed with a minus or plus sign ('-' or '+'). - * - * The [radix] must be in the range 2..36. The digits used are - * first the decimal digits 0..9, and then the letters 'a'..'z' with - * values 10 through 35. Also accepts upper-case letters with the same - * values as the lower-case ones. - * - * If no [radix] is given then it defaults to 10. In this case, the [source] - * digits may also start with `0x`, in which case the number is interpreted - * as a hexadecimal literal, which effectively means that the `0x` is ignored - * and the radix is instead set to 16. - * - * For any int `n` and radix `r`, it is guaranteed that - * `n == int.parse(n.toRadixString(r), radix: r)`. - * - * Throws a [FormatException] if the [source] is not a valid integer literal, - * optionally prefixed by a sign. - */ - external static BigInt parse(String source, {int? radix}); - - /** - * Parses [source] as a, possibly signed, integer literal and returns its - * value. - * - * As [parse] except that this method returns `null` if the input is not - * valid - */ - external static BigInt? tryParse(String source, {int? radix}); - - /// Allocates a big integer from the provided [value] number. - external factory BigInt.from(num value); - - /** - * Returns the absolute value of this integer. - * - * For any integer `x`, the result is the same as `x < 0 ? -x : x`. - */ - BigInt abs(); - - /** - * Return the negative value of this integer. - * - * The result of negating an integer always has the opposite sign, except - * for zero, which is its own negation. - */ - BigInt operator -(); - - /// Addition operator. - BigInt operator +(BigInt other); - - /// Subtraction operator. - BigInt operator -(BigInt other); - - /// Multiplication operator. - BigInt operator *(BigInt other); - - /// Division operator. - double operator /(BigInt other); - - /** - * Truncating division operator. - * - * Performs a truncating integer division, where the remainder is discarded. - * - * The remainder can be computed using the [remainder] method. - * - * Examples: - * ``` - * var seven = new BigInt.from(7); - * var three = new BigInt.from(3); - * seven ~/ three; // => 2 - * (-seven) ~/ three; // => -2 - * seven ~/ -three; // => -2 - * seven.remainder(three); // => 1 - * (-seven).remainder(three); // => -1 - * seven.remainder(-three); // => 1 - * ``` - */ - BigInt operator ~/(BigInt other); - - /** - * Euclidean modulo operator. - * - * Returns the remainder of the Euclidean division. The Euclidean division of - * two integers `a` and `b` yields two integers `q` and `r` such that - * `a == b * q + r` and `0 <= r < b.abs()`. - * - * The sign of the returned value `r` is always positive. - * - * See [remainder] for the remainder of the truncating division. - */ - BigInt operator %(BigInt other); - - /** - * Returns the remainder of the truncating division of `this` by [other]. - * - * The result `r` of this operation satisfies: - * `this == (this ~/ other) * other + r`. - * As a consequence the remainder `r` has the same sign as the divider `this`. - */ - BigInt remainder(BigInt other); - - /** - * Shift the bits of this integer to the left by [shiftAmount]. - * - * Shifting to the left makes the number larger, effectively multiplying - * the number by `pow(2, shiftIndex)`. - * - * There is no limit on the size of the result. It may be relevant to - * limit intermediate values by using the "and" operator with a suitable - * mask. - * - * It is an error if [shiftAmount] is negative. - */ - BigInt operator <<(int shiftAmount); - - /** - * Shift the bits of this integer to the right by [shiftAmount]. - * - * Shifting to the right makes the number smaller and drops the least - * significant bits, effectively doing an integer division by - *`pow(2, shiftIndex)`. - * - * It is an error if [shiftAmount] is negative. - */ - BigInt operator >>(int shiftAmount); - - /** - * Bit-wise and operator. - * - * Treating both `this` and [other] as sufficiently large two's component - * integers, the result is a number with only the bits set that are set in - * both `this` and [other] - * - * Of both operands are negative, the result is negative, otherwise - * the result is non-negative. - */ - BigInt operator &(BigInt other); - - /** - * Bit-wise or operator. - * - * Treating both `this` and [other] as sufficiently large two's component - * integers, the result is a number with the bits set that are set in either - * of `this` and [other] - * - * If both operands are non-negative, the result is non-negative, - * otherwise the result us negative. - */ - BigInt operator |(BigInt other); - - /** - * Bit-wise exclusive-or operator. - * - * Treating both `this` and [other] as sufficiently large two's component - * integers, the result is a number with the bits set that are set in one, - * but not both, of `this` and [other] - * - * If the operands have the same sign, the result is non-negative, - * otherwise the result is negative. - */ - BigInt operator ^(BigInt other); - - /** - * The bit-wise negate operator. - * - * Treating `this` as a sufficiently large two's component integer, - * the result is a number with the opposite bits set. - * - * This maps any integer `x` to `-x - 1`. - */ - BigInt operator ~(); - - /** Relational less than operator. */ - bool operator <(BigInt other); - - /** Relational less than or equal operator. */ - bool operator <=(BigInt other); - - /** Relational greater than operator. */ - bool operator >(BigInt other); - - /** Relational greater than or equal operator. */ - bool operator >=(BigInt other); - - /** - * Compares this to `other`. - * - * Returns a negative number if `this` is less than `other`, zero if they are - * equal, and a positive number if `this` is greater than `other`. - */ - int compareTo(BigInt other); - - /** - * Returns the minimum number of bits required to store this big integer. - * - * The number of bits excludes the sign bit, which gives the natural length - * for non-negative (unsigned) values. Negative values are complemented to - * return the bit position of the first bit that differs from the sign bit. - * - * To find the number of bits needed to store the value as a signed value, - * add one, i.e. use `x.bitLength + 1`. - * - * ``` - * x.bitLength == (-x-1).bitLength - * - * new BigInt.from(3).bitLength == 2; // 00000011 - * new BigInt.from(2).bitLength == 2; // 00000010 - * new BigInt.from(1).bitLength == 1; // 00000001 - * new BigInt.from(0).bitLength == 0; // 00000000 - * new BigInt.from(-1).bitLength == 0; // 11111111 - * new BigInt.from(-2).bitLength == 1; // 11111110 - * new BigInt.from(-3).bitLength == 2; // 11111101 - * new BigInt.from(-4).bitLength == 2; // 11111100 - * ``` - */ - int get bitLength; - - /** - * Returns the sign of this big integer. - * - * Returns 0 for zero, -1 for values less than zero and - * +1 for values greater than zero. - */ - int get sign; - - /// Whether this big integer is even. - bool get isEven; - - /// Whether this big integer is odd. - bool get isOdd; - - /// Whether this number is negative. - bool get isNegative; - - /** - * Returns `this` to the power of [exponent]. - * - * Returns [one] if the [exponent] equals 0. - * - * The [exponent] must otherwise be positive. - * - * The result is always equal to the mathematical result of this to the power - * [exponent], only limited by the available memory. - */ - BigInt pow(int exponent); - - /** - * Returns this integer to the power of [exponent] modulo [modulus]. - * - * The [exponent] must be non-negative and [modulus] must be - * positive. - */ - BigInt modPow(BigInt exponent, BigInt modulus); - - /** - * Returns the modular multiplicative inverse of this big integer - * modulo [modulus]. - * - * The [modulus] must be positive. - * - * It is an error if no modular inverse exists. - */ - // Returns 1/this % modulus, with modulus > 0. - BigInt modInverse(BigInt modulus); - - /** - * Returns the greatest common divisor of this big integer and [other]. - * - * If either number is non-zero, the result is the numerically greatest - * integer dividing both `this` and `other`. - * - * The greatest common divisor is independent of the order, - * so `x.gcd(y)` is always the same as `y.gcd(x)`. - * - * For any integer `x`, `x.gcd(x)` is `x.abs()`. - * - * If both `this` and `other` is zero, the result is also zero. - */ - BigInt gcd(BigInt other); - - /** - * Returns the least significant [width] bits of this big integer as a - * non-negative number (i.e. unsigned representation). The returned value has - * zeros in all bit positions higher than [width]. - * - * ``` - * new BigInt.from(-1).toUnsigned(5) == 31 // 11111111 -> 00011111 - * ``` - * - * This operation can be used to simulate arithmetic from low level languages. - * For example, to increment an 8 bit quantity: - * - * ``` - * q = (q + 1).toUnsigned(8); - * ``` - * - * `q` will count from `0` up to `255` and then wrap around to `0`. - * - * If the input fits in [width] bits without truncation, the result is the - * same as the input. The minimum width needed to avoid truncation of `x` is - * given by `x.bitLength`, i.e. - * - * ``` - * x == x.toUnsigned(x.bitLength); - * ``` - */ - BigInt toUnsigned(int width); - - /** - * Returns the least significant [width] bits of this integer, extending the - * highest retained bit to the sign. This is the same as truncating the value - * to fit in [width] bits using an signed 2-s complement representation. The - * returned value has the same bit value in all positions higher than [width]. - * - * ``` - * var big15 = new BigInt.from(15); - * var big16 = new BigInt.from(16); - * var big239 = new BigInt.from(239); - * V--sign bit-V - * big16.toSigned(5) == -big16 // 00010000 -> 11110000 - * big239.toSigned(5) == big15 // 11101111 -> 00001111 - * ^ ^ - * ``` - * - * This operation can be used to simulate arithmetic from low level languages. - * For example, to increment an 8 bit signed quantity: - * - * ``` - * q = (q + 1).toSigned(8); - * ``` - * - * `q` will count from `0` up to `127`, wrap to `-128` and count back up to - * `127`. - * - * If the input value fits in [width] bits without truncation, the result is - * the same as the input. The minimum width needed to avoid truncation of `x` - * is `x.bitLength + 1`, i.e. - * - * ``` - * x == x.toSigned(x.bitLength + 1); - * ``` - */ - BigInt toSigned(int width); - - /** - * Whether this big integer can be represented as an `int` without losing - * precision. - * - * Warning: this function may give a different result on - * dart2js, dev compiler, and the VM, due to the differences in - * integer precision. - */ - bool get isValidInt; - - /** - * Returns this [BigInt] as an [int]. - * - * If the number does not fit, clamps to the max (or min) - * integer. - * - * Warning: the clamping behaves differently on dart2js, dev - * compiler, and the VM, due to the differences in integer - * precision. - */ - int toInt(); - - /** - * Returns this [BigInt] as a [double]. - * - * If the number is not representable as a [double], an - * approximation is returned. For numerically large integers, the - * approximation may be infinite. - */ - double toDouble(); - - /** - * Returns a String-representation of this integer. - * - * The returned string is parsable by [parse]. - * For any `BigInt` `i`, it is guaranteed that - * `i == BigInt.parse(i.toString())`. - */ - String toString(); - - /** - * Converts [this] to a string representation in the given [radix]. - * - * In the string representation, lower-case letters are used for digits above - * '9', with 'a' being 10 an 'z' being 35. - * - * The [radix] argument must be an integer in the range 2 to 36. - */ - String toRadixString(int radix); -} diff --git a/sdk_nnbd/lib/core/bool.dart b/sdk_nnbd/lib/core/bool.dart deleted file mode 100644 index 3d35d8011cd..00000000000 --- a/sdk_nnbd/lib/core/bool.dart +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright (c) 2012, 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. - -part of dart.core; - -/** - * The reserved words `true` and `false` denote objects that are the only two - * instances of this class. - * - * It is a compile-time error for a class to attempt to extend or implement - * bool. - */ -@pragma("vm:entry-point") -class bool { - /** - * Returns the boolean value of the environment declaration [name]. - * - * The boolean value of the declaration is `true` if the declared value is - * the string `"true"`, and `false` if the value is `"false"`. - * - * In all other cases, including when there is no declaration for `name`, - * the result is the [defaultValue]. - * - * The result is the same as would be returned by: - * ```dart - * (const String.fromEnvironment(name) == "true") - * ? true - * : (const String.fromEnvironment(name) == "false") - * ? false - * : defaultValue - * ``` - * Example: - * ```dart - * const loggingFlag = const bool.fromEnvironment("logging"); - * ``` - * If you want to use a different truth-string than `"true"`, you can use the - * [String.fromEnvironment] constructor directly: - * ```dart - * const isLoggingOn = (const String.fromEnvironment("logging") == "on"); - * ``` - */ - // The .fromEnvironment() constructors are special in that we do not want - // users to call them using "new". We prohibit that by giving them bodies - // that throw, even though const constructors are not allowed to have bodies. - // Disable those static errors. - //ignore: const_constructor_with_body - //ignore: const_factory - external const factory bool.fromEnvironment(String name, - {bool defaultValue = false}); - - /// Whether there is an environment declaration [name]. - /// - /// Returns true iff there is an environment declaration with the name [name] - /// If there is then the value of that declaration can be accessed using - /// `const String.fromEnvironment(name)`. Otherwise, - /// `String.fromEnvironment(name, defaultValue: someString)` - /// will evaluate to the given `defaultValue`. - /// - /// This constructor can be used to handle an absent declaration - /// specifically, in ways that cannot be represented by providing - /// a default value to the `C.fromEnvironment` constructor where `C` - /// is [String], [int], or [bool]. - /// - /// Example: - /// ```dart - /// const loggingIsDeclared = const bool.hasEnvironment("logging"); - /// - /// const String? logger = loggingIsDeclared - /// ? String.fromEnvironment("logging") - /// : null; - /// ``` - // The .hasEnvironment() constructor is special in that we do not want - // users to call them using "new". We prohibit that by giving them bodies - // that throw, even though const constructors are not allowed to have bodies. - // Disable those static errors. - //ignore: const_constructor_with_body - //ignore: const_factory - external const factory bool.hasEnvironment(String name); - - external int get hashCode; - - /// The logical conjunction ("and") of this and [other]. - /// - /// Returns `true` if both this and [other] are `true`, and `false` otherwise. - @Since("2.1") - bool operator &(bool other) => other && this; - - /// The logical disjunction ("inclusive or") of this and [other]. - /// - /// Returns `true` if either this or [other] is `true`, and `false` otherwise. - @Since("2.1") - bool operator |(bool other) => other || this; - - /// The logical exclusive disjunction ("exclusive or") of this and [other]. - /// - /// Returns whether this and [other] are neither both `true` nor both `false`. - @Since("2.1") - bool operator ^(bool other) => !other == this; - - /** - * Returns either `"true"` for `true` and `"false"` for `false`. - */ - String toString() { - return this ? "true" : "false"; - } -} diff --git a/sdk_nnbd/lib/core/comparable.dart b/sdk_nnbd/lib/core/comparable.dart deleted file mode 100644 index 835aa34b1f6..00000000000 --- a/sdk_nnbd/lib/core/comparable.dart +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright (c) 2011, 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. - -part of dart.core; - -/** - * The signature of a generic comparison function. - * - * A comparison function represents an ordering on a type of objects. - * A total ordering on a type means that for two values, either they - * are equal or one is greater than the other (and the latter must then be - * smaller than the former). - * - * A [Comparator] function represents such a total ordering by returning - * - * * a negative integer if [a] is smaller than [b], - * * zero if [a] is equal to [b], and - * * a positive integer if [a] is greater than [b]. - */ -typedef Comparator = int Function(T a, T b); - -/** - * Interface used by types that have an intrinsic ordering. - * - * The [compareTo] operation defines a total ordering of objects, - * which can be used for ordering and sorting. - * - * The [Comparable] interface should be used for the natural ordering of a type. - * If a type can be ordered in more than one way, - * and none of them is the obvious natural ordering, - * then it might be better not to use the [Comparable] interface, - * and to provide separate [Comparator]s instead. - * - * It is recommended that the order of a [Comparable] agrees - * with its operator [operator ==] equality (`a.compareTo(b) == 0` iff `a == b`), - * but this is not a requirement. - * For example, [double] and [DateTime] have `compareTo` methods - * that do not agree with operator [operator ==]. - * For doubles the [compareTo] method is more precise than the equality, - * and for [DateTime] it is less precise. - * - * Examples: - * - * (0.0).compareTo(-0.0); // => 1 - * 0.0 == -0.0; // => true - * var dt = new DateTime.now(); - * var dt2 = dt.toUtc(); - * dt == dt2; // => false - * dt.compareTo(dt2); // => 0 - * - * The [Comparable] interface does not imply the existence - * of the comparison operators `<`, `<=`, `>` and `>=`. - * These should only be defined - * if the ordering is a less-than/greater-than ordering, - * that is, an ordering where you would naturally - * use the words "less than" about the order of two elements. - * - * If the equality operator and [compareTo] disagree, - * the comparison operators should follow the equality operator, - * and will likely also disagree with [compareTo]. - * Otherwise they should match the [compareTo] method, - * so that `a < b` iff `a.compareTo(b) < 0`. - * - * The [double] class defines comparison operators - * that are compatible with equality. - * The operators differ from `double.compareTo` on -0.0 and NaN. - * - * The [DateTime] class has no comparison operators, instead it has the more - * precisely named [DateTime.isBefore] and [DateTime.isAfter]. - */ -abstract class Comparable { - /** - * Compares this object to another [Comparable] - * - * Returns a value like a [Comparator] when comparing `this` to [other]. - * That is, it returns a negative integer if `this` is ordered before [other], - * a positive integer if `this` is ordered after [other], - * and zero if `this` and [other] are ordered together. - * - * The [other] argument must be a value that is comparable to this object. - */ - int compareTo(T other); - - /** - * A [Comparator] that compares one comparable to another. - * - * It returns the result of `a.compareTo(b)`. - * - * This utility function is used as the default comparator - * for ordering collections, for example in the [List] sort function. - */ - static int compare(Comparable a, Comparable b) => a.compareTo(b); -} diff --git a/sdk_nnbd/lib/core/core.dart b/sdk_nnbd/lib/core/core.dart deleted file mode 100644 index dc037a377df..00000000000 --- a/sdk_nnbd/lib/core/core.dart +++ /dev/null @@ -1,208 +0,0 @@ -// Copyright (c) 2012, 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. - -/** - * - * Built-in types, collections, - * and other core functionality for every Dart program. - * - * This library is automatically imported. - * - * Some classes in this library, - * such as [String] and [num], - * support Dart's built-in data types. - * Other classes, such as [List] and [Map], provide data structures - * for managing collections of objects. - * And still other classes represent commonly used types of data - * such as URIs, dates and times, and errors. - * - * ## Numbers and booleans - * - * [int] and [double] provide support for Dart's built-in numerical data types: - * integers and double-precision floating point numbers, respectively. - * An object of type [bool] is either true or false. - * Variables of these types can be constructed from literals: - * - * int meaningOfLife = 42; - * double valueOfPi = 3.141592; - * bool visible = true; - * - * ## Strings and regular expressions - * - * A [String] is immutable and represents a sequence of characters. - * - * String shakespeareQuote = "All the world's a stage, ..."; - * - * [StringBuffer] provides a way to construct strings efficiently. - * - * StringBuffer moreShakespeare = new StringBuffer(); - * moreShakespeare.write('And all the men and women '); - * moreShakespeare.write('merely players; ...'); - * - * The String and StringBuffer classes implement string concatenation, - * interpolation, and other string manipulation features. - * - * String philosophy = 'Live on '; - * String get palindrome => philosophy + philosophy.split('').reversed.join(); - * - * [RegExp] implements Dart regular expressions, - * which provide a grammar for matching patterns within text. - * For example, here's a regular expression that matches - * a string of one or more digits: - * - * var numbers = new RegExp(r'\d+'); - * - * Dart regular expressions have the same syntax and semantics as - * JavaScript regular expressions. See - * - * for the specification of JavaScript regular expressions. - * - * ## Collections - * - * The dart:core library provides basic collections, - * such as [List], [Map], and [Set]. - * - * A List is an ordered collection of objects, with a length. - * Lists are sometimes called arrays. - * Use a List when you need to access objects by index. - * - * List superheroes = [ 'Batman', 'Superman', 'Harry Potter' ]; - * - * A Set is an unordered collection of unique objects. - * You cannot get an item by index (position). - * Adding a duplicate item has no effect. - * - * Set villains = new Set(); - * villains.add('Joker'); - * villains.addAll( ['Lex Luther', 'Voldemort'] ); - * - * A Map is an unordered collection of key-value pairs. - * Maps are sometimes called associative arrays because - * maps associate a key to some value for easy retrieval. - * Keys are unique. - * Use a Map when you need to access objects - * by a unique identifier. - * - * Map sidekicks = { 'Batman': 'Robin', - * 'Superman': 'Lois Lane', - * 'Harry Potter': 'Ron and Hermione' }; - * - * In addition to these classes, - * dart:core contains [Iterable], - * an interface that defines functionality - * common in collections of objects. - * Examples include the ability - * to run a function on each element in the collection, - * to apply a test to each element, - * to retrieve an object, and to determine length. - * - * Iterable is implemented by List and Set, - * and used by Map for its keys and values. - * - * For other kinds of collections, check out the - * `dart:collection` library. - * - * ## Date and time - * - * Use [DateTime] to represent a point in time - * and [Duration] to represent a span of time. - * - * You can create DateTime objects with constructors - * or by parsing a correctly formatted string. - * - * DateTime now = new DateTime.now(); - * DateTime berlinWallFell = new DateTime(1989, 11, 9); - * DateTime moonLanding = DateTime.parse("1969-07-20"); - * - * Create a Duration object specifying the individual time units. - * - * Duration timeRemaining = new Duration(hours:56, minutes:14); - * - * In addition to DateTime and Duration, - * dart:core contains the [Stopwatch] class for measuring elapsed time. - * - * ## Uri - * - * A [Uri] object represents a uniform resource identifier, - * which identifies a resource on the web. - * - * Uri dartlang = Uri.parse('http://dartlang.org/'); - * - * ## Errors - * - * The [Error] class represents the occurrence of an error - * during runtime. - * Subclasses of this class represent specific kinds of errors. - * - * ## Other documentation - * - * For more information about how to use the built-in types, refer to [Built-in - * Types](http://www.dartlang.org/docs/dart-up-and-running/contents/ch02.html#built-in-types) - * in Chapter 2 of - * [Dart: Up and Running](http://www.dartlang.org/docs/dart-up-and-running/). - * - * Also, see [dart:core - Numbers, Collections, Strings, and - * More](https://www.dartlang.org/docs/dart-up-and-running/ch03.html#dartcore---numbers-collections-strings-and-more) - * for more coverage of classes in this package. - * - * The - * [Dart Language Specification](http://www.dartlang.org/docs/spec/) - * provides technical details. - * - * {@category Core} - */ -library dart.core; - -import "dart:collection"; -import "dart:_internal" hide Symbol, LinkedList, LinkedListEntry; -import "dart:_internal" as internal show Symbol; -import "dart:convert" - show - ascii, - base64, - Base64Codec, - Encoding, - latin1, - StringConversionSink, - utf8; -import "dart:math" show Random; // Used by List.shuffle. -import "dart:typed_data" show Uint8List; - -@Since("2.1") -export "dart:async" show Future, Stream; - -part "annotations.dart"; -part "bigint.dart"; -part "bool.dart"; -part "comparable.dart"; -part "date_time.dart"; -part "double.dart"; -part "duration.dart"; -part "errors.dart"; -part "exceptions.dart"; -part "expando.dart"; -part "function.dart"; -part "identical.dart"; -part "int.dart"; -part "invocation.dart"; -part "iterable.dart"; -part "iterator.dart"; -part "list.dart"; -part "map.dart"; -part "null.dart"; -part "num.dart"; -part "object.dart"; -part "pattern.dart"; -part "print.dart"; -part "regexp.dart"; -part "set.dart"; -part "sink.dart"; -part "stacktrace.dart"; -part "stopwatch.dart"; -part "string.dart"; -part "string_buffer.dart"; -part "string_sink.dart"; -part "symbol.dart"; -part "type.dart"; -part "uri.dart"; diff --git a/sdk_nnbd/lib/core/core_sources.gni b/sdk_nnbd/lib/core/core_sources.gni deleted file mode 100644 index ce2785ecc83..00000000000 --- a/sdk_nnbd/lib/core/core_sources.gni +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright (c) 2017, 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. - -core_sdk_sources = [ - "core.dart", - - # The above file needs to be first as it lists the parts below. - "annotations.dart", - "bigint.dart", - "bool.dart", - "comparable.dart", - "date_time.dart", - "double.dart", - "duration.dart", - "errors.dart", - "exceptions.dart", - "expando.dart", - "function.dart", - "identical.dart", - "int.dart", - "invocation.dart", - "iterable.dart", - "iterator.dart", - "list.dart", - "map.dart", - "null.dart", - "num.dart", - "object.dart", - "pattern.dart", - "print.dart", - "regexp.dart", - "set.dart", - "sink.dart", - "stacktrace.dart", - "stopwatch.dart", - "string.dart", - "string_buffer.dart", - "string_sink.dart", - "symbol.dart", - "type.dart", - "uri.dart", -] diff --git a/sdk_nnbd/lib/core/date_time.dart b/sdk_nnbd/lib/core/date_time.dart deleted file mode 100644 index ae139229566..00000000000 --- a/sdk_nnbd/lib/core/date_time.dart +++ /dev/null @@ -1,875 +0,0 @@ -// Copyright (c) 2011, 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. - -part of dart.core; - -/** - * An instant in time, such as July 20, 1969, 8:18pm GMT. - * - * DateTimes can represent time values that are at a distance of at most - * 100,000,000 days from epoch (1970-01-01 UTC): -271821-04-20 to 275760-09-13. - * - * Create a DateTime object by using one of the constructors - * or by parsing a correctly formatted string, - * which complies with a subset of ISO 8601. - * Note that hours are specified between 0 and 23, - * as in a 24-hour clock. - * For example: - * - * ``` - * var now = new DateTime.now(); - * var berlinWallFell = new DateTime.utc(1989, 11, 9); - * var moonLanding = DateTime.parse("1969-07-20 20:18:04Z"); // 8:18pm - * ``` - * - * A DateTime object is anchored either in the UTC time zone - * or in the local time zone of the current computer - * when the object is created. - * - * Once created, neither the value nor the time zone - * of a DateTime object may be changed. - * - * You can use properties to get - * the individual units of a DateTime object. - * - * ``` - * assert(berlinWallFell.month == 11); - * assert(moonLanding.hour == 20); - * ``` - * - * For convenience and readability, - * the DateTime class provides a constant for each day and month - * name - for example, [august] and [friday]. - * You can use these constants to improve code readability: - * - * ``` - * var berlinWallFell = new DateTime.utc(1989, DateTime.november, 9); - * assert(berlinWallFell.weekday == DateTime.thursday); - * ``` - * - * Day and month values begin at 1, and the week starts on Monday. - * That is, the constants [january] and [monday] are both 1. - * - * ## Working with UTC and local time - * - * A DateTime object is in the local time zone - * unless explicitly created in the UTC time zone. - * - * ``` - * var dDay = new DateTime.utc(1944, 6, 6); - * ``` - * - * Use [isUtc] to determine whether a DateTime object is based in UTC. - * Use the methods [toLocal] and [toUtc] - * to get the equivalent date/time value specified in the other time zone. - * Use [timeZoneName] to get an abbreviated name of the time zone - * for the DateTime object. - * To find the difference - * between UTC and the time zone of a DateTime object - * call [timeZoneOffset]. - * - * ## Comparing DateTime objects - * - * The DateTime class contains several handy methods, - * such as [isAfter], [isBefore], and [isAtSameMomentAs], - * for comparing DateTime objects. - * - * ``` - * assert(berlinWallFell.isAfter(moonLanding) == true); - * assert(berlinWallFell.isBefore(moonLanding) == false); - * ``` - * - * ## Using DateTime with Duration - * - * Use the [add] and [subtract] methods with a [Duration] object - * to create a new DateTime object based on another. - * For example, to find the date that is sixty days (24 * 60 hours) after today, - * write: - * - * ``` - * var now = new DateTime.now(); - * var sixtyDaysFromNow = now.add(new Duration(days: 60)); - * ``` - * - * To find out how much time is between two DateTime objects use - * [difference], which returns a [Duration] object: - * - * ``` - * var difference = berlinWallFell.difference(moonLanding); - * assert(difference.inDays == 7416); - * ``` - * - * The difference between two dates in different time zones - * is just the number of nanoseconds between the two points in time. - * It doesn't take calendar days into account. - * That means that the difference between two midnights in local time may be - * less than 24 hours times the number of days between them, - * if there is a daylight saving change in between. - * If the difference above is calculated using Australian local time, the - * difference is 7415 days and 23 hours, which is only 7415 whole days as - * reported by `inDays`. - * - * ## Other resources - * - * See [Duration] to represent a span of time. - * See [Stopwatch] to measure timespans. - * - * The DateTime class does not provide internationalization. - * To internationalize your code, use - * the [intl](https://pub.dev/packages/intl) package. - * - */ -class DateTime implements Comparable { - // Weekday constants that are returned by [weekday] method: - static const int monday = 1; - static const int tuesday = 2; - static const int wednesday = 3; - static const int thursday = 4; - static const int friday = 5; - static const int saturday = 6; - static const int sunday = 7; - static const int daysPerWeek = 7; - - // Month constants that are returned by the [month] getter. - static const int january = 1; - static const int february = 2; - static const int march = 3; - static const int april = 4; - static const int may = 5; - static const int june = 6; - static const int july = 7; - static const int august = 8; - static const int september = 9; - static const int october = 10; - static const int november = 11; - static const int december = 12; - static const int monthsPerYear = 12; - - /** - * The value of this DateTime. - * - * The content of this field is implementation dependent. On JavaScript it is - * equal to [millisecondsSinceEpoch]. On the VM it is equal to - * [microsecondsSinceEpoch]. - */ - final int _value; - - /** - * True if this [DateTime] is set to UTC time. - * - * ``` - * var dDay = new DateTime.utc(1944, 6, 6); - * assert(dDay.isUtc); - * ``` - * - */ - final bool isUtc; - - /** - * Constructs a [DateTime] instance specified in the local time zone. - * - * For example, - * to create a new DateTime object representing the 7th of September 2017, - * 5:30pm - * - * ``` - * var dentistAppointment = new DateTime(2017, 9, 7, 17, 30); - * ``` - */ - DateTime(int year, - [int month = 1, - int day = 1, - int hour = 0, - int minute = 0, - int second = 0, - int millisecond = 0, - int microsecond = 0]) - : this._internal(year, month, day, hour, minute, second, millisecond, - microsecond, false); - - /** - * Constructs a [DateTime] instance specified in the UTC time zone. - * - * ``` - * var moonLanding = new DateTime.utc(1969, 7, 20, 20, 18, 04); - * ``` - * - * When dealing with dates or historic events prefer to use UTC DateTimes, - * since they are unaffected by daylight-saving changes and are unaffected - * by the local timezone. - */ - DateTime.utc(int year, - [int month = 1, - int day = 1, - int hour = 0, - int minute = 0, - int second = 0, - int millisecond = 0, - int microsecond = 0]) - : this._internal(year, month, day, hour, minute, second, millisecond, - microsecond, true); - - /** - * Constructs a [DateTime] instance with current date and time in the - * local time zone. - * - * ``` - * var thisInstant = new DateTime.now(); - * ``` - */ - DateTime.now() : this._now(); - - /** - * Constructs a new [DateTime] instance based on [formattedString]. - * - * The [formattedString] must not be `null`. - * Throws a [FormatException] if the input string cannot be parsed. - * - * The function parses a subset of ISO 8601 - * which includes the subset accepted by RFC 3339. - * - * The accepted inputs are currently: - * - * * A date: A signed four-to-six digit year, two digit month and - * two digit day, optionally separated by `-` characters. - * Examples: "19700101", "-0004-12-24", "81030-04-01". - * * An optional time part, separated from the date by either `T` or a space. - * The time part is a two digit hour, - * then optionally a two digit minutes value, - * then optionally a two digit seconds value, and - * then optionally a '.' or ',' followed by at least a one digit - * second fraction. - * The minutes and seconds may be separated from the previous parts by a - * ':'. - * Examples: "12", "12:30:24.124", "12:30:24,124", "123010.50". - * * An optional time-zone offset part, - * possibly separated from the previous by a space. - * The time zone is either 'z' or 'Z', or it is a signed two digit hour - * part and an optional two digit minute part. The sign must be either - * "+" or "-", and can not be omitted. - * The minutes may be separated from the hours by a ':'. - * Examples: "Z", "-10", "+01:30", "+1130". - * - * This includes the output of both [toString] and [toIso8601String], which - * will be parsed back into a `DateTime` object with the same time as the - * original. - * - * The result is always in either local time or UTC. - * If a time zone offset other than UTC is specified, - * the time is converted to the equivalent UTC time. - * - * Examples of accepted strings: - * - * * `"2012-02-27 13:27:00"` - * * `"2012-02-27 13:27:00.123456789z"` - * * `"2012-02-27 13:27:00,123456789z"` - * * `"20120227 13:27:00"` - * * `"20120227T132700"` - * * `"20120227"` - * * `"+20120227"` - * * `"2012-02-27T14Z"` - * * `"2012-02-27T14+00:00"` - * * `"-123450101 00:00:00 Z"`: in the year -12345. - * * `"2002-02-27T14:00:00-0500"`: Same as `"2002-02-27T19:00:00Z"` - */ - // TODO(lrn): restrict incorrect values like 2003-02-29T50:70:80. - // Or not, that may be a breaking change. - static DateTime parse(String formattedString) { - var re = _parseFormat; - Match? match = re.firstMatch(formattedString); - if (match != null) { - int parseIntOrZero(String? matched) { - if (matched == null) return 0; - return int.parse(matched); - } - - // Parses fractional second digits of '.(\d+)' into the combined - // microseconds. We only use the first 6 digits because of DateTime - // precision of 999 milliseconds and 999 microseconds. - int parseMilliAndMicroseconds(String? matched) { - if (matched == null) return 0; - int length = matched.length; - assert(length >= 1); - int result = 0; - for (int i = 0; i < 6; i++) { - result *= 10; - if (i < matched.length) { - result += matched.codeUnitAt(i) ^ 0x30; - } - } - return result; - } - - int years = int.parse(match[1]!); - int month = int.parse(match[2]!); - int day = int.parse(match[3]!); - int hour = parseIntOrZero(match[4]); - int minute = parseIntOrZero(match[5]); - int second = parseIntOrZero(match[6]); - int milliAndMicroseconds = parseMilliAndMicroseconds(match[7]); - int millisecond = - milliAndMicroseconds ~/ Duration.microsecondsPerMillisecond; - int microsecond = milliAndMicroseconds - .remainder(Duration.microsecondsPerMillisecond) as int; - bool isUtc = false; - if (match[8] != null) { - // timezone part - isUtc = true; - String? tzSign = match[9]; - if (tzSign != null) { - // timezone other than 'Z' and 'z'. - int sign = (tzSign == '-') ? -1 : 1; - int hourDifference = int.parse(match[10]!); - int minuteDifference = parseIntOrZero(match[11]); - minuteDifference += 60 * hourDifference; - minute -= sign * minuteDifference; - } - } - int? value = _brokenDownDateToValue(years, month, day, hour, minute, - second, millisecond, microsecond, isUtc); - if (value == null) { - throw FormatException("Time out of range", formattedString); - } - return DateTime._withValue(value, isUtc: isUtc); - } else { - throw FormatException("Invalid date format", formattedString); - } - } - - /** - * Constructs a new [DateTime] instance based on [formattedString]. - * - * Works like [parse] except that this function returns `null` - * where [parse] would throw a [FormatException]. - */ - static DateTime? tryParse(String formattedString) { - // TODO: Optimize to avoid throwing. - try { - return parse(formattedString); - } on FormatException { - return null; - } - } - - static const int _maxMillisecondsSinceEpoch = 8640000000000000; - - /** - * Constructs a new [DateTime] instance - * with the given [millisecondsSinceEpoch]. - * - * If [isUtc] is false then the date is in the local time zone. - * - * The constructed [DateTime] represents - * 1970-01-01T00:00:00Z + [millisecondsSinceEpoch] ms in the given - * time zone (local or UTC). - */ - external DateTime.fromMillisecondsSinceEpoch(int millisecondsSinceEpoch, - {bool isUtc = false}); - - /** - * Constructs a new [DateTime] instance - * with the given [microsecondsSinceEpoch]. - * - * If [isUtc] is false then the date is in the local time zone. - * - * The constructed [DateTime] represents - * 1970-01-01T00:00:00Z + [microsecondsSinceEpoch] us in the given - * time zone (local or UTC). - */ - external DateTime.fromMicrosecondsSinceEpoch(int microsecondsSinceEpoch, - {bool isUtc = false}); - - /** - * Constructs a new [DateTime] instance with the given value. - * - * If [isUtc] is false then the date is in the local time zone. - */ - DateTime._withValue(this._value, {required this.isUtc}) { - if (millisecondsSinceEpoch.abs() > _maxMillisecondsSinceEpoch || - (millisecondsSinceEpoch.abs() == _maxMillisecondsSinceEpoch && - microsecond != 0)) { - throw ArgumentError( - "DateTime is outside valid range: $millisecondsSinceEpoch"); - } - // For backwards compatibility with legacy mode. - ArgumentError.checkNotNull(isUtc, "isUtc"); - } - - /** - * Returns true if [other] is a [DateTime] at the same moment and in the - * same time zone (UTC or local). - * - * ``` - * var dDayUtc = new DateTime.utc(1944, 6, 6); - * var dDayLocal = dDayUtc.toLocal(); - * - * // These two dates are at the same moment, but are in different zones. - * assert(dDayUtc != dDayLocal); - * ``` - * - * See [isAtSameMomentAs] for a comparison that compares moments in time - * independently of their zones. - */ - external bool operator ==(Object other); - - /** - * Returns true if [this] occurs before [other]. - * - * The comparison is independent - * of whether the time is in UTC or in the local time zone. - * - * ``` - * var now = new DateTime.now(); - * var earlier = now.subtract(const Duration(seconds: 5)); - * assert(earlier.isBefore(now)); - * assert(!now.isBefore(now)); - * - * // This relation stays the same, even when changing timezones. - * assert(earlier.isBefore(now.toUtc())); - * assert(earlier.toUtc().isBefore(now)); - * - * assert(!now.toUtc().isBefore(now)); - * assert(!now.isBefore(now.toUtc())); - * ``` - */ - external bool isBefore(DateTime other); - - /** - * Returns true if [this] occurs after [other]. - * - * The comparison is independent - * of whether the time is in UTC or in the local time zone. - * - * ``` - * var now = new DateTime.now(); - * var later = now.add(const Duration(seconds: 5)); - * assert(later.isAfter(now)); - * assert(!now.isBefore(now)); - * - * // This relation stays the same, even when changing timezones. - * assert(later.isAfter(now.toUtc())); - * assert(later.toUtc().isAfter(now)); - * - * assert(!now.toUtc().isBefore(now)); - * assert(!now.isBefore(now.toUtc())); - * ``` - */ - external bool isAfter(DateTime other); - - /** - * Returns true if [this] occurs at the same moment as [other]. - * - * The comparison is independent of whether the time is in UTC or in the local - * time zone. - * - * ``` - * var now = new DateTime.now(); - * var later = now.add(const Duration(seconds: 5)); - * assert(!later.isAtSameMomentAs(now)); - * assert(now.isAtSameMomentAs(now)); - * - * // This relation stays the same, even when changing timezones. - * assert(!later.isAtSameMomentAs(now.toUtc())); - * assert(!later.toUtc().isAtSameMomentAs(now)); - * - * assert(now.toUtc().isAtSameMomentAs(now)); - * assert(now.isAtSameMomentAs(now.toUtc())); - * ``` - */ - external bool isAtSameMomentAs(DateTime other); - - /** - * Compares this DateTime object to [other], - * returning zero if the values are equal. - * - * Returns a negative value if this DateTime [isBefore] [other]. It returns 0 - * if it [isAtSameMomentAs] [other], and returns a positive value otherwise - * (when this [isAfter] [other]). - */ - external int compareTo(DateTime other); - - int get hashCode => (_value ^ (_value >> 30)) & 0x3FFFFFFF; - - /** - * Returns this DateTime value in the local time zone. - * - * Returns [this] if it is already in the local time zone. - * Otherwise this method is equivalent to: - * - * ``` - * new DateTime.fromMicrosecondsSinceEpoch(microsecondsSinceEpoch, - * isUtc: false) - * ``` - */ - DateTime toLocal() { - if (isUtc) { - return DateTime._withValue(_value, isUtc: false); - } - return this; - } - - /** - * Returns this DateTime value in the UTC time zone. - * - * Returns [this] if it is already in UTC. - * Otherwise this method is equivalent to: - * - * ``` - * new DateTime.fromMicrosecondsSinceEpoch(microsecondsSinceEpoch, - * isUtc: true) - * ``` - */ - DateTime toUtc() { - if (isUtc) return this; - return DateTime._withValue(_value, isUtc: true); - } - - static String _fourDigits(int n) { - int absN = n.abs(); - String sign = n < 0 ? "-" : ""; - if (absN >= 1000) return "$n"; - if (absN >= 100) return "${sign}0$absN"; - if (absN >= 10) return "${sign}00$absN"; - return "${sign}000$absN"; - } - - static String _sixDigits(int n) { - assert(n < -9999 || n > 9999); - int absN = n.abs(); - String sign = n < 0 ? "-" : "+"; - if (absN >= 100000) return "$sign$absN"; - return "${sign}0$absN"; - } - - static String _threeDigits(int n) { - if (n >= 100) return "${n}"; - if (n >= 10) return "0${n}"; - return "00${n}"; - } - - static String _twoDigits(int n) { - if (n >= 10) return "${n}"; - return "0${n}"; - } - - /** - * Returns a human-readable string for this instance. - * - * The returned string is constructed for the time zone of this instance. - * The `toString()` method provides a simply formatted string. - * It does not support internationalized strings. - * Use the [intl](https://pub.dev/packages/intl) package - * at the pub shared packages repo. - * - * The resulting string can be parsed back using [parse]. - */ - String toString() { - String y = _fourDigits(year); - String m = _twoDigits(month); - String d = _twoDigits(day); - String h = _twoDigits(hour); - String min = _twoDigits(minute); - String sec = _twoDigits(second); - String ms = _threeDigits(millisecond); - String us = microsecond == 0 ? "" : _threeDigits(microsecond); - if (isUtc) { - return "$y-$m-$d $h:$min:$sec.$ms${us}Z"; - } else { - return "$y-$m-$d $h:$min:$sec.$ms$us"; - } - } - - /** - * Returns an ISO-8601 full-precision extended format representation. - * - * The format is `yyyy-MM-ddTHH:mm:ss.mmmuuuZ` for UTC time, and - * `yyyy-MM-ddTHH:mm:ss.mmmuuu` (no trailing "Z") for local/non-UTC time, - * where: - * - * * `yyyy` is a, possibly negative, four digit representation of the year, - * if the year is in the range -9999 to 9999, - * otherwise it is a signed six digit representation of the year. - * * `MM` is the month in the range 01 to 12, - * * `dd` is the day of the month in the range 01 to 31, - * * `HH` are hours in the range 00 to 23, - * * `mm` are minutes in the range 00 to 59, - * * `ss` are seconds in the range 00 to 59 (no leap seconds), - * * `mmm` are milliseconds in the range 000 to 999, and - * * `uuu` are microseconds in the range 001 to 999. If [microsecond] equals - * 0, then this part is omitted. - * - * The resulting string can be parsed back using [parse]. - */ - String toIso8601String() { - String y = - (year >= -9999 && year <= 9999) ? _fourDigits(year) : _sixDigits(year); - String m = _twoDigits(month); - String d = _twoDigits(day); - String h = _twoDigits(hour); - String min = _twoDigits(minute); - String sec = _twoDigits(second); - String ms = _threeDigits(millisecond); - String us = microsecond == 0 ? "" : _threeDigits(microsecond); - if (isUtc) { - return "$y-$m-${d}T$h:$min:$sec.$ms${us}Z"; - } else { - return "$y-$m-${d}T$h:$min:$sec.$ms$us"; - } - } - - /** - * Returns a new [DateTime] instance with [duration] added to [this]. - * - * ``` - * var today = new DateTime.now(); - * var fiftyDaysFromNow = today.add(new Duration(days: 50)); - * ``` - * - * Notice that the duration being added is actually 50 * 24 * 60 * 60 - * seconds. If the resulting `DateTime` has a different daylight saving offset - * than `this`, then the result won't have the same time-of-day as `this`, and - * may not even hit the calendar date 50 days later. - * - * Be careful when working with dates in local time. - */ - external DateTime add(Duration duration); - - /** - * Returns a new [DateTime] instance with [duration] subtracted from [this]. - * - * ``` - * DateTime today = new DateTime.now(); - * DateTime fiftyDaysAgo = today.subtract(new Duration(days: 50)); - * ``` - * - * Notice that the duration being subtracted is actually 50 * 24 * 60 * 60 - * seconds. If the resulting `DateTime` has a different daylight saving offset - * than `this`, then the result won't have the same time-of-day as `this`, and - * may not even hit the calendar date 50 days earlier. - * - * Be careful when working with dates in local time. - */ - external DateTime subtract(Duration duration); - - /** - * Returns a [Duration] with the difference when subtracting [other] from - * [this]. - * - * The returned [Duration] will be negative if [other] occurs after [this]. - * - * ``` - * var berlinWallFell = new DateTime.utc(1989, DateTime.november, 9); - * var dDay = new DateTime.utc(1944, DateTime.june, 6); - * - * Duration difference = berlinWallFell.difference(dDay); - * assert(difference.inDays == 16592); - * ``` - * - * The difference is measured in seconds and fractions of seconds. - * The difference above counts the number of fractional seconds between - * midnight at the beginning of those dates. - * If the dates above had been in local time, not UTC, then the difference - * between two midnights may not be a multiple of 24 hours due to daylight - * saving differences. - * - * For example, in Australia, similar code using local time instead of UTC: - * - * ``` - * var berlinWallFell = new DateTime(1989, DateTime.november, 9); - * var dDay = new DateTime(1944, DateTime.june, 6); - * Duration difference = berlinWallFell.difference(dDay); - * assert(difference.inDays == 16592); - * ``` - * will fail because the difference is actually 16591 days and 23 hours, and - * [Duration.inDays] only returns the number of whole days. - */ - external Duration difference(DateTime other); - - external DateTime._internal(int year, int month, int day, int hour, - int minute, int second, int millisecond, int microsecond, bool isUtc); - - external DateTime._now(); - - /// Returns the time as value (millisecond or microsecond since epoch), or - /// null if the values are out of range. - external static int? _brokenDownDateToValue( - int year, - int month, - int day, - int hour, - int minute, - int second, - int millisecond, - int microsecond, - bool isUtc); - - /** - * The number of milliseconds since - * the "Unix epoch" 1970-01-01T00:00:00Z (UTC). - * - * This value is independent of the time zone. - * - * This value is at most - * 8,640,000,000,000,000ms (100,000,000 days) from the Unix epoch. - * In other words: `millisecondsSinceEpoch.abs() <= 8640000000000000`. - */ - external int get millisecondsSinceEpoch; - - /** - * The number of microseconds since - * the "Unix epoch" 1970-01-01T00:00:00Z (UTC). - * - * This value is independent of the time zone. - * - * This value is at most - * 8,640,000,000,000,000,000us (100,000,000 days) from the Unix epoch. - * In other words: `microsecondsSinceEpoch.abs() <= 8640000000000000000`. - * - * Note that this value does not fit into 53 bits (the size of a IEEE double). - * A JavaScript number is not able to hold this value. - */ - external int get microsecondsSinceEpoch; - - /** - * The time zone name. - * - * This value is provided by the operating system and may be an - * abbreviation or a full name. - * - * In the browser or on Unix-like systems commonly returns abbreviations, - * such as "CET" or "CEST". On Windows returns the full name, for example - * "Pacific Standard Time". - */ - external String get timeZoneName; - - /** - * The time zone offset, which - * is the difference between local time and UTC. - * - * The offset is positive for time zones east of UTC. - * - * Note, that JavaScript, Python and C return the difference between UTC and - * local time. Java, C# and Ruby return the difference between local time and - * UTC. - */ - external Duration get timeZoneOffset; - - /** - * The year. - * - * ``` - * var moonLanding = DateTime.parse("1969-07-20 20:18:04Z"); - * assert(moonLanding.year == 1969); - * ``` - */ - external int get year; - - /** - * The month [1..12]. - * - * ``` - * var moonLanding = DateTime.parse("1969-07-20 20:18:04Z"); - * assert(moonLanding.month == 7); - * assert(moonLanding.month == DateTime.july); - * ``` - */ - external int get month; - - /** - * The day of the month [1..31]. - * - * ``` - * var moonLanding = DateTime.parse("1969-07-20 20:18:04Z"); - * assert(moonLanding.day == 20); - * ``` - */ - external int get day; - - /** - * The hour of the day, expressed as in a 24-hour clock [0..23]. - * - * ``` - * var moonLanding = DateTime.parse("1969-07-20 20:18:04Z"); - * assert(moonLanding.hour == 20); - * ``` - */ - external int get hour; - - /** - * The minute [0...59]. - * - * ``` - * var moonLanding = DateTime.parse("1969-07-20 20:18:04Z"); - * assert(moonLanding.minute == 18); - * ``` - */ - external int get minute; - - /** - * The second [0...59]. - * - * ``` - * var moonLanding = DateTime.parse("1969-07-20 20:18:04Z"); - * assert(moonLanding.second == 4); - * ``` - */ - external int get second; - - /** - * The millisecond [0...999]. - * - * ``` - * var moonLanding = DateTime.parse("1969-07-20 20:18:04Z"); - * assert(moonLanding.millisecond == 0); - * ``` - */ - external int get millisecond; - - /** - * The microsecond [0...999]. - * - * ``` - * var moonLanding = DateTime.parse("1969-07-20 20:18:04Z"); - * assert(moonLanding.microsecond == 0); - * ``` - */ - external int get microsecond; - - /** - * The day of the week [monday]..[sunday]. - * - * In accordance with ISO 8601 - * a week starts with Monday, which has the value 1. - * - * ``` - * var moonLanding = DateTime.parse("1969-07-20 20:18:04Z"); - * assert(moonLanding.weekday == 7); - * assert(moonLanding.weekday == DateTime.sunday); - * ``` - */ - external int get weekday; - - /* - * date ::= yeardate time_opt timezone_opt - * yeardate ::= year colon_opt month colon_opt day - * year ::= sign_opt digit{4,6} - * colon_opt :: | ':' - * sign ::= '+' | '-' - * sign_opt ::= | sign - * month ::= digit{2} - * day ::= digit{2} - * time_opt ::= | (' ' | 'T') hour minutes_opt - * minutes_opt ::= | colon_opt digit{2} seconds_opt - * seconds_opt ::= | colon_opt digit{2} millis_opt - * micros_opt ::= | ('.' | ',') digit+ - * timezone_opt ::= | space_opt timezone - * space_opt :: ' ' | - * timezone ::= 'z' | 'Z' | sign digit{2} timezonemins_opt - * timezonemins_opt ::= | colon_opt digit{2} - */ - static final RegExp _parseFormat = - RegExp(r'^([+-]?\d{4,6})-?(\d\d)-?(\d\d)' // Day part. - r'(?:[ T](\d\d)(?::?(\d\d)(?::?(\d\d)(?:[.,](\d+))?)?)?' // Time part. - r'( ?[zZ]| ?([-+])(\d\d)(?::?(\d\d))?)?)?$'); // Timezone part. -} diff --git a/sdk_nnbd/lib/core/double.dart b/sdk_nnbd/lib/core/double.dart deleted file mode 100644 index 42ff5661f99..00000000000 --- a/sdk_nnbd/lib/core/double.dart +++ /dev/null @@ -1,218 +0,0 @@ -// Copyright (c) 2012, 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. - -part of dart.core; - -// TODO: Convert this abstract class into a concrete class double -// that uses the patch class functionality to account for the -// different platform implementations. - -/** - * A double-precision floating point number. - * - * Representation of Dart doubles containing double specific constants - * and operations and specializations of operations inherited from - * [num]. Dart doubles are 64-bit floating-point numbers as specified in the - * IEEE 754 standard. - * - * The [double] type is contagious. Operations on [double]s return - * [double] results. - * - * It is a compile-time error for a class to attempt to extend or implement - * double. - */ -abstract class double extends num { - static const double nan = 0.0 / 0.0; - static const double infinity = 1.0 / 0.0; - static const double negativeInfinity = -infinity; - static const double minPositive = 5e-324; - static const double maxFinite = 1.7976931348623157e+308; - - double remainder(num other); - - /** Addition operator. */ - double operator +(num other); - - /** Subtraction operator. */ - double operator -(num other); - - /** Multiplication operator. */ - double operator *(num other); - - double operator %(num other); - - /** Division operator. */ - double operator /(num other); - - /** - * Truncating division operator. - * - * The result of the truncating division `a ~/ b` is equivalent to - * `(a / b).truncate()`. - */ - int operator ~/(num other); - - /** Negate operator. */ - double operator -(); - - /** Returns the absolute value of this [double]. */ - double abs(); - - /** - * Returns the sign of the double's numerical value. - * - * Returns -1.0 if the value is less than zero, - * +1.0 if the value is greater than zero, - * and the value itself if it is -0.0, 0.0 or NaN. - */ - double get sign; - - /** - * Returns the integer closest to `this`. - * - * Rounds away from zero when there is no closest integer: - * `(3.5).round() == 4` and `(-3.5).round() == -4`. - * - * If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError]. - */ - int round(); - - /** - * Returns the greatest integer no greater than `this`. - * - * If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError]. - */ - int floor(); - - /** - * Returns the least integer no smaller than `this`. - * - * If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError]. - */ - int ceil(); - - /** - * Returns the integer obtained by discarding any fractional - * digits from `this`. - * - * If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError]. - */ - int truncate(); - - /** - * Returns the integer double value closest to `this`. - * - * Rounds away from zero when there is no closest integer: - * `(3.5).roundToDouble() == 4` and `(-3.5).roundToDouble() == -4`. - * - * If this is already an integer valued double, including `-0.0`, or it is not - * a finite value, the value is returned unmodified. - * - * For the purpose of rounding, `-0.0` is considered to be below `0.0`, - * and `-0.0` is therefore considered closer to negative numbers than `0.0`. - * This means that for a value, `d` in the range `-0.5 < d < 0.0`, - * the result is `-0.0`. - */ - double roundToDouble(); - - /** - * Returns the greatest integer double value no greater than `this`. - * - * If this is already an integer valued double, including `-0.0`, or it is not - * a finite value, the value is returned unmodified. - * - * For the purpose of rounding, `-0.0` is considered to be below `0.0`. - * A number `d` in the range `0.0 < d < 1.0` will return `0.0`. - */ - double floorToDouble(); - - /** - * Returns the least integer double value no smaller than `this`. - * - * If this is already an integer valued double, including `-0.0`, or it is not - * a finite value, the value is returned unmodified. - * - * For the purpose of rounding, `-0.0` is considered to be below `0.0`. - * A number `d` in the range `-1.0 < d < 0.0` will return `-0.0`. - */ - double ceilToDouble(); - - /** - * Returns the integer double value obtained by discarding any fractional - * digits from `this`. - * - * If this is already an integer valued double, including `-0.0`, or it is not - * a finite value, the value is returned unmodified. - * - * For the purpose of rounding, `-0.0` is considered to be below `0.0`. - * A number `d` in the range `-1.0 < d < 0.0` will return `-0.0`, and - * in the range `0.0 < d < 1.0` it will return 0.0. - */ - double truncateToDouble(); - - /** - * Provide a representation of this [double] value. - * - * The representation is a number literal such that the closest double value - * to the representation's mathematical value is this [double]. - * - * Returns "NaN" for the Not-a-Number value. - * Returns "Infinity" and "-Infinity" for positive and negative Infinity. - * Returns "-0.0" for negative zero. - * - * For all doubles, `d`, converting to a string and parsing the string back - * gives the same value again: `d == double.parse(d.toString())` (except when - * `d` is NaN). - */ - String toString(); - - /** - * Parse [source] as an double literal and return its value. - * - * Accepts an optional sign (`+` or `-`) followed by either the characters - * "Infinity", the characters "NaN" or a floating-point representation. - * A floating-point representation is composed of a mantissa and an optional - * exponent part. The mantissa is either a decimal point (`.`) followed by a - * sequence of (decimal) digits, or a sequence of digits - * optionally followed by a decimal point and optionally more digits. The - * (optional) exponent part consists of the character "e" or "E", an optional - * sign, and one or more digits. - * The [source] must not be `null`. - * - * Leading and trailing whitespace is ignored. - * - * If the [source] string is not a valid double literal, the [onError] - * is called with the [source] as argument, and its return value is - * used instead. If no `onError` is provided, a [FormatException] - * is thrown instead. - * - * The [onError] function is only invoked if [source] is a [String] with an - * invalid format. It is not invoked if [source] is `null`. - * - * Examples of accepted strings: - * - * "3.14" - * " 3.14 \xA0" - * "0." - * ".0" - * "-1.e3" - * "1234E+7" - * "+.12e-9" - * "-NaN" - * - * The [onError] parameter is deprecated and will be removed. - * Instead of `double.parse(string, (string) { ... })`, - * you should use `double.tryParse(string) ?? (...)`. - */ - external static double parse(String source, - [@deprecated double onError(String source)?]); - - /** - * Parse [source] as an double literal and return its value. - * - * Like [parse] except that this function returns `null` for invalid inputs - * instead of throwing, and the [source] must still not be `null`. - */ - external static double? tryParse(String source); -} diff --git a/sdk_nnbd/lib/core/duration.dart b/sdk_nnbd/lib/core/duration.dart deleted file mode 100644 index 2a1f406c35d..00000000000 --- a/sdk_nnbd/lib/core/duration.dart +++ /dev/null @@ -1,295 +0,0 @@ -// Copyright (c) 2011, 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. - -part of dart.core; - -/** - * A span of time, such as 27 days, 4 hours, 12 minutes, and 3 seconds. - * - * A `Duration` represents a difference from one point in time to another. The - * duration may be "negative" if the difference is from a later time to an - * earlier. - * - * Durations are context independent. For example, a duration of 2 days is - * always 48 hours, even when it is added to a `DateTime` just when the - * time zone is about to do a daylight-savings switch. (See [DateTime.add]). - * - * Despite the same name, a `Duration` object does not implement "Durations" - * as specified by ISO 8601. In particular, a duration object does not keep - * track of the individually provided members (such as "days" or "hours"), but - * only uses these arguments to compute the length of the corresponding time - * interval. - * - * To create a new Duration object, use this class's single constructor - * giving the appropriate arguments: - * ```dart - * Duration fastestMarathon = new Duration(hours:2, minutes:3, seconds:2); - * ``` - * The [Duration] is the sum of all individual parts. - * This means that individual parts can be larger than the next-bigger unit. - * For example, [inMinutes] can be greater than 59. - * ```dart - * assert(fastestMarathon.inMinutes == 123); - * ``` - * All individual parts are allowed to be negative. - * - * Use one of the properties, such as [inDays], - * to retrieve the integer value of the Duration in the specified time unit. - * Note that the returned value is rounded down. - * For example, - * ```dart - * Duration aLongWeekend = new Duration(hours:88); - * assert(aLongWeekend.inDays == 3); - * ``` - * This class provides a collection of arithmetic - * and comparison operators, - * plus a set of constants useful for converting time units. - * - * See [DateTime] to represent a point in time. - * See [Stopwatch] to measure time-spans. - */ -class Duration implements Comparable { - static const int microsecondsPerMillisecond = 1000; - static const int millisecondsPerSecond = 1000; - static const int secondsPerMinute = 60; - static const int minutesPerHour = 60; - static const int hoursPerDay = 24; - - static const int microsecondsPerSecond = - microsecondsPerMillisecond * millisecondsPerSecond; - static const int microsecondsPerMinute = - microsecondsPerSecond * secondsPerMinute; - static const int microsecondsPerHour = microsecondsPerMinute * minutesPerHour; - static const int microsecondsPerDay = microsecondsPerHour * hoursPerDay; - - static const int millisecondsPerMinute = - millisecondsPerSecond * secondsPerMinute; - static const int millisecondsPerHour = millisecondsPerMinute * minutesPerHour; - static const int millisecondsPerDay = millisecondsPerHour * hoursPerDay; - - static const int secondsPerHour = secondsPerMinute * minutesPerHour; - static const int secondsPerDay = secondsPerHour * hoursPerDay; - - static const int minutesPerDay = minutesPerHour * hoursPerDay; - - static const Duration zero = Duration(seconds: 0); - - /* - * The value of this Duration object in microseconds. - */ - final int _duration; - - /** - * Creates a new Duration object whose value - * is the sum of all individual parts. - * - * Individual parts can be larger than the next-bigger unit. - * For example, [hours] can be greater than 23. - * - * All individual parts are allowed to be negative. - * All arguments are 0 by default. - */ - const Duration( - {int days = 0, - int hours = 0, - int minutes = 0, - int seconds = 0, - int milliseconds = 0, - int microseconds = 0}) - : this._microseconds(microsecondsPerDay * days + - microsecondsPerHour * hours + - microsecondsPerMinute * minutes + - microsecondsPerSecond * seconds + - microsecondsPerMillisecond * milliseconds + - microseconds); - - // Fast path internal direct constructor to avoids the optional arguments and - // [_microseconds] recomputation. - const Duration._microseconds(this._duration); - - /** - * Adds this Duration and [other] and - * returns the sum as a new Duration object. - */ - Duration operator +(Duration other) { - return Duration._microseconds(_duration + other._duration); - } - - /** - * Subtracts [other] from this Duration and - * returns the difference as a new Duration object. - */ - Duration operator -(Duration other) { - return Duration._microseconds(_duration - other._duration); - } - - /** - * Multiplies this Duration by the given [factor] and returns the result - * as a new Duration object. - * - * Note that when [factor] is a double, and the duration is greater than - * 53 bits, precision is lost because of double-precision arithmetic. - */ - Duration operator *(num factor) { - return Duration._microseconds((_duration * factor).round()); - } - - /** - * Divides this Duration by the given [quotient] and returns the truncated - * result as a new Duration object. - * - * Throws an [IntegerDivisionByZeroException] if [quotient] is `0`. - */ - Duration operator ~/(int quotient) { - // By doing the check here instead of relying on "~/" below we get the - // exception even with dart2js. - if (quotient == 0) throw IntegerDivisionByZeroException(); - return Duration._microseconds(_duration ~/ quotient); - } - - /** - * Returns `true` if the value of this Duration - * is less than the value of [other]. - */ - bool operator <(Duration other) => this._duration < other._duration; - - /** - * Returns `true` if the value of this Duration - * is greater than the value of [other]. - */ - bool operator >(Duration other) => this._duration > other._duration; - - /** - * Returns `true` if the value of this Duration - * is less than or equal to the value of [other]. - */ - bool operator <=(Duration other) => this._duration <= other._duration; - - /** - * Returns `true` if the value of this Duration - * is greater than or equal to the value of [other]. - */ - bool operator >=(Duration other) => this._duration >= other._duration; - - /** - * Returns the number of whole days spanned by this Duration. - */ - int get inDays => _duration ~/ Duration.microsecondsPerDay; - - /** - * Returns the number of whole hours spanned by this Duration. - * - * The returned value can be greater than 23. - */ - int get inHours => _duration ~/ Duration.microsecondsPerHour; - - /** - * Returns the number of whole minutes spanned by this Duration. - * - * The returned value can be greater than 59. - */ - int get inMinutes => _duration ~/ Duration.microsecondsPerMinute; - - /** - * Returns the number of whole seconds spanned by this Duration. - * - * The returned value can be greater than 59. - */ - int get inSeconds => _duration ~/ Duration.microsecondsPerSecond; - - /** - * Returns number of whole milliseconds spanned by this Duration. - * - * The returned value can be greater than 999. - */ - int get inMilliseconds => _duration ~/ Duration.microsecondsPerMillisecond; - - /** - * Returns number of whole microseconds spanned by this Duration. - */ - int get inMicroseconds => _duration; - - /** - * Returns `true` if this [Duration] has the same value as [other]. - */ - bool operator ==(Object other) => - other is Duration && _duration == other.inMicroseconds; - - int get hashCode => _duration.hashCode; - - /** - * Compares this [Duration] to [other], returning zero if the values are equal. - * - * Returns a negative integer if this `Duration` is shorter than - * [other], or a positive integer if it is longer. - * - * A negative `Duration` is always considered shorter than a positive one. - * - * It is always the case that `duration1.compareTo(duration2) < 0` iff - * `(someDate + duration1).compareTo(someDate + duration2) < 0`. - */ - int compareTo(Duration other) => _duration.compareTo(other._duration); - - /** - * Returns a string representation of this `Duration`. - * - * Returns a string with hours, minutes, seconds, and microseconds, in the - * following format: `HH:MM:SS.mmmmmm`. For example, - * - * var d = new Duration(days:1, hours:1, minutes:33, microseconds: 500); - * d.toString(); // "25:33:00.000500" - */ - String toString() { - String sixDigits(int n) { - if (n >= 100000) return "$n"; - if (n >= 10000) return "0$n"; - if (n >= 1000) return "00$n"; - if (n >= 100) return "000$n"; - if (n >= 10) return "0000$n"; - return "00000$n"; - } - - String twoDigits(int n) { - if (n >= 10) return "$n"; - return "0$n"; - } - - if (inMicroseconds < 0) { - return "-${-this}"; - } - String twoDigitMinutes = - twoDigits(inMinutes.remainder(minutesPerHour) as int); - String twoDigitSeconds = - twoDigits(inSeconds.remainder(secondsPerMinute) as int); - String sixDigitUs = - sixDigits(inMicroseconds.remainder(microsecondsPerSecond) as int); - return "$inHours:$twoDigitMinutes:$twoDigitSeconds.$sixDigitUs"; - } - - /** - * Returns whether this `Duration` is negative. - * - * A negative `Duration` represents the difference from a later time to an - * earlier time. - */ - bool get isNegative => _duration < 0; - - /** - * Returns a new `Duration` representing the absolute value of this - * `Duration`. - * - * The returned `Duration` has the same length as this one, but is always - * positive. - */ - Duration abs() => Duration._microseconds(_duration.abs()); - - /** - * Returns a new `Duration` representing this `Duration` negated. - * - * The returned `Duration` has the same length as this one, but will have the - * opposite sign of this one. - */ - // Using subtraction helps dart2js avoid negative zeros. - Duration operator -() => Duration._microseconds(0 - _duration); -} diff --git a/sdk_nnbd/lib/core/errors.dart b/sdk_nnbd/lib/core/errors.dart deleted file mode 100644 index a84c6ee35f6..00000000000 --- a/sdk_nnbd/lib/core/errors.dart +++ /dev/null @@ -1,643 +0,0 @@ -// Copyright (c) 2012, 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. - -part of dart.core; - -/** - * Error objects thrown in the case of a program failure. - * - * An `Error` object represents a program failure that the programmer - * should have avoided. - * - * Examples include calling a function with invalid arguments, - * or even with the wrong number of arguments, - * or calling it at a time when it is not allowed. - * - * These are not errors that a caller should expect or catch - - * if they occur, the program is erroneous, - * and terminating the program may be the safest response. - * - * When deciding that a function throws an error, - * the conditions where it happens should be clearly described, - * and they should be detectable and predictable, - * so the programmer using the function can avoid triggering the error. - * - * Such descriptions often uses words like - * "must" or "must not" to describe the condition, - * and if you see words like that in a function's documentation, - * then not satisfying the requirement - * is very likely to cause an error to be thrown. - * - * Example (from [String.contains]): - * - * `startIndex` must not be negative or greater than `length`. - * - * In this case, an error will be thrown if `startIndex` is negative - * or too large. - * - * If the conditions are not detectable before calling a function, - * the called function should not throw an `Error`. - * It may still throw a value, - * but the caller will have to catch the thrown value, - * effectively making it an alternative result rather than an error. - * The thrown object can choose to implement [Exception] - * to document that it represents an exceptional, but not erroneous, occurrence, - * but it has no other effect than documentation. - * - * All non-`null` values can be thrown in Dart. - * Objects extending `Error` are handled specially: - * The first time they are thrown, - * the stack trace at the throw point is recorded - * and stored in the error object. - * It can be retrieved using the [stackTrace] getter. - * An error object that merely implements `Error`, and doesn't extend it, - * will not store the stack trace automatically. - * - * Error objects are also used for system wide failures - * like stack overflow or an out-of-memory situation. - * - * Since errors are not created to be caught, - * there is no need for subclasses to distinguish the errors. - * Instead subclasses have been created in order to make groups - * of related errors easy to create with consistent error messages. - * For example, the [String.contains] method will use a [RangeError] - * if its `startIndex` isn't in the range `0..length`, - * which is easily created by `new RangeError.range(startIndex, 0, length)`. - */ -class Error { - Error(); // Prevent use as mixin. - - /** - * Safely convert a value to a [String] description. - * - * The conversion is guaranteed to not throw, so it won't use the object's - * toString method. - */ - static String safeToString(Object? object) { - if (object is num || object is bool || null == object) { - return object.toString(); - } - if (object is String) { - return _stringToSafeString(object); - } - return _objectToString(object); - } - - /** Convert string to a valid string literal with no control characters. */ - external static String _stringToSafeString(String string); - - external static String _objectToString(Object object); - - external StackTrace? get stackTrace; -} - -/** - * Error thrown by the runtime system when an assert statement fails. - */ -class AssertionError extends Error { - /** Message describing the assertion error. */ - final Object? message; - - AssertionError([this.message]); - - String toString() { - if (message != null) { - return "Assertion failed: ${Error.safeToString(message)}"; - } - return "Assertion failed"; - } -} - -/** - * Error thrown by the runtime system when a dynamic type error happens. - */ -class TypeError extends Error {} - -/** - * Error thrown by the runtime system when a cast operation fails. - */ -@Deprecated("Use TypeError instead") -class CastError extends Error {} - -/** - * Error thrown when attempting to throw `null`. - */ -class NullThrownError extends Error { - @pragma("vm:entry-point") - NullThrownError(); - String toString() => "Throw of null."; -} - -/** - * Error thrown when a function is passed an unacceptable argument. - */ -class ArgumentError extends Error { - /** Whether value was provided. */ - final bool _hasValue; - /** The invalid value. */ - final dynamic invalidValue; - /** Name of the invalid argument, if available. */ - final String? name; - /** Message describing the problem. */ - final dynamic message; - - /** - * The [message] describes the erroneous argument. - * - * Existing code may be using `message` to hold the invalid value. - * If the `message` is not a [String], it is assumed to be a value instead - * of a message. - */ - @pragma("vm:entry-point") - ArgumentError([this.message]) - : invalidValue = null, - _hasValue = false, - name = null; - - /** - * Creates error containing the invalid [value]. - * - * A message is built by suffixing the [message] argument with - * the [name] argument (if provided) and the value. Example - * - * "Invalid argument (foo): null" - * - * The `name` should match the argument name of the function, but if - * the function is a method implementing an interface, and its argument - * names differ from the interface, it might be more useful to use the - * interface method's argument name (or just rename arguments to match). - */ - @pragma("vm:entry-point") - ArgumentError.value(value, [this.name, this.message]) - : invalidValue = value, - _hasValue = true; - - /** - * Create an argument error for a `null` argument that must not be `null`. - */ - ArgumentError.notNull([this.name]) - : _hasValue = false, - message = "Must not be null", - invalidValue = null; - - /** - * Throws if [argument] is `null`. - * - * If [name] is supplied, it is used as the parameter name - * in the error message. - * - * Returns the [argument] if it is not null. - */ - @Since("2.1") - static T checkNotNull<@Since("2.8") T>(T? argument, [String? name]) { - if (argument == null) throw ArgumentError.notNull(name); - return argument; - } - - // Helper functions for toString overridden in subclasses. - String get _errorName => "Invalid argument${!_hasValue ? "(s)" : ""}"; - String get _errorExplanation => ""; - - String toString() { - String? name = this.name; - String nameString = (name == null) ? "" : " ($name)"; - Object? message = this.message; - var messageString = (message == null) ? "" : ": ${message}"; - String prefix = "$_errorName$nameString$messageString"; - if (!_hasValue) return prefix; - // If we know the invalid value, we can try to describe the problem. - String explanation = _errorExplanation; - String errorValue = Error.safeToString(invalidValue); - return "$prefix$explanation: $errorValue"; - } -} - -/** - * Error thrown due to an index being outside a valid range. - */ -class RangeError extends ArgumentError { - /** The minimum value that [value] is allowed to assume. */ - final num? start; - /** The maximum value that [value] is allowed to assume. */ - final num? end; - - // TODO(lrn): This constructor should be called only with string values. - // It currently isn't in all cases. - /** - * Create a new [RangeError] with the given [message]. - */ - @pragma("vm:entry-point") - RangeError(var message) - : start = null, - end = null, - super(message); - - /** - * Create a new [RangeError] with a message for the given [value]. - * - * An optional [name] can specify the argument name that has the - * invalid value, and the [message] can override the default error - * description. - */ - RangeError.value(num value, [String? name, String? message]) - : start = null, - end = null, - super.value(value, name, message ?? "Value not in range"); - - /** - * Create a new [RangeError] for a value being outside the valid range. - * - * The allowed range is from [minValue] to [maxValue], inclusive. - * If `minValue` or `maxValue` are `null`, the range is infinite in - * that direction. - * - * For a range from 0 to the length of something, end exclusive, use - * [RangeError.index]. - * - * An optional [name] can specify the argument name that has the - * invalid value, and the [message] can override the default error - * description. - */ - @pragma("vm:entry-point") - RangeError.range(num invalidValue, int? minValue, int? maxValue, - [String? name, String? message]) - : start = minValue, - end = maxValue, - super.value(invalidValue, name, message ?? "Invalid value"); - - /** - * Creates a new [RangeError] stating that [index] is not a valid index - * into [indexable]. - * - * An optional [name] can specify the argument name that has the - * invalid value, and the [message] can override the default error - * description. - * - * The [length] is the length of [indexable] at the time of the error. - * If `length` is omitted, it defaults to `indexable.length`. - */ - factory RangeError.index(int index, dynamic indexable, - [String? name, String? message, int? length]) = IndexError; - - /** - * Check that an integer [value] lies in a specific interval. - * - * Throws if [value] is not in the interval. - * The interval is from [minValue] to [maxValue], both inclusive. - * - * If [name] or [message] are provided, they are used as the parameter - * name and message text of the thrown error. - * - * Returns [value] if it is in the interval. - */ - static int checkValueInInterval(int value, int minValue, int maxValue, - [String? name, String? message]) { - if (value < minValue || value > maxValue) { - throw RangeError.range(value, minValue, maxValue, name, message); - } - return value; - } - - /** - * Check that [index] is a valid index into an indexable object. - * - * Throws if [index] is not a valid index into [indexable]. - * - * An indexable object is one that has a `length` and a and index-operator - * `[]` that accepts an index if `0 <= index < length`. - * - * If [name] or [message] are provided, they are used as the parameter - * name and message text of the thrown error. If [name] is omitted, it - * defaults to `"index"`. - * - * If [length] is provided, it is used as the length of the indexable object, - * otherwise the length is found as `indexable.length`. - * - * Returns [index] if it is a valid index. - */ - static int checkValidIndex(int index, dynamic indexable, - [String? name, int? length, String? message]) { - length ??= (indexable.length as int); - // Comparing with `0` as receiver produces better dart2js type inference. - if (0 > index || index >= length) { - name ??= "index"; - throw RangeError.index(index, indexable, name, message, length); - } - return index; - } - - /** - * Check that a range represents a slice of an indexable object. - * - * Throws if the range is not valid for an indexable object with - * the given [length]. - * A range is valid for an indexable object with a given [length] - * - * if `0 <= [start] <= [end] <= [length]`. - * An `end` of `null` is considered equivalent to `length`. - * - * The [startName] and [endName] defaults to `"start"` and `"end"`, - * respectively. - * - * Returns the actual `end` value, which is `length` if `end` is `null`, - * and `end` otherwise. - */ - static int checkValidRange(int start, int? end, int length, - [String? startName, String? endName, String? message]) { - // Comparing with `0` as receiver produces better dart2js type inference. - // Ditto `start > end` below. - if (0 > start || start > length) { - startName ??= "start"; - throw RangeError.range(start, 0, length, startName, message); - } - if (end != null) { - if (start > end || end > length) { - endName ??= "end"; - throw RangeError.range(end, start, length, endName, message); - } - return end; - } - return length; - } - - /** - * Check that an integer value is non-negative. - * - * Throws if the value is negative. - * - * If [name] or [message] are provided, they are used as the parameter - * name and message text of the thrown error. If [name] is omitted, it - * defaults to `index`. - * - * Returns [value] if it is not negative. - */ - static int checkNotNegative(int value, [String? name, String? message]) { - if (value < 0) throw RangeError.range(value, 0, null, name, message); - return value; - } - - String get _errorName => "RangeError"; - String get _errorExplanation { - assert(_hasValue); - String explanation = ""; - num? start = this.start; - num? end = this.end; - if (start == null) { - if (end != null) { - explanation = ": Not less than or equal to $end"; - } - // If both are null, we don't add a description of the limits. - } else if (end == null) { - explanation = ": Not greater than or equal to $start"; - } else if (end > start) { - explanation = ": Not in inclusive range $start..$end"; - } else if (end < start) { - explanation = ": Valid value range is empty"; - } else { - // end == start. - explanation = ": Only valid value is $start"; - } - return explanation; - } -} - -/** - * A specialized [RangeError] used when an index is not in the range - * `0..indexable.length-1`. - * - * Also contains the indexable object, its length at the time of the error, - * and the invalid index itself. - */ -class IndexError extends ArgumentError implements RangeError { - /** The indexable object that [invalidValue] was not a valid index into. */ - final indexable; - /** The length of [indexable] at the time of the error. */ - final int length; - - /** - * Creates a new [IndexError] stating that [invalidValue] is not a valid index - * into [indexable]. - * - * The [length] is the length of [indexable] at the time of the error. - * If `length` is omitted, it defaults to `indexable.length`. - * - * The message is used as part of the string representation of the error. - */ - IndexError(int invalidValue, dynamic indexable, - [String? name, String? message, int? length]) - : this.indexable = indexable, - this.length = length ?? indexable.length, - super.value(invalidValue, name, message ?? "Index out of range"); - - // Getters inherited from RangeError. - int get start => 0; - int get end => length - 1; - - String get _errorName => "RangeError"; - String get _errorExplanation { - assert(_hasValue); - int invalidValue = this.invalidValue; - if (invalidValue < 0) { - return ": index must not be negative"; - } - if (length == 0) { - return ": no indices are valid"; - } - return ": index should be less than $length"; - } -} - -/** - * Error thrown when control reaches the end of a switch case. - * - * The Dart specification requires this error to be thrown when - * control reaches the end of a switch case (except the last case - * of a switch) without meeting a break or similar end of the control - * flow. - */ -class FallThroughError extends Error { - FallThroughError(); - @pragma("vm:entry-point") - external FallThroughError._create(String url, int line); - - external String toString(); -} - -/** - * Error thrown when trying to instantiate an abstract class. - */ -class AbstractClassInstantiationError extends Error { - final String _className; - AbstractClassInstantiationError(String className) : _className = className; - - external String toString(); -} - -/** - * Error thrown by the default implementation of [:noSuchMethod:] on [Object]. - */ -class NoSuchMethodError extends Error { - /** - * Create a [NoSuchMethodError] corresponding to a failed method call. - * - * The [receiver] is the receiver of the method call. - * That is, the object on which the method was attempted called. - * - * The [invocation] represents the method call that failed. It - * should not be `null`. - */ - external NoSuchMethodError.withInvocation( - Object? receiver, Invocation invocation); - - // Deprecated constructor to be removed after dart2js updates to the above. - /** - * Create a [NoSuchMethodError] corresponding to a failed method call. - * - * The [receiver] is the receiver of the method call. - * That is, the object on which the method was attempted called. - * If the receiver is `null`, it is interpreted as a call to a top-level - * function of a library. - * - * The [memberName] is a [Symbol] representing the name of the called method - * or accessor. It should not be `null`. - * - * The [positionalArguments] is a list of the positional arguments that the - * method was called with. If `null`, it is considered equivalent to the - * empty list. - * - * The [namedArguments] is a map from [Symbol]s to the values of named - * arguments that the method was called with. If null, it is considered - * equivalent to the empty map. - * - * This constructor does not handle type arguments. - * To include type variables, create an [Invocation] and use - * [NoSuchMethodError.withInvocation]. - */ - @Deprecated("Use NoSuchMethod.withInvocation instead") - external NoSuchMethodError(Object? receiver, Symbol memberName, - List? positionalArguments, Map? namedArguments); - - external String toString(); -} - -/** - * The operation was not allowed by the object. - * - * This [Error] is thrown when an instance cannot implement one of the methods - * in its signature. - */ -@pragma("vm:entry-point") -class UnsupportedError extends Error { - final String? message; - @pragma("vm:entry-point") - UnsupportedError(String this.message); - String toString() => "Unsupported operation: $message"; -} - -/** - * Thrown by operations that have not been implemented yet. - * - * This [Error] is thrown by unfinished code that hasn't yet implemented - * all the features it needs. - * - * If a class is not intending to implement the feature, it should throw - * an [UnsupportedError] instead. This error is only intended for - * use during development. - */ -class UnimplementedError extends Error implements UnsupportedError { - final String? message; - UnimplementedError([this.message]); - String toString() { - var message = this.message; - return (message != null) - ? "UnimplementedError: $message" - : "UnimplementedError"; - } -} - -/** - * The operation was not allowed by the current state of the object. - * - * This is a generic error used for a variety of different erroneous - * actions. The message should be descriptive. - */ -class StateError extends Error { - final String message; - StateError(this.message); - String toString() => "Bad state: $message"; -} - -/** - * Error occurring when a collection is modified during iteration. - * - * Some modifications may be allowed for some collections, so each collection - * ([Iterable] or similar collection of values) should declare which operations - * are allowed during an iteration. - */ -class ConcurrentModificationError extends Error { - /** The object that was modified in an incompatible way. */ - final Object? modifiedObject; - - ConcurrentModificationError([this.modifiedObject]); - - String toString() { - if (modifiedObject == null) { - return "Concurrent modification during iteration."; - } - return "Concurrent modification during iteration: " - "${Error.safeToString(modifiedObject)}."; - } -} - -class OutOfMemoryError implements Error { - @pragma("vm:entry-point") - const OutOfMemoryError(); - String toString() => "Out of Memory"; - - StackTrace? get stackTrace => null; -} - -class StackOverflowError implements Error { - @pragma("vm:entry-point") - const StackOverflowError(); - String toString() => "Stack Overflow"; - - StackTrace? get stackTrace => null; -} - -/** - * Error thrown when a lazily initialized variable cannot be initialized. - * - * A static/library variable with an initializer expression is initialized - * the first time it is read. If evaluating the initializer expression causes - * another read of the variable, this error is thrown. - */ -class CyclicInitializationError extends Error { - final String? variableName; - @pragma("vm:entry-point") - CyclicInitializationError([this.variableName]); - String toString() { - var variableName = this.variableName; - return variableName == null - ? "Reading static variable during its initialization" - : "Reading static variable '$variableName' during its initialization"; - } -} - -/** - * Error thrown when a late variable is accessed in an invalid manner. - * - * A late variable must be initialized before it's read. - * If a late variable has no initializer expression and has not - * been written to, then reading it will throw a - * late initialization error. - * - * A late final variable with no initializer expression may only - * be written to once. - * If it is written to again, the writing will throw a - * late initialization error. - */ -abstract class LateInitializationError extends Error { - factory LateInitializationError._() => throw UnsupportedError(""); -} diff --git a/sdk_nnbd/lib/core/exceptions.dart b/sdk_nnbd/lib/core/exceptions.dart deleted file mode 100644 index 7d76a665504..00000000000 --- a/sdk_nnbd/lib/core/exceptions.dart +++ /dev/null @@ -1,186 +0,0 @@ -// Copyright (c) 2012, 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. - -part of dart.core; - -// Exceptions are thrown either by the VM or from Dart code. - -/** - * A marker interface implemented by all core library exceptions. - * - * An [Exception] is intended to convey information to the user about a failure, - * so that the error can be addressed programmatically. It is intended to be - * caught, and it should contain useful data fields. - * - * Creating instances of [Exception] directly with `Exception("message")` - * is discouraged in library code since it doesn't give users a precise - * type they can catch. It may be reasonable to use instances of this - * class in tests or during development. - */ -abstract class Exception { - factory Exception([var message]) => _Exception(message); -} - -/** Default implementation of [Exception] which carries a message. */ -class _Exception implements Exception { - final dynamic message; - - _Exception([this.message]); - - String toString() { - Object? message = this.message; - if (message == null) return "Exception"; - return "Exception: $message"; - } -} - -/** - * Exception thrown when a string or some other data does not have an expected - * format and cannot be parsed or processed. - */ -class FormatException implements Exception { - /** - * A message describing the format error. - */ - final String message; - - /** - * The actual source input which caused the error. - * - * This is usually a [String], but can be other types too. - * If it is a string, parts of it may be included in the [toString] message. - * - * The source is `null` if omitted or unknown. - */ - final dynamic source; - - /** - * The offset in [source] where the error was detected. - * - * A zero-based offset into the source that marks the format error causing - * this exception to be created. If `source` is a string, this should be a - * string index in the range `0 <= offset <= source.length`. - * - * If input is a string, the [toString] method may represent this offset as - * a line and character position. The offset should be inside the string, - * or at the end of the string. - * - * May be omitted. If present, [source] should also be present if possible. - */ - final int? offset; - - /** - * Creates a new FormatException with an optional error [message]. - * - * Optionally also supply the actual [source] with the incorrect format, - * and the [offset] in the format where a problem was detected. - */ - @pragma("vm:entry-point") - const FormatException([this.message = "", this.source, this.offset]); - - /** - * Returns a description of the format exception. - * - * The description always contains the [message]. - * - * If [source] is present and is a string, the description will contain - * (at least a part of) the source. - * If [offset] is also provided, the part of the source included will - * contain that offset, and the offset will be marked. - * - * If the source is a string and it contains a line break before offset, - * only the line containing offset will be included, and its line number - * will also be part of the description. Line and character offsets are - * 1-based. - */ - String toString() { - String report = "FormatException"; - Object? message = this.message; - if (message != null && "" != message) { - report = "$report: $message"; - } - int? offset = this.offset; - Object? source = this.source; - if (source is String) { - if (offset != null && (offset < 0 || offset > source.length)) { - offset = null; - } - // Source is string and offset is null or valid. - if (offset == null) { - if (source.length > 78) { - source = source.substring(0, 75) + "..."; - } - return "$report\n$source"; - } - int lineNum = 1; - int lineStart = 0; - bool previousCharWasCR = false; - for (int i = 0; i < offset; i++) { - int char = source.codeUnitAt(i); - if (char == 0x0a) { - if (lineStart != i || !previousCharWasCR) { - lineNum++; - } - lineStart = i + 1; - previousCharWasCR = false; - } else if (char == 0x0d) { - lineNum++; - lineStart = i + 1; - previousCharWasCR = true; - } - } - if (lineNum > 1) { - report += " (at line $lineNum, character ${offset - lineStart + 1})\n"; - } else { - report += " (at character ${offset + 1})\n"; - } - int lineEnd = source.length; - for (int i = offset; i < source.length; i++) { - int char = source.codeUnitAt(i); - if (char == 0x0a || char == 0x0d) { - lineEnd = i; - break; - } - } - int length = lineEnd - lineStart; - int start = lineStart; - int end = lineEnd; - String prefix = ""; - String postfix = ""; - if (length > 78) { - // Can't show entire line. Try to anchor at the nearest end, if - // one is within reach. - int index = offset - lineStart; - if (index < 75) { - end = start + 75; - postfix = "..."; - } else if (end - offset < 75) { - start = end - 75; - prefix = "..."; - } else { - // Neither end is near, just pick an area around the offset. - start = offset - 36; - end = offset + 36; - prefix = postfix = "..."; - } - } - String slice = source.substring(start, end); - int markOffset = offset - start + prefix.length; - return "$report$prefix$slice$postfix\n${" " * markOffset}^\n"; - } else { - // The source is not a string. - if (offset != null) { - report += " (at offset $offset)"; - } - return report; - } - } -} - -// Exception thrown when doing integer division with a zero divisor. -class IntegerDivisionByZeroException implements Exception { - @pragma("vm:entry-point") - const IntegerDivisionByZeroException(); - String toString() => "IntegerDivisionByZeroException"; -} diff --git a/sdk_nnbd/lib/core/expando.dart b/sdk_nnbd/lib/core/expando.dart deleted file mode 100644 index ac36b9b7a9d..00000000000 --- a/sdk_nnbd/lib/core/expando.dart +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) 2012, 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. - -part of dart.core; - -/** - * An [Expando] allows adding new properties to objects. - * - * Does not work on numbers, strings, booleans or `null`. - * - * An `Expando` does not hold on to the added property value after an object - * becomes inaccessible. - * - * Since you can always create a new number that is identical to an existing - * number, it means that an expando property on a number could never be - * released. To avoid this, expando properties cannot be added to numbers. - * The same argument applies to strings, booleans and `null`, which also have - * literals that evaluate to identical values when they occur more than once. - * - * There is no restriction on other classes, even for compile time constant - * objects. Be careful if adding expando properties to compile time constants, - * since they will stay alive forever. - */ -class Expando { - /** - * The name of the this [Expando] as passed to the constructor. If - * no name was passed to the constructor, the name is `null`. - */ - final String? name; - - /** - * Creates a new [Expando]. The optional name is only used for - * debugging purposes and creating two different [Expando]s with the - * same name yields two [Expando]s that work on different properties - * of the objects they are used on. - */ - external Expando([String? name]); - - /** - * Expando toString method override. - */ - String toString() => "Expando:${name.toString()}"; - - /** - * Gets the value of this [Expando]'s property on the given - * object. If the object hasn't been expanded, the method returns - * `null`. - * - * The object must not be a number, a string, a boolean or null. - */ - external T? operator [](Object object); - - /** - * Sets the value of this [Expando]'s property on the given - * object. Properties can effectively be removed again by setting - * their value to null. - * - * The object must not be a number, a string, a boolean or null. - */ - external void operator []=(Object object, T? value); -} diff --git a/sdk_nnbd/lib/core/function.dart b/sdk_nnbd/lib/core/function.dart deleted file mode 100644 index b21f6759e45..00000000000 --- a/sdk_nnbd/lib/core/function.dart +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) 2011, 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. - -part of dart.core; - -/** - * The base class for all function types. - * - * A function value, or an instance of a class with a "call" method, is a - * subtype of a function type, and as such, a subtype of [Function]. - */ -abstract class Function { - /** - * Dynamically call [function] with the specified arguments. - * - * Acts the same as calling function with positional arguments - * corresponding to the elements of [positionalArguments] and - * named arguments corresponding to the elements of [namedArguments]. - * - * This includes giving the same errors if [function] isn't callable or - * if it expects different parameters. - * - * Example: - * ``` - * Function.apply(foo, [1,2,3], {#f: 4, #g: 5}); - * ``` - * - * gives exactly the same result as - * ``` - * foo(1, 2, 3, f: 4, g: 5). - * ``` - * - * If [positionalArguments] is null, it's considered an empty list. - * If [namedArguments] is omitted or null, it is considered an empty map. - */ - external static apply(Function function, List? positionalArguments, - [Map? namedArguments]); - - /** - * Returns a hash code value that is compatible with `operator==`. - */ - int get hashCode; - - /** - * Test whether another object is equal to this function. - * - * Function objects are only equal to other function objects - * (an object satisfying `object is Function`), - * and never to non-function objects. - * - * Some function objects are considered equal by `==` - * because they are recognized as representing the "same function": - * - * - It is the same object. Static and top-level functions are compile time - * constants when used as values, so referring to the same function twice - * always give the same object, as does referring to a local function - * declaration twice in the same scope where it was declared. - * - if they refer to the same member method extracted from the same object. - * Repeatedly extracting an instance method of an object as a function value - * gives equal, but not necessarily identical, function values. - * - * Different evaluations of function literals - * never give rise to equal function objects. - * Each time a function literal is evaluated, - * it creates a new function value that is not equal to any other function - * value, not even ones created by the same expression. - */ - bool operator ==(Object other); -} diff --git a/sdk_nnbd/lib/core/identical.dart b/sdk_nnbd/lib/core/identical.dart deleted file mode 100644 index 20d331ea5ff..00000000000 --- a/sdk_nnbd/lib/core/identical.dart +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) 2012, 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. - -part of dart.core; - -/** - * Check whether two references are to the same object. - */ -external bool identical(Object? a, Object? b); - -/** - * Returns the identity hash code of `object`. - * - * Returns the same value as `object.hashCode` if [object] has not overridden - * [Object.hashCode]. Returns the value that [Object.hashCode] would return - * on this object, even if `hashCode` has been overridden. - * - * This hash code is compatible with [identical]. - */ -@pragma("vm:entry-point") -external int identityHashCode(Object? object); diff --git a/sdk_nnbd/lib/core/int.dart b/sdk_nnbd/lib/core/int.dart deleted file mode 100644 index b1203ed3f1a..00000000000 --- a/sdk_nnbd/lib/core/int.dart +++ /dev/null @@ -1,356 +0,0 @@ -// Copyright (c) 2012, 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. - -part of dart.core; - -/** - * An integer number. - * - * The default implementation of `int` is 64-bit two's complement integers - * with operations that wrap to that range on overflow. - * - * **Note:** When compiling to JavaScript, integers are restricted to values - * that can be represented exactly by double-precision floating point values. - * The available integer values include all integers between -2^53 and 2^53, - * and some integers with larger magnitude. That includes some integers larger - * than 2^63. - * The behavior of the operators and methods in the [int] - * class therefore sometimes differs between the Dart VM and Dart code - * compiled to JavaScript. For example, the bitwise operators truncate their - * operands to 32-bit integers when compiled to JavaScript. - * - * Classes cannot extend, implement, or mix in `int`. - */ -abstract class int extends num { - /** - * Returns the integer value of the given environment declaration [name]. - * - * The result is the same as would be returned by: - * ``` - * int.tryParse(const String.fromEnvironment(name, defaultValue: "")) - * ?? defaultValue - * ``` - * Example: - * ``` - * const int.fromEnvironment("defaultPort", defaultValue: 80) - * ``` - */ - // The .fromEnvironment() constructors are special in that we do not want - // users to call them using "new". We prohibit that by giving them bodies - // that throw, even though const constructors are not allowed to have bodies. - // Disable those static errors. - //ignore: const_constructor_with_body - //ignore: const_factory - external const factory int.fromEnvironment(String name, - {int defaultValue = 0}); - - /** - * Bit-wise and operator. - * - * Treating both `this` and [other] as sufficiently large two's component - * integers, the result is a number with only the bits set that are set in - * both `this` and [other] - * - * If both operands are negative, the result is negative, otherwise - * the result is non-negative. - */ - int operator &(int other); - - /** - * Bit-wise or operator. - * - * Treating both `this` and [other] as sufficiently large two's component - * integers, the result is a number with the bits set that are set in either - * of `this` and [other] - * - * If both operands are non-negative, the result is non-negative, - * otherwise the result is negative. - */ - int operator |(int other); - - /** - * Bit-wise exclusive-or operator. - * - * Treating both `this` and [other] as sufficiently large two's component - * integers, the result is a number with the bits set that are set in one, - * but not both, of `this` and [other] - * - * If the operands have the same sign, the result is non-negative, - * otherwise the result is negative. - */ - int operator ^(int other); - - /** - * The bit-wise negate operator. - * - * Treating `this` as a sufficiently large two's component integer, - * the result is a number with the opposite bits set. - * - * This maps any integer `x` to `-x - 1`. - */ - int operator ~(); - - /** - * Shift the bits of this integer to the left by [shiftAmount]. - * - * Shifting to the left makes the number larger, effectively multiplying - * the number by `pow(2, shiftIndex)`. - * - * There is no limit on the size of the result. It may be relevant to - * limit intermediate values by using the "and" operator with a suitable - * mask. - * - * It is an error if [shiftAmount] is negative. - */ - int operator <<(int shiftAmount); - - /** - * Shift the bits of this integer to the right by [shiftAmount]. - * - * Shifting to the right makes the number smaller and drops the least - * significant bits, effectively doing an integer division by - *`pow(2, shiftIndex)`. - * - * It is an error if [shiftAmount] is negative. - */ - int operator >>(int shiftAmount); - - /** - * Returns this integer to the power of [exponent] modulo [modulus]. - * - * The [exponent] must be non-negative and [modulus] must be - * positive. - */ - int modPow(int exponent, int modulus); - - /** - * Returns the modular multiplicative inverse of this integer - * modulo [modulus]. - * - * The [modulus] must be positive. - * - * It is an error if no modular inverse exists. - */ - int modInverse(int modulus); - - /** - * Returns the greatest common divisor of this integer and [other]. - * - * If either number is non-zero, the result is the numerically greatest - * integer dividing both `this` and `other`. - * - * The greatest common divisor is independent of the order, - * so `x.gcd(y)` is always the same as `y.gcd(x)`. - * - * For any integer `x`, `x.gcd(x)` is `x.abs()`. - * - * If both `this` and `other` is zero, the result is also zero. - */ - int gcd(int other); - - /** Returns true if and only if this integer is even. */ - bool get isEven; - - /** Returns true if and only if this integer is odd. */ - bool get isOdd; - - /** - * Returns the minimum number of bits required to store this integer. - * - * The number of bits excludes the sign bit, which gives the natural length - * for non-negative (unsigned) values. Negative values are complemented to - * return the bit position of the first bit that differs from the sign bit. - * - * To find the number of bits needed to store the value as a signed value, - * add one, i.e. use `x.bitLength + 1`. - * ``` - * x.bitLength == (-x-1).bitLength - * - * 3.bitLength == 2; // 00000011 - * 2.bitLength == 2; // 00000010 - * 1.bitLength == 1; // 00000001 - * 0.bitLength == 0; // 00000000 - * (-1).bitLength == 0; // 11111111 - * (-2).bitLength == 1; // 11111110 - * (-3).bitLength == 2; // 11111101 - * (-4).bitLength == 2; // 11111100 - * ``` - */ - int get bitLength; - - /** - * Returns the least significant [width] bits of this integer as a - * non-negative number (i.e. unsigned representation). The returned value has - * zeros in all bit positions higher than [width]. - * ``` - * (-1).toUnsigned(5) == 31 // 11111111 -> 00011111 - * ``` - * This operation can be used to simulate arithmetic from low level languages. - * For example, to increment an 8 bit quantity: - * ``` - * q = (q + 1).toUnsigned(8); - * ``` - * `q` will count from `0` up to `255` and then wrap around to `0`. - * - * If the input fits in [width] bits without truncation, the result is the - * same as the input. The minimum width needed to avoid truncation of `x` is - * given by `x.bitLength`, i.e. - * ``` - * x == x.toUnsigned(x.bitLength); - * ``` - */ - int toUnsigned(int width); - - /** - * Returns the least significant [width] bits of this integer, extending the - * highest retained bit to the sign. This is the same as truncating the value - * to fit in [width] bits using an signed 2-s complement representation. The - * returned value has the same bit value in all positions higher than [width]. - * - * ``` - * V--sign bit-V - * 16.toSigned(5) == -16 // 00010000 -> 11110000 - * 239.toSigned(5) == 15 // 11101111 -> 00001111 - * ^ ^ - * ``` - * This operation can be used to simulate arithmetic from low level languages. - * For example, to increment an 8 bit signed quantity: - * ``` - * q = (q + 1).toSigned(8); - * ``` - * `q` will count from `0` up to `127`, wrap to `-128` and count back up to - * `127`. - * - * If the input value fits in [width] bits without truncation, the result is - * the same as the input. The minimum width needed to avoid truncation of `x` - * is `x.bitLength + 1`, i.e. - * ``` - * x == x.toSigned(x.bitLength + 1); - * ``` - */ - int toSigned(int width); - - /** - * Return the negative value of this integer. - * - * The result of negating an integer always has the opposite sign, except - * for zero, which is its own negation. - */ - int operator -(); - - /** - * Returns the absolute value of this integer. - * - * For any integer `x`, the result is the same as `x < 0 ? -x : x`. - */ - int abs(); - - /** - * Returns the sign of this integer. - * - * Returns 0 for zero, -1 for values less than zero and - * +1 for values greater than zero. - */ - int get sign; - - /** Returns `this`. */ - int round(); - - /** Returns `this`. */ - int floor(); - - /** Returns `this`. */ - int ceil(); - - /** Returns `this`. */ - int truncate(); - - /** Returns `this.toDouble()`. */ - double roundToDouble(); - - /** Returns `this.toDouble()`. */ - double floorToDouble(); - - /** Returns `this.toDouble()`. */ - double ceilToDouble(); - - /** Returns `this.toDouble()`. */ - double truncateToDouble(); - - /** - * Returns a string representation of this integer. - * - * The returned string is parsable by [parse]. - * For any `int` `i`, it is guaranteed that - * `i == int.parse(i.toString())`. - */ - String toString(); - - /** - * Converts [this] to a string representation in the given [radix]. - * - * In the string representation, lower-case letters are used for digits above - * '9', with 'a' being 10 an 'z' being 35. - * - * The [radix] argument must be an integer in the range 2 to 36. - */ - String toRadixString(int radix); - - /** - * Parse [source] as a, possibly signed, integer literal and return its value. - * - * The [source] must be a non-empty sequence of base-[radix] digits, - * optionally prefixed with a minus or plus sign ('-' or '+'). - * It must not be `null`. - * - * The [radix] must be in the range 2..36. The digits used are - * first the decimal digits 0..9, and then the letters 'a'..'z' with - * values 10 through 35. Also accepts upper-case letters with the same - * values as the lower-case ones. - * - * If no [radix] is given then it defaults to 10. In this case, the [source] - * digits may also start with `0x`, in which case the number is interpreted - * as a hexadecimal integer literal, - * When `int` is implemented by 64-bit signed integers, - * hexadecimal integer literals may represent values larger than - * 263, in which case the value is parsed as if it is an - * *unsigned* number, and the resulting value is the corresponding - * signed integer value. - * - * For any int `n` and valid radix `r`, it is guaranteed that - * `n == int.parse(n.toRadixString(r), radix: r)`. - * - * If the [source] string does not contain a valid integer literal, - * optionally prefixed by a sign, a [FormatException] is thrown - * (unless the deprecated [onError] parameter is used, see below). - * - * Instead of throwing and immediately catching the [FormatException], - * instead use [tryParse] to handle a parsing error. - * Example: - * ```dart - * var value = int.tryParse(text); - * if (value == null) ... handle the problem - * ``` - * - * The [onError] parameter is deprecated and will be removed. - * Instead of `int.parse(string, onError: (string) => ...)`, - * you should use `int.tryParse(string) ?? (...)`. - * - * When the source string is not valid and [onError] is provided, - * whenever a [FormatException] would be thrown, - * [onError] is instead called with [source] as argument, - * and the result of that call is returned by [parse]. - */ - external static int parse(String source, - {int? radix, @deprecated int onError(String source)?}); - - /** - * Parse [source] as a, possibly signed, integer literal and return its value. - * - * Like [parse] except that this function returns `null` where a - * similar call to [parse] would throw a [FormatException], - * and the [source] must still not be `null`. - */ - external static int? tryParse(String source, {int? radix}); -} diff --git a/sdk_nnbd/lib/core/invocation.dart b/sdk_nnbd/lib/core/invocation.dart deleted file mode 100644 index 7d28cea9dfd..00000000000 --- a/sdk_nnbd/lib/core/invocation.dart +++ /dev/null @@ -1,160 +0,0 @@ -// Copyright (c) 2012, 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. - -part of dart.core; - -/** - * Representation of the invocation of a member on an object. - * - * This is the type of objects passed to [Object.noSuchMethod] when - * an object doesn't support the member invocation that was attempted - * on it. - */ -abstract class Invocation { - Invocation(); - - /** - * Creates an invocation corresponding to a method invocation. - * - * The method invocation has no type arguments. - * If the named arguments are omitted, they default to no named arguments. - */ - factory Invocation.method( - Symbol memberName, Iterable? positionalArguments, - [Map? namedArguments]) => - _Invocation.method(memberName, null, positionalArguments, namedArguments); - - /** - * Creates an invocation corresponding to a generic method invocation. - * - * If [typeArguments] is `null` or empty, the constructor is equivalent to - * calling [Invocation.method] with the remaining arguments. - * All the individual type arguments must be non-null. - * - * If the named arguments are omitted, they default to no named arguments. - */ - factory Invocation.genericMethod(Symbol memberName, - Iterable? typeArguments, Iterable? positionalArguments, - [Map? namedArguments]) => - _Invocation.method( - memberName, typeArguments, positionalArguments, namedArguments); - - /** - * Creates an invocation corresponding to a getter invocation. - */ - factory Invocation.getter(Symbol name) = _Invocation.getter; - - /** - * Creates an invocation corresponding to a setter invocation. - * - * This constructor accepts any [Symbol] as [memberName], but remember that - * *actual setter names* end in `=`, so the invocation corresponding - * to `object.member = value` is - * ```dart - * Invocation.setter(const Symbol("member="), value) - * ``` - */ - factory Invocation.setter(Symbol memberName, Object? argument) = - _Invocation.setter; - - /** The name of the invoked member. */ - Symbol get memberName; - - /** - * An unmodifiable view of the type arguments of the call. - * - * If the member is a getter, setter or operator, - * the type argument list is always empty. - */ - List get typeArguments => const []; - - /** - * An unmodifiable view of the positional arguments of the call. - * - * If the member is a getter, the positional arguments list is - * always empty. - */ - List get positionalArguments; - - /** - * An unmodifiable view of the named arguments of the call. - * - * If the member is a getter, setter or operator, - * the named arguments map is always empty. - */ - Map get namedArguments; - - /** Whether the invocation was a method call. */ - bool get isMethod; - - /** - * Whether the invocation was a getter call. - * If so, all three types of arguments lists are empty. - */ - bool get isGetter; - - /** - * Whether the invocation was a setter call. - * - * If so, [positionalArguments] has exactly one positional - * argument, [namedArguments] is empty, and typeArguments is - * empty. - */ - bool get isSetter; - - /** Whether the invocation was a getter or a setter call. */ - bool get isAccessor => isGetter || isSetter; -} - -/** Implementation of [Invocation] used by its factory constructors. */ -class _Invocation implements Invocation { - final Symbol memberName; - final List typeArguments; - // Positional arguments is `null` for getters only. - final List? _positional; - // Named arguments is `null` for accessors only. - final Map? _named; - - _Invocation.method(this.memberName, Iterable? types, - Iterable? positional, Map? named) - : typeArguments = _ensureNonNullTypes(types), - _positional = positional == null - ? const [] - : List.unmodifiable(positional), - _named = (named == null || named.isEmpty) - ? const {} - : Map.unmodifiable(named); - - _Invocation.getter(this.memberName) - : typeArguments = const [], - _positional = null, - _named = null; - - _Invocation.setter(this.memberName, Object? argument) - : typeArguments = const [], - _positional = List.unmodifiable([argument]), - _named = null; - - List get positionalArguments => _positional ?? const []; - - Map get namedArguments => _named ?? const {}; - - bool get isMethod => _named != null; - bool get isGetter => _positional == null; - bool get isSetter => _positional != null && _named == null; - bool get isAccessor => _named == null; - - /// Checks that the elements of [types] are not null. - static List _ensureNonNullTypes(Iterable? types) { - if (types == null) return const []; - List typeArguments = List.unmodifiable(types); - for (int i = 0; i < typeArguments.length; i++) { - if (typeArguments[i] == null) { - throw ArgumentError.value(types, "types", - "Type arguments must be non-null, was null at index $i."); - } - } - return typeArguments; - } -} diff --git a/sdk_nnbd/lib/core/iterable.dart b/sdk_nnbd/lib/core/iterable.dart deleted file mode 100644 index 839792ec857..00000000000 --- a/sdk_nnbd/lib/core/iterable.dart +++ /dev/null @@ -1,711 +0,0 @@ -// Copyright (c) 2011, 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. - -part of dart.core; - -/** - * A collection of values, or "elements", that can be accessed sequentially. - * - * The elements of the iterable are accessed by getting an [Iterator] - * using the [iterator] getter, and using it to step through the values. - * Stepping with the iterator is done by calling [Iterator.moveNext], - * and if the call returns `true`, - * the iterator has now moved to the next element, - * which is then available as [Iterator.current]. - * If the call returns `false`, there are no more elements. - * The [Iterator.current] value must only be used when the most - * recent call to [Iterator.moveNext] has returned `true`. - * If it is used before calling [Iterator.moveNext] the first time - * on an iterator, or after a call has returned false or has thrown an error, - * reading [Iterator.current] may throw or may return an arbitrary value. - * - * You can create more than one iterator from the same `Iterable`. - * Each time `iterator` is read, it returns a new iterator, - * and different iterators can be stepped through independently, - * each giving access to all the elements of the iterable. - * The iterators of the same iterable *should* provide the same values - * in the same order (unless the underlying collection is modified between - * the iterations, which some collections allow). - * - * You can also iterate over the elements of an `Iterable` - * using the for-in loop construct, which uses the `iterator` getter behind the - * scenes. - * For example, you can iterate over all of the keys of a [Map], - * because `Map` keys are iterable. - * - * Map kidsBooks = {'Matilda': 'Roald Dahl', - * 'Green Eggs and Ham': 'Dr Seuss', - * 'Where the Wild Things Are': 'Maurice Sendak'}; - * for (var book in kidsBooks.keys) { - * print('$book was written by ${kidsBooks[book]}'); - * } - * - * The [List] and [Set] classes are both `Iterable`, - * as are most classes in the `dart:collection` library. - * - * Some [Iterable] collections can be modified. - * Adding an element to a `List` or `Set` will change which elements it - * contains, and adding a new key to a `Map` changes the elements of [Map.keys]. - * Iterators created after the change will provide the new elements, and may - * or may not preserve the order of existing elements - * (for example, a [HashSet] may completely change its order when a single - * element is added). - * - * Changing a collection *while* it is being iterated - * is generally *not* allowed. - * Doing so will break the iteration, which is typically signalled - * by throwing a [ConcurrentModificationError] - * the next time [Iterator.moveNext] is called. - * The current value of [Iterator.current] getter - * should not be affected by the change in the collection, - * the `current` value was set by the previous call to [Iterator.moveNext]. - * - * Some iterables compute their elements dynamically every time they are - * iterated, like the one returned by [Iterable.generate] or the iterable - * returned by a `sync*` generator function. If the computation doesn't depend - * on other objects that may change, then the generated sequence should be - * the same one every time it's iterated. - * - * The members of `Iterable`, other than `iterator` itself, - * work by looking at the elements of the iterable. - * This can be implemented by running through the [iterator], but some classes - * may have more efficient ways of finding the result - * (like [last] or [length] on a [List], or [contains] on a [Set]). - * - * The methods that return another `Iterable` (like [map] and [where]) - * are all *lazy* - they will iterate the original (as necessary) - * every time the returned iterable is iterated, and not before. - * - * Since an iterable may be iterated more than once, it's not recommended to - * have detectable side-effects in the iterator. - * For methods like [map] and [where], the returned iterable will execute the - * argument function on every iteration, so those functions should also not - * have side effects. - */ -abstract class Iterable { - // TODO(lrn): When we allow forwarding const constructors through - // mixin applications, make this class implement [IterableMixin]. - const Iterable(); - - /** - * Creates an `Iterable` which generates its elements dynamically. - * - * The generated iterable has [count] elements, - * and the element at index `n` is computed by calling `generator(n)`. - * Values are not cached, so each iteration computes the values again. - * - * If [generator] is omitted, it defaults to an identity function - * on integers `(int x) => x`, so it may only be omitted if the type - * parameter allows integer values. That is, if [E] is a super-type - * of [int]. - * - * As an `Iterable`, `new Iterable.generate(n, generator))` is equivalent to - * `const [0, ..., n - 1].map(generator)`. - */ - factory Iterable.generate(int count, [E generator(int index)?]) { - if (count <= 0) return EmptyIterable(); - return _GeneratorIterable(count, generator); - } - - /** - * Creates an empty iterable. - * - * The empty iterable has no elements, and iterating it always stops - * immediately. - */ - const factory Iterable.empty() = EmptyIterable; - - /** - * Adapts [source] to be an `Iterable`. - * - * Any time the iterable would produce an element that is not a [T], - * the element access will throw. If all elements of [source] are actually - * instances of [T], or if only elements that are actually instances of [T] - * are accessed, then the resulting iterable can be used as an `Iterable`. - */ - static Iterable castFrom(Iterable source) => - CastIterable(source); - - /** - * Returns a new `Iterator` that allows iterating the elements of this - * `Iterable`. - * - * Iterable classes may specify the iteration order of their elements - * (for example [List] always iterate in index order), - * or they may leave it unspecified (for example a hash-based [Set] - * may iterate in any order). - * - * Each time `iterator` is read, it returns a new iterator, - * which can be used to iterate through all the elements again. - * The iterators of the same iterable can be stepped through independently, - * but should return the same elements in the same order, - * as long as the underlying collection isn't changed. - * - * Modifying the collection may cause new iterators to produce - * different elements, and may change the order of existing elements. - * A [List] specifies its iteration order precisely, - * so modifying the list changes the iteration order predictably. - * A hash-based [Set] may change its iteration order completely - * when adding a new element to the set. - * - * Modifying the underlying collection after creating the new iterator - * may cause an error the next time [Iterator.moveNext] is called - * on that iterator. - * Any *modifiable* iterable class should specify which operations will - * break iteration. - */ - Iterator get iterator; - - /** - * Provides a view of this iterable as an iterable of [R] instances. - * - * If this iterable only contains instances of [R], all operations - * will work correctly. If any operation tries to access an element - * that is not an instance of [R], the access will throw instead. - * - * When the returned iterable creates a new object that depends on - * the type [R], e.g., from [toList], it will have exactly the type [R]. - */ - Iterable cast() => Iterable.castFrom(this); - - /** - * Returns the lazy concatentation of this iterable and [other]. - * - * The returned iterable will provide the same elements as this iterable, - * and, after that, the elements of [other], in the same order as in the - * original iterables. - */ - Iterable followedBy(Iterable other) { - var self = this; // TODO(lrn): Remove when we can promote `this`. - if (self is EfficientLengthIterable) { - return FollowedByIterable.firstEfficient(self, other); - } - return FollowedByIterable(this, other); - } - - /** - * Returns a new lazy [Iterable] with elements that are created by - * calling `f` on each element of this `Iterable` in iteration order. - * - * This method returns a view of the mapped elements. As long as the - * returned [Iterable] is not iterated over, the supplied function [f] will - * not be invoked. The transformed elements will not be cached. Iterating - * multiple times over the returned [Iterable] will invoke the supplied - * function [f] multiple times on the same element. - * - * Methods on the returned iterable are allowed to omit calling `f` - * on any element where the result isn't needed. - * For example, [elementAt] may call `f` only once. - */ - Iterable map(T f(E e)) => MappedIterable(this, f); - - /** - * Returns a new lazy [Iterable] with all elements that satisfy the - * predicate [test]. - * - * The matching elements have the same order in the returned iterable - * as they have in [iterator]. - * - * This method returns a view of the mapped elements. - * As long as the returned [Iterable] is not iterated over, - * the supplied function [test] will not be invoked. - * Iterating will not cache results, and thus iterating multiple times over - * the returned [Iterable] may invoke the supplied - * function [test] multiple times on the same element. - */ - Iterable where(bool test(E element)) => WhereIterable(this, test); - - /** - * Returns a new lazy [Iterable] with all elements that have type [T]. - * - * The matching elements have the same order in the returned iterable - * as they have in [iterator]. - * - * This method returns a view of the mapped elements. - * Iterating will not cache results, and thus iterating multiple times over - * the returned [Iterable] may yield different results, - * if the underlying elements change between iterations. - */ - Iterable whereType() => WhereTypeIterable(this); - - /** - * Expands each element of this [Iterable] into zero or more elements. - * - * The resulting Iterable runs through the elements returned - * by [f] for each element of this, in iteration order. - * - * The returned [Iterable] is lazy, and calls [f] for each element - * of this every time it's iterated. - * - * Example: - * - * var pairs = [[1, 2], [3, 4]]; - * var flattened = pairs.expand((pair) => pair).toList(); - * print(flattened); // => [1, 2, 3, 4]; - * - * var input = [1, 2, 3]; - * var duplicated = input.expand((i) => [i, i]).toList(); - * print(duplicated); // => [1, 1, 2, 2, 3, 3] - * - */ - Iterable expand(Iterable f(E element)) => - ExpandIterable(this, f); - - /** - * Returns true if the collection contains an element equal to [element]. - * - * This operation will check each element in order for being equal to - * [element], unless it has a more efficient way to find an element - * equal to [element]. - * - * The equality used to determine whether [element] is equal to an element of - * the iterable defaults to the [Object.==] of the element. - * - * Some types of iterable may have a different equality used for its elements. - * For example, a [Set] may have a custom equality - * (see [Set.identity]) that its `contains` uses. - * Likewise the `Iterable` returned by a [Map.keys] call - * should use the same equality that the `Map` uses for keys. - */ - bool contains(Object? element) { - for (E e in this) { - if (e == element) return true; - } - return false; - } - - /** - * Applies the function [f] to each element of this collection in iteration - * order. - */ - void forEach(void f(E element)) { - for (E element in this) f(element); - } - - /** - * Reduces a collection to a single value by iteratively combining elements - * of the collection using the provided function. - * - * The iterable must have at least one element. - * If it has only one element, that element is returned. - * - * Otherwise this method starts with the first element from the iterator, - * and then combines it with the remaining elements in iteration order, - * as if by: - * - * E value = iterable.first; - * iterable.skip(1).forEach((element) { - * value = combine(value, element); - * }); - * return value; - * - * Example of calculating the sum of an iterable: - * - * iterable.reduce((value, element) => value + element); - * - */ - E reduce(E combine(E value, E element)) { - Iterator iterator = this.iterator; - if (!iterator.moveNext()) { - throw IterableElementError.noElement(); - } - E value = iterator.current; - while (iterator.moveNext()) { - value = combine(value, iterator.current); - } - return value; - } - - /** - * Reduces a collection to a single value by iteratively combining each - * element of the collection with an existing value - * - * Uses [initialValue] as the initial value, - * then iterates through the elements and updates the value with - * each element using the [combine] function, as if by: - * - * var value = initialValue; - * for (E element in this) { - * value = combine(value, element); - * } - * return value; - * - * Example of calculating the sum of an iterable: - * - * iterable.fold(0, (prev, element) => prev + element); - * - */ - T fold(T initialValue, T combine(T previousValue, E element)) { - var value = initialValue; - for (E element in this) value = combine(value, element); - return value; - } - - /** - * Checks whether every element of this iterable satisfies [test]. - * - * Checks every element in iteration order, and returns `false` if - * any of them make [test] return `false`, otherwise returns `true`. - */ - bool every(bool test(E element)) { - for (E element in this) { - if (!test(element)) return false; - } - return true; - } - - /** - * Converts each element to a [String] and concatenates the strings. - * - * Iterates through elements of this iterable, - * converts each one to a [String] by calling [Object.toString], - * and then concatenates the strings, with the - * [separator] string interleaved between the elements. - */ - String join([String separator = ""]) { - Iterator iterator = this.iterator; - if (!iterator.moveNext()) return ""; - StringBuffer buffer = StringBuffer(); - if (separator == null || separator == "") { - do { - buffer.write(iterator.current.toString()); - } while (iterator.moveNext()); - } else { - buffer.write(iterator.current.toString()); - while (iterator.moveNext()) { - buffer.write(separator); - buffer.write(iterator.current.toString()); - } - } - return buffer.toString(); - } - - /** - * Checks whether any element of this iterable satisfies [test]. - * - * Checks every element in iteration order, and returns `true` if - * any of them make [test] return `true`, otherwise returns false. - */ - bool any(bool test(E element)) { - for (E element in this) { - if (test(element)) return true; - } - return false; - } - - /** - * Creates a [List] containing the elements of this [Iterable]. - * - * The elements are in iteration order. - * The list is fixed-length if [growable] is false. - */ - List toList({bool growable = true}) { - return List.of(this, growable: growable); - } - - /** - * Creates a [Set] containing the same elements as this iterable. - * - * The set may contain fewer elements than the iterable, - * if the iterable contains an element more than once, - * or it contains one or more elements that are equal. - * The order of the elements in the set is not guaranteed to be the same - * as for the iterable. - */ - Set toSet() => Set.of(this); - - /** - * Returns the number of elements in [this]. - * - * Counting all elements may involve iterating through all elements and can - * therefore be slow. - * Some iterables have a more efficient way to find the number of elements. - */ - int get length { - assert(this is! EfficientLengthIterable); - int count = 0; - Iterator it = iterator; - while (it.moveNext()) { - count++; - } - return count; - } - - /** - * Returns `true` if there are no elements in this collection. - * - * May be computed by checking if `iterator.moveNext()` returns `false`. - */ - bool get isEmpty => !iterator.moveNext(); - - /** - * Returns true if there is at least one element in this collection. - * - * May be computed by checking if `iterator.moveNext()` returns `true`. - */ - bool get isNotEmpty => !isEmpty; - - /** - * Returns a lazy iterable of the [count] first elements of this iterable. - * - * The returned `Iterable` may contain fewer than `count` elements, if `this` - * contains fewer than `count` elements. - * - * The elements can be computed by stepping through [iterator] until [count] - * elements have been seen. - * - * The `count` must not be negative. - */ - Iterable take(int count) { - return TakeIterable(this, count); - } - - /** - * Returns a lazy iterable of the leading elements satisfying [test]. - * - * The filtering happens lazily. Every new iterator of the returned - * iterable starts iterating over the elements of `this`. - * - * The elements can be computed by stepping through [iterator] until an - * element is found where `test(element)` is false. At that point, - * the returned iterable stops (its `moveNext()` returns false). - */ - Iterable takeWhile(bool test(E value)) { - return TakeWhileIterable(this, test); - } - - /** - * Returns an [Iterable] that provides all but the first [count] elements. - * - * When the returned iterable is iterated, it starts iterating over `this`, - * first skipping past the initial [count] elements. - * If `this` has fewer than `count` elements, then the resulting Iterable is - * empty. - * After that, the remaining elements are iterated in the same order as - * in this iterable. - * - * Some iterables may be able to find later elements without first iterating - * through earlier elements, for example when iterating a [List]. - * Such iterables are allowed to ignore the initial skipped elements. - * - * The [count] must not be negative. - */ - Iterable skip(int count) { - return SkipIterable(this, count); - } - - /** - * Returns an `Iterable` that skips leading elements while [test] is satisfied. - * - * The filtering happens lazily. Every new [Iterator] of the returned - * iterable iterates over all elements of `this`. - * - * The returned iterable provides elements by iterating this iterable, - * but skipping over all initial elements where `test(element)` returns - * true. If all elements satisfy `test` the resulting iterable is empty, - * otherwise it iterates the remaining elements in their original order, - * starting with the first element for which `test(element)` returns `false`. - */ - Iterable skipWhile(bool test(E value)) { - return SkipWhileIterable(this, test); - } - - /** - * Returns the first element. - * - * Throws a [StateError] if `this` is empty. - * Otherwise returns the first element in the iteration order, - * equivalent to `this.elementAt(0)`. - */ - E get first { - Iterator it = iterator; - if (!it.moveNext()) { - throw IterableElementError.noElement(); - } - return it.current; - } - - /** - * Returns the last element. - * - * Throws a [StateError] if `this` is empty. - * Otherwise may iterate through the elements and returns the last one - * seen. - * Some iterables may have more efficient ways to find the last element - * (for example a list can directly access the last element, - * without iterating through the previous ones). - */ - E get last { - Iterator it = iterator; - if (!it.moveNext()) { - throw IterableElementError.noElement(); - } - E result; - do { - result = it.current; - } while (it.moveNext()); - return result; - } - - /** - * Checks that this iterable has only one element, and returns that element. - * - * Throws a [StateError] if `this` is empty or has more than one element. - */ - E get single { - Iterator it = iterator; - if (!it.moveNext()) throw IterableElementError.noElement(); - E result = it.current; - if (it.moveNext()) throw IterableElementError.tooMany(); - return result; - } - - /** - * Returns the first element that satisfies the given predicate [test]. - * - * Iterates through elements and returns the first to satisfy [test]. - * - * If no element satisfies [test], the result of invoking the [orElse] - * function is returned. - * If [orElse] is omitted, it defaults to throwing a [StateError]. - */ - E firstWhere(bool test(E element), {E orElse()?}) { - for (E element in this) { - if (test(element)) return element; - } - if (orElse != null) return orElse(); - throw IterableElementError.noElement(); - } - - /** - * Returns the last element that satisfies the given predicate [test]. - * - * An iterable that can access its elements directly may check its - * elements in any order (for example a list starts by checking the - * last element and then moves towards the start of the list). - * The default implementation iterates elements in iteration order, - * checks `test(element)` for each, - * and finally returns that last one that matched. - * - * If no element satisfies [test], the result of invoking the [orElse] - * function is returned. - * If [orElse] is omitted, it defaults to throwing a [StateError]. - */ - E lastWhere(bool test(E element), {E orElse()?}) { - late E result; - bool foundMatching = false; - for (E element in this) { - if (test(element)) { - result = element; - foundMatching = true; - } - } - if (foundMatching) return result; - if (orElse != null) return orElse(); - throw IterableElementError.noElement(); - } - - /** - * Returns the single element that satisfies [test]. - * - * Checks elements to see if `test(element)` returns true. - * If exactly one element satisfies [test], that element is returned. - * If more than one matching element is found, throws [StateError]. - * If no matching element is found, returns the result of [orElse]. - * If [orElse] is omitted, it defaults to throwing a [StateError]. - */ - E singleWhere(bool test(E element), {E orElse()?}) { - late E result; - bool foundMatching = false; - for (E element in this) { - if (test(element)) { - if (foundMatching) { - throw IterableElementError.tooMany(); - } - result = element; - foundMatching = true; - } - } - if (foundMatching) return result; - if (orElse != null) return orElse(); - throw IterableElementError.noElement(); - } - - /** - * Returns the [index]th element. - * - * The [index] must be non-negative and less than [length]. - * Index zero represents the first element (so `iterable.elementAt(0)` is - * equivalent to `iterable.first`). - * - * May iterate through the elements in iteration order, ignoring the - * first [index] elements and then returning the next. - * Some iterables may have a more efficient way to find the element. - */ - E elementAt(int index) { - RangeError.checkNotNegative(index, "index"); - int elementIndex = 0; - for (E element in this) { - if (index == elementIndex) return element; - elementIndex++; - } - throw RangeError.index(index, this, "index", null, elementIndex); - } - - /** - * Returns a string representation of (some of) the elements of `this`. - * - * Elements are represented by their own `toString` results. - * - * The default representation always contains the first three elements. - * If there are less than a hundred elements in the iterable, it also - * contains the last two elements. - * - * If the resulting string isn't above 80 characters, more elements are - * included from the start of the iterable. - * - * The conversion may omit calling `toString` on some elements if they - * are known to not occur in the output, and it may stop iterating after - * a hundred elements. - */ - String toString() => IterableBase.iterableToShortString(this, '(', ')'); -} - -class _GeneratorIterable extends ListIterable { - /// The length of the generated iterable. - final int length; - - /// The function mapping indices to values. - final E Function(int) _generator; - - /// Creates the generated iterable. - /// - /// If [generator] is `null`, it is checked that `int` is assignable to [E]. - _GeneratorIterable(this.length, E generator(int index)?) - : // The `as` below is used as check to make sure that `int` is assignable - // to [E]. - _generator = generator ?? (_id as E Function(int)); - - E elementAt(int index) { - RangeError.checkValidIndex(index, this); - return _generator(index); - } - - /// Helper function used as default _generator function. - static int _id(int n) => n; -} - -/** - * An [Iterator] that allows moving backwards as well as forwards. - */ -abstract class BidirectionalIterator implements Iterator { - /** - * Move back to the previous element. - * - * Returns true and updates [current] if successful. Returns false - * and updates [current] to an implementation defined state if there is no - * previous element - */ - bool movePrevious(); -} diff --git a/sdk_nnbd/lib/core/iterator.dart b/sdk_nnbd/lib/core/iterator.dart deleted file mode 100644 index f116c1be722..00000000000 --- a/sdk_nnbd/lib/core/iterator.dart +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) 2012, 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. - -part of dart.core; - -/** - * An interface for getting items, one at a time, from an object. - * - * The for-in construct transparently uses `Iterator` to test for the end - * of the iteration, and to get each item (or _element_). - * - * If the object iterated over is changed during the iteration, the - * behavior is unspecified. - * - * The `Iterator` is initially positioned before the first element. - * Before accessing the first element the iterator must thus be advanced using - * [moveNext] to point to the first element. - * If no element is left, then [moveNext] returns false, - * and all further calls to [moveNext] will also return false. - * - * The [current] value must not be accessed before calling [moveNext] - * or after a call to [moveNext] has returned false. - * - * A typical usage of an Iterator looks as follows: - * - * var it = obj.iterator; - * while (it.moveNext()) { - * use(it.current); - * } - * - * **See also:** - * [Iteration](http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html#iteration) - * in the [library tour](http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html) - */ -abstract class Iterator { - /** - * Advances the iterator to the next element of the iteration. - * - * Should be called before reading [current]. - * It the call to `moveNext` returns `true`, - * then [current] will contain the next element of the iteration - * until `moveNext` is called again. - * If the call returns `false`, there are no further elements - * and [current] should not be used any more. - * - * It is safe to call [moveNext] after it has already returned `false`, - * but it must keep returning `false` and not have any other effect. - * - * A call to `moveNext` may throw for various reasons, - * including a concurrent change to an underlying collection. - * If that happens, the iterator may be in an inconsistent - * state, and any further behavior of the iterator is unspecified, - * including the effect of reading [current]. - */ - bool moveNext(); - - /** - * Returns the current element. - * - * If the iterator has not yet been moved to the first element - * ([moveNext] has not been called yet), - * or if the iterator has been moved past the last element of the [Iterable] - * ([moveNext] has returned false), - * then [current] is unspecified. - * An [Iterator] may either throw or return an iterator specific default value - * in that case. - * - * The `current` getter should keep its value until the next call to - * [moveNext], even if an underlying collection changes. - * After a successful call to `moveNext`, the user doesn't need to cache - * the current value, but can keep reading it from the iterator. - */ - E get current; -} diff --git a/sdk_nnbd/lib/core/list.dart b/sdk_nnbd/lib/core/list.dart deleted file mode 100644 index afd7f1124f3..00000000000 --- a/sdk_nnbd/lib/core/list.dart +++ /dev/null @@ -1,759 +0,0 @@ -// Copyright (c) 2012, 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. - -part of dart.core; - -/** - * An indexable collection of objects with a length. - * - * Subclasses of this class implement different kinds of lists. - * The most common kinds of lists are: - * - * * Fixed-length list. - * An error occurs when attempting to use operations - * that can change the length of the list. - * - * * Growable list. Full implementation of the API defined in this class. - * - * The default growable list, as created by `[]`, keeps - * an internal buffer, and grows that buffer when necessary. This guarantees - * that a sequence of [add] operations will each execute in amortized constant - * time. Setting the length directly may take time proportional to the new - * length, and may change the internal capacity so that a following add - * operation will need to immediately increase the buffer capacity. - * Other list implementations may have different performance behavior. - * - * The following code illustrates that some List implementations support - * only a subset of the API. - * - * List fixedLengthList = new List(5); - * fixedLengthList.length = 0; // Error - * fixedLengthList.add(499); // Error - * fixedLengthList[0] = 87; - * List growableList = [1, 2]; - * growableList.length = 0; - * growableList.add(499); - * growableList[0] = 87; - * - * Lists are [Iterable]. Iteration occurs over values in index order. Changing - * the values does not affect iteration, but changing the valid - * indices—that is, changing the list's length—between iteration - * steps causes a [ConcurrentModificationError]. This means that only growable - * lists can throw ConcurrentModificationError. If the length changes - * temporarily and is restored before continuing the iteration, the iterator - * does not detect it. - * - * It is generally not allowed to modify the list's length (adding or removing - * elements) while an operation on the list is being performed, - * for example during a call to [forEach] or [sort]. - * Changing the list's length while it is being iterated, either by iterating it - * directly or through iterating an [Iterable] that is backed by the list, will - * break the iteration. - */ -abstract class List implements EfficientLengthIterable { - /** - * Creates a list of the given length. - * - * This constructor will throw an exception if [E] is not a nullable type. - * In this case, another constructor such as [List.filled] must be used - * instead. - * - * The created list is fixed-length if [length] is provided. - * - * List fixedLengthList = new List(3); - * fixedLengthList.length; // 3 - * fixedLengthList.length = 1; // Error - * - * The list has length 0 and is growable if [length] is omitted. - * - * List growableList = []; - * growableList.length; // 0; - * growableList.length = 3; - * - * To create a growable list with a given length, for a nullable element type, - * just assign the length right after creation: - * - * List growableList = []..length = 500; - * - * For a non-nullable element type, an alternative is the following: - * - * List growableList = List.filled(500, 0, growable: true); - * - * The [length] must not be negative or null, if it is provided. - * - * If the element type is not nullable, [length] must not be greater than - * zero. - * - * This constructor cannot be used in null-safe code. - * Use [List.filled] to create a non-empty list. - * This requires a fill value to initialize the list elements with. - * To create an empty list, use `[]` for a growable list or - * `List.empty` for a fixed length list (or where growability is determined - * at run-time). - */ - external factory List([int? length]); - - /** - * Creates a list of the given length with [fill] at each position. - * - * The [length] must be a non-negative integer. - * - * Example: - * ```dart - * new List.filled(3, 0, growable: true); // [0, 0, 0] - * ``` - * - * The created list is fixed-length if [growable] is false (the default) - * and growable if [growable] is true. - * If the list is growable, changing its length will not initialize new - * entries with [fill]. - * After being created and filled, the list is no different from any other - * growable or fixed-length list created using [List]. - * - * All elements of the returned list share the same [fill] value. - * ``` - * var shared = new List.filled(3, []); - * shared[0].add(499); - * print(shared); // => [[499], [499], [499]] - * ``` - * - * You can use [List.generate] to create a list with a new object at - * each position. - * ``` - * var unique = new List.generate(3, (_) => []); - * unique[0].add(499); - * print(unique); // => [[499], [], []] - * ``` - */ - external factory List.filled(int length, E fill, {bool growable = false}); - - /** - * Creates a new empty list. - * - * If [growable] is `false`, which is the default, - * the list is a fixed-length list of length zero. - * If [growable] is `true`, the list is growable and equivalent to `[]`. - */ - @Since("2.8") - external factory List.empty({bool growable = false}); - - /** - * Creates a list containing all [elements]. - * - * The [Iterator] of [elements] provides the order of the elements. - * - * All the [elements] should be instances of [E]. - * The `elements` iterable itself may have any element type, so this - * constructor can be used to down-cast a `List`, for example as: - * ```dart - * List superList = ...; - * List subList = - * new List.from(superList.whereType()); - * ``` - * - * This constructor creates a growable list when [growable] is true; - * otherwise, it returns a fixed-length list. - */ - external factory List.from(Iterable elements, {bool growable = true}); - - /** - * Creates a list from [elements]. - * - * The [Iterator] of [elements] provides the order of the elements. - * - * This constructor creates a growable list when [growable] is true; - * otherwise, it returns a fixed-length list. - */ - external factory List.of(Iterable elements, {bool growable = true}); - - /** - * Generates a list of values. - * - * Creates a list with [length] positions and fills it with values created by - * calling [generator] for each index in the range `0` .. `length - 1` - * in increasing order. - * ```dart - * List.generate(3, (int index) => index * index); // [0, 1, 4] - * ``` - * The created list is fixed-length if [growable] is set to false. - * - * The [length] must be non-negative. - */ - external factory List.generate(int length, E generator(int index), - {bool growable = true}); - - /** - * Creates an unmodifiable list containing all [elements]. - * - * The [Iterator] of [elements] provides the order of the elements. - * - * An unmodifiable list cannot have its length or elements changed. - * If the elements are themselves immutable, then the resulting list - * is also immutable. - */ - external factory List.unmodifiable(Iterable elements); - - /** - * Adapts [source] to be a `List`. - * - * Any time the list would produce an element that is not a [T], - * the element access will throw. - * - * Any time a [T] value is attempted stored into the adapted list, - * the store will throw unless the value is also an instance of [S]. - * - * If all accessed elements of [source] are actually instances of [T], - * and if all elements stored into the returned list are actually instance - * of [S], - * then the returned list can be used as a `List`. - */ - static List castFrom(List source) => CastList(source); - - /** - * Copy a range of one list into another list. - * - * This is a utility function that can be used to implement methods like - * [setRange]. - * - * The range from [start] to [end] must be a valid range of [source], - * and there must be room for `end - start` elements from position [at]. - * If [start] is omitted, it defaults to zero. - * If [end] is omitted, it defaults to [source.length]. - * - * If [source] and [target] is the same list, overlapping source and target - * ranges are respected so that the target range ends up containing the - * initial content of the source range. - * Otherwise the order of element copying is not guaranteed. - */ - static void copyRange(List target, int at, List source, - [int? start, int? end]) { - start ??= 0; - end = RangeError.checkValidRange(start, end, source.length); - if (end == null) { - // TODO(dart-lang/language#440): Remove when promotion works. - throw "unreachable"; - } - int length = end - start; - if (target.length < at + length) { - throw ArgumentError.value(target, "target", - "Not big enough to hold $length elements at position $at"); - } - if (!identical(source, target) || start >= at) { - for (int i = 0; i < length; i++) { - target[at + i] = source[start + i]; - } - } else { - for (int i = length; --i >= 0;) { - target[at + i] = source[start + i]; - } - } - } - - /** - * Write the elements of an iterable into a list. - * - * This is a utility function that can be used to implement methods like - * [setAll]. - * - * The elements of [source] are written into [target] from position [at]. - * The [source] must not contain more elements after writing the last - * position of [target]. - * - * If the source is a list, the [copyRange] function is likely to be more - * efficient. - */ - static void writeIterable(List target, int at, Iterable source) { - RangeError.checkValueInInterval(at, 0, target.length, "at"); - int index = at; - int targetLength = target.length; - for (var element in source) { - if (index == targetLength) { - throw IndexError(targetLength, target); - } - target[index] = element; - index++; - } - } - - /** - * Returns a view of this list as a list of [R] instances. - * - * If this list contains only instances of [R], all read operations - * will work correctly. If any operation tries to access an element - * that is not an instance of [R], the access will throw instead. - * - * Elements added to the list (e.g., by using [add] or [addAll]) - * must be instance of [R] to be valid arguments to the adding function, - * and they must be instances of [E] as well to be accepted by - * this list as well. - * - * Typically implemented as `List.castFrom(this)`. - */ - List cast(); - - /** - * Returns the object at the given [index] in the list - * or throws a [RangeError] if [index] is out of bounds. - */ - E operator [](int index); - - /** - * Sets the value at the given [index] in the list to [value] - * or throws a [RangeError] if [index] is out of bounds. - */ - void operator []=(int index, E value); - - /** - * Updates the first position of the list to contain [value]. - * - * Equivalent to `theList[0] = value;`. - * - * The list must be non-empty. - */ - void set first(E value); - - /** - * Updates the last position of the list to contain [value]. - * - * Equivalent to `theList[theList.length - 1] = value;`. - * - * The list must be non-empty. - */ - void set last(E value); - - /** - * The number of objects in this list. - * - * The valid indices for a list are `0` through `length - 1`. - */ - int get length; - - /** - * Changes the length of this list. - * - * If [newLength] is greater than - * the current length, entries are initialized to `null`. - * Increasing the length fails if the element type does not allow `null`. - * - * Throws an [UnsupportedError] if the list is fixed-length or - * if attempting tp enlarge the list when `null` is not a valid element. - */ - set length(int newLength); - - /** - * Adds [value] to the end of this list, - * extending the length by one. - * - * Throws an [UnsupportedError] if the list is fixed-length. - */ - void add(E value); - - /** - * Appends all objects of [iterable] to the end of this list. - * - * Extends the length of the list by the number of objects in [iterable]. - * Throws an [UnsupportedError] if this list is fixed-length. - */ - void addAll(Iterable iterable); - - /** - * Returns an [Iterable] of the objects in this list in reverse order. - */ - Iterable get reversed; - - /** - * Sorts this list according to the order specified by the [compare] function. - * - * The [compare] function must act as a [Comparator]. - * - * List numbers = ['two', 'three', 'four']; - * // Sort from shortest to longest. - * numbers.sort((a, b) => a.length.compareTo(b.length)); - * print(numbers); // [two, four, three] - * - * The default List implementations use [Comparable.compare] if - * [compare] is omitted. - * - * List nums = [13, 2, -11]; - * nums.sort(); - * print(nums); // [-11, 2, 13] - * - * A [Comparator] may compare objects as equal (return zero), even if they - * are distinct objects. - * The sort function is not guaranteed to be stable, so distinct objects - * that compare as equal may occur in any order in the result: - * - * List numbers = ['one', 'two', 'three', 'four']; - * numbers.sort((a, b) => a.length.compareTo(b.length)); - * print(numbers); // [one, two, four, three] OR [two, one, four, three] - */ - void sort([int compare(E a, E b)?]); - - /** - * Shuffles the elements of this list randomly. - */ - void shuffle([Random? random]); - - /** - * Returns the first index of [element] in this list. - * - * Searches the list from index [start] to the end of the list. - * The first time an object [:o:] is encountered so that [:o == element:], - * the index of [:o:] is returned. - * - * List notes = ['do', 're', 'mi', 're']; - * notes.indexOf('re'); // 1 - * notes.indexOf('re', 2); // 3 - * - * Returns -1 if [element] is not found. - * - * notes.indexOf('fa'); // -1 - */ - int indexOf(E element, [int start = 0]); - - /** - * Returns the first index in the list that satisfies the provided [test]. - * - * Searches the list from index [start] to the end of the list. - * The first time an object `o` is encountered so that `test(o)` is true, - * the index of `o` is returned. - * - * ``` - * List notes = ['do', 're', 'mi', 're']; - * notes.indexWhere((note) => note.startsWith('r')); // 1 - * notes.indexWhere((note) => note.startsWith('r'), 2); // 3 - * ``` - * - * Returns -1 if [element] is not found. - * ``` - * notes.indexWhere((note) => note.startsWith('k')); // -1 - * ``` - */ - int indexWhere(bool test(E element), [int start = 0]); - - /** - * Returns the last index in the list that satisfies the provided [test]. - * - * Searches the list from index [start] to 0. - * The first time an object `o` is encountered so that `test(o)` is true, - * the index of `o` is returned. - * If [start] is omitted, it defaults to the [length] of the list. - * - * ``` - * List notes = ['do', 're', 'mi', 're']; - * notes.lastIndexWhere((note) => note.startsWith('r')); // 3 - * notes.lastIndexWhere((note) => note.startsWith('r'), 2); // 1 - * ``` - * - * Returns -1 if [element] is not found. - * ``` - * notes.lastIndexWhere((note) => note.startsWith('k')); // -1 - * ``` - */ - int lastIndexWhere(bool test(E element), [int? start]); - - /** - * Returns the last index of [element] in this list. - * - * Searches the list backwards from index [start] to 0. - * - * The first time an object [:o:] is encountered so that [:o == element:], - * the index of [:o:] is returned. - * - * List notes = ['do', 're', 'mi', 're']; - * notes.lastIndexOf('re', 2); // 1 - * - * If [start] is not provided, this method searches from the end of the - * list. - * - * notes.lastIndexOf('re'); // 3 - * - * Returns -1 if [element] is not found. - * - * notes.lastIndexOf('fa'); // -1 - */ - int lastIndexOf(E element, [int? start]); - - /** - * Removes all objects from this list; - * the length of the list becomes zero. - * - * Throws an [UnsupportedError], and retains all objects, if this - * is a fixed-length list. - */ - void clear(); - - /** - * Inserts the object at position [index] in this list. - * - * This increases the length of the list by one and shifts all objects - * at or after the index towards the end of the list. - * - * The list must be growable. - * The [index] value must be non-negative and no greater than [length]. - */ - void insert(int index, E element); - - /** - * Inserts all objects of [iterable] at position [index] in this list. - * - * This increases the length of the list by the length of [iterable] and - * shifts all later objects towards the end of the list. - * - * The list must be growable. - * The [index] value must be non-negative and no greater than [length]. - */ - void insertAll(int index, Iterable iterable); - - /** - * Overwrites objects of `this` with the objects of [iterable], starting - * at position [index] in this list. - * - * List list = ['a', 'b', 'c']; - * list.setAll(1, ['bee', 'sea']); - * list.join(', '); // 'a, bee, sea' - * - * This operation does not increase the length of `this`. - * - * The [index] must be non-negative and no greater than [length]. - * - * The [iterable] must not have more elements than what can fit from [index] - * to [length]. - * - * If `iterable` is based on this list, its values may change /during/ the - * `setAll` operation. - */ - void setAll(int index, Iterable iterable); - - /** - * Removes the first occurrence of [value] from this list. - * - * Returns true if [value] was in the list, false otherwise. - * - * List parts = ['head', 'shoulders', 'knees', 'toes']; - * parts.remove('head'); // true - * parts.join(', '); // 'shoulders, knees, toes' - * - * The method has no effect if [value] was not in the list. - * - * // Note: 'head' has already been removed. - * parts.remove('head'); // false - * parts.join(', '); // 'shoulders, knees, toes' - * - * An [UnsupportedError] occurs if the list is fixed-length. - */ - bool remove(Object? value); - - /** - * Removes the object at position [index] from this list. - * - * This method reduces the length of `this` by one and moves all later objects - * down by one position. - * - * Returns the removed object. - * - * The [index] must be in the range `0 ≤ index < length`. - * - * Throws an [UnsupportedError] if this is a fixed-length list. In that case - * the list is not modified. - */ - E removeAt(int index); - - /** - * Pops and returns the last object in this list. - * - * The list must not be empty. - * - * Throws an [UnsupportedError] if this is a fixed-length list. - */ - E removeLast(); - - /** - * Removes all objects from this list that satisfy [test]. - * - * An object [:o:] satisfies [test] if [:test(o):] is true. - * - * List numbers = ['one', 'two', 'three', 'four']; - * numbers.removeWhere((item) => item.length == 3); - * numbers.join(', '); // 'three, four' - * - * Throws an [UnsupportedError] if this is a fixed-length list. - */ - void removeWhere(bool test(E element)); - - /** - * Removes all objects from this list that fail to satisfy [test]. - * - * An object [:o:] satisfies [test] if [:test(o):] is true. - * - * List numbers = ['one', 'two', 'three', 'four']; - * numbers.retainWhere((item) => item.length == 3); - * numbers.join(', '); // 'one, two' - * - * Throws an [UnsupportedError] if this is a fixed-length list. - */ - void retainWhere(bool test(E element)); - - /** - * Returns the concatenation of this list and [other]. - * - * Returns a new list containing the elements of this list followed by - * the elements of [other]. - * - * The default behavior is to return a normal growable list. - * Some list types may choose to return a list of the same type as themselves - * (see [Uint8List.+]); - */ - List operator +(List other); - - /** - * Returns a new list containing the elements between [start] and [end]. - * - * The new list is a `List` containing the elements of this list at - * positions greater than or equal to [start] and less than [end] in the same - * order as they occur in this list. - * - * ```dart - * var colors = ["red", "green", "blue", "orange", "pink"]; - * print(colors.sublist(1, 3)); // [green, blue] - * ``` - * - * If [end] is omitted, it defaults to the [length] of this list. - * - * ```dart - * print(colors.sublist(1)); // [green, blue, orange, pink] - * ``` - * - * The `start` and `end` positions must satisfy the relations - * 0 ≤ `start` ≤ `end` ≤ `this.length` - * If `end` is equal to `start`, then the returned list is empty. - */ - List sublist(int start, [int? end]); - - /** - * Returns an [Iterable] that iterates over the objects in the range - * [start] inclusive to [end] exclusive. - * - * The provided range, given by [start] and [end], must be valid at the time - * of the call. - * - * A range from [start] to [end] is valid if `0 <= start <= end <= len`, where - * `len` is this list's `length`. The range starts at `start` and has length - * `end - start`. An empty range (with `end == start`) is valid. - * - * The returned [Iterable] behaves like `skip(start).take(end - start)`. - * That is, it does *not* throw if this list changes size. - * - * List colors = ['red', 'green', 'blue', 'orange', 'pink']; - * Iterable range = colors.getRange(1, 4); - * range.join(', '); // 'green, blue, orange' - * colors.length = 3; - * range.join(', '); // 'green, blue' - */ - Iterable getRange(int start, int end); - - /** - * Copies the objects of [iterable], skipping [skipCount] objects first, - * into the range [start], inclusive, to [end], exclusive, of the list. - * - * List list1 = [1, 2, 3, 4]; - * List list2 = [5, 6, 7, 8, 9]; - * // Copies the 4th and 5th items in list2 as the 2nd and 3rd items - * // of list1. - * list1.setRange(1, 3, list2, 3); - * list1.join(', '); // '1, 8, 9, 4' - * - * The provided range, given by [start] and [end], must be valid. - * A range from [start] to [end] is valid if `0 <= start <= end <= len`, where - * `len` is this list's `length`. The range starts at `start` and has length - * `end - start`. An empty range (with `end == start`) is valid. - * - * The [iterable] must have enough objects to fill the range from `start` - * to `end` after skipping [skipCount] objects. - * - * If `iterable` is this list, the operation copies the elements - * originally in the range from `skipCount` to `skipCount + (end - start)` to - * the range `start` to `end`, even if the two ranges overlap. - * - * If `iterable` depends on this list in some other way, no guarantees are - * made. - */ - void setRange(int start, int end, Iterable iterable, [int skipCount = 0]); - - /** - * Removes the objects in the range [start] inclusive to [end] exclusive. - * - * The provided range, given by [start] and [end], must be valid. - * A range from [start] to [end] is valid if `0 <= start <= end <= len`, where - * `len` is this list's `length`. The range starts at `start` and has length - * `end - start`. An empty range (with `end == start`) is valid. - * - * Throws an [UnsupportedError] if this is a fixed-length list. In that case - * the list is not modified. - */ - void removeRange(int start, int end); - - /** - * Sets the objects in the range [start] inclusive to [end] exclusive - * to the given [fillValue]. - * - * The provided range, given by [start] and [end], must be valid. - * A range from [start] to [end] is valid if `0 <= start <= end <= len`, where - * `len` is this list's `length`. The range starts at `start` and has length - * `end - start`. An empty range (with `end == start`) is valid. - * - * Example: - * ```dart - * List list = new List(3); - * list.fillRange(0, 2, 1); - * print(list); // [1, 1, null] - * ``` - * - * If the element type is not nullable, omitting [fillValue] or passing `null` - * as [fillValue] will make the `fillRange` fail. - */ - void fillRange(int start, int end, [E? fillValue]); - - /** - * Removes the objects in the range [start] inclusive to [end] exclusive - * and inserts the contents of [replacement] in its place. - * - * List list = [1, 2, 3, 4, 5]; - * list.replaceRange(1, 4, [6, 7]); - * list.join(', '); // '1, 6, 7, 5' - * - * The provided range, given by [start] and [end], must be valid. - * A range from [start] to [end] is valid if `0 <= start <= end <= len`, where - * `len` is this list's `length`. The range starts at `start` and has length - * `end - start`. An empty range (with `end == start`) is valid. - * - * This method does not work on fixed-length lists, even when [replacement] - * has the same number of elements as the replaced range. In that case use - * [setRange] instead. - */ - void replaceRange(int start, int end, Iterable replacement); - - /** - * Returns an unmodifiable [Map] view of `this`. - * - * The map uses the indices of this list as keys and the corresponding objects - * as values. The `Map.keys` [Iterable] iterates the indices of this list - * in numerical order. - * - * List words = ['fee', 'fi', 'fo', 'fum']; - * Map map = words.asMap(); - * map[0] + map[1]; // 'feefi'; - * map.keys.toList(); // [0, 1, 2, 3] - */ - Map asMap(); - - /** - * Whether this list is equal to [other]. - * - * Lists are, by default, only equal to themselves. - * Even if [other] is also a list, the equality comparison - * does not compare the elements of the two lists. - */ - bool operator ==(Object other); -} diff --git a/sdk_nnbd/lib/core/map.dart b/sdk_nnbd/lib/core/map.dart deleted file mode 100644 index a92d08d60c3..00000000000 --- a/sdk_nnbd/lib/core/map.dart +++ /dev/null @@ -1,405 +0,0 @@ -// Copyright (c) 2011, 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. - -part of dart.core; - -/** - * A collection of key/value pairs, from which you retrieve a value - * using its associated key. - * - * There is a finite number of keys in the map, - * and each key has exactly one value associated with it. - * - * Maps, and their keys and values, can be iterated. - * The order of iteration is defined by the individual type of map. - * Examples: - * - * * The plain [HashMap] is unordered (no order is guaranteed), - * * the [LinkedHashMap] iterates in key insertion order, - * * and a sorted map like [SplayTreeMap] iterates the keys in sorted order. - * - * It is generally not allowed to modify the map (add or remove keys) while - * an operation is being performed on the map, for example in functions called - * during a [forEach] or [putIfAbsent] call. - * Modifying the map while iterating the keys or values - * may also break the iteration. - * - * It is generally not allowed to modify the equality of keys (and thus not - * their hashcode) while they are in the map. Some specialized subtypes may be - * more permissive, in which case they should document this behavior. - */ -abstract class Map { - /** - * Creates a Map instance with the default implementation, [LinkedHashMap]. - * - * This constructor is equivalent to the non-const map literal `{}`. - * - * A `LinkedHashMap` requires the keys to implement compatible - * `operator==` and `hashCode`, and it allows null as a key. - * It iterates in key insertion order. - */ - external factory Map(); - - /** - * Creates a [LinkedHashMap] instance that contains all key/value pairs of - * [other]. - * - * The keys must all be instances of [K] and the values of [V]. - * The [other] map itself can have any type. - * - * A `LinkedHashMap` requires the keys to implement compatible - * `operator==` and `hashCode`, and it allows `null` as a key. - * It iterates in key insertion order. - */ - factory Map.from(Map other) = LinkedHashMap.from; - - /** - * Creates a [LinkedHashMap] with the same keys and values as [other]. - * - * A `LinkedHashMap` requires the keys to implement compatible - * `operator==` and `hashCode`, and it allows `null` as a key. - * It iterates in key insertion order. - */ - factory Map.of(Map other) = LinkedHashMap.of; - - /** - * Creates an unmodifiable hash based map containing the entries of [other]. - * - * The keys must all be instances of [K] and the values of [V]. - * The [other] map itself can have any type. - * - * The map requires the keys to implement compatible - * `operator==` and `hashCode`, and it allows `null` as a key. - * The created map iterates keys in a fixed order, - * preserving the order provided by [other]. - * - * The resulting map behaves like the result of [Map.from], - * except that the map returned by this constructor is not modifiable. - */ - external factory Map.unmodifiable(Map other); - - /** - * Creates an identity map with the default implementation, [LinkedHashMap]. - * - * An identity map uses [identical] for equality and [identityHashCode] - * for hash codes of keys instead of the intrinsic [Object.operator==] and - * [Object.hashCode] of the keys. - * - * The returned map allows `null` as a key. - * It iterates in key insertion order. - */ - factory Map.identity() = LinkedHashMap.identity; - - /** - * Creates a Map instance in which the keys and values are computed from the - * [iterable]. - * - * The created map is a [LinkedHashMap]. - * A `LinkedHashMap` requires the keys to implement compatible - * `operator==` and `hashCode`, and it allows null as a key. - * It iterates in key insertion order. - * - * For each element of the [iterable] this constructor computes a key/value - * pair, by applying [key] and [value] respectively. - * - * The example below creates a new Map from a List. The keys of `map` are - * `list` values converted to strings, and the values of the `map` are the - * squares of the `list` values: - * - * List list = [1, 2, 3]; - * Map map = new Map.fromIterable(list, - * key: (item) => item.toString(), - * value: (item) => item * item); - * - * map['1'] + map['2']; // 1 + 4 - * map['3'] - map['2']; // 9 - 4 - * - * If no values are specified for [key] and [value] the default is the - * identity function. - * - * In the following example, the keys and corresponding values of `map` - * are `list` values: - * - * map = new Map.fromIterable(list); - * map[1] + map[2]; // 1 + 2 - * map[3] - map[2]; // 3 - 2 - * - * The keys computed by the source [iterable] do not need to be unique. The - * last occurrence of a key will simply overwrite any previous value. - */ - factory Map.fromIterable(Iterable iterable, - {K key(element)?, V value(element)?}) = LinkedHashMap.fromIterable; - - /** - * Creates a Map instance associating the given [keys] to [values]. - * - * The created map is a [LinkedHashMap]. - * A `LinkedHashMap` requires the keys to implement compatible - * `operator==` and `hashCode`, and it allows null as a key. - * It iterates in key insertion order. - * - * This constructor iterates over [keys] and [values] and maps each element of - * [keys] to the corresponding element of [values]. - * - * List letters = ['b', 'c']; - * List words = ['bad', 'cat']; - * Map map = new Map.fromIterables(letters, words); - * map['b'] + map['c']; // badcat - * - * If [keys] contains the same object multiple times, the last occurrence - * overwrites the previous value. - * - * The two [Iterable]s must have the same length. - */ - factory Map.fromIterables(Iterable keys, Iterable values) = - LinkedHashMap.fromIterables; - - /** - * Adapts [source] to be a `Map`. - * - * Any time the set would produce a key or value that is not a [K2] or [V2], - * the access will throw. - * - * Any time [K2] key or [V2] value is attempted added into the adapted map, - * the store will throw unless the key is also an instance of [K] and - * the value is also an instance of [V]. - * - * If all accessed entries of [source] are have [K2] keys and [V2] values - * and if all entries added to the returned map have [K] keys and [V]] values, - * then the returned map can be used as a `Map`. - */ - static Map castFrom(Map source) => - CastMap(source); - - /** - * Creates a new map and adds all entries. - * - * Returns a new `Map` where all entries of [entries] - * have been added in iteration order. - * - * If multiple [entries] have the same key, - * later occurrences overwrite the earlier ones. - */ - factory Map.fromEntries(Iterable> entries) => - {}..addEntries(entries); - - /** - * Provides a view of this map as having [RK] keys and [RV] instances, - * if necessary. - * - * If this map is already a `Map`, it is returned unchanged. - * - * If this set contains only keys of type [RK] and values of type [RV], - * all read operations will work correctly. - * If any operation exposes a non-[RK] key or non-[RV] value, - * the operation will throw instead. - * - * Entries added to the map must be valid for both a `Map` and a - * `Map`. - */ - Map cast(); - - /** - * Returns true if this map contains the given [value]. - * - * Returns true if any of the values in the map are equal to `value` - * according to the `==` operator. - */ - bool containsValue(Object? value); - - /** - * Returns true if this map contains the given [key]. - * - * Returns true if any of the keys in the map are equal to `key` - * according to the equality used by the map. - */ - bool containsKey(Object? key); - - /** - * Returns the value for the given [key] or null if [key] is not in the map. - * - * Some maps allow keys to have `null` as a value. - * For those maps, a lookup using this operator cannot distinguish between a - * key not being in the map and the key having a `null` value. - * Methods like [containsKey] or [putIfAbsent] can be used if the distinction - * is important. - */ - V? operator [](Object? key); - - /** - * Associates the [key] with the given [value]. - * - * If the key was already in the map, its associated value is changed. - * Otherwise the key/value pair is added to the map. - */ - void operator []=(K key, V value); - - /** - * The map entries of [this]. - */ - Iterable> get entries; - - /** - * Returns a new map where all entries of this map are transformed by - * the given [f] function. - */ - Map map(MapEntry f(K key, V value)); - - /** - * Adds all key/value pairs of [newEntries] to this map. - * - * If a key of [newEntries] is already in this map, - * the corresponding value is overwritten. - * - * The operation is equivalent to doing `this[entry.key] = entry.value` - * for each [MapEntry] of the iterable. - */ - void addEntries(Iterable> newEntries); - - /** - * Updates the value for the provided [key]. - * - * Returns the new value of the key. - * - * If the key is present, invokes [update] with the current value and stores - * the new value in the map. - * - * If the key is not present and [ifAbsent] is provided, calls [ifAbsent] - * and adds the key with the returned value to the map. - * - * It's an error if the key is not present and [ifAbsent] is not provided. - */ - V update(K key, V update(V value), {V ifAbsent()?}); - - /** - * Updates all values. - * - * Iterates over all entries in the map and updates them with the result - * of invoking [update]. - */ - void updateAll(V update(K key, V value)); - - /** - * Removes all entries of this map that satisfy the given [predicate]. - */ - void removeWhere(bool predicate(K key, V value)); - - /** - * Look up the value of [key], or add a new value if it isn't there. - * - * Returns the value associated to [key], if there is one. - * Otherwise calls [ifAbsent] to get a new value, associates [key] to - * that value, and then returns the new value. - * - * Map scores = {'Bob': 36}; - * for (var key in ['Bob', 'Rohan', 'Sophena']) { - * scores.putIfAbsent(key, () => key.length); - * } - * scores['Bob']; // 36 - * scores['Rohan']; // 5 - * scores['Sophena']; // 7 - * - * Calling [ifAbsent] must not add or remove keys from the map. - */ - V putIfAbsent(K key, V ifAbsent()); - - /** - * Adds all key/value pairs of [other] to this map. - * - * If a key of [other] is already in this map, its value is overwritten. - * - * The operation is equivalent to doing `this[key] = value` for each key - * and associated value in other. It iterates over [other], which must - * therefore not change during the iteration. - */ - void addAll(Map other); - - /** - * Removes [key] and its associated value, if present, from the map. - * - * Returns the value associated with `key` before it was removed. - * Returns `null` if `key` was not in the map. - * - * Note that values can be `null` and a returned `null` value doesn't - * always mean that the key was absent. - */ - V? remove(Object? key); - - /** - * Removes all pairs from the map. - * - * After this, the map is empty. - */ - void clear(); - - /** - * Applies [f] to each key/value pair of the map. - * - * Calling `f` must not add or remove keys from the map. - */ - void forEach(void f(K key, V value)); - - /** - * The keys of [this]. - * - * The returned iterable has efficient `length` and `contains` operations, - * based on [length] and [containsKey] of the map. - * - * The order of iteration is defined by the individual `Map` implementation, - * but must be consistent between changes to the map. - * - * Modifying the map while iterating the keys - * may break the iteration. - */ - Iterable get keys; - - /** - * The values of [this]. - * - * The values are iterated in the order of their corresponding keys. - * This means that iterating [keys] and [values] in parallel will - * provide matching pairs of keys and values. - * - * The returned iterable has an efficient `length` method based on the - * [length] of the map. Its [Iterable.contains] method is based on - * `==` comparison. - * - * Modifying the map while iterating the - * values may break the iteration. - */ - Iterable get values; - - /** - * The number of key/value pairs in the map. - */ - int get length; - - /** - * Returns true if there is no key/value pair in the map. - */ - bool get isEmpty; - - /** - * Returns true if there is at least one key/value pair in the map. - */ - bool get isNotEmpty; -} - -/** - * A key/value pair representing an entry in a [Map]. - */ -class MapEntry { - /** The key of the entry. */ - final K key; - - /** The value associated to [key] in the map. */ - final V value; - - /** Creates an entry with [key] and [value]. */ - const factory MapEntry(K key, V value) = MapEntry._; - - const MapEntry._(this.key, this.value); - - String toString() => "MapEntry(${key.toString()}: ${value.toString()})"; -} diff --git a/sdk_nnbd/lib/core/null.dart b/sdk_nnbd/lib/core/null.dart deleted file mode 100644 index f8588a173f1..00000000000 --- a/sdk_nnbd/lib/core/null.dart +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) 2013, 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. - -part of dart.core; - -/** - * The reserved word `null` denotes an object that is the sole instance of - * this class. - * - * It is a compile-time error for a class to attempt to extend or implement - * [Null]. - */ -@pragma("vm:entry-point") -class Null { - factory Null._uninstantiable() { - throw UnsupportedError('class Null cannot be instantiated'); - } - - external int get hashCode; - - /** Returns the string `"null"`. */ - String toString() => "null"; -} diff --git a/sdk_nnbd/lib/core/num.dart b/sdk_nnbd/lib/core/num.dart deleted file mode 100644 index 55bb9106769..00000000000 --- a/sdk_nnbd/lib/core/num.dart +++ /dev/null @@ -1,489 +0,0 @@ -// Copyright (c) 2012, 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. - -part of dart.core; - -/** - * An integer or floating-point number. - * - * It is a compile-time error for any type other than [int] or [double] - * to attempt to extend or implement num. - */ -abstract class num implements Comparable { - /** - * Test whether this value is numerically equal to `other`. - * - * If both operands are doubles, they are equal if they have the same - * representation, except that: - * - * * zero and minus zero (0.0 and -0.0) are considered equal. They - * both have the numerical value zero. - * * NaN is not equal to anything, including NaN. If either operand is - * NaN, the result is always false. - * - * If one operand is a double and the other is an int, they are equal if - * the double has an integer value (finite with no fractional part) and - * `identical(doubleValue.toInt(), intValue)` is true. - * - * If both operands are integers, they are equal if they have the same value. - * - * Returns false if `other` is not a [num]. - * - * Notice that the behavior for NaN is non-reflexive. This means that - * equality of double values is not a proper equality relation, as is - * otherwise required of `operator==`. Using NaN in, e.g., a [HashSet] - * will fail to work. The behavior is the standard IEEE-754 equality of - * doubles. - * - * If you can avoid NaN values, the remaining doubles do have a proper - * equality relation, and can be used safely. - * - * Use [compareTo] for a comparison that distinguishes zero and minus zero, - * and that considers NaN values as equal. - */ - bool operator ==(Object other); - - /** - * Returns a hash code for a numerical value. - * - * The hash code is compatible with equality. It returns the same value - * for an [int] and a [double] with the same numerical value, and therefore - * the same value for the doubles zero and minus zero. - * - * No guarantees are made about the hash code of NaN values. - */ - int get hashCode; - - /** - * Compares this to `other`. - * - * Returns a negative number if `this` is less than `other`, zero if they are - * equal, and a positive number if `this` is greater than `other`. - * - * The ordering represented by this method is a total ordering of [num] - * values. All distinct doubles are non-equal, as are all distinct integers, - * but integers are equal to doubles if they have the same numerical - * value. - * - * For doubles, the `compareTo` operation is different from the partial - * ordering given by [operator==], [operator<] and [operator>]. For example, - * IEEE doubles impose that `0.0 == -0.0` and all comparison operations on - * NaN return false. - * - * This function imposes a complete ordering for doubles. When using - * `compareTo` the following properties hold: - * - * - All NaN values are considered equal, and greater than any numeric value. - * - -0.0 is less than 0.0 (and the integer 0), but greater than any non-zero - * negative value. - * - Negative infinity is less than all other values and positive infinity is - * greater than all non-NaN values. - * - All other values are compared using their numeric value. - * - * Examples: - * ``` - * print(1.compareTo(2)); // => -1 - * print(2.compareTo(1)); // => 1 - * print(1.compareTo(1)); // => 0 - * - * // The following comparisons yield different results than the - * // corresponding comparison operators. - * print((-0.0).compareTo(0.0)); // => -1 - * print(double.nan.compareTo(double.nan)); // => 0 - * print(double.infinity.compareTo(double.nan)); // => -1 - * - * // -0.0, and NaN comparison operators have rules imposed by the IEEE - * // standard. - * print(-0.0 == 0.0); // => true - * print(double.nan == double.nan); // => false - * print(double.infinity < double.nan); // => false - * print(double.nan < double.infinity); // => false - * print(double.nan == double.infinity); // => false - * ``` - */ - int compareTo(num other); - - /** Addition operator. */ - num operator +(num other); - - /** Subtraction operator. */ - num operator -(num other); - - /** Multiplication operator. */ - num operator *(num other); - - /** - * Euclidean modulo operator. - * - * Returns the remainder of the Euclidean division. The Euclidean division of - * two integers `a` and `b` yields two integers `q` and `r` such that - * `a == b * q + r` and `0 <= r < b.abs()`. - * - * The Euclidean division is only defined for integers, but can be easily - * extended to work with doubles. In that case `r` may have a non-integer - * value, but it still verifies `0 <= r < |b|`. - * - * The sign of the returned value `r` is always positive. - * - * See [remainder] for the remainder of the truncating division. - */ - num operator %(num other); - - /** Division operator. */ - double operator /(num other); - - /** - * Truncating division operator. - * - * If either operand is a [double] then the result of the truncating division - * `a ~/ b` is equivalent to `(a / b).truncate().toInt()`. - * - * If both operands are [int]s then `a ~/ b` performs the truncating - * integer division. - */ - int operator ~/(num other); - - /** Negate operator. */ - num operator -(); - - /** - * Returns the remainder of the truncating division of `this` by [other]. - * - * The result `r` of this operation satisfies: - * `this == (this ~/ other) * other + r`. - * As a consequence the remainder `r` has the same sign as the divider `this`. - */ - num remainder(num other); - - /** Relational less than operator. */ - bool operator <(num other); - - /** Relational less than or equal operator. */ - bool operator <=(num other); - - /** Relational greater than operator. */ - bool operator >(num other); - - /** Relational greater than or equal operator. */ - bool operator >=(num other); - - /** True if the number is the double Not-a-Number value; otherwise, false. */ - bool get isNaN; - - /** - * True if the number is negative; otherwise, false. - * - * Negative numbers are those less than zero, and the double `-0.0`. - */ - bool get isNegative; - - /** - * True if the number is positive infinity or negative infinity; otherwise, - * false. - */ - bool get isInfinite; - - /** - * True if the number is finite; otherwise, false. - * - * The only non-finite numbers are NaN, positive infinity, and - * negative infinity. - */ - bool get isFinite; - - /** Returns the absolute value of this [num]. */ - num abs(); - - /** - * Returns minus one, zero or plus one depending on the sign and - * numerical value of the number. - * - * Returns minus one if the number is less than zero, - * plus one if the number is greater than zero, - * and zero if the number is equal to zero. - * - * Returns NaN if the number is the double NaN value. - * - * Returns a number of the same type as this number. - * For doubles, `-0.0.sign == -0.0`. - - * The result satisfies: - * - * n == n.sign * n.abs() - * - * for all numbers `n` (except NaN, because NaN isn't `==` to itself). - */ - num get sign; - - /** - * Returns the integer closest to `this`. - * - * Rounds away from zero when there is no closest integer: - * `(3.5).round() == 4` and `(-3.5).round() == -4`. - * - * If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError]. - */ - int round(); - - /** - * Returns the greatest integer no greater than `this`. - * - * If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError]. - */ - int floor(); - - /** - * Returns the least integer no smaller than `this`. - * - * If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError]. - */ - int ceil(); - - /** - * Returns the integer obtained by discarding any fractional - * digits from `this`. - * - * If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError]. - */ - int truncate(); - - /** - * Returns the double integer value closest to `this`. - * - * Rounds away from zero when there is no closest integer: - * `(3.5).roundToDouble() == 4` and `(-3.5).roundToDouble() == -4`. - * - * If this is already an integer valued double, including `-0.0`, or it is a - * non-finite double value, the value is returned unmodified. - * - * For the purpose of rounding, `-0.0` is considered to be below `0.0`, - * and `-0.0` is therefore considered closer to negative numbers than `0.0`. - * This means that for a value, `d` in the range `-0.5 < d < 0.0`, - * the result is `-0.0`. - * - * The result is always a double. - * If this is a numerically large integer, the result may be an infinite - * double. - */ - double roundToDouble(); - - /** - * Returns the greatest double integer value no greater than `this`. - * - * If this is already an integer valued double, including `-0.0`, or it is a - * non-finite double value, the value is returned unmodified. - * - * For the purpose of rounding, `-0.0` is considered to be below `0.0`. - * A number `d` in the range `0.0 < d < 1.0` will return `0.0`. - * - * The result is always a double. - * If this is a numerically large integer, the result may be an infinite - * double. - */ - double floorToDouble(); - - /** - * Returns the least double integer value no smaller than `this`. - * - * If this is already an integer valued double, including `-0.0`, or it is a - * non-finite double value, the value is returned unmodified. - * - * For the purpose of rounding, `-0.0` is considered to be below `0.0`. - * A number `d` in the range `-1.0 < d < 0.0` will return `-0.0`. - * - * The result is always a double. - * If this is a numerically large integer, the result may be an infinite - * double. - */ - double ceilToDouble(); - - /** - * Returns the double integer value obtained by discarding any fractional - * digits from the double value of `this`. - * - * If this is already an integer valued double, including `-0.0`, or it is a - * non-finite double value, the value is returned unmodified. - * - * For the purpose of rounding, `-0.0` is considered to be below `0.0`. - * A number `d` in the range `-1.0 < d < 0.0` will return `-0.0`, and - * in the range `0.0 < d < 1.0` it will return 0.0. - * - * The result is always a double. - * If this is a numerically large integer, the result may be an infinite - * double. - */ - double truncateToDouble(); - - /** - * Returns this [num] clamped to be in the range [lowerLimit]-[upperLimit]. - * - * The comparison is done using [compareTo] and therefore takes `-0.0` into - * account. This also implies that [double.nan] is treated as the maximal - * double value. - * - * The arguments [lowerLimit] and [upperLimit] must form a valid range where - * `lowerLimit.compareTo(upperLimit) <= 0`. - */ - num clamp(num lowerLimit, num upperLimit); - - /** Truncates this [num] to an integer and returns the result as an [int]. */ - int toInt(); - - /** - * Return this [num] as a [double]. - * - * If the number is not representable as a [double], an - * approximation is returned. For numerically large integers, the - * approximation may be infinite. - */ - double toDouble(); - - /** - * Returns a decimal-point string-representation of `this`. - * - * Converts `this` to a [double] before computing the string representation. - * - * If the absolute value of `this` is greater or equal to `10^21` then this - * methods returns an exponential representation computed by - * `this.toStringAsExponential()`. Otherwise the result - * is the closest string representation with exactly [fractionDigits] digits - * after the decimal point. If [fractionDigits] equals 0 then the decimal - * point is omitted. - * - * The parameter [fractionDigits] must be an integer satisfying: - * `0 <= fractionDigits <= 20`. - * - * Examples: - * - * 1.toStringAsFixed(3); // 1.000 - * (4321.12345678).toStringAsFixed(3); // 4321.123 - * (4321.12345678).toStringAsFixed(5); // 4321.12346 - * 123456789012345.toStringAsFixed(3); // 123456789012345.000 - * 10000000000000000.toStringAsFixed(4); // 10000000000000000.0000 - * 5.25.toStringAsFixed(0); // 5 - */ - String toStringAsFixed(int fractionDigits); - - /** - * Returns an exponential string-representation of `this`. - * - * Converts `this` to a [double] before computing the string representation. - * - * If [fractionDigits] is given then it must be an integer satisfying: - * `0 <= fractionDigits <= 20`. In this case the string contains exactly - * [fractionDigits] after the decimal point. Otherwise, without the parameter, - * the returned string uses the shortest number of digits that accurately - * represent [this]. - * - * If [fractionDigits] equals 0 then the decimal point is omitted. - * Examples: - * - * 1.toStringAsExponential(); // 1e+0 - * 1.toStringAsExponential(3); // 1.000e+0 - * 123456.toStringAsExponential(); // 1.23456e+5 - * 123456.toStringAsExponential(3); // 1.235e+5 - * 123.toStringAsExponential(0); // 1e+2 - */ - String toStringAsExponential([int? fractionDigits]); - - /** - * Converts `this` to a double and returns a string representation with - * exactly [precision] significant digits. - * - * The parameter [precision] must be an integer satisfying: - * `1 <= precision <= 21`. - * - * Examples: - * - * 1.toStringAsPrecision(2); // 1.0 - * 1e15.toStringAsPrecision(3); // 1.00e+15 - * 1234567.toStringAsPrecision(3); // 1.23e+6 - * 1234567.toStringAsPrecision(9); // 1234567.00 - * 12345678901234567890.toStringAsPrecision(20); // 12345678901234567168 - * 12345678901234567890.toStringAsPrecision(14); // 1.2345678901235e+19 - * 0.00000012345.toStringAsPrecision(15); // 1.23450000000000e-7 - * 0.0000012345.toStringAsPrecision(15); // 0.00000123450000000000 - */ - String toStringAsPrecision(int precision); - - /** - * Returns the shortest string that correctly represent the input number. - * - * All [double]s in the range `10^-6` (inclusive) to `10^21` (exclusive) - * are converted to their decimal representation with at least one digit - * after the decimal point. For all other doubles, - * except for special values like `NaN` or `Infinity`, this method returns an - * exponential representation (see [toStringAsExponential]). - * - * Returns `"NaN"` for [double.nan], `"Infinity"` for [double.infinity], and - * `"-Infinity"` for [double.negativeInfinity]. - * - * An [int] is converted to a decimal representation with no decimal point. - * - * Examples: - * - * (0.000001).toString(); // "0.000001" - * (0.0000001).toString(); // "1e-7" - * (111111111111111111111.0).toString(); // "111111111111111110000.0" - * (100000000000000000000.0).toString(); // "100000000000000000000.0" - * (1000000000000000000000.0).toString(); // "1e+21" - * (1111111111111111111111.0).toString(); // "1.1111111111111111e+21" - * 1.toString(); // "1" - * 111111111111111111111.toString(); // "111111111111111110000" - * 100000000000000000000.toString(); // "100000000000000000000" - * 1000000000000000000000.toString(); // "1000000000000000000000" - * 1111111111111111111111.toString(); // "1111111111111111111111" - * 1.234e5.toString(); // 123400 - * 1234.5e6.toString(); // 1234500000 - * 12.345e67.toString(); // 1.2345e+68 - * - * Note: the conversion may round the output if the returned string - * is accurate enough to uniquely identify the input-number. - * For example the most precise representation of the [double] `9e59` equals - * `"899999999999999918767229449717619953810131273674690656206848"`, but - * this method returns the shorter (but still uniquely identifying) `"9e59"`. - * - */ - String toString(); - - /** - * Parses a string containing a number literal into a number. - * - * The method first tries to read the [input] as integer (similar to - * [int.parse] without a radix). - * If that fails, it tries to parse the [input] as a double (similar to - * [double.parse]). - * If that fails, too, it invokes [onError] with [input], and the result - * of that invocation becomes the result of calling `parse`. - * - * If no [onError] is supplied, it defaults to a function that throws a - * [FormatException]. - * - * For any number `n`, this function satisfies - * `identical(n, num.parse(n.toString()))` (except when `n` is a NaN `double` - * with a payload). - * - * The [onError] parameter is deprecated and will be removed. - * Instead of `num.parse(string, (string) { ... })`, - * you should use `num.tryParse(string) ?? (...)`. - */ - static num parse(String input, [@deprecated num onError(String input)?]) { - num? result = tryParse(input); - if (result != null) return result; - if (onError == null) throw FormatException(input); - return onError(input); - } - - /** - * Parses a string containing a number literal into a number. - * - * Like [parse] except that this function returns `null` for invalid inputs - * instead of throwing. - */ - static num? tryParse(String input) { - String source = input.trim(); - // TODO(lrn): Optimize to detect format and result type in one check. - return int.tryParse(source) ?? double.tryParse(source); - } -} diff --git a/sdk_nnbd/lib/core/object.dart b/sdk_nnbd/lib/core/object.dart deleted file mode 100644 index 31602dfd96d..00000000000 --- a/sdk_nnbd/lib/core/object.dart +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright (c) 2012, 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. - -part of dart.core; - -/** - * The base class for all Dart objects. - * - * Because Object is the root of the Dart class hierarchy, - * every other Dart class is a subclass of Object. - * - * When you define a class, you should override [toString] - * to return a string describing an instance of that class. - * You might also need to define [hashCode] and [operator ==], as described in the - * [Implementing map - * keys](https://www.dartlang.org/docs/dart-up-and-running/ch03.html#implementing-map-keys) - * section of the [library - * tour](http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html). - */ -@pragma("vm:entry-point") -class Object { - /** - * Creates a new [Object] instance. - * - * [Object] instances have no meaningful state, and are only useful - * through their identity. An [Object] instance is equal to itself - * only. - */ - const Object(); - - /** - * The equality operator. - * - * The default behavior for all [Object]s is to return true if and - * only if `this` and [other] are the same object. - * - * Override this method to specify a different equality relation on - * a class. The overriding method must still be an equivalence relation. - * That is, it must be: - * - * * Total: It must return a boolean for all arguments. It should never throw - * or return `null`. - * - * * Reflexive: For all objects `o`, `o == o` must be true. - * - * * Symmetric: For all objects `o1` and `o2`, `o1 == o2` and `o2 == o1` must - * either both be true, or both be false. - * - * * Transitive: For all objects `o1`, `o2`, and `o3`, if `o1 == o2` and - * `o2 == o3` are true, then `o1 == o3` must be true. - * - * The method should also be consistent over time, - * so whether two objects are equal should only change - * if at least one of the objects was modified. - * - * If a subclass overrides the equality operator it should override - * the [hashCode] method as well to maintain consistency. - */ - external bool operator ==(Object other); - - /** - * The hash code for this object. - * - * A hash code is a single integer which represents the state of the object - * that affects [operator ==] comparisons. - * - * All objects have hash codes. - * The default hash code represents only the identity of the object, - * the same way as the default [operator ==] implementation only considers objects - * equal if they are identical (see [identityHashCode]). - * - * If [operator ==] is overridden to use the object state instead, - * the hash code must also be changed to represent that state. - * - * Hash codes must be the same for objects that are equal to each other - * according to [operator ==]. - * The hash code of an object should only change if the object changes - * in a way that affects equality. - * There are no further requirements for the hash codes. - * They need not be consistent between executions of the same program - * and there are no distribution guarantees. - * - * Objects that are not equal are allowed to have the same hash code, - * it is even technically allowed that all instances have the same hash code, - * but if clashes happen too often, it may reduce the efficiency of hash-based - * data structures like [HashSet] or [HashMap]. - * - * If a subclass overrides [hashCode], it should override the - * [operator ==] operator as well to maintain consistency. - */ - external int get hashCode; - - /** - * Returns a string representation of this object. - */ - external String toString(); - - /** - * Invoked when a non-existent method or property is accessed. - * - * Classes can override [noSuchMethod] to provide custom behavior. - * - * If a value is returned, it becomes the result of the original invocation. - * - * The default behavior is to throw a [NoSuchMethodError]. - */ - @pragma("vm:entry-point") - external dynamic noSuchMethod(Invocation invocation); - - /** - * A representation of the runtime type of the object. - */ - external Type get runtimeType; -} diff --git a/sdk_nnbd/lib/core/pattern.dart b/sdk_nnbd/lib/core/pattern.dart deleted file mode 100644 index 7a3d933f8db..00000000000 --- a/sdk_nnbd/lib/core/pattern.dart +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright (c) 2011, 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. - -part of dart.core; - -/** - * An interface for basic searches within strings. - */ -abstract class Pattern { - /** - * Match this pattern against the string repeatedly. - * - * If [start] is provided, matching will start at that index. - * - * The returned iterable lazily computes all the non-overlapping matches - * of the pattern on the string, ordered by start index. - * If a user only requests the first - * match, this function should not compute all possible matches. - * - * The matches are found by repeatedly finding the first match - * of the pattern on the string, starting from the end of the previous - * match, and initially starting from index zero. - * - * If the pattern matches the empty string at some point, the next - * match is found by starting at the previous match's end plus one. - */ - Iterable allMatches(String string, [int start = 0]); - - /** - * Match this pattern against the start of `string`. - * - * If [start] is provided, it must be an integer in the range `0` .. - * `string.length`. In that case, this patten is tested against the - * string at the [start] position. That is, a [Match] is returned if the - * pattern can match a part of the string starting from position [start]. - * Returns `null` if the pattern doesn't match. - */ - Match? matchAsPrefix(String string, [int start = 0]); -} - -/** - * A result from searching within a string. - * - * A Match or an [Iterable] of Match objects is returned from [Pattern] - * matching methods. - * - * The following example finds all matches of a [RegExp] in a [String] - * and iterates through the returned iterable of Match objects. - * - * RegExp exp = new RegExp(r"(\w+)"); - * String str = "Parse my string"; - * Iterable matches = exp.allMatches(str); - * for (Match m in matches) { - * String match = m.group(0); - * print(match); - * } - * - * The output of the example is: - * - * Parse - * my - * string - * - * Some patterns, regular expressions in particular, may record substrings - * that were part of the matching. These are called _groups_ in the Match - * object. Some patterns may never have any groups, and their matches always - * have zero [groupCount]. - */ -abstract class Match { - /** - * Returns the index in the string where the match starts. - */ - int get start; - - /** - * Returns the index in the string after the last character of the - * match. - */ - int get end; - - /** - * Returns the string matched by the given [group]. - * - * If [group] is 0, returns the match of the pattern. - * - * The result may be `null` if the pattern didn't assign a value to it - * as part of this match. - */ - String? group(int group); - - /** - * Returns the string matched by the given [group]. - * - * If [group] is 0, returns the match of the pattern. - * - * Short alias for [Match.group]. - */ - String? operator [](int group); - - /** - * Returns a list of the groups with the given indices. - * - * The list contains the strings returned by [group] for each index in - * [groupIndices]. - */ - List groups(List groupIndices); - - /** - * Returns the number of captured groups in the match. - * - * Some patterns may capture parts of the input that was used to - * compute the full match. This is the number of captured groups, - * which is also the maximal allowed argument to the [group] method. - */ - int get groupCount; - - /** - * The string on which this match was computed. - */ - String get input; - - /** - * The pattern used to search in [input]. - */ - Pattern get pattern; -} diff --git a/sdk_nnbd/lib/core/print.dart b/sdk_nnbd/lib/core/print.dart deleted file mode 100644 index d88ea7f3c4d..00000000000 --- a/sdk_nnbd/lib/core/print.dart +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) 2012, 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. - -part of dart.core; - -/// Prints a string representation of the object to the console. -void print(Object? object) { - String line = object.toString(); - var toZone = printToZone; - if (toZone == null) { - printToConsole(line); - } else { - toZone(line); - } -} diff --git a/sdk_nnbd/lib/core/regexp.dart b/sdk_nnbd/lib/core/regexp.dart deleted file mode 100644 index b75882d618f..00000000000 --- a/sdk_nnbd/lib/core/regexp.dart +++ /dev/null @@ -1,189 +0,0 @@ -// Copyright (c) 2012, 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. - -part of dart.core; - -/** - * A regular expression pattern. - * - * Regular expressions are [Pattern]s, and can as such be used to match strings - * or parts of strings. - * - * Dart regular expressions have the same syntax and semantics as - * JavaScript regular expressions. See - * - * for the specification of JavaScript regular expressions. - * - * [firstMatch] is the main implementation method that applies a regular - * expression to a string and returns the first [RegExpMatch]. All - * other methods in [RegExp] can build on it. - * - * Use [allMatches] to look for all matches of a regular expression in - * a string. - * - * The following example finds all matches of a regular expression in - * a string. - * ```dart - * RegExp exp = new RegExp(r"(\w+)"); - * String str = "Parse my string"; - * Iterable matches = exp.allMatches(str); - * ``` - * - * Note the use of a _raw string_ (a string prefixed with `r`) - * in the example above. Use a raw string to treat each character in a string - * as a literal character. - */ -abstract class RegExp implements Pattern { - /** - * Constructs a regular expression. - * - * Throws a [FormatException] if [source] is not valid regular - * expression syntax. - * - * If `multiLine` is enabled, then `^` and `$` will match the beginning and - * end of a _line_, in addition to matching beginning and end of input, - * respectively. - * - * If `caseSensitive` is disabled, then case is ignored. - * - * If `unicode` is enabled, then the pattern is treated as a Unicode - * pattern as described by the ECMAScript standard. - * - * If `dotAll` is enabled, then the `.` pattern will match _all_ characters, - * including line terminators. - * - * Example: - * - * ```dart - * var wordPattern = RegExp(r"(\w+)"); - * var bracketedNumberValue = RegExp("$key: \\[\\d+\\]"); - * ``` - * - * Notice the use of a _raw string_ in the first example, and a regular - * string in the second. Because of the many character classes used in - * regular expressions, it is common to use a raw string here, unless string - * interpolation is required. - */ - external factory RegExp(String source, - {bool multiLine = false, - bool caseSensitive = true, - @Since("2.4") bool unicode = false, - @Since("2.4") bool dotAll = false}); - - /** - * Returns a regular expression that matches [text]. - * - * If [text] contains characters that are meaningful in regular expressions, - * the resulting regular expression will match those characters literally. - * If [text] contains no characters that have special meaning in a regular - * expression, it is returned unmodified. - * - * The characters that have special meaning in regular expressions are: - * `(`, `)`, `[`, `]`, `{`, `}`, `*`, `+`, `?`, `.`, `^`, `$`, `|` and `\`. - */ - external static String escape(String text); - - /** - * Searches for the first match of the regular expression - * in the string [input]. Returns `null` if there is no match. - */ - RegExpMatch? firstMatch(String input); - - /** - * Returns an iterable of the matches of the regular expression on [input]. - * - * If [start] is provided, only start looking for matches at `start`. - */ - Iterable allMatches(String input, [int start = 0]); - - /** - * Returns whether the regular expression has a match in the string [input]. - */ - bool hasMatch(String input); - - /** - * Returns the first substring match of this regular expression in [input]. - */ - String? stringMatch(String input); - - /** - * The source regular expression string used to create this `RegExp`. - */ - String get pattern; - - /** - * Whether this regular expression matches multiple lines. - * - * If the regexp does match multiple lines, the "^" and "$" characters - * match the beginning and end of lines. If not, the character match the - * beginning and end of the input. - */ - bool get isMultiLine; - - /** - * Whether this regular expression is case sensitive. - * - * If the regular expression is not case sensitive, it will match an input - * letter with a pattern letter even if the two letters are different case - * versions of the same letter. - */ - bool get isCaseSensitive; - - /** - * Whether this regular expression is in Unicode mode. - * - * In Unicode mode, UTF-16 surrogate pairs in the original string will be - * treated as a single code point and will not match separately. Otherwise, - * the target string will be treated purely as a sequence of individual code - * units and surrogates will not be treated specially. - * - * In Unicode mode, the syntax of the RegExp pattern is more restricted, but - * some pattern features, like Unicode property escapes, are only available in - * this mode. - */ - @Since("2.4") - bool get isUnicode; - - /** - * Whether "." in this regular expression matches line terminators. - * - * When false, the "." character matches a single character, unless that - * character is a line terminator. When true, then the "." character will - * match any single character including line terminators. - * - * This feature is distinct from [isMultiline], as they affect the behavior - * of different pattern characters, and so they can be used together or - * separately. - */ - @Since("2.4") - bool get isDotAll; -} - -/** - * A regular expression match. - * - * Regular expression matches are [Match]es, but also include the ability - * to retrieve the names for any named capture groups and to retrieve - * matches for named capture groups by name instead of their index. - */ -@Since("2.3") -abstract class RegExpMatch implements Match { - /** - * The string matched by the group named [name]. - * - * Returns the string matched by the capture group named [name], or - * `null` if no string was matched by that capture group as part of - * this match. - * - * The [name] must be the name of a named capture group in the regular - * expression creating this match (that is, the name must be in - * [groupNames]). - */ - String? namedGroup(String name); - - /** - * The names of the captured groups in the match. - */ - Iterable get groupNames; -} diff --git a/sdk_nnbd/lib/core/set.dart b/sdk_nnbd/lib/core/set.dart deleted file mode 100644 index ae1e381ee58..00000000000 --- a/sdk_nnbd/lib/core/set.dart +++ /dev/null @@ -1,265 +0,0 @@ -// Copyright (c) 2011, 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. - -part of dart.core; - -/** - * A collection of objects in which each object can occur only once. - * - * That is, for each object of the element type, the object is either considered - * to be in the set, or to _not_ be in the set. - * - * Set implementations may consider some elements indistinguishable. These - * elements are treated as being the same for any operation on the set. - * - * The default [Set] implementation, [LinkedHashSet], considers objects - * indistinguishable if they are equal with regard to - * operator [Object.==]. - * - * Iterating over elements of a set may be either unordered - * or ordered in some way. Examples: - * - * * A [HashSet] is unordered, which means that its iteration order is - * unspecified, - * * [LinkedHashSet] iterates in the insertion order of its elements, and - * * a sorted set like [SplayTreeSet] iterates the elements in sorted order. - * - * It is generally not allowed to modify the set (add or remove elements) while - * an operation on the set is being performed, for example during a call to - * [forEach] or [containsAll]. Nor is it allowed to modify the set while - * iterating either the set itself or any [Iterable] that is backed by the set, - * such as the ones returned by methods like [where] and [map]. - * - * It is generally not allowed to modify the equality of elements (and thus not - * their hashcode) while they are in the set. Some specialized subtypes may be - * more permissive, in which case they should document this behavior. - */ -abstract class Set extends EfficientLengthIterable { - /** - * Creates an empty [Set]. - * - * The created [Set] is a plain [LinkedHashSet]. - * As such, it considers elements that are equal (using [operator ==]) to be - * indistinguishable, and requires them to have a compatible - * [Object.hashCode] implementation. - * - * The set is equivalent to one created by `new LinkedHashSet()`. - */ - factory Set() = LinkedHashSet; - - /** - * Creates an empty identity [Set]. - * - * The created [Set] is a [LinkedHashSet] that uses identity as equality - * relation. - * - * The set is equivalent to one created by `new LinkedHashSet.identity()`. - */ - factory Set.identity() = LinkedHashSet.identity; - - /** - * Creates a [Set] that contains all [elements]. - * - * All the [elements] should be instances of [E]. - * The `elements` iterable itself can have any type, - * so this constructor can be used to down-cast a `Set`, for example as: - * - * Set superSet = ...; - * Set subSet = - * new Set.from(superSet.where((e) => e is SubType)); - * - * The created [Set] is a [LinkedHashSet]. As such, it considers elements that - * are equal (using [operator ==]) to be indistinguishable, and requires them to - * have a compatible [Object.hashCode] implementation. - * - * The set is equivalent to one created by - * `new LinkedHashSet.from(elements)`. - */ - factory Set.from(Iterable elements) = LinkedHashSet.from; - - /** - * Creates a [Set] from [elements]. - * - * The created [Set] is a [LinkedHashSet]. As such, it considers elements that - * are equal (using [operator ==]) to be indistinguishable, and requires them to - * have a compatible [Object.hashCode] implementation. - * - * The set is equivalent to one created by - * `new LinkedHashSet.of(elements)`. - */ - factory Set.of(Iterable elements) = LinkedHashSet.of; - - /** - * Adapts [source] to be a `Set`. - * - * If [newSet] is provided, it is used to create the new sets returned - * by [toSet], [union], and is also used for [intersection] and [difference]. - * If [newSet] is omitted, it defaults to creating a new set using the - * default [Set] constructor, and [intersection] and [difference] - * returns an adapted version of calling the same method on the source. - * - * Any time the set would produce an element that is not a [T], - * the element access will throw. - * - * Any time a [T] value is attempted added into the adapted set, - * the store will throw unless the value is also an instance of [S]. - * - * If all accessed elements of [source] are actually instances of [T], - * and if all elements added to the returned set are actually instance - * of [S], - * then the returned set can be used as a `Set`. - */ - static Set castFrom(Set source, {Set Function()? newSet}) => - CastSet(source, newSet); - - /** - * Provides a view of this set as a set of [R] instances. - * - * If this set contains only instances of [R], all read operations - * will work correctly. If any operation tries to access an element - * that is not an instance of [R], the access will throw instead. - * - * Elements added to the set (e.g., by using [add] or [addAll]) - * must be instance of [R] to be valid arguments to the adding function, - * and they must be instances of [E] as well to be accepted by - * this set as well. - */ - Set cast(); - - /** - * Provides an iterator that iterates over the elements of this set. - * - * The order of iteration is defined by the individual `Set` implementation, - * but must be consistent between changes to the set. - */ - Iterator get iterator; - - /** - * Returns true if [value] is in the set. - */ - bool contains(Object? value); - - /** - * Adds [value] to the set. - * - * Returns `true` if [value] (or an equal value) was not yet in the set. - * Otherwise returns `false` and the set is not changed. - * - * Example: - * - * var set = new Set(); - * var time1 = new DateTime.fromMillisecondsSinceEpoch(0); - * var time2 = new DateTime.fromMillisecondsSinceEpoch(0); - * // time1 and time2 are equal, but not identical. - * Expect.isTrue(time1 == time2); - * Expect.isFalse(identical(time1, time2)); - * set.add(time1); // => true. - * // A value equal to time2 exists already in the set, and the call to - * // add doesn't change the set. - * set.add(time2); // => false. - * Expect.isTrue(set.length == 1); - * Expect.isTrue(identical(time1, set.first)); - */ - bool add(E value); - - /** - * Adds all [elements] to this Set. - * - * Equivalent to adding each element in [elements] using [add], - * but some collections may be able to optimize it. - */ - void addAll(Iterable elements); - - /** - * Removes [value] from the set. Returns true if [value] was - * in the set. Returns false otherwise. The method has no effect - * if [value] value was not in the set. - */ - bool remove(Object? value); - - /** - * If an object equal to [object] is in the set, return it. - * - * Checks whether [object] is in the set, like [contains], and if so, - * returns the object in the set, otherwise returns `null`. - * - * If the equality relation used by the set is not identity, - * then the returned object may not be *identical* to [object]. - * Some set implementations may not be able to implement this method. - * If the [contains] method is computed, - * rather than being based on an actual object instance, - * then there may not be a specific object instance representing the - * set element. - */ - E? lookup(Object? object); - - /** - * Removes each element of [elements] from this set. - */ - void removeAll(Iterable elements); - - /** - * Removes all elements of this set that are not elements in [elements]. - * - * Checks for each element of [elements] whether there is an element in this - * set that is equal to it (according to `this.contains`), and if so, the - * equal element in this set is retained, and elements that are not equal - * to any element in `elements` are removed. - */ - void retainAll(Iterable elements); - - /** - * Removes all elements of this set that satisfy [test]. - */ - void removeWhere(bool test(E element)); - - /** - * Removes all elements of this set that fail to satisfy [test]. - */ - void retainWhere(bool test(E element)); - - /** - * Returns whether this Set contains all the elements of [other]. - */ - bool containsAll(Iterable other); - - /** - * Returns a new set which is the intersection between this set and [other]. - * - * That is, the returned set contains all the elements of this [Set] that - * are also elements of [other] according to `other.contains`. - */ - Set intersection(Set other); - - /** - * Returns a new set which contains all the elements of this set and [other]. - * - * That is, the returned set contains all the elements of this [Set] and - * all the elements of [other]. - */ - Set union(Set other); - - /** - * Returns a new set with the elements of this that are not in [other]. - * - * That is, the returned set contains all the elements of this [Set] that - * are not elements of [other] according to `other.contains`. - */ - Set difference(Set other); - - /** - * Removes all elements in the set. - */ - void clear(); - - /* Creates a [Set] with the same elements and behavior as this `Set`. - * - * The returned set behaves the same as this set - * with regard to adding and removing elements. - * It initially contains the same elements. - * If this set specifies an ordering of the elements, - * the returned set will have the same order. - */ - Set toSet(); -} diff --git a/sdk_nnbd/lib/core/sink.dart b/sdk_nnbd/lib/core/sink.dart deleted file mode 100644 index c79214bbf5d..00000000000 --- a/sdk_nnbd/lib/core/sink.dart +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) 2014, 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. - -part of dart.core; - -/** - * A generic destination for data. - * - * Multiple data values can be put into a sink, and when no more data is - * available, the sink should be closed. - * - * This is a generic interface that other data receivers can implement. - */ -abstract class Sink { - /** - * Adds [data] to the sink. - * - * Must not be called after a call to [close]. - */ - void add(T data); - - /** - * Closes the sink. - * - * The [add] method must not be called after this method. - * - * Calling this method more than once is allowed, but does nothing. - */ - void close(); -} diff --git a/sdk_nnbd/lib/core/stacktrace.dart b/sdk_nnbd/lib/core/stacktrace.dart deleted file mode 100644 index ef08f71433a..00000000000 --- a/sdk_nnbd/lib/core/stacktrace.dart +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (c) 2013, 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. - -part of dart.core; - -/** - * An interface implemented by all stack trace objects. - * - * A [StackTrace] is intended to convey information to the user about the call - * sequence that triggered an exception. - * - * These objects are created by the runtime, it is not possible to create - * them programmatically. - */ -abstract class StackTrace { - /// A stack trace object with no information. - /// - /// This stack trace is used as the default in situations where - /// a stack trace is required, but the user has not supplied one. - @Since("2.8") - static const empty = const _StringStackTrace(""); - - StackTrace(); // In case existing classes extend StackTrace. - - /** - * Create a `StackTrace` object from [stackTraceString]. - * - * The created stack trace will have a `toString` method returning - * `stackTraceString`. - * - * The `stackTraceString` can be a string returned by some other - * stack trace, or it can be any string at all. - * If the string doesn't look like a stack trace, code that interprets - * stack traces is likely to fail, so fake stack traces should be used - * with care. - */ - factory StackTrace.fromString(String stackTraceString) = _StringStackTrace; - - /** - * Returns a representation of the current stack trace. - * - * This is similar to what can be achieved by doing: - * - * try { throw 0; } catch (_, stack) { return stack; } - * - * The getter achieves this without throwing, except on platforms that - * have no other way to get a stack trace. - */ - external static StackTrace get current; - - /** - * Returns a [String] representation of the stack trace. - * - * The string represents the full stack trace starting from - * the point where a throw occurred to the top of the current call sequence. - * - * The exact format of the string representation is not final. - */ - String toString(); -} - -class _StringStackTrace implements StackTrace { - final String _stackTrace; - const _StringStackTrace(this._stackTrace); - String toString() => _stackTrace; -} diff --git a/sdk_nnbd/lib/core/stopwatch.dart b/sdk_nnbd/lib/core/stopwatch.dart deleted file mode 100644 index 311db3dc073..00000000000 --- a/sdk_nnbd/lib/core/stopwatch.dart +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright (c) 2011, 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. - -part of dart.core; - -/** - * A simple stopwatch interface to measure elapsed time. - */ -class Stopwatch { - /** - * Cached frequency of the system in Hz (ticks per second). - * - * Value must be returned by [_initTicker], which is called only once. - */ - static final int _frequency = _initTicker(); - - // The _start and _stop fields capture the time when [start] and [stop] - // are called respectively. - // If _stop is null, the stopwatch is running. - int _start = 0; - int? _stop = 0; - - /** - * Creates a [Stopwatch] in stopped state with a zero elapsed count. - * - * The following example shows how to start a [Stopwatch] - * immediately after allocation. - * ``` - * var stopwatch = new Stopwatch()..start(); - * ``` - */ - Stopwatch() { - _frequency; // Ensures initialization before using any method. - } - - /** - * Frequency of the elapsed counter in Hz. - */ - int get frequency => _frequency; - - /** - * Starts the [Stopwatch]. - * - * The [elapsed] count is increasing monotonically. If the [Stopwatch] has - * been stopped, then calling start again restarts it without resetting the - * [elapsed] count. - * - * If the [Stopwatch] is currently running, then calling start does nothing. - */ - void start() { - int? stop = _stop; - if (stop != null) { - // (Re)start this stopwatch. - // Don't count the time while the stopwatch has been stopped. - _start += _now() - stop; - _stop = null; - } - } - - /** - * Stops the [Stopwatch]. - * - * The [elapsedTicks] count stops increasing after this call. If the - * [Stopwatch] is currently not running, then calling this method has no - * effect. - */ - void stop() { - _stop ??= _now(); - } - - /** - * Resets the [elapsed] count to zero. - * - * This method does not stop or start the [Stopwatch]. - */ - void reset() { - _start = _stop ?? _now(); - } - - /** - * The elapsed number of clock ticks since calling [start] while the - * [Stopwatch] is running. - * - * This is the elapsed number of clock ticks between calling [start] and - * calling [stop]. - * - * Is 0 if the [Stopwatch] has never been started. - * - * The elapsed number of clock ticks increases by [frequency] every second. - */ - int get elapsedTicks { - return (_stop ?? _now()) - _start; - } - - /** - * The [elapsedTicks] counter converted to a [Duration]. - */ - Duration get elapsed { - return Duration(microseconds: elapsedMicroseconds); - } - - /** - * The [elapsedTicks] counter converted to microseconds. - */ - external int get elapsedMicroseconds; - - /** - * The [elapsedTicks] counter converted to milliseconds. - */ - external int get elapsedMilliseconds; - - /** - * Whether the [Stopwatch] is currently running. - */ - bool get isRunning => _stop == null; - - /** - * Initializes the time-measuring system. *Must* return the [_frequency] - * variable. May do other necessary initialization. - */ - external static int _initTicker(); - external static int _now(); -} diff --git a/sdk_nnbd/lib/core/string.dart b/sdk_nnbd/lib/core/string.dart deleted file mode 100644 index 4a353b2b8f1..00000000000 --- a/sdk_nnbd/lib/core/string.dart +++ /dev/null @@ -1,840 +0,0 @@ -// Copyright (c) 2012, 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. - -part of dart.core; - -/** - * A sequence of UTF-16 code units. - * - * Strings are mainly used to represent text. A character may be represented by - * multiple code points, each code point consisting of one or two code - * units. For example the Papua New Guinea flag character requires four code - * units to represent two code points, but should be treated like a single - * character: "🇵🇬". Platforms that do not support the flag character may show - * the letters "PG" instead. If the code points are swapped, it instead becomes - * the Guadeloupe flag "🇬🇵" ("GP"). - * - * A string can be either single or multiline. Single line strings are - * written using matching single or double quotes, and multiline strings are - * written using triple quotes. The following are all valid Dart strings: - * - * 'Single quotes'; - * "Double quotes"; - * 'Double quotes in "single" quotes'; - * "Single quotes in 'double' quotes"; - * - * '''A - * multiline - * string'''; - * - * """ - * Another - * multiline - * string"""; - * - * Strings are immutable. Although you cannot change a string, you can perform - * an operation on a string and assign the result to a new string: - * - * var string = 'Dart is fun'; - * var newString = string.substring(0, 5); - * - * You can use the plus (`+`) operator to concatenate strings: - * - * 'Dart ' + 'is ' + 'fun!'; // 'Dart is fun!' - * - * You can also use adjacent string literals for concatenation: - * - * 'Dart ' 'is ' 'fun!'; // 'Dart is fun!' - * - * You can use `${}` to interpolate the value of Dart expressions - * within strings. The curly braces can be omitted when evaluating identifiers: - * - * string = 'dartlang'; - * '$string has ${string.length} letters'; // 'dartlang has 8 letters' - * - * A string is represented by a sequence of Unicode UTF-16 code units - * accessible through the [codeUnitAt] or the [codeUnits] members: - * - * string = 'Dart'; - * string.codeUnitAt(0); // 68 - * string.codeUnits; // [68, 97, 114, 116] - * - * The string representation of code units is accessible through the index - * operator: - * - * string[0]; // 'D' - * - * The characters of a string are encoded in UTF-16. Decoding UTF-16, which - * combines surrogate pairs, yields Unicode code points. Following a similar - * terminology to Go, we use the name 'rune' for an integer representing a - * Unicode code point. Use the [runes] property to get the runes of a string: - * - * string.runes.toList(); // [68, 97, 114, 116] - * - * For a character outside the Basic Multilingual Plane (plane 0) that is - * composed of a surrogate pair, [runes] combines the pair and returns a - * single integer. For example, the Unicode character for a - * musical G-clef ('𝄞') with rune value 0x1D11E consists of a UTF-16 surrogate - * pair: `0xD834` and `0xDD1E`. Using [codeUnits] returns the surrogate pair, - * and using `runes` returns their combined value: - * - * var clef = '\u{1D11E}'; - * clef.codeUnits; // [0xD834, 0xDD1E] - * clef.runes.toList(); // [0x1D11E] - * - * The String class can not be extended or implemented. Attempting to do so - * yields a compile-time error. - * - * ## Other resources - * - * See [StringBuffer] to efficiently build a string incrementally. See - * [RegExp] to work with regular expressions. - * - * Also see: - * - * * [Dart Cookbook](https://www.dartlang.org/docs/cookbook/#strings) - * for String examples and recipes. - * * [Dart Up and Running](https://www.dartlang.org/docs/dart-up-and-running/ch03.html#strings-and-regular-expressions) - */ -@pragma('vm:entry-point') -abstract class String implements Comparable, Pattern { - /** - * Allocates a new String for the specified [charCodes]. - * - * The [charCodes] can be UTF-16 code units or runes. If a char-code value is - * 16-bit, it is copied verbatim: - * - * new String.fromCharCodes([68]); // 'D' - * - * If a char-code value is greater than 16-bits, it is decomposed into a - * surrogate pair: - * - * var clef = new String.fromCharCodes([0x1D11E]); - * clef.codeUnitAt(0); // 0xD834 - * clef.codeUnitAt(1); // 0xDD1E - * - * If [start] and [end] is provided, only the values of [charCodes] - * at positions from `start` to, but not including, `end`, are used. - * The `start` and `end` values must satisfy - * `0 <= start <= end <= charCodes.length`. - */ - external factory String.fromCharCodes(Iterable charCodes, - [int start = 0, int? end]); - - /** - * Allocates a new String for the specified [charCode]. - * - * If the [charCode] can be represented by a single UTF-16 code unit, the new - * string contains a single code unit. Otherwise, the [length] is 2 and - * the code units form a surrogate pair. See documentation for - * [fromCharCodes]. - * - * Creating a [String] with one half of a surrogate pair is allowed. - */ - external factory String.fromCharCode(int charCode); - - /** - * Returns the string value of the environment declaration [name]. - * - * Environment declarations are provided by the surrounding system compiling - * or running the Dart program. Declarations map a string key to a string - * value. - * - * If [name] is not declared in the environment, the result is instead - * [defaultValue]. - * - * Example of getting a value: - * ``` - * const String.fromEnvironment("defaultFloo", defaultValue: "no floo") - * ``` - * In order to check whether a declaration is there at all, use - * [bool.hasEnvironment]. Example: - * ``` - * const maybeDeclared = bool.hasEnvironment("maybeDeclared") - * ? String.fromEnvironment("maybeDeclared") - * : null; - * ``` - */ - // The .fromEnvironment() constructors are special in that we do not want - // users to call them using "new". We prohibit that by giving them bodies - // that throw, even though const constructors are not allowed to have bodies. - // Disable those static errors. - //ignore: const_constructor_with_body - //ignore: const_factory - external const factory String.fromEnvironment(String name, - {String defaultValue = ""}); - - /** - * Gets the character (as a single-code-unit [String]) at the given [index]. - * - * The returned string represents exactly one UTF-16 code unit, which may be - * half of a surrogate pair. A single member of a surrogate pair is an - * invalid UTF-16 string: - * - * var clef = '\u{1D11E}'; - * // These represent invalid UTF-16 strings. - * clef[0].codeUnits; // [0xD834] - * clef[1].codeUnits; // [0xDD1E] - * - * This method is equivalent to - * `new String.fromCharCode(this.codeUnitAt(index))`. - */ - String operator [](int index); - - /** - * Returns the 16-bit UTF-16 code unit at the given [index]. - */ - int codeUnitAt(int index); - - /** - * The length of the string. - * - * Returns the number of UTF-16 code units in this string. The number - * of [runes] might be fewer, if the string contains characters outside - * the Basic Multilingual Plane (plane 0): - * - * 'Dart'.length; // 4 - * 'Dart'.runes.length; // 4 - * - * var clef = '\u{1D11E}'; - * clef.length; // 2 - * clef.runes.length; // 1 - */ - int get length; - - /** - * Returns a hash code derived from the code units of the string. - * - * This is compatible with [operator ==]. Strings with the same sequence - * of code units have the same hash code. - */ - int get hashCode; - - /** - * Returns true if other is a `String` with the same sequence of code units. - * - * This method compares each individual code unit of the strings. - * It does not check for Unicode equivalence. - * For example, both the following strings represent the string 'Amélie', - * but due to their different encoding, are not equal: - * - * 'Am\xe9lie' == 'Ame\u{301}lie'; // false - * - * The first string encodes 'é' as a single unicode code unit (also - * a single rune), whereas the second string encodes it as 'e' with the - * combining accent character '◌́'. - */ - bool operator ==(Object other); - - /** - * Compares this string to [other]. - * - * Returns a negative value if `this` is ordered before `other`, - * a positive value if `this` is ordered after `other`, - * or zero if `this` and `other` are equivalent. - * - * The ordering is the same as the ordering of the code points at the first - * position where the two strings differ. - * If one string is a prefix of the other, - * then the shorter string is ordered before the longer string. - * If the strings have exactly the same content, they are equivalent with - * regard to the ordering. - * Ordering does not check for Unicode equivalence. - * The comparison is case sensitive. - */ - int compareTo(String other); - - /** - * Returns true if this string ends with [other]. For example: - * - * 'Dart'.endsWith('t'); // true - */ - bool endsWith(String other); - - /** - * Returns true if this string starts with a match of [pattern]. - * - * var string = 'Dart'; - * string.startsWith('D'); // true - * string.startsWith(new RegExp(r'[A-Z][a-z]')); // true - * - * If [index] is provided, this method checks if the substring starting - * at that index starts with a match of [pattern]: - * - * string.startsWith('art', 1); // true - * string.startsWith(new RegExp(r'\w{3}')); // true - * - * [index] must not be negative or greater than [length]. - * - * A [RegExp] containing '^' does not match if the [index] is greater than - * zero. The pattern works on the string as a whole, and does not extract - * a substring starting at [index] first: - * - * string.startsWith(new RegExp(r'^art'), 1); // false - * string.startsWith(new RegExp(r'art'), 1); // true - */ - bool startsWith(Pattern pattern, [int index = 0]); - - /** - * Returns the position of the first match of [pattern] in this string, - * starting at [start], inclusive: - * - * var string = 'Dartisans'; - * string.indexOf('art'); // 1 - * string.indexOf(new RegExp(r'[A-Z][a-z]')); // 0 - * - * Returns -1 if no match is found: - * - * string.indexOf(new RegExp(r'dart')); // -1 - * - * [start] must be non-negative and not greater than [length]. - */ - int indexOf(Pattern pattern, [int start = 0]); - - /** - * Returns the starting position of the last match [pattern] in this string, - * searching backward starting at [start], inclusive: - * - * var string = 'Dartisans'; - * string.lastIndexOf('a'); // 6 - * string.lastIndexOf(RegExp(r'a(r|n)')); // 6 - * - * Returns -1 if [pattern] could not be found in this string. - * - * string.lastIndexOf(RegExp(r'DART')); // -1 - * - * If [start] is omitted, search starts from the end of the string. - * If supplied, [start] must be non-negative and not greater than [length]. - */ - int lastIndexOf(Pattern pattern, [int? start]); - - /** - * Returns true if this string is empty. - */ - bool get isEmpty; - - /** - * Returns true if this string is not empty. - */ - bool get isNotEmpty; - - /** - * Creates a new string by concatenating this string with [other]. - * - * 'dart' + 'lang'; // 'dartlang' - */ - String operator +(String other); - - /** - * Returns the substring of this string that extends from [startIndex], - * inclusive, to [endIndex], exclusive. - * - * var string = 'dartlang'; - * string.substring(1); // 'artlang' - * string.substring(1, 4); // 'art' - */ - String substring(int startIndex, [int? endIndex]); - - /** - * Returns the string without any leading and trailing whitespace. - * - * If the string contains leading or trailing whitespace, a new string with no - * leading and no trailing whitespace is returned: - * ```dart - * '\tDart is fun\n'.trim(); // 'Dart is fun' - * ``` - * Otherwise, the original string itself is returned: - * ```dart - * var str1 = 'Dart'; - * var str2 = str1.trim(); - * identical(str1, str2); // true - * ``` - * Whitespace is defined by the Unicode White_Space property (as defined in - * version 6.2 or later) and the BOM character, 0xFEFF. - * - * Here is the list of trimmed characters according to Unicode version 6.3: - * ``` - * 0009..000D ; White_Space # Cc .. - * 0020 ; White_Space # Zs SPACE - * 0085 ; White_Space # Cc - * 00A0 ; White_Space # Zs NO-BREAK SPACE - * 1680 ; White_Space # Zs OGHAM SPACE MARK - * 2000..200A ; White_Space # Zs EN QUAD..HAIR SPACE - * 2028 ; White_Space # Zl LINE SEPARATOR - * 2029 ; White_Space # Zp PARAGRAPH SEPARATOR - * 202F ; White_Space # Zs NARROW NO-BREAK SPACE - * 205F ; White_Space # Zs MEDIUM MATHEMATICAL SPACE - * 3000 ; White_Space # Zs IDEOGRAPHIC SPACE - * - * FEFF ; BOM ZERO WIDTH NO_BREAK SPACE - * ``` - * Some later versions of Unicode do not include U+0085 as a whitespace - * character. Whether it is trimmed depends on the Unicode version - * used by the system. - */ - String trim(); - - /** - * Returns the string without any leading whitespace. - * - * As [trim], but only removes leading whitespace. - */ - String trimLeft(); - - /** - * Returns the string without any trailing whitespace. - * - * As [trim], but only removes trailing whitespace. - */ - String trimRight(); - - /** - * Creates a new string by concatenating this string with itself a number - * of times. - * - * The result of `str * n` is equivalent to - * `str + str + ...`(n times)`... + str`. - * - * Returns an empty string if [times] is zero or negative. - */ - String operator *(int times); - - /** - * Pads this string on the left if it is shorter than [width]. - * - * Return a new string that prepends [padding] onto this string - * one time for each position the length is less than [width]. - * - * If [width] is already smaller than or equal to `this.length`, - * no padding is added. A negative `width` is treated as zero. - * - * If [padding] has length different from 1, the result will not - * have length `width`. This may be useful for cases where the - * padding is a longer string representing a single character, like - * `" "` or `"\u{10002}`". - * In that case, the user should make sure that `this.length` is - * the correct measure of the strings length. - */ - String padLeft(int width, [String padding = ' ']); - - /** - * Pads this string on the right if it is shorter than [width]. - * - * Return a new string that appends [padding] after this string - * one time for each position the length is less than [width]. - * - * If [width] is already smaller than or equal to `this.length`, - * no padding is added. A negative `width` is treated as zero. - * - * If [padding] has length different from 1, the result will not - * have length `width`. This may be useful for cases where the - * padding is a longer string representing a single character, like - * `" "` or `"\u{10002}`". - * In that case, the user should make sure that `this.length` is - * the correct measure of the strings length. - */ - String padRight(int width, [String padding = ' ']); - - /** - * Returns true if this string contains a match of [other]: - * - * var string = 'Dart strings'; - * string.contains('D'); // true - * string.contains(new RegExp(r'[A-Z]')); // true - * - * If [startIndex] is provided, this method matches only at or after that - * index: - * - * string.contains('X', 1); // false - * string.contains(new RegExp(r'[A-Z]'), 1); // false - * - * [startIndex] must not be negative or greater than [length]. - */ - bool contains(Pattern other, [int startIndex = 0]); - - /** - * Returns a new string in which the first occurrence of [from] in this string - * is replaced with [to], starting from [startIndex]: - * - * '0.0001'.replaceFirst(new RegExp(r'0'), ''); // '.0001' - * '0.0001'.replaceFirst(new RegExp(r'0'), '7', 1); // '0.7001' - */ - String replaceFirst(Pattern from, String to, [int startIndex = 0]); - - /** - * Replace the first occurrence of [from] in this string. - * - * Returns a new string, which is this string - * except that the first match of [from], starting from [startIndex], - * is replaced by the result of calling [replace] with the match object. - * - * The optional [startIndex] is by default set to 0. If provided, it must be - * an integer in the range `[0 .. len]`, where `len` is this string's length. - */ - String replaceFirstMapped(Pattern from, String replace(Match match), - [int startIndex = 0]); - - /** - * Replaces all substrings that match [from] with [replace]. - * - * Returns a new string in which the non-overlapping substrings matching - * [from] (the ones iterated by `from.allMatches(thisString)`) are replaced - * by the literal string [replace]. - * - * 'resume'.replaceAll(new RegExp(r'e'), 'é'); // 'résumé' - * - * Notice that the [replace] string is not interpreted. If the replacement - * depends on the match (for example on a [RegExp]'s capture groups), use - * the [replaceAllMapped] method instead. - */ - String replaceAll(Pattern from, String replace); - - /** - * Replace all substrings that match [from] by a string computed from the - * match. - * - * Returns a new string in which the non-overlapping substrings that match - * [from] (the ones iterated by `from.allMatches(thisString)`) are replaced - * by the result of calling [replace] on the corresponding [Match] object. - * - * This can be used to replace matches with new content that depends on the - * match, unlike [replaceAll] where the replacement string is always the same. - * - * The [replace] function is called with the [Match] generated - * by the pattern, and its result is used as replacement. - * - * The function defined below converts each word in a string to simplified - * 'pig latin' using [replaceAllMapped]: - * - * pigLatin(String words) => words.replaceAllMapped( - * new RegExp(r'\b(\w*?)([aeiou]\w*)', caseSensitive: false), - * (Match m) => "${m[2]}${m[1]}${m[1].isEmpty ? 'way' : 'ay'}"); - * - * pigLatin('I have a secret now!'); // 'Iway avehay away ecretsay ownay!' - */ - String replaceAllMapped(Pattern from, String Function(Match match) replace); - - /** - * Replaces the substring from [start] to [end] with [replacement]. - * - * Returns a new string equivalent to: - * - * this.substring(0, start) + replacement + this.substring(end) - * - * The [start] and [end] indices must specify a valid range of this string. - * That is `0 <= start <= end <= this.length`. - * If [end] is `null`, it defaults to [length]. - */ - String replaceRange(int start, int? end, String replacement); - - /** - * Splits the string at matches of [pattern] and returns a list of substrings. - * - * Finds all the matches of `pattern` in this string, - * and returns the list of the substrings between the matches. - * - * var string = "Hello world!"; - * string.split(" "); // ['Hello', 'world!']; - * - * Empty matches at the beginning and end of the strings are ignored, - * and so are empty matches right after another match. - * - * var string = "abba"; - * string.split(new RegExp(r"b*")); // ['a', 'a'] - * // not ['', 'a', 'a', ''] - * - * If this string is empty, the result is an empty list if `pattern` matches - * the empty string, and it is `[""]` if the pattern doesn't match. - * - * var string = ''; - * string.split(''); // [] - * string.split("a"); // [''] - * - * Splitting with an empty pattern splits the string into single-code unit - * strings. - * - * var string = 'Pub'; - * string.split(''); // ['P', 'u', 'b'] - * - * string.codeUnits.map((unit) { - * return new String.fromCharCode(unit); - * }).toList(); // ['P', 'u', 'b'] - * - * Splitting happens at UTF-16 code unit boundaries, - * and not at rune boundaries: - * - * // String made up of two code units, but one rune. - * string = '\u{1D11E}'; - * string.split('').length; // 2 surrogate values - * - * To get a list of strings containing the individual runes of a string, - * you should not use split. You can instead map each rune to a string - * as follows: - * - * string.runes.map((rune) => new String.fromCharCode(rune)).toList(); - */ - List split(Pattern pattern); - - /** - * Splits the string, converts its parts, and combines them into a new - * string. - * - * [pattern] is used to split the string into parts and separating matches. - * - * Each match is converted to a string by calling [onMatch]. If [onMatch] - * is omitted, the matched string is used. - * - * Each non-matched part is converted by a call to [onNonMatch]. If - * [onNonMatch] is omitted, the non-matching part is used. - * - * Then all the converted parts are combined into the resulting string. - * - * 'Eats shoots leaves'.splitMapJoin((new RegExp(r'shoots')), - * onMatch: (m) => '${m.group(0)}', - * onNonMatch: (n) => '*'); // *shoots* - */ - String splitMapJoin(Pattern pattern, - {String Function(Match)? onMatch, String Function(String)? onNonMatch}); - - /** - * Returns an unmodifiable list of the UTF-16 code units of this string. - */ - List get codeUnits; - - /** - * Returns an [Iterable] of Unicode code-points of this string. - * - * If the string contains surrogate pairs, they are combined and returned - * as one integer by this iterator. Unmatched surrogate halves are treated - * like valid 16-bit code-units. - */ - Runes get runes; - - /** - * Converts all characters in this string to lower case. - * If the string is already in all lower case, this method returns `this`. - * - * 'ALPHABET'.toLowerCase(); // 'alphabet' - * 'abc'.toLowerCase(); // 'abc' - * - * This function uses the language independent Unicode mapping and thus only - * works in some languages. - */ - // TODO(floitsch): document better. (See EcmaScript for description). - String toLowerCase(); - - /** - * Converts all characters in this string to upper case. - * If the string is already in all upper case, this method returns `this`. - * - * 'alphabet'.toUpperCase(); // 'ALPHABET' - * 'ABC'.toUpperCase(); // 'ABC' - * - * This function uses the language independent Unicode mapping and thus only - * works in some languages. - */ - // TODO(floitsch): document better. (See EcmaScript for description). - String toUpperCase(); -} - -/** - * The runes (integer Unicode code points) of a [String]. - */ -class Runes extends Iterable { - final String string; - Runes(this.string); - - RuneIterator get iterator => RuneIterator(string); - - int get last { - if (string.length == 0) { - throw StateError('No elements.'); - } - int length = string.length; - int code = string.codeUnitAt(length - 1); - if (_isTrailSurrogate(code) && string.length > 1) { - int previousCode = string.codeUnitAt(length - 2); - if (_isLeadSurrogate(previousCode)) { - return _combineSurrogatePair(previousCode, code); - } - } - return code; - } -} - -// Is then code (a 16-bit unsigned integer) a UTF-16 lead surrogate. -bool _isLeadSurrogate(int code) => (code & 0xFC00) == 0xD800; - -// Is then code (a 16-bit unsigned integer) a UTF-16 trail surrogate. -bool _isTrailSurrogate(int code) => (code & 0xFC00) == 0xDC00; - -// Combine a lead and a trail surrogate value into a single code point. -int _combineSurrogatePair(int start, int end) { - return 0x10000 + ((start & 0x3FF) << 10) + (end & 0x3FF); -} - -/** - * [Iterator] for reading runes (integer Unicode code points) of a Dart string. - */ -class RuneIterator implements BidirectionalIterator { - /** String being iterated. */ - final String string; - /** Position before the current code point. */ - int _position; - /** Position after the current code point. */ - int _nextPosition; - /** - * Current code point. - * - * If the iterator has hit either end, the [_currentCodePoint] is -1 - * and `_position == _nextPosition`. - */ - int _currentCodePoint = -1; - - /** Create an iterator positioned at the beginning of the string. */ - RuneIterator(String string) - : this.string = string, - _position = 0, - _nextPosition = 0; - - /** - * Create an iterator positioned before the [index]th code unit of the string. - * - * When created, there is no [current] value. - * A [moveNext] will use the rune starting at [index] the current value, - * and a [movePrevious] will use the rune ending just before [index] as the - * the current value. - * - * The [index] position must not be in the middle of a surrogate pair. - */ - RuneIterator.at(String string, int index) - : string = string, - _position = index, - _nextPosition = index { - RangeError.checkValueInInterval(index, 0, string.length); - _checkSplitSurrogate(index); - } - - /** Throw an error if the index is in the middle of a surrogate pair. */ - void _checkSplitSurrogate(int index) { - if (index > 0 && - index < string.length && - _isLeadSurrogate(string.codeUnitAt(index - 1)) && - _isTrailSurrogate(string.codeUnitAt(index))) { - throw ArgumentError('Index inside surrogate pair: $index'); - } - } - - /** - * The starting position of the current rune in the string. - * - * Returns -1 if there is no current rune ([current] is -1). - */ - int get rawIndex => (_position != _nextPosition) ? _position : -1; - - /** - * Resets the iterator to the rune at the specified index of the string. - * - * Setting a negative [rawIndex], or one greater than or equal to - * `string.length`, is an error. So is setting it in the middle of a surrogate - * pair. - * - * Setting the position to the end of then string means that there is no - * current rune. - */ - void set rawIndex(int rawIndex) { - RangeError.checkValidIndex(rawIndex, string, "rawIndex"); - reset(rawIndex); - moveNext(); - } - - /** - * Resets the iterator to the given index into the string. - * - * After this the [current] value is unset. - * You must call [moveNext] make the rune at the position current, - * or [movePrevious] for the last rune before the position. - * - * The [rawIndex] must be non-negative and no greater than `string.length`. - * It must also not be the index of the trailing surrogate of a surrogate - * pair. - */ - void reset([int rawIndex = 0]) { - RangeError.checkValueInInterval(rawIndex, 0, string.length, "rawIndex"); - _checkSplitSurrogate(rawIndex); - _position = _nextPosition = rawIndex; - _currentCodePoint = -1; - } - - /** - * The rune (integer Unicode code point) starting at the current position in - * the string. - * - * The value is -1 if there is no current code point. - */ - int get current => _currentCodePoint; - - /** - * The number of code units comprising the current rune. - * - * Returns zero if there is no current rune ([current] is -1). - */ - int get currentSize => _nextPosition - _position; - - /** - * A string containing the current rune. - * - * For runes outside the basic multilingual plane, this will be - * a String of length 2, containing two code units. - * - * Returns an empty string if there is no [current] value. - */ - String get currentAsString { - if (_position == _nextPosition) return ""; - if (_position + 1 == _nextPosition) return string[_position]; - return string.substring(_position, _nextPosition); - } - - bool moveNext() { - _position = _nextPosition; - if (_position == string.length) { - _currentCodePoint = -1; - return false; - } - int codeUnit = string.codeUnitAt(_position); - int nextPosition = _position + 1; - if (_isLeadSurrogate(codeUnit) && nextPosition < string.length) { - int nextCodeUnit = string.codeUnitAt(nextPosition); - if (_isTrailSurrogate(nextCodeUnit)) { - _nextPosition = nextPosition + 1; - _currentCodePoint = _combineSurrogatePair(codeUnit, nextCodeUnit); - return true; - } - } - _nextPosition = nextPosition; - _currentCodePoint = codeUnit; - return true; - } - - bool movePrevious() { - _nextPosition = _position; - if (_position == 0) { - _currentCodePoint = -1; - return false; - } - int position = _position - 1; - int codeUnit = string.codeUnitAt(position); - if (_isTrailSurrogate(codeUnit) && position > 0) { - int prevCodeUnit = string.codeUnitAt(position - 1); - if (_isLeadSurrogate(prevCodeUnit)) { - _position = position - 1; - _currentCodePoint = _combineSurrogatePair(prevCodeUnit, codeUnit); - return true; - } - } - _position = position; - _currentCodePoint = codeUnit; - return true; - } -} diff --git a/sdk_nnbd/lib/core/string_buffer.dart b/sdk_nnbd/lib/core/string_buffer.dart deleted file mode 100644 index d664101988c..00000000000 --- a/sdk_nnbd/lib/core/string_buffer.dart +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2011, 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. - -part of dart.core; - -/** - * A class for concatenating strings efficiently. - * - * Allows for the incremental building of a string using write*() methods. - * The strings are concatenated to a single string only when [toString] is - * called. - */ -class StringBuffer implements StringSink { - /** Creates the string buffer with an initial content. */ - external StringBuffer([Object content = ""]); - - /** - * Returns the length of the content that has been accumulated so far. - * This is a constant-time operation. - */ - external int get length; - - /** Returns whether the buffer is empty. This is a constant-time operation. */ - bool get isEmpty => length == 0; - - /** - * Returns whether the buffer is not empty. This is a constant-time - * operation. - */ - bool get isNotEmpty => !isEmpty; - - /// Adds the contents of [obj], converted to a string, to the buffer. - external void write(Object? obj); - - /// Adds the string representation of [charCode] to the buffer. - external void writeCharCode(int charCode); - - external void writeAll(Iterable objects, [String separator = ""]); - - external void writeln([Object? obj = ""]); - - /** - * Clears the string buffer. - */ - external void clear(); - - /// Returns the contents of buffer as a concatenated string. - external String toString(); -} diff --git a/sdk_nnbd/lib/core/string_sink.dart b/sdk_nnbd/lib/core/string_sink.dart deleted file mode 100644 index c507424713e..00000000000 --- a/sdk_nnbd/lib/core/string_sink.dart +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) 2013, 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. - -part of dart.core; - -abstract class StringSink { - /** - * Converts [obj] to a String by invoking [Object.toString] and - * adds the result to `this`. - */ - void write(Object? obj); - - /** - * Iterates over the given [objects] and [write]s them in sequence. - */ - void writeAll(Iterable objects, [String separator = ""]); - - /** - * Converts [obj] to a String by invoking [Object.toString] and - * adds the result to `this`, followed by a newline. - */ - void writeln([Object? obj = ""]); - - /** - * Writes the [charCode] to `this`. - * - * This method is equivalent to `write(new String.fromCharCode(charCode))`. - */ - void writeCharCode(int charCode); -} diff --git a/sdk_nnbd/lib/core/symbol.dart b/sdk_nnbd/lib/core/symbol.dart deleted file mode 100644 index 65e83ff6611..00000000000 --- a/sdk_nnbd/lib/core/symbol.dart +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (c) 2013, 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. - -part of dart.core; - -/// Opaque name used by mirrors, invocations and [Function.apply]. -abstract class Symbol { - /** The symbol corresponding to the name of the unary minus operator. */ - static const Symbol unaryMinus = Symbol("unary-"); - - /** - * The empty symbol. - * - * The empty symbol is the name of libraries with no library declaration, - * and the base-name of the unnamed constructor. - */ - static const Symbol empty = Symbol(""); - - /** - * Constructs a new [Symbol] representing the provided name. - * - * The name must be a valid public Dart member name, - * public constructor name, or library name, optionally qualified. - * - * A qualified name is a valid name preceded by a public identifier name - * and a '`.`', e.g., `foo.bar.baz=` is a qualified version of `baz=`. - * That means that the content of the [name] String must be either - * - * * a valid public Dart identifier - * (that is, an identifier not starting with "`_`"), - * * such an identifier followed by "=" (a setter name), - * * the name of a declarable operator - * (one of "`+`", "`-`", "`*`", "`/`", "`%`", "`~/`", "`&`", "`|`", - * "`^`", "`~`", "`<<`", "`>>`", "`<`", "`<=`", "`>`", "`>=`", "`==`", - * "`[]`", "`[]=`", or "`unary-`"), - * * any of the above preceded by any number of qualifiers, - * where a qualifier is a non-private identifier followed by '`.`', - * * or the empty string (the default name of a library with no library - * name declaration). - * - * Symbol instances created from the same [name] are equal, - * but not necessarily identical, but symbols created as compile-time - * constants are canonicalized, as all other constant object creations. - * - * ```dart - * assert(new Symbol("foo") == new Symbol("foo")); - * assert(identical(const Symbol("foo"), const Symbol("foo"))); - * ``` - * - * If [name] is a single identifier that does not start with an underscore, - * or it is a qualified identifier, - * or it is an operator name different from `unary-`, - * then the result of `const Symbol(name)` is the same instance that - * the symbol literal created by prefixing `#` to the content of [name] - * would evaluate to. - * - * ```dart - * assert(new Symbol("foo") == #foo); - * assert(new Symbol("[]=") == #[]=]); - * assert(new Symbol("foo.bar") == #foo.bar); - * assert(identical(const Symbol("foo"), #foo)); - * assert(identical(const Symbol("[]="), #[]=])); - * assert(identical(const Symbol("foo.bar"), #foo.bar)); - * ``` - * - * This constructor cannot create a [Symbol] instance that is equal to - * a private symbol literal like `#_foo`. - * ```dart - * const Symbol("_foo") // Invalid - * ``` - * - * The created instance overrides [Object.==]. - * - * The following text is non-normative: - * - * Creating non-const Symbol instances may result in larger output. If - * possible, use `MirrorsUsed` from "dart:mirrors" to specify which names - * might be passed to this constructor. - */ - const factory Symbol(String name) = internal.Symbol; - - /** - * Returns a hash code compatible with [operator==]. - * - * Equal symbols have the same hash code. - */ - int get hashCode; - - /** - * Symbols are equal to other symbols that correspond to the same member name. - * - * Qualified member names, like `#foo.bar` are equal only if they have the - * same identifiers before the same final member name. - */ - bool operator ==(Object other); -} diff --git a/sdk_nnbd/lib/core/type.dart b/sdk_nnbd/lib/core/type.dart deleted file mode 100644 index d2e107b6b18..00000000000 --- a/sdk_nnbd/lib/core/type.dart +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) 2012, 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. - -part of dart.core; - -/** - * Runtime representation of a type. - */ -abstract class Type {} diff --git a/sdk_nnbd/lib/core/uri.dart b/sdk_nnbd/lib/core/uri.dart deleted file mode 100644 index 234241c9c38..00000000000 --- a/sdk_nnbd/lib/core/uri.dart +++ /dev/null @@ -1,4695 +0,0 @@ -// Copyright (c) 2012, 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. - -part of dart.core; - -// Frequently used character codes. -const int _SPACE = 0x20; -const int _PERCENT = 0x25; -const int _AMPERSAND = 0x26; -const int _PLUS = 0x2B; -const int _DOT = 0x2E; -const int _SLASH = 0x2F; -const int _COLON = 0x3A; -const int _EQUALS = 0x3d; -const int _UPPER_CASE_A = 0x41; -const int _UPPER_CASE_Z = 0x5A; -const int _LEFT_BRACKET = 0x5B; -const int _BACKSLASH = 0x5C; -const int _RIGHT_BRACKET = 0x5D; -const int _LOWER_CASE_A = 0x61; -const int _LOWER_CASE_F = 0x66; -const int _LOWER_CASE_Z = 0x7A; - -const String _hexDigits = "0123456789ABCDEF"; - -/** - * A parsed URI, such as a URL. - * - * **See also:** - * - * * [URIs][uris] in the [library tour][libtour] - * * [RFC-3986](http://tools.ietf.org/html/rfc3986) - * - * [uris]: https://www.dartlang.org/docs/dart-up-and-running/ch03.html#uris - * [libtour]: https://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html - */ -abstract class Uri { - /** - * Returns the natural base URI for the current platform. - * - * When running in a browser this is the current URL of the current page - * (from `window.location.href`). - * - * When not running in a browser this is the file URI referencing - * the current working directory. - */ - external static Uri get base; - - /** - * Creates a new URI from its components. - * - * Each component is set through a named argument. Any number of - * components can be provided. The [path] and [query] components can be set - * using either of two different named arguments. - * - * The scheme component is set through [scheme]. The scheme is - * normalized to all lowercase letters. If the scheme is omitted or empty, - * the URI will not have a scheme part. - * - * The user info part of the authority component is set through - * [userInfo]. It defaults to the empty string, which will be omitted - * from the string representation of the URI. - * - * The host part of the authority component is set through - * [host]. The host can either be a hostname, an IPv4 address or an - * IPv6 address, contained in '[' and ']'. If the host contains a - * ':' character, the '[' and ']' are added if not already provided. - * The host is normalized to all lowercase letters. - * - * The port part of the authority component is set through - * [port]. - * If [port] is omitted or `null`, it implies the default port for - * the URI's scheme, and is equivalent to passing that port explicitly. - * The recognized schemes, and their default ports, are "http" (80) and - * "https" (443). All other schemes are considered as having zero as the - * default port. - * - * If any of `userInfo`, `host` or `port` are provided, - * the URI has an authority according to [hasAuthority]. - * - * The path component is set through either [path] or - * [pathSegments]. - * When [path] is used, it should be a valid URI path, - * but invalid characters, except the general delimiters ':/@[]?#', - * will be escaped if necessary. - * When [pathSegments] is used, each of the provided segments - * is first percent-encoded and then joined using the forward slash - * separator. - * - * The percent-encoding of the path segments encodes all - * characters except for the unreserved characters and the following - * list of characters: `!$&'()*+,;=:@`. If the other components - * necessitate an absolute path, a leading slash `/` is prepended if - * not already there. - * - * The query component is set through either [query] or [queryParameters]. - * When [query] is used, the provided string should be a valid URI query, - * but invalid characters, other than general delimiters, - * will be escaped if necessary. - * When [queryParameters] is used the query is built from the - * provided map. Each key and value in the map is percent-encoded - * and joined using equal and ampersand characters. - * A value in the map must be either a string, or an [Iterable] of strings, - * where the latter corresponds to multiple values for the same key. - * - * The percent-encoding of the keys and values encodes all characters - * except for the unreserved characters, and replaces spaces with `+`. - * If `query` is the empty string, it is equivalent to omitting it. - * To have an actual empty query part, - * use an empty map for `queryParameters`. - * - * If both `query` and `queryParameters` are omitted or `null`, - * the URI has no query part. - * - * The fragment component is set through [fragment]. - * It should be a valid URI fragment, but invalid characters other than - * general delimiters, are escaped if necessary. - * If `fragment` is omitted or `null`, the URI has no fragment part. - */ - factory Uri( - {String? scheme, - String? userInfo, - String? host, - int? port, - String? path, - Iterable? pathSegments, - String? query, - Map*/ >? queryParameters, - String? fragment}) = _Uri; - - /** - * Creates a new `http` URI from authority, path and query. - * - * Examples: - * - * ``` - * // http://example.org/path?q=dart. - * new Uri.http("example.org", "/path", { "q" : "dart" }); - * - * // http://user:pass@localhost:8080 - * new Uri.http("user:pass@localhost:8080", ""); - * - * // http://example.org/a%20b - * new Uri.http("example.org", "a b"); - * - * // http://example.org/a%252F - * new Uri.http("example.org", "/a%2F"); - * ``` - * - * The `scheme` is always set to `http`. - * - * The `userInfo`, `host` and `port` components are set from the - * [authority] argument. If `authority` is `null` or empty, - * the created `Uri` has no authority, and isn't directly usable - * as an HTTP URL, which must have a non-empty host. - * - * The `path` component is set from the [unencodedPath] - * argument. The path passed must not be encoded as this constructor - * encodes the path. - * - * The `query` component is set from the optional [queryParameters] - * argument. - */ - factory Uri.http(String authority, String unencodedPath, - [Map? queryParameters]) = _Uri.http; - - /** - * Creates a new `https` URI from authority, path and query. - * - * This constructor is the same as [Uri.http] except for the scheme - * which is set to `https`. - */ - factory Uri.https(String authority, String unencodedPath, - [Map? queryParameters]) = _Uri.https; - - /** - * Creates a new file URI from an absolute or relative file path. - * - * The file path is passed in [path]. - * - * This path is interpreted using either Windows or non-Windows - * semantics. - * - * With non-Windows semantics the slash (`/`) is used to separate - * path segments in the input [path]. - * - * With Windows semantics, backslash (`\`) and forward-slash (`/`) - * are used to separate path segments in the input [path], - * except if the path starts with `\\?\` in which case - * only backslash (`\`) separates path segments in [path]. - * - * If the path starts with a path separator, an absolute URI (with the - * `file` scheme and an empty authority) is created. - * Otherwise a relative URI reference with no scheme or authority is created. - * One exception from this rule is that when Windows semantics is used - * and the path starts with a drive letter followed by a colon (":") and a - * path separator, then an absolute URI is created. - * - * The default for whether to use Windows or non-Windows semantics - * determined from the platform Dart is running on. When running in - * the standalone VM, this is detected by the VM based on the - * operating system. When running in a browser non-Windows semantics - * is always used. - * - * To override the automatic detection of which semantics to use pass - * a value for [windows]. Passing `true` will use Windows - * semantics and passing `false` will use non-Windows semantics. - * - * Examples using non-Windows semantics: - * - * ``` - * // xxx/yyy - * new Uri.file("xxx/yyy", windows: false); - * - * // xxx/yyy/ - * new Uri.file("xxx/yyy/", windows: false); - * - * // file:///xxx/yyy - * new Uri.file("/xxx/yyy", windows: false); - * - * // file:///xxx/yyy/ - * new Uri.file("/xxx/yyy/", windows: false); - * - * // C%3A - * new Uri.file("C:", windows: false); - * ``` - * - * Examples using Windows semantics: - * - * ``` - * // xxx/yyy - * new Uri.file(r"xxx\yyy", windows: true); - * - * // xxx/yyy/ - * new Uri.file(r"xxx\yyy\", windows: true); - * - * file:///xxx/yyy - * new Uri.file(r"\xxx\yyy", windows: true); - * - * file:///xxx/yyy/ - * new Uri.file(r"\xxx\yyy/", windows: true); - * - * // file:///C:/xxx/yyy - * new Uri.file(r"C:\xxx\yyy", windows: true); - * - * // This throws an error. A path with a drive letter, but no following - * // path, is not allowed. - * new Uri.file(r"C:", windows: true); - * - * // This throws an error. A path with a drive letter is not absolute. - * new Uri.file(r"C:xxx\yyy", windows: true); - * - * // file://server/share/file - * new Uri.file(r"\\server\share\file", windows: true); - * ``` - * - * If the path passed is not a valid file path, an error is thrown. - */ - factory Uri.file(String path, {bool? windows}) = _Uri.file; - - /** - * Like [Uri.file] except that a non-empty URI path ends in a slash. - * - * If [path] is not empty, and it doesn't end in a directory separator, - * then a slash is added to the returned URI's path. - * In all other cases, the result is the same as returned by `Uri.file`. - */ - factory Uri.directory(String path, {bool? windows}) = _Uri.directory; - - /** - * Creates a `data:` URI containing the [content] string. - * - * Converts the content to a bytes using [encoding] or the charset specified - * in [parameters] (defaulting to US-ASCII if not specified or unrecognized), - * then encodes the bytes into the resulting data URI. - * - * Defaults to encoding using percent-encoding (any non-ASCII or non-URI-valid - * bytes is replaced by a percent encoding). If [base64] is true, the bytes - * are instead encoded using [base64]. - * - * If [encoding] is not provided and [parameters] has a `charset` entry, - * that name is looked up using [Encoding.getByName], - * and if the lookup returns an encoding, that encoding is used to convert - * [content] to bytes. - * If providing both an [encoding] and a charset in [parameters], they should - * agree, otherwise decoding won't be able to use the charset parameter - * to determine the encoding. - * - * If [mimeType] and/or [parameters] are supplied, they are added to the - * created URI. If any of these contain characters that are not allowed - * in the data URI, the character is percent-escaped. If the character is - * non-ASCII, it is first UTF-8 encoded and then the bytes are percent - * encoded. An omitted [mimeType] in a data URI means `text/plain`, just - * as an omitted `charset` parameter defaults to meaning `US-ASCII`. - * - * To read the content back, use [UriData.contentAsString]. - */ - factory Uri.dataFromString(String content, - {String? mimeType, - Encoding? encoding, - Map? parameters, - bool base64 = false}) { - UriData data = UriData.fromString(content, - mimeType: mimeType, - encoding: encoding, - parameters: parameters, - base64: base64); - return data.uri; - } - - /** - * Creates a `data:` URI containing an encoding of [bytes]. - * - * Defaults to Base64 encoding the bytes, but if [percentEncoded] - * is `true`, the bytes will instead be percent encoded (any non-ASCII - * or non-valid-ASCII-character byte is replaced by a percent encoding). - * - * To read the bytes back, use [UriData.contentAsBytes]. - * - * It defaults to having the mime-type `application/octet-stream`. - * The [mimeType] and [parameters] are added to the created URI. - * If any of these contain characters that are not allowed - * in the data URI, the character is percent-escaped. If the character is - * non-ASCII, it is first UTF-8 encoded and then the bytes are percent - * encoded. - */ - factory Uri.dataFromBytes(List bytes, - {String mimeType = "application/octet-stream", - Map? parameters, - bool percentEncoded = false}) { - UriData data = UriData.fromBytes(bytes, - mimeType: mimeType, - parameters: parameters, - percentEncoded: percentEncoded); - return data.uri; - } - - /** - * The scheme component of the URI. - * - * Returns the empty string if there is no scheme component. - * - * A URI scheme is case insensitive. - * The returned scheme is canonicalized to lowercase letters. - */ - String get scheme; - - /** - * Returns the authority component. - * - * The authority is formatted from the [userInfo], [host] and [port] - * parts. - * - * Returns the empty string if there is no authority component. - */ - String get authority; - - /** - * Returns the user info part of the authority component. - * - * Returns the empty string if there is no user info in the - * authority component. - */ - String get userInfo; - - /** - * Returns the host part of the authority component. - * - * Returns the empty string if there is no authority component and - * hence no host. - * - * If the host is an IP version 6 address, the surrounding `[` and `]` is - * removed. - * - * The host string is case-insensitive. - * The returned host name is canonicalized to lower-case - * with upper-case percent-escapes. - */ - String get host; - - /** - * Returns the port part of the authority component. - * - * Returns the default port if there is no port number in the authority - * component. That's 80 for http, 443 for https, and 0 for everything else. - */ - int get port; - - /** - * Returns the path component. - * - * The returned path is encoded. To get direct access to the decoded - * path use [pathSegments]. - * - * Returns the empty string if there is no path component. - */ - String get path; - - /** - * Returns the query component. The returned query is encoded. To get - * direct access to the decoded query use [queryParameters]. - * - * Returns the empty string if there is no query component. - */ - String get query; - - /** - * Returns the fragment identifier component. - * - * Returns the empty string if there is no fragment identifier - * component. - */ - String get fragment; - - /** - * Returns the URI path split into its segments. Each of the segments in the - * returned list have been decoded. If the path is empty the empty list will - * be returned. A leading slash `/` does not affect the segments returned. - * - * The returned list is unmodifiable and will throw [UnsupportedError] on any - * calls that would mutate it. - */ - List get pathSegments; - - /** - * Returns the URI query split into a map according to the rules - * specified for FORM post in the [HTML 4.01 specification section - * 17.13.4](http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4 "HTML 4.01 section 17.13.4"). - * Each key and value in the returned map has been decoded. - * If there is no query the empty map is returned. - * - * Keys in the query string that have no value are mapped to the - * empty string. - * If a key occurs more than once in the query string, it is mapped to - * an arbitrary choice of possible value. - * The [queryParametersAll] getter can provide a map - * that maps keys to all of their values. - * - * The returned map is unmodifiable. - */ - Map get queryParameters; - - /** - * Returns the URI query split into a map according to the rules - * specified for FORM post in the [HTML 4.01 specification section - * 17.13.4](http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4 "HTML 4.01 section 17.13.4"). - * Each key and value in the returned map has been decoded. If there is no - * query the empty map is returned. - * - * Keys are mapped to lists of their values. If a key occurs only once, - * its value is a singleton list. If a key occurs with no value, the - * empty string is used as the value for that occurrence. - * - * The returned map and the lists it contains are unmodifiable. - */ - Map> get queryParametersAll; - - /** - * Returns whether the URI is absolute. - * - * A URI is an absolute URI in the sense of RFC 3986 if it has a scheme - * and no fragment. - */ - bool get isAbsolute; - - /** - * Returns whether the URI has a [scheme] component. - */ - bool get hasScheme => scheme.isNotEmpty; - - /** - * Returns whether the URI has an [authority] component. - */ - bool get hasAuthority; - - /** - * Returns whether the URI has an explicit port. - * - * If the port number is the default port number - * (zero for unrecognized schemes, with http (80) and https (443) being - * recognized), - * then the port is made implicit and omitted from the URI. - */ - bool get hasPort; - - /** - * Returns whether the URI has a query part. - */ - bool get hasQuery; - - /** - * Returns whether the URI has a fragment part. - */ - bool get hasFragment; - - /** - * Returns whether the URI has an empty path. - */ - bool get hasEmptyPath; - - /** - * Returns whether the URI has an absolute path (starting with '/'). - */ - bool get hasAbsolutePath; - - /** - * Returns the origin of the URI in the form scheme://host:port for the - * schemes http and https. - * - * It is an error if the scheme is not "http" or "https", or if the host name - * is missing or empty. - * - * See: http://www.w3.org/TR/2011/WD-html5-20110405/origin-0.html#origin - */ - String get origin; - - /// Whether the scheme of this [Uri] is [scheme]. - /// - /// The [scheme] should be the same as the one returned by [Uri.scheme], - /// but doesn't have to be case-normalized to lower-case characters. - /// - /// Example: - /// ```dart - /// var uri = Uri.parse("http://example.com/"); - /// print(uri.isScheme("HTTP")); // Prints true. - /// ``` - /// - /// A `null` or empty [scheme] string matches a URI with no scheme - /// (one where [hasScheme] returns false). - bool isScheme(String scheme); - - /** - * Returns the file path from a file URI. - * - * The returned path has either Windows or non-Windows - * semantics. - * - * For non-Windows semantics the slash ("/") is used to separate - * path segments. - * - * For Windows semantics the backslash ("\\") separator is used to - * separate path segments. - * - * If the URI is absolute the path starts with a path separator - * unless Windows semantics is used and the first path segment is a - * drive letter. When Windows semantics is used a host component in - * the uri in interpreted as a file server and a UNC path is - * returned. - * - * The default for whether to use Windows or non-Windows semantics - * determined from the platform Dart is running on. When running in - * the standalone VM this is detected by the VM based on the - * operating system. When running in a browser non-Windows semantics - * is always used. - * - * To override the automatic detection of which semantics to use pass - * a value for [windows]. Passing `true` will use Windows - * semantics and passing `false` will use non-Windows semantics. - * - * If the URI ends with a slash (i.e. the last path component is - * empty) the returned file path will also end with a slash. - * - * With Windows semantics URIs starting with a drive letter cannot - * be relative to the current drive on the designated drive. That is - * for the URI `file:///c:abc` calling `toFilePath` will throw as a - * path segment cannot contain colon on Windows. - * - * Examples using non-Windows semantics (resulting of calling - * toFilePath in comment): - * - * Uri.parse("xxx/yyy"); // xxx/yyy - * Uri.parse("xxx/yyy/"); // xxx/yyy/ - * Uri.parse("file:///xxx/yyy"); // /xxx/yyy - * Uri.parse("file:///xxx/yyy/"); // /xxx/yyy/ - * Uri.parse("file:///C:"); // /C: - * Uri.parse("file:///C:a"); // /C:a - * - * Examples using Windows semantics (resulting URI in comment): - * - * Uri.parse("xxx/yyy"); // xxx\yyy - * Uri.parse("xxx/yyy/"); // xxx\yyy\ - * Uri.parse("file:///xxx/yyy"); // \xxx\yyy - * Uri.parse("file:///xxx/yyy/"); // \xxx\yyy\ - * Uri.parse("file:///C:/xxx/yyy"); // C:\xxx\yyy - * Uri.parse("file:C:xxx/yyy"); // Throws as a path segment - * // cannot contain colon on Windows. - * Uri.parse("file://server/share/file"); // \\server\share\file - * - * If the URI is not a file URI calling this throws - * [UnsupportedError]. - * - * If the URI cannot be converted to a file path calling this throws - * [UnsupportedError]. - */ - // TODO(lrn): Deprecate and move functionality to File class or similar. - // The core libraries should not worry about the platform. - String toFilePath({bool? windows}); - - /** - * Access the structure of a `data:` URI. - * - * Returns a [UriData] object for `data:` URIs and `null` for all other - * URIs. - * The [UriData] object can be used to access the media type and data - * of a `data:` URI. - */ - UriData? get data; - - /// Returns a hash code computed as `toString().hashCode`. - /// - /// This guarantees that URIs with the same normalized - int get hashCode; - - /// A URI is equal to another URI with the same normalized representation. - bool operator ==(Object other); - - /// Returns the normalized string representation of the URI. - String toString(); - - /** - * Returns a new `Uri` based on this one, but with some parts replaced. - * - * This method takes the same parameters as the [new Uri] constructor, - * and they have the same meaning. - * - * At most one of [path] and [pathSegments] must be provided. - * Likewise, at most one of [query] and [queryParameters] must be provided. - * - * Each part that is not provided will default to the corresponding - * value from this `Uri` instead. - * - * This method is different from [Uri.resolve] which overrides in a - * hierarchical manner, - * and can instead replace each part of a `Uri` individually. - * - * Example: - * - * Uri uri1 = Uri.parse("a://b@c:4/d/e?f#g"); - * Uri uri2 = uri1.replace(scheme: "A", path: "D/E/E", fragment: "G"); - * print(uri2); // prints "a://b@c:4/D/E/E?f#G" - * - * This method acts similarly to using the `new Uri` constructor with - * some of the arguments taken from this `Uri`. Example: - * - * Uri uri3 = new Uri( - * scheme: "A", - * userInfo: uri1.userInfo, - * host: uri1.host, - * port: uri1.port, - * path: "D/E/E", - * query: uri1.query, - * fragment: "G"); - * print(uri3); // prints "a://b@c:4/D/E/E?f#G" - * print(uri2 == uri3); // prints true. - * - * Using this method can be seen as a shorthand for the `Uri` constructor - * call above, but may also be slightly faster because the parts taken - * from this `Uri` need not be checked for validity again. - */ - Uri replace( - {String? scheme, - String? userInfo, - String? host, - int? port, - String? path, - Iterable? pathSegments, - String? query, - Map*/ >? queryParameters, - String? fragment}); - - /** - * Returns a `Uri` that differs from this only in not having a fragment. - * - * If this `Uri` does not have a fragment, it is itself returned. - */ - Uri removeFragment(); - - /** - * Resolve [reference] as an URI relative to `this`. - * - * First turn [reference] into a URI using [Uri.parse]. Then resolve the - * resulting URI relative to `this`. - * - * Returns the resolved URI. - * - * See [resolveUri] for details. - */ - Uri resolve(String reference); - - /** - * Resolve [reference] as an URI relative to `this`. - * - * Returns the resolved URI. - * - * The algorithm "Transform Reference" for resolving a reference is described - * in [RFC-3986 Section 5](http://tools.ietf.org/html/rfc3986#section-5 "RFC-1123"). - * - * Updated to handle the case where the base URI is just a relative path - - * that is: when it has no scheme and no authority and the path does not start - * with a slash. - * In that case, the paths are combined without removing leading "..", and - * an empty path is not converted to "/". - */ - Uri resolveUri(Uri reference); - - /** - * Returns a URI where the path has been normalized. - * - * A normalized path does not contain `.` segments or non-leading `..` - * segments. - * Only a relative path with no scheme or authority may contain - * leading `..` segments, - * a path that starts with `/` will also drop any leading `..` segments. - * - * This uses the same normalization strategy as `new Uri().resolve(this)`. - * - * Does not change any part of the URI except the path. - * - * The default implementation of `Uri` always normalizes paths, so calling - * this function has no effect. - */ - Uri normalizePath(); - - /** - * Creates a new `Uri` object by parsing a URI string. - * - * If [start] and [end] are provided, they must specify a valid substring - * of [uri], and only the substring from `start` to `end` is parsed as a URI. - * - * The [uri] must not be `null`. - * If the [uri] string is not valid as a URI or URI reference, - * a [FormatException] is thrown. - */ - static Uri parse(String uri, [int start = 0, int? end]) { - // This parsing will not validate percent-encoding, IPv6, etc. - // When done splitting into parts, it will call, e.g., [_makeFragment] - // to do the final parsing. - // - // Important parts of the RFC 3986 used here: - // URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] - // - // hier-part = "//" authority path-abempty - // / path-absolute - // / path-rootless - // / path-empty - // - // URI-reference = URI / relative-ref - // - // absolute-URI = scheme ":" hier-part [ "?" query ] - // - // relative-ref = relative-part [ "?" query ] [ "#" fragment ] - // - // relative-part = "//" authority path-abempty - // / path-absolute - // / path-noscheme - // / path-empty - // - // scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) - // - // authority = [ userinfo "@" ] host [ ":" port ] - // userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) - // host = IP-literal / IPv4address / reg-name - // IP-literal = "[" ( IPv6address / IPv6addrz / IPvFuture ) "]" - // IPv6addrz = IPv6address "%25" ZoneID - // ZoneID = 1*( unreserved / pct-encoded ) - // port = *DIGIT - // reg-name = *( unreserved / pct-encoded / sub-delims ) - // - // path = path-abempty ; begins with "/" or is empty - // / path-absolute ; begins with "/" but not "//" - // / path-noscheme ; begins with a non-colon segment - // / path-rootless ; begins with a segment - // / path-empty ; zero characters - // - // path-abempty = *( "/" segment ) - // path-absolute = "/" [ segment-nz *( "/" segment ) ] - // path-noscheme = segment-nz-nc *( "/" segment ) - // path-rootless = segment-nz *( "/" segment ) - // path-empty = 0 - // - // segment = *pchar - // segment-nz = 1*pchar - // segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" ) - // ; non-zero-length segment without any colon ":" - // - // pchar = unreserved / pct-encoded / sub-delims / ":" / "@" - // - // query = *( pchar / "/" / "?" ) - // - // fragment = *( pchar / "/" / "?" ) - end ??= uri.length; - - // Special case data:URIs. Ignore case when testing. - if (end >= start + 5) { - int dataDelta = _startsWithData(uri, start); - if (dataDelta == 0) { - // The case is right. - if (start > 0 || end < uri.length) uri = uri.substring(start, end); - return UriData._parse(uri, 5, null).uri; - } else if (dataDelta == 0x20) { - return UriData._parse(uri.substring(start + 5, end), 0, null).uri; - } - // Otherwise the URI doesn't start with "data:" or any case variant of it. - } - - // The following index-normalization belongs with the scanning, but is - // easier to do here because we already have extracted variables from the - // indices list. - var indices = List.filled(8, 0, growable: false); - - // Set default values for each position. - // The value will either be correct in some cases where it isn't set - // by the scanner, or it is clearly recognizable as an unset value. - indices - ..[0] = 0 - ..[_schemeEndIndex] = start - 1 - ..[_hostStartIndex] = start - 1 - ..[_notSimpleIndex] = start - 1 - ..[_portStartIndex] = start - ..[_pathStartIndex] = start - ..[_queryStartIndex] = end - ..[_fragmentStartIndex] = end; - var state = _scan(uri, start, end, _uriStart, indices); - // Some states that should be non-simple, but the URI ended early. - // Paths that end at a ".." must be normalized to end in "../". - if (state >= _nonSimpleEndStates) { - indices[_notSimpleIndex] = end; - } - int schemeEnd = indices[_schemeEndIndex]; - if (schemeEnd >= start) { - // Rescan the scheme part now that we know it's not a path. - state = _scan(uri, start, schemeEnd, _schemeStart, indices); - if (state == _schemeStart) { - // Empty scheme. - indices[_notSimpleIndex] = schemeEnd; - } - } - // The returned positions are limited by the scanners ability to write only - // one position per character, and only the current position. - // Scanning from left to right, we only know whether something is a scheme - // or a path when we see a `:` or `/`, and likewise we only know if the first - // `/` is part of the path or is leading an authority component when we see - // the next character. - - int hostStart = indices[_hostStartIndex] + 1; - int portStart = indices[_portStartIndex]; - int pathStart = indices[_pathStartIndex]; - int queryStart = indices[_queryStartIndex]; - int fragmentStart = indices[_fragmentStartIndex]; - - // We may discover the scheme while handling special cases. - String? scheme; - - // Derive some positions that weren't set to normalize the indices. - if (fragmentStart < queryStart) queryStart = fragmentStart; - // If pathStart isn't set (it's before scheme end or host start), then - // the path is empty, or there is no authority part and the path - // starts with a non-simple character. - if (pathStart < hostStart) { - // There is an authority, but no path. The path would start with `/` - // if it was there. - pathStart = queryStart; - } else if (pathStart <= schemeEnd) { - // There is a scheme, but no authority. - pathStart = schemeEnd + 1; - } - // If there is an authority with no port, set the port position - // to be at the end of the authority (equal to pathStart). - // This also handles a ":" in a user-info component incorrectly setting - // the port start position. - if (portStart < hostStart) portStart = pathStart; - - assert(hostStart == start || schemeEnd <= hostStart); - assert(hostStart <= portStart); - assert(schemeEnd <= pathStart); - assert(portStart <= pathStart); - assert(pathStart <= queryStart); - assert(queryStart <= fragmentStart); - - bool isSimple = indices[_notSimpleIndex] < start; - - if (isSimple) { - // Check/do normalizations that weren't detected by the scanner. - // This includes removal of empty port or userInfo, - // or scheme specific port and path normalizations. - if (hostStart > schemeEnd + 3) { - // Always be non-simple if URI contains user-info. - // The scanner doesn't set the not-simple position in this case because - // it's setting the host-start position instead. - isSimple = false; - } else if (portStart > start && portStart + 1 == pathStart) { - // If the port is empty, it should be omitted. - // Pathological case, don't bother correcting it. - isSimple = false; - } else if (queryStart < end && - (queryStart == pathStart + 2 && - uri.startsWith("..", pathStart)) || - (queryStart > pathStart + 2 && - uri.startsWith("/..", queryStart - 3))) { - // The path ends in a ".." segment. This should be normalized to "../". - // We didn't detect this while scanning because a query or fragment was - // detected at the same time (which is why we only need to check this - // if there is something after the path). - isSimple = false; - } else { - // There are a few scheme-based normalizations that - // the scanner couldn't check. - // That means that the input is very close to simple, so just do - // the normalizations. - if (schemeEnd == start + 4) { - // Do scheme based normalizations for file, http. - if (uri.startsWith("file", start)) { - scheme = "file"; - if (hostStart <= start) { - // File URIs should have an authority. - // Paths after an authority should be absolute. - String schemeAuth = "file://"; - int delta = 2; - if (!uri.startsWith("/", pathStart)) { - schemeAuth = "file:///"; - delta = 3; - } - uri = schemeAuth + uri.substring(pathStart, end); - schemeEnd -= start; - hostStart = 7; - portStart = 7; - pathStart = 7; - queryStart += delta - start; - fragmentStart += delta - start; - start = 0; - end = uri.length; - } else if (pathStart == queryStart) { - // Uri has authority and empty path. Add "/" as path. - if (start == 0 && end == uri.length) { - uri = uri.replaceRange(pathStart, queryStart, "/"); - queryStart += 1; - fragmentStart += 1; - end += 1; - } else { - uri = "${uri.substring(start, pathStart)}/" - "${uri.substring(queryStart, end)}"; - schemeEnd -= start; - hostStart -= start; - portStart -= start; - pathStart -= start; - queryStart += 1 - start; - fragmentStart += 1 - start; - start = 0; - end = uri.length; - } - } - } else if (uri.startsWith("http", start)) { - scheme = "http"; - // HTTP URIs should not have an explicit port of 80. - if (portStart > start && - portStart + 3 == pathStart && - uri.startsWith("80", portStart + 1)) { - if (start == 0 && end == uri.length) { - uri = uri.replaceRange(portStart, pathStart, ""); - pathStart -= 3; - queryStart -= 3; - fragmentStart -= 3; - end -= 3; - } else { - uri = uri.substring(start, portStart) + - uri.substring(pathStart, end); - schemeEnd -= start; - hostStart -= start; - portStart -= start; - pathStart -= 3 + start; - queryStart -= 3 + start; - fragmentStart -= 3 + start; - start = 0; - end = uri.length; - } - } - } - } else if (schemeEnd == start + 5 && uri.startsWith("https", start)) { - scheme = "https"; - // HTTPS URIs should not have an explicit port of 443. - if (portStart > start && - portStart + 4 == pathStart && - uri.startsWith("443", portStart + 1)) { - if (start == 0 && end == uri.length) { - uri = uri.replaceRange(portStart, pathStart, ""); - pathStart -= 4; - queryStart -= 4; - fragmentStart -= 4; - end -= 3; - } else { - uri = uri.substring(start, portStart) + - uri.substring(pathStart, end); - schemeEnd -= start; - hostStart -= start; - portStart -= start; - pathStart -= 4 + start; - queryStart -= 4 + start; - fragmentStart -= 4 + start; - start = 0; - end = uri.length; - } - } - } - } - } - - if (isSimple) { - if (start > 0 || end < uri.length) { - uri = uri.substring(start, end); - schemeEnd -= start; - hostStart -= start; - portStart -= start; - pathStart -= start; - queryStart -= start; - fragmentStart -= start; - } - return _SimpleUri(uri, schemeEnd, hostStart, portStart, pathStart, - queryStart, fragmentStart, scheme); - } - - return _Uri.notSimple(uri, start, end, schemeEnd, hostStart, portStart, - pathStart, queryStart, fragmentStart, scheme); - } - - /** - * Creates a new `Uri` object by parsing a URI string. - * - * If [start] and [end] are provided, they must specify a valid substring - * of [uri], and only the substring from `start` to `end` is parsed as a URI. - * The [uri] must not be `null`. - * - * Returns `null` if the [uri] string is not valid as a URI or URI reference. - */ - static Uri? tryParse(String uri, [int start = 0, int? end]) { - // TODO: Optimize to avoid throwing-and-recatching. - try { - return parse(uri, start, end); - } on FormatException { - return null; - } - } - - /** - * Encode the string [component] using percent-encoding to make it - * safe for literal use as a URI component. - * - * All characters except uppercase and lowercase letters, digits and - * the characters `-_.!~*'()` are percent-encoded. This is the - * set of characters specified in RFC 2396 and the which is - * specified for the encodeUriComponent in ECMA-262 version 5.1. - * - * When manually encoding path segments or query components remember - * to encode each part separately before building the path or query - * string. - * - * For encoding the query part consider using - * [encodeQueryComponent]. - * - * To avoid the need for explicitly encoding use the [pathSegments] - * and [queryParameters] optional named arguments when constructing - * a [Uri]. - */ - static String encodeComponent(String component) { - return _Uri._uriEncode(_Uri._unreserved2396Table, component, utf8, false); - } - - /** - * Encode the string [component] according to the HTML 4.01 rules - * for encoding the posting of a HTML form as a query string - * component. - * - * Encode the string [component] according to the HTML 4.01 rules - * for encoding the posting of a HTML form as a query string - * component. - - * The component is first encoded to bytes using [encoding]. - * The default is to use [utf8] encoding, which preserves all - * the characters that don't need encoding. - - * Then the resulting bytes are "percent-encoded". This transforms - * spaces (U+0020) to a plus sign ('+') and all bytes that are not - * the ASCII decimal digits, letters or one of '-._~' are written as - * a percent sign '%' followed by the two-digit hexadecimal - * representation of the byte. - - * Note that the set of characters which are percent-encoded is a - * superset of what HTML 4.01 requires, since it refers to RFC 1738 - * for reserved characters. - * - * When manually encoding query components remember to encode each - * part separately before building the query string. - * - * To avoid the need for explicitly encoding the query use the - * [queryParameters] optional named arguments when constructing a - * [Uri]. - * - * See http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2 for more - * details. - */ - static String encodeQueryComponent(String component, - {Encoding encoding = utf8}) { - return _Uri._uriEncode(_Uri._unreservedTable, component, encoding, true); - } - - /** - * Decodes the percent-encoding in [encodedComponent]. - * - * Note that decoding a URI component might change its meaning as - * some of the decoded characters could be characters with are - * delimiters for a given URI component type. Always split a URI - * component using the delimiters for the component before decoding - * the individual parts. - * - * For handling the [path] and [query] components consider using - * [pathSegments] and [queryParameters] to get the separated and - * decoded component. - */ - static String decodeComponent(String encodedComponent) { - return _Uri._uriDecode( - encodedComponent, 0, encodedComponent.length, utf8, false); - } - - /** - * Decodes the percent-encoding in [encodedComponent], converting - * pluses to spaces. - * - * It will create a byte-list of the decoded characters, and then use - * [encoding] to decode the byte-list to a String. The default encoding is - * UTF-8. - */ - static String decodeQueryComponent(String encodedComponent, - {Encoding encoding = utf8}) { - return _Uri._uriDecode( - encodedComponent, 0, encodedComponent.length, encoding, true); - } - - /** - * Encode the string [uri] using percent-encoding to make it - * safe for literal use as a full URI. - * - * All characters except uppercase and lowercase letters, digits and - * the characters `!#$&'()*+,-./:;=?@_~` are percent-encoded. This - * is the set of characters specified in in ECMA-262 version 5.1 for - * the encodeURI function . - */ - static String encodeFull(String uri) { - return _Uri._uriEncode(_Uri._encodeFullTable, uri, utf8, false); - } - - /** - * Decodes the percent-encoding in [uri]. - * - * Note that decoding a full URI might change its meaning as some of - * the decoded characters could be reserved characters. In most - * cases an encoded URI should be parsed into components using - * [Uri.parse] before decoding the separate components. - */ - static String decodeFull(String uri) { - return _Uri._uriDecode(uri, 0, uri.length, utf8, false); - } - - /** - * Returns the [query] split into a map according to the rules - * specified for FORM post in the [HTML 4.01 specification section - * 17.13.4](http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4 "HTML 4.01 section 17.13.4"). - * Each key and value in the returned map has been decoded. If the [query] - * is the empty string an empty map is returned. - * - * Keys in the query string that have no value are mapped to the - * empty string. - * - * Each query component will be decoded using [encoding]. The default encoding - * is UTF-8. - */ - static Map splitQueryString(String query, - {Encoding encoding = utf8}) { - return query.split("&").fold({}, (map, element) { - int index = element.indexOf("="); - if (index == -1) { - if (element != "") { - map[decodeQueryComponent(element, encoding: encoding)] = ""; - } - } else if (index != 0) { - var key = element.substring(0, index); - var value = element.substring(index + 1); - map[decodeQueryComponent(key, encoding: encoding)] = - decodeQueryComponent(value, encoding: encoding); - } - return map; - }); - } - - /** - * Parse the [host] as an IP version 4 (IPv4) address, returning the address - * as a list of 4 bytes in network byte order (big endian). - * - * Throws a [FormatException] if [host] is not a valid IPv4 address - * representation. - */ - static List parseIPv4Address(String host) => - _parseIPv4Address(host, 0, host.length); - - /// Implementation of [parseIPv4Address] that can work on a substring. - static List _parseIPv4Address(String host, int start, int end) { - void error(String msg, int position) { - throw FormatException('Illegal IPv4 address, $msg', host, position); - } - - var result = Uint8List(4); - int partIndex = 0; - int partStart = start; - for (int i = start; i < end; i++) { - int char = host.codeUnitAt(i); - if (char != _DOT) { - if (char ^ 0x30 > 9) { - // Fail on a non-digit character. - error("invalid character", i); - } - } else { - if (partIndex == 3) { - error('IPv4 address should contain exactly 4 parts', i); - } - int part = int.parse(host.substring(partStart, i)); - if (part > 255) { - error("each part must be in the range 0..255", partStart); - } - result[partIndex++] = part; - partStart = i + 1; - } - } - - if (partIndex != 3) { - error('IPv4 address should contain exactly 4 parts', end); - } - - int part = int.parse(host.substring(partStart, end)); - if (part > 255) { - error("each part must be in the range 0..255", partStart); - } - result[partIndex] = part; - - return result; - } - - /** - * Parse the [host] as an IP version 6 (IPv6) address, returning the address - * as a list of 16 bytes in network byte order (big endian). - * - * Throws a [FormatException] if [host] is not a valid IPv6 address - * representation. - * - * Acts on the substring from [start] to [end]. If [end] is omitted, it - * defaults ot the end of the string. - * - * Some examples of IPv6 addresses: - * * `::1` - * * `FEDC:BA98:7654:3210:FEDC:BA98:7654:3210` - * * `3ffe:2a00:100:7031::1` - * * `::FFFF:129.144.52.38` - * * `2010:836B:4179::836B:4179` - */ - static List parseIPv6Address(String host, [int start = 0, int? end]) { - end ??= host.length; - // An IPv6 address consists of exactly 8 parts of 1-4 hex digits, separated - // by `:`'s, with the following exceptions: - // - // - One (and only one) wildcard (`::`) may be present, representing a fill - // of 0's. The IPv6 `::` is thus 16 bytes of `0`. - // - The last two parts may be replaced by an IPv4 "dotted-quad" address. - - // Helper function for reporting a badly formatted IPv6 address. - void error(String msg, [position]) { - throw FormatException('Illegal IPv6 address, $msg', host, position); - } - - // Parse a hex block. - int parseHex(int start, int end) { - if (end - start > 4) { - error('an IPv6 part can only contain a maximum of 4 hex digits', start); - } - int value = int.parse(host.substring(start, end), radix: 16); - if (value < 0 || value > 0xFFFF) { - error('each part must be in the range of `0x0..0xFFFF`', start); - } - return value; - } - - if (host.length < 2) error('address is too short'); - List parts = []; - bool wildcardSeen = false; - // Set if seeing a ".", suggesting that there is an IPv4 address. - bool seenDot = false; - int partStart = start; - // Parse all parts, except a potential last one. - for (int i = start; i < end; i++) { - int char = host.codeUnitAt(i); - if (char == _COLON) { - if (i == start) { - // If we see a `:` in the beginning, expect wildcard. - i++; - if (host.codeUnitAt(i) != _COLON) { - error('invalid start colon.', i); - } - partStart = i; - } - if (i == partStart) { - // Wildcard. We only allow one. - if (wildcardSeen) { - error('only one wildcard `::` is allowed', i); - } - wildcardSeen = true; - parts.add(-1); - } else { - // Found a single colon. Parse [partStart..i] as a hex entry. - parts.add(parseHex(partStart, i)); - } - partStart = i + 1; - } else if (char == _DOT) { - seenDot = true; - } - } - if (parts.length == 0) error('too few parts'); - bool atEnd = (partStart == end); - bool isLastWildcard = (parts.last == -1); - if (atEnd && !isLastWildcard) { - error('expected a part after last `:`', end); - } - if (!atEnd) { - if (!seenDot) { - parts.add(parseHex(partStart, end)); - } else { - List last = _parseIPv4Address(host, partStart, end); - parts.add(last[0] << 8 | last[1]); - parts.add(last[2] << 8 | last[3]); - } - } - if (wildcardSeen) { - if (parts.length > 7) { - error('an address with a wildcard must have less than 7 parts'); - } - } else if (parts.length != 8) { - error('an address without a wildcard must contain exactly 8 parts'); - } - List bytes = Uint8List(16); - for (int i = 0, index = 0; i < parts.length; i++) { - int value = parts[i]; - if (value == -1) { - int wildCardLength = 9 - parts.length; - for (int j = 0; j < wildCardLength; j++) { - bytes[index] = 0; - bytes[index + 1] = 0; - index += 2; - } - } else { - bytes[index] = value >> 8; - bytes[index + 1] = value & 0xff; - index += 2; - } - } - return bytes; - } -} - -class _Uri implements Uri { - // We represent the missing scheme as an empty string. - // A valid scheme cannot be empty. - final String scheme; - - /** - * The user-info part of the authority. - * - * Does not distinguish between an empty user-info and an absent one. - * The value is always non-null. - * Is considered absent if [_host] is `null`. - */ - final String _userInfo; - - /** - * The host name of the URI. - * - * Set to `null` if there is no authority in the URI. - * The host name is the only mandatory part of an authority, so we use - * it to mark whether an authority part was present or not. - */ - final String? _host; - - /** - * The port number part of the authority. - * - * The port. Set to null if there is no port. Normalized to null if - * the port is the default port for the scheme. - */ - int? _port; - - /** - * The path of the URI. - * - * Always non-null. - */ - final String path; - - /// The query content, or null if there is no query. - final String? _query; - - // The fragment content, or null if there is no fragment. - final String? _fragment; - - /// Cache of the full normalized text representation of the URI. - late final String _text = this._initializeText(); - - /// Cache of the list of path segments. - late final List pathSegments = _computePathSegments(this.path); - - /// Lazily computed and cached hashCode of [_text]. - late final int hashCode = this._text.hashCode; - - /// Cache the computed return value of [queryParameters]. - late final Map queryParameters = - UnmodifiableMapView(Uri.splitQueryString(this.query)); - - /// Cache the computed return value of [queryParametersAll]. - late final Map> queryParametersAll = - _computeQueryParametersAll(this.query); - - /// Internal non-verifying constructor. Only call with validated arguments. - /// - /// The components must be properly normalized. - /// - /// Use `null` for [_host] if there is no authority. In that case, always - /// pass `null` for [_port] and an empty string for [_userInfo] as well. - /// - /// Use `null` for [_port], [_query] and [_fragment] if there is - /// component of that type, and empty string for [_userInfo]. - /// - /// The [path] and [scheme] are never empty. - _Uri._internal(this.scheme, this._userInfo, this._host, this._port, this.path, - this._query, this._fragment); - - /// Create a [_Uri] from parts of [uri]. - /// - /// The parameters specify the start/end of particular components of the URI. - /// The [scheme] may contain a string representing a normalized scheme - /// component if one has already been discovered. - factory _Uri.notSimple( - String uri, - int start, - int end, - int schemeEnd, - int hostStart, - int portStart, - int pathStart, - int queryStart, - int fragmentStart, - String? scheme) { - if (scheme == null) { - scheme = ""; - if (schemeEnd > start) { - scheme = _makeScheme(uri, start, schemeEnd); - } else if (schemeEnd == start) { - _fail(uri, start, "Invalid empty scheme"); - } - } - String userInfo = ""; - String? host; - int? port; - if (hostStart > start) { - int userInfoStart = schemeEnd + 3; - if (userInfoStart < hostStart) { - userInfo = _makeUserInfo(uri, userInfoStart, hostStart - 1); - } - host = _makeHost(uri, hostStart, portStart, false); - if (portStart + 1 < pathStart) { - int portNumber = - int.tryParse(uri.substring(portStart + 1, pathStart)) ?? - (throw FormatException("Invalid port", uri, portStart + 1)); - port = _makePort(portNumber, scheme); - } - } - String path = - _makePath(uri, pathStart, queryStart, null, scheme, host != null); - String? query; - if (queryStart < fragmentStart) { - query = _makeQuery(uri, queryStart + 1, fragmentStart, null); - } - String? fragment; - if (fragmentStart < end) { - fragment = _makeFragment(uri, fragmentStart + 1, end); - } - return _Uri._internal(scheme, userInfo, host, port, path, query, fragment); - } - - /// Implementation of [Uri.Uri]. - factory _Uri( - {String? scheme, - String? userInfo, - String? host, - int? port, - String? path, - Iterable? pathSegments, - String? query, - Map*/ >? queryParameters, - String? fragment}) { - if (scheme == null) { - scheme = ""; - } else { - scheme = _makeScheme(scheme, 0, scheme.length); - } - userInfo = _makeUserInfo(userInfo, 0, _stringOrNullLength(userInfo)); - if (userInfo == null) { - // TODO(dart-lang/language#440): Remove when promotion works. - throw "unreachable"; - } - host = _makeHost(host, 0, _stringOrNullLength(host), false); - // Special case this constructor for backwards compatibility. - if (query == "") query = null; - query = _makeQuery(query, 0, _stringOrNullLength(query), queryParameters); - fragment = _makeFragment(fragment, 0, _stringOrNullLength(fragment)); - port = _makePort(port, scheme); - bool isFile = (scheme == "file"); - if (host == null && (userInfo.isNotEmpty || port != null || isFile)) { - host = ""; - } - bool hasAuthority = (host != null); - path = _makePath( - path, 0, _stringOrNullLength(path), pathSegments, scheme, hasAuthority); - if (path == null) { - // TODO(dart-lang/language#440): Remove when promotion works. - throw "unreachable"; - } - if (scheme.isEmpty && host == null && !path.startsWith('/')) { - bool allowScheme = scheme.isNotEmpty || host != null; - path = _normalizeRelativePath(path, allowScheme); - } else { - path = _removeDotSegments(path); - } - if (host == null && path.startsWith("//")) { - host = ""; - } - return _Uri._internal(scheme, userInfo, host, port, path, query, fragment); - } - - /// Implementation of [Uri.http]. - factory _Uri.http(String authority, String unencodedPath, - [Map? queryParameters]) { - return _makeHttpUri("http", authority, unencodedPath, queryParameters); - } - - /// Implementation of [Uri.https]. - factory _Uri.https(String authority, String unencodedPath, - [Map? queryParameters]) { - return _makeHttpUri("https", authority, unencodedPath, queryParameters); - } - - String get authority { - if (!hasAuthority) return ""; - var sb = StringBuffer(); - _writeAuthority(sb); - return sb.toString(); - } - - String get userInfo => _userInfo; - - String get host { - String? host = _host; - if (host == null) return ""; - if (host.startsWith('[')) { - return host.substring(1, host.length - 1); - } - return host; - } - - int get port { - return _port ?? _defaultPort(scheme); - } - - /// The default port for the scheme of this Uri. - static int _defaultPort(String scheme) { - if (scheme == "http") return 80; - if (scheme == "https") return 443; - return 0; - } - - String get query => _query ?? ""; - - String get fragment => _fragment ?? ""; - - bool isScheme(String scheme) { - String thisScheme = this.scheme; - if (scheme == null) return thisScheme.isEmpty; - if (scheme.length != thisScheme.length) return false; - return _compareScheme(scheme, thisScheme); - } - - /// Compares scheme characters in [scheme] and at the start of [uri]. - /// - /// Returns `true` if [scheme] represents the same scheme as the start of - /// [uri]. That means having the same characters, but possibly different case - /// for letters. - /// - /// This function doesn't check that the characters are valid URI scheme - /// characters. The [uri] is assumed to be valid, so if [scheme] matches - /// it, it has to be valid too. - /// - /// The length should be tested before calling this function, - /// so the scheme part of [uri] is known to have the same length as [scheme]. - static bool _compareScheme(String scheme, String uri) { - for (int i = 0; i < scheme.length; i++) { - int schemeChar = scheme.codeUnitAt(i); - int uriChar = uri.codeUnitAt(i); - int delta = schemeChar ^ uriChar; - if (delta != 0) { - if (delta == 0x20) { - // Might be a case difference. - int lowerChar = uriChar | delta; - if (0x61 /*a*/ <= lowerChar && lowerChar <= 0x7a /*z*/) { - continue; - } - } - return false; - } - } - return true; - } - - /// Report a parse failure. - static Never _fail(String uri, int index, String message) { - throw FormatException(message, uri, index); - } - - static _Uri _makeHttpUri(String scheme, String? authority, - String unencodedPath, Map? queryParameters) { - var userInfo = ""; - String? host; - int? port; - - if (authority != null && authority.isNotEmpty) { - var hostStart = 0; - // Split off the user info. - for (int i = 0; i < authority.length; i++) { - const int atSign = 0x40; - if (authority.codeUnitAt(i) == atSign) { - userInfo = authority.substring(0, i); - hostStart = i + 1; - break; - } - } - var hostEnd = hostStart; - if (hostStart < authority.length && - authority.codeUnitAt(hostStart) == _LEFT_BRACKET) { - // IPv6 host. - int escapeForZoneID = -1; - for (; hostEnd < authority.length; hostEnd++) { - int char = authority.codeUnitAt(hostEnd); - if (char == _PERCENT && escapeForZoneID < 0) { - escapeForZoneID = hostEnd; - if (authority.startsWith("25", hostEnd + 1)) { - hostEnd += 2; // Might as well skip the already checked escape. - } - } else if (char == _RIGHT_BRACKET) { - break; - } - } - if (hostEnd == authority.length) { - throw FormatException( - "Invalid IPv6 host entry.", authority, hostStart); - } - Uri.parseIPv6Address(authority, hostStart + 1, - (escapeForZoneID < 0) ? hostEnd : escapeForZoneID); - hostEnd++; // Skip the closing bracket. - if (hostEnd != authority.length && - authority.codeUnitAt(hostEnd) != _COLON) { - throw FormatException("Invalid end of authority", authority, hostEnd); - } - } - // Split host and port. - for (; hostEnd < authority.length; hostEnd++) { - if (authority.codeUnitAt(hostEnd) == _COLON) { - var portString = authority.substring(hostEnd + 1); - // We allow the empty port - falling back to initial value. - if (portString.isNotEmpty) port = int.parse(portString); - break; - } - } - host = authority.substring(hostStart, hostEnd); - } - return _Uri( - scheme: scheme, - userInfo: userInfo, - host: host, - port: port, - pathSegments: unencodedPath.split("/"), - queryParameters: queryParameters); - } - - /// Implementation of [Uri.file]. - factory _Uri.file(String path, {bool? windows}) { - return (windows ?? _Uri._isWindows) - ? _makeWindowsFileUrl(path, false) - : _makeFileUri(path, false); - } - - /// Implementation of [Uri.directory]. - factory _Uri.directory(String path, {bool? windows}) { - return (windows ?? _Uri._isWindows) - ? _makeWindowsFileUrl(path, true) - : _makeFileUri(path, true); - } - - /// Used internally in path-related constructors. - external static bool get _isWindows; - - static void _checkNonWindowsPathReservedCharacters( - List segments, bool argumentError) { - for (var segment in segments) { - if (segment.contains("/")) { - if (argumentError) { - throw ArgumentError("Illegal path character $segment"); - } else { - throw UnsupportedError("Illegal path character $segment"); - } - } - } - } - - static void _checkWindowsPathReservedCharacters( - List segments, bool argumentError, - [int firstSegment = 0]) { - for (var segment in segments.skip(firstSegment)) { - if (segment.contains(RegExp(r'["*/:<>?\\|]'))) { - if (argumentError) { - throw ArgumentError("Illegal character in path"); - } else { - throw UnsupportedError("Illegal character in path: $segment"); - } - } - } - } - - static void _checkWindowsDriveLetter(int charCode, bool argumentError) { - if ((_UPPER_CASE_A <= charCode && charCode <= _UPPER_CASE_Z) || - (_LOWER_CASE_A <= charCode && charCode <= _LOWER_CASE_Z)) { - return; - } - if (argumentError) { - throw ArgumentError( - "Illegal drive letter " + String.fromCharCode(charCode)); - } else { - throw UnsupportedError( - "Illegal drive letter " + String.fromCharCode(charCode)); - } - } - - static Uri _makeFileUri(String path, bool slashTerminated) { - const String sep = "/"; - var segments = path.split(sep); - if (slashTerminated && segments.isNotEmpty && segments.last.isNotEmpty) { - segments.add(""); // Extra separator at end. - } - if (path.startsWith(sep)) { - // Absolute file:// URI. - return Uri(scheme: "file", pathSegments: segments); - } else { - // Relative URI. - return Uri(pathSegments: segments); - } - } - - static _makeWindowsFileUrl(String path, bool slashTerminated) { - if (path.startsWith(r"\\?\")) { - if (path.startsWith(r"UNC\", 4)) { - path = path.replaceRange(0, 7, r'\'); - } else { - path = path.substring(4); - if (path.length < 3 || - path.codeUnitAt(1) != _COLON || - path.codeUnitAt(2) != _BACKSLASH) { - throw ArgumentError( - r"Windows paths with \\?\ prefix must be absolute"); - } - } - } else { - path = path.replaceAll("/", r'\'); - } - const String sep = r'\'; - if (path.length > 1 && path.codeUnitAt(1) == _COLON) { - _checkWindowsDriveLetter(path.codeUnitAt(0), true); - if (path.length == 2 || path.codeUnitAt(2) != _BACKSLASH) { - throw ArgumentError("Windows paths with drive letter must be absolute"); - } - // Absolute file://C:/ URI. - var pathSegments = path.split(sep); - if (slashTerminated && pathSegments.last.isNotEmpty) { - pathSegments.add(""); // Extra separator at end. - } - _checkWindowsPathReservedCharacters(pathSegments, true, 1); - return Uri(scheme: "file", pathSegments: pathSegments); - } - - if (path.startsWith(sep)) { - if (path.startsWith(sep, 1)) { - // Absolute file:// URI with host. - int pathStart = path.indexOf(r'\', 2); - String hostPart = - (pathStart < 0) ? path.substring(2) : path.substring(2, pathStart); - String pathPart = (pathStart < 0) ? "" : path.substring(pathStart + 1); - var pathSegments = pathPart.split(sep); - _checkWindowsPathReservedCharacters(pathSegments, true); - if (slashTerminated && pathSegments.last.isNotEmpty) { - pathSegments.add(""); // Extra separator at end. - } - return Uri(scheme: "file", host: hostPart, pathSegments: pathSegments); - } else { - // Absolute file:// URI. - var pathSegments = path.split(sep); - if (slashTerminated && pathSegments.last.isNotEmpty) { - pathSegments.add(""); // Extra separator at end. - } - _checkWindowsPathReservedCharacters(pathSegments, true); - return Uri(scheme: "file", pathSegments: pathSegments); - } - } else { - // Relative URI. - var pathSegments = path.split(sep); - _checkWindowsPathReservedCharacters(pathSegments, true); - if (slashTerminated && - pathSegments.isNotEmpty && - pathSegments.last.isNotEmpty) { - pathSegments.add(""); // Extra separator at end. - } - return Uri(pathSegments: pathSegments); - } - } - - Uri replace( - {String? scheme, - String? userInfo, - String? host, - int? port, - String? path, - Iterable? pathSegments, - String? query, - Map*/ >? queryParameters, - String? fragment}) { - // Set to true if the scheme has (potentially) changed. - // In that case, the default port may also have changed and we need - // to check even the existing port. - bool schemeChanged = false; - if (scheme != null) { - scheme = _makeScheme(scheme, 0, scheme.length); - schemeChanged = (scheme != this.scheme); - } else { - scheme = this.scheme; - } - - bool isFile = (scheme == "file"); - if (userInfo != null) { - userInfo = _makeUserInfo(userInfo, 0, userInfo.length); - } else { - userInfo = this._userInfo; - } - - if (port != null) { - port = _makePort(port, scheme); - } else { - port = this._port; - if (schemeChanged) { - // The default port might have changed. - port = _makePort(port, scheme); - } - } - if (host != null) { - host = _makeHost(host, 0, host.length, false); - } else if (this.hasAuthority) { - host = this._host; - } else if (userInfo.isNotEmpty || port != null || isFile) { - host = ""; - } - - bool hasAuthority = host != null; - if (path != null || pathSegments != null) { - path = _makePath(path, 0, _stringOrNullLength(path), pathSegments, scheme, - hasAuthority); - } else { - var currentPath = this.path; - if ((isFile || (hasAuthority && !currentPath.isEmpty)) && - !currentPath.startsWith('/')) { - currentPath = "/" + currentPath; - } - path = currentPath; - } - - if (query != null || queryParameters != null) { - query = _makeQuery(query, 0, _stringOrNullLength(query), queryParameters); - } else { - query = this._query; - } - - if (fragment != null) { - fragment = _makeFragment(fragment, 0, fragment.length); - } else { - fragment = this._fragment; - } - - return _Uri._internal(scheme, userInfo, host, port, path, query, fragment); - } - - Uri removeFragment() { - if (!this.hasFragment) return this; - return _Uri._internal(scheme, _userInfo, _host, _port, path, _query, null); - } - - static List _computePathSegments(String pathToSplit) { - if (pathToSplit.isNotEmpty && pathToSplit.codeUnitAt(0) == _SLASH) { - pathToSplit = pathToSplit.substring(1); - } - return (pathToSplit.isEmpty) - ? const [] - : List.unmodifiable( - pathToSplit.split("/").map(Uri.decodeComponent)); - } - - static Map> _computeQueryParametersAll(String? query) { - if (query == null || query.isEmpty) return const >{}; - Map> queryParameterLists = _splitQueryStringAll(query); - queryParameterLists.updateAll(_toUnmodifiableStringList); - return Map>.unmodifiable(queryParameterLists); - } - - Uri normalizePath() { - String path = _normalizePath(this.path, scheme, hasAuthority); - if (identical(path, this.path)) return this; - return this.replace(path: path); - } - - static int? _makePort(int? port, String scheme) { - // Perform scheme specific normalization. - if (port != null && port == _defaultPort(scheme)) return null; - return port; - } - - /** - * Check and normalize a host name. - * - * If the host name starts and ends with '[' and ']', it is considered an - * IPv6 address. If [strictIPv6] is false, the address is also considered - * an IPv6 address if it contains any ':' character. - * - * If it is not an IPv6 address, it is case- and escape-normalized. - * This escapes all characters not valid in a reg-name, - * and converts all non-escape upper-case letters to lower-case. - */ - static String? _makeHost(String? host, int start, int end, bool strictIPv6) { - // TODO(lrn): Should we normalize IPv6 addresses according to RFC 5952? - if (host == null) return null; - if (start == end) return ""; - // Host is an IPv6 address if it starts with '[' or contains a colon. - if (host.codeUnitAt(start) == _LEFT_BRACKET) { - if (host.codeUnitAt(end - 1) != _RIGHT_BRACKET) { - _fail(host, start, 'Missing end `]` to match `[` in host'); - } - String zoneID = ""; - int index = _checkZoneID(host, start + 1, end - 1); - if (index < end - 1) { - int zoneIDstart = - (host.startsWith("25", index + 1)) ? index + 3 : index + 1; - zoneID = _normalizeZoneID(host, zoneIDstart, end - 1, "%25"); - } - Uri.parseIPv6Address(host, start + 1, index); - // RFC 5952 requires hex digits to be lower case. - return host.substring(start, index).toLowerCase() + zoneID + ']'; - } - if (!strictIPv6) { - // TODO(lrn): skip if too short to be a valid IPv6 address? - for (int i = start; i < end; i++) { - if (host.codeUnitAt(i) == _COLON) { - String zoneID = ""; - int index = _checkZoneID(host, start, end); - if (index < end) { - int zoneIDstart = - (host.startsWith("25", index + 1)) ? index + 3 : index + 1; - zoneID = _normalizeZoneID(host, zoneIDstart, end, "%25"); - } - Uri.parseIPv6Address(host, start, index); - return '[${host.substring(start, index)}' + zoneID + ']'; - } - } - } - return _normalizeRegName(host, start, end); - } - - /// RFC 6874 check for ZoneID - /// Return the index of first appeared `%`. - static int _checkZoneID(String host, int start, int end) { - int index = host.indexOf('%', start); - index = (index >= start && index < end) ? index : end; - return index; - } - - static bool _isZoneIDChar(int char) { - return char < 127 && (_zoneIDTable[char >> 4] & (1 << (char & 0xf))) != 0; - } - - /** - * Validates and does case- and percent-encoding normalization. - * - * The same as [_normalizeOrSubstring] - * except this function does not convert characters to lower case. - * The [host] must be an RFC6874 "ZoneID". - * ZoneID = 1*(unreserved / pct-encoded) - */ - static String _normalizeZoneID(String host, int start, int end, - [String prefix = '']) { - StringBuffer? buffer; - if (prefix != '') { - buffer = StringBuffer(prefix); - } - int sectionStart = start; - int index = start; - // Whether all characters between sectionStart and index are normalized, - bool isNormalized = true; - - while (index < end) { - int char = host.codeUnitAt(index); - if (char == _PERCENT) { - String? replacement = _normalizeEscape(host, index, true); - if (replacement == null && isNormalized) { - index += 3; - continue; - } - buffer ??= StringBuffer(); - String slice = host.substring(sectionStart, index); - buffer.write(slice); - int sourceLength = 3; - if (replacement == null) { - replacement = host.substring(index, index + 3); - } else if (replacement == "%") { - _fail(host, index, "ZoneID should not contain % anymore"); - } - buffer.write(replacement); - index += sourceLength; - sectionStart = index; - isNormalized = true; - } else if (_isZoneIDChar(char)) { - if (isNormalized && _UPPER_CASE_A <= char && _UPPER_CASE_Z >= char) { - // Put initial slice in buffer and continue in non-normalized mode - buffer ??= StringBuffer(); - if (sectionStart < index) { - buffer.write(host.substring(sectionStart, index)); - sectionStart = index; - } - isNormalized = false; - } - index++; - } else { - int sourceLength = 1; - if ((char & 0xFC00) == 0xD800 && (index + 1) < end) { - int tail = host.codeUnitAt(index + 1); - if ((tail & 0xFC00) == 0xDC00) { - char = 0x10000 | ((char & 0x3ff) << 10) | (tail & 0x3ff); - sourceLength = 2; - } - } - String slice = host.substring(sectionStart, index); - (buffer ??= StringBuffer())..write(slice)..write(_escapeChar(char)); - index += sourceLength; - sectionStart = index; - } - } - if (buffer == null) return host.substring(start, end); - if (sectionStart < end) { - String slice = host.substring(sectionStart, end); - buffer.write(slice); - } - return buffer.toString(); - } - - static bool _isRegNameChar(int char) { - return char < 127 && (_regNameTable[char >> 4] & (1 << (char & 0xf))) != 0; - } - - /** - * Validates and does case- and percent-encoding normalization. - * - * The [host] must be an RFC3986 "reg-name". It is converted - * to lower case, and percent escapes are converted to either - * lower case unreserved characters or upper case escapes. - */ - static String _normalizeRegName(String host, int start, int end) { - StringBuffer? buffer; - int sectionStart = start; - int index = start; - // Whether all characters between sectionStart and index are normalized, - bool isNormalized = true; - - while (index < end) { - int char = host.codeUnitAt(index); - if (char == _PERCENT) { - // The _regNameTable contains "%", so we check that first. - String? replacement = _normalizeEscape(host, index, true); - if (replacement == null && isNormalized) { - index += 3; - continue; - } - buffer ??= StringBuffer(); - String slice = host.substring(sectionStart, index); - if (!isNormalized) slice = slice.toLowerCase(); - buffer.write(slice); - int sourceLength = 3; - if (replacement == null) { - replacement = host.substring(index, index + 3); - } else if (replacement == "%") { - replacement = "%25"; - sourceLength = 1; - } - buffer.write(replacement); - index += sourceLength; - sectionStart = index; - isNormalized = true; - } else if (_isRegNameChar(char)) { - if (isNormalized && _UPPER_CASE_A <= char && _UPPER_CASE_Z >= char) { - // Put initial slice in buffer and continue in non-normalized mode - buffer ??= StringBuffer(); - if (sectionStart < index) { - buffer.write(host.substring(sectionStart, index)); - sectionStart = index; - } - isNormalized = false; - } - index++; - } else if (_isGeneralDelimiter(char)) { - _fail(host, index, "Invalid character"); - } else { - int sourceLength = 1; - if ((char & 0xFC00) == 0xD800 && (index + 1) < end) { - int tail = host.codeUnitAt(index + 1); - if ((tail & 0xFC00) == 0xDC00) { - char = 0x10000 | ((char & 0x3ff) << 10) | (tail & 0x3ff); - sourceLength = 2; - } - } - String slice = host.substring(sectionStart, index); - if (!isNormalized) slice = slice.toLowerCase(); - (buffer ??= StringBuffer())..write(slice)..write(_escapeChar(char)); - index += sourceLength; - sectionStart = index; - } - } - if (buffer == null) return host.substring(start, end); - if (sectionStart < end) { - String slice = host.substring(sectionStart, end); - if (!isNormalized) slice = slice.toLowerCase(); - buffer.write(slice); - } - return buffer.toString(); - } - - /** - * Validates scheme characters and does case-normalization. - * - * Schemes are converted to lower case. They cannot contain escapes. - */ - static String _makeScheme(String scheme, int start, int end) { - if (start == end) return ""; - final int firstCodeUnit = scheme.codeUnitAt(start); - if (!_isAlphabeticCharacter(firstCodeUnit)) { - _fail(scheme, start, "Scheme not starting with alphabetic character"); - } - bool containsUpperCase = false; - for (int i = start; i < end; i++) { - final int codeUnit = scheme.codeUnitAt(i); - if (!_isSchemeCharacter(codeUnit)) { - _fail(scheme, i, "Illegal scheme character"); - } - if (_UPPER_CASE_A <= codeUnit && codeUnit <= _UPPER_CASE_Z) { - containsUpperCase = true; - } - } - scheme = scheme.substring(start, end); - if (containsUpperCase) scheme = scheme.toLowerCase(); - return _canonicalizeScheme(scheme); - } - - /// Canonicalize a few often-used scheme strings. - /// - /// This improves memory usage and makes comparison faster. - static String _canonicalizeScheme(String scheme) { - if (scheme == "http") return "http"; - if (scheme == "file") return "file"; - if (scheme == "https") return "https"; - if (scheme == "package") return "package"; - return scheme; - } - - static String _makeUserInfo(String? userInfo, int start, int end) { - if (userInfo == null) return ""; - return _normalizeOrSubstring(userInfo, start, end, _userinfoTable); - } - - static String _makePath(String? path, int start, int end, - Iterable? pathSegments, String scheme, bool hasAuthority) { - bool isFile = (scheme == "file"); - bool ensureLeadingSlash = isFile || hasAuthority; - String result; - if (path == null) { - if (pathSegments == null) return isFile ? "/" : ""; - result = pathSegments - .map((s) => _uriEncode(_pathCharTable, s, utf8, false)) - .join("/"); - } else if (pathSegments != null) { - throw ArgumentError('Both path and pathSegments specified'); - } else { - result = _normalizeOrSubstring(path, start, end, _pathCharOrSlashTable, - escapeDelimiters: true); - } - if (result.isEmpty) { - if (isFile) return "/"; - } else if (ensureLeadingSlash && !result.startsWith('/')) { - result = "/" + result; - } - result = _normalizePath(result, scheme, hasAuthority); - return result; - } - - /// Performs path normalization (remove dot segments) on a path. - /// - /// If the URI has neither scheme nor authority, it's considered a - /// "pure path" and normalization won't remove leading ".." segments. - /// Otherwise it follows the RFC 3986 "remove dot segments" algorithm. - static String _normalizePath(String path, String scheme, bool hasAuthority) { - if (scheme.isEmpty && !hasAuthority && !path.startsWith('/')) { - return _normalizeRelativePath(path, scheme.isNotEmpty || hasAuthority); - } - return _removeDotSegments(path); - } - - static String? _makeQuery(String? query, int start, int end, - Map*/ >? queryParameters) { - if (query != null) { - if (queryParameters != null) { - throw ArgumentError('Both query and queryParameters specified'); - } - return _normalizeOrSubstring(query, start, end, _queryCharTable, - escapeDelimiters: true); - } - if (queryParameters == null) return null; - - var result = StringBuffer(); - var separator = ""; - - void writeParameter(String key, String? value) { - result.write(separator); - separator = "&"; - result.write(Uri.encodeQueryComponent(key)); - if (value != null && value.isNotEmpty) { - result.write("="); - result.write(Uri.encodeQueryComponent(value)); - } - } - - queryParameters.forEach((key, value) { - if (value == null || value is String) { - writeParameter(key, value); - } else { - Iterable values = value; - for (String value in values) { - writeParameter(key, value); - } - } - }); - return result.toString(); - } - - static String? _makeFragment(String? fragment, int start, int end) { - if (fragment == null) return null; - return _normalizeOrSubstring(fragment, start, end, _queryCharTable, - escapeDelimiters: true); - } - - /** - * Performs RFC 3986 Percent-Encoding Normalization. - * - * Returns a replacement string that should be replace the original escape. - * Returns null if no replacement is necessary because the escape is - * not for an unreserved character and is already non-lower-case. - * - * Returns "%" if the escape is invalid (not two valid hex digits following - * the percent sign). The calling code should replace the percent - * sign with "%25", but leave the following two characters unmodified. - * - * If [lowerCase] is true, a single character returned is always lower case, - */ - static String? _normalizeEscape(String source, int index, bool lowerCase) { - assert(source.codeUnitAt(index) == _PERCENT); - if (index + 2 >= source.length) { - return "%"; // Marks the escape as invalid. - } - int firstDigit = source.codeUnitAt(index + 1); - int secondDigit = source.codeUnitAt(index + 2); - int firstDigitValue = hexDigitValue(firstDigit); - int secondDigitValue = hexDigitValue(secondDigit); - if (firstDigitValue < 0 || secondDigitValue < 0) { - return "%"; // Marks the escape as invalid. - } - int value = firstDigitValue * 16 + secondDigitValue; - if (_isUnreservedChar(value)) { - if (lowerCase && _UPPER_CASE_A <= value && _UPPER_CASE_Z >= value) { - value |= 0x20; - } - return String.fromCharCode(value); - } - if (firstDigit >= _LOWER_CASE_A || secondDigit >= _LOWER_CASE_A) { - // Either digit is lower case. - return source.substring(index, index + 3).toUpperCase(); - } - // Escape is retained, and is already non-lower case, so return null to - // represent "no replacement necessary". - return null; - } - - static String _escapeChar(int char) { - assert(char <= 0x10ffff); // It's a valid unicode code point. - List codeUnits; - if (char < 0x80) { - // ASCII, a single percent encoded sequence. - codeUnits = Uint8List(3); - codeUnits[0] = _PERCENT; - codeUnits[1] = _hexDigits.codeUnitAt(char >> 4); - codeUnits[2] = _hexDigits.codeUnitAt(char & 0xf); - } else { - // Do UTF-8 encoding of character, then percent encode bytes. - int flag = 0xc0; // The high-bit markers on the first byte of UTF-8. - int encodedBytes = 2; - if (char > 0x7ff) { - flag = 0xe0; - encodedBytes = 3; - if (char > 0xffff) { - encodedBytes = 4; - flag = 0xf0; - } - } - codeUnits = Uint8List(3 * encodedBytes); - int index = 0; - while (--encodedBytes >= 0) { - int byte = ((char >> (6 * encodedBytes)) & 0x3f) | flag; - codeUnits[index] = _PERCENT; - codeUnits[index + 1] = _hexDigits.codeUnitAt(byte >> 4); - codeUnits[index + 2] = _hexDigits.codeUnitAt(byte & 0xf); - index += 3; - flag = 0x80; // Following bytes have only high bit set. - } - } - return String.fromCharCodes(codeUnits); - } - - /** - * Normalizes using [_normalize] or returns substring of original. - * - * If [_normalize] returns `null` (original content is already normalized), - * this methods returns the substring if [component] from [start] to [end]. - */ - static String _normalizeOrSubstring( - String component, int start, int end, List charTable, - {bool escapeDelimiters = false}) { - return _normalize(component, start, end, charTable, - escapeDelimiters: escapeDelimiters) ?? - component.substring(start, end); - } - - /** - * Runs through component checking that each character is valid and - * normalize percent escapes. - * - * Uses [charTable] to check if a non-`%` character is allowed. - * Each `%` character must be followed by two hex digits. - * If the hex-digits are lower case letters, they are converted to - * upper case. - * - * Returns `null` if the original content was already normalized. - */ - static String? _normalize( - String component, int start, int end, List charTable, - {bool escapeDelimiters = false}) { - StringBuffer? buffer; - int sectionStart = start; - int index = start; - // Loop while characters are valid and escapes correct and upper-case. - while (index < end) { - int char = component.codeUnitAt(index); - if (char < 127 && (charTable[char >> 4] & (1 << (char & 0x0f))) != 0) { - index++; - } else { - String? replacement; - int sourceLength; - if (char == _PERCENT) { - replacement = _normalizeEscape(component, index, false); - // Returns null if we should keep the existing escape. - if (replacement == null) { - index += 3; - continue; - } - // Returns "%" if we should escape the existing percent. - if ("%" == replacement) { - replacement = "%25"; - sourceLength = 1; - } else { - sourceLength = 3; - } - } else if (!escapeDelimiters && _isGeneralDelimiter(char)) { - _fail(component, index, "Invalid character"); - throw "unreachable"; // TODO(lrn): Remove when Never-returning functions are recognized as throwing. - } else { - sourceLength = 1; - if ((char & 0xFC00) == 0xD800) { - // Possible lead surrogate. - if (index + 1 < end) { - int tail = component.codeUnitAt(index + 1); - if ((tail & 0xFC00) == 0xDC00) { - // Tail surrogate. - sourceLength = 2; - char = 0x10000 | ((char & 0x3ff) << 10) | (tail & 0x3ff); - } - } - } - replacement = _escapeChar(char); - } - (buffer ??= StringBuffer()) - ..write(component.substring(sectionStart, index)) - ..write(replacement); - index += sourceLength; - sectionStart = index; - } - } - if (buffer == null) { - return null; - } - if (sectionStart < end) { - buffer.write(component.substring(sectionStart, end)); - } - return buffer.toString(); - } - - static bool _isSchemeCharacter(int ch) { - return ch < 128 && ((_schemeTable[ch >> 4] & (1 << (ch & 0x0f))) != 0); - } - - static bool _isGeneralDelimiter(int ch) { - return ch <= _RIGHT_BRACKET && - ((_genDelimitersTable[ch >> 4] & (1 << (ch & 0x0f))) != 0); - } - - /** - * Returns whether the URI is absolute. - */ - bool get isAbsolute => scheme != "" && fragment == ""; - - String _mergePaths(String base, String reference) { - // Optimize for the case: absolute base, reference beginning with "../". - int backCount = 0; - int refStart = 0; - // Count number of "../" at beginning of reference. - while (reference.startsWith("../", refStart)) { - refStart += 3; - backCount++; - } - - // Drop last segment - everything after last '/' of base. - int baseEnd = base.lastIndexOf('/'); - // Drop extra segments for each leading "../" of reference. - while (baseEnd > 0 && backCount > 0) { - int newEnd = base.lastIndexOf('/', baseEnd - 1); - if (newEnd < 0) { - break; - } - int delta = baseEnd - newEnd; - // If we see a "." or ".." segment in base, stop here and let - // _removeDotSegments handle it. - if ((delta == 2 || delta == 3) && - base.codeUnitAt(newEnd + 1) == _DOT && - (delta == 2 || base.codeUnitAt(newEnd + 2) == _DOT)) { - break; - } - baseEnd = newEnd; - backCount--; - } - return base.replaceRange( - baseEnd + 1, null, reference.substring(refStart - 3 * backCount)); - } - - /// Make a guess at whether a path contains a `..` or `.` segment. - /// - /// This is a primitive test that can cause false positives. - /// It's only used to avoid a more expensive operation in the case where - /// it's not necessary. - static bool _mayContainDotSegments(String path) { - if (path.startsWith('.')) return true; - int index = path.indexOf("/."); - return index != -1; - } - - /// Removes '.' and '..' segments from a path. - /// - /// Follows the RFC 2986 "remove dot segments" algorithm. - /// This algorithm is only used on paths of URIs with a scheme, - /// and it treats the path as if it is absolute (leading '..' are removed). - static String _removeDotSegments(String path) { - if (!_mayContainDotSegments(path)) return path; - assert(path.isNotEmpty); // An empty path would not have dot segments. - List output = []; - bool appendSlash = false; - for (String segment in path.split("/")) { - appendSlash = false; - if (segment == "..") { - if (output.isNotEmpty) { - output.removeLast(); - if (output.isEmpty) { - output.add(""); - } - } - appendSlash = true; - } else if ("." == segment) { - appendSlash = true; - } else { - output.add(segment); - } - } - if (appendSlash) output.add(""); - return output.join("/"); - } - - /// Removes all `.` segments and any non-leading `..` segments. - /// - /// If the path starts with something that looks like a scheme, - /// and [allowScheme] is false, the colon is escaped. - /// - /// Removing the ".." from a "bar/foo/.." sequence results in "bar/" - /// (trailing "/"). If the entire path is removed (because it contains as - /// many ".." segments as real segments), the result is "./". - /// This is different from an empty string, which represents "no path", - /// when you resolve it against a base URI with a path with a non-empty - /// final segment. - static String _normalizeRelativePath(String path, bool allowScheme) { - assert(!path.startsWith('/')); // Only get called for relative paths. - if (!_mayContainDotSegments(path)) { - if (!allowScheme) path = _escapeScheme(path); - return path; - } - assert(path.isNotEmpty); // An empty path would not have dot segments. - List output = []; - bool appendSlash = false; - for (String segment in path.split("/")) { - appendSlash = false; - if (".." == segment) { - if (!output.isEmpty && output.last != "..") { - output.removeLast(); - appendSlash = true; - } else { - output.add(".."); - } - } else if ("." == segment) { - appendSlash = true; - } else { - output.add(segment); - } - } - if (output.isEmpty || (output.length == 1 && output[0].isEmpty)) { - return "./"; - } - if (appendSlash || output.last == '..') output.add(""); - if (!allowScheme) output[0] = _escapeScheme(output[0]); - return output.join("/"); - } - - /// If [path] starts with a valid scheme, escape the percent. - static String _escapeScheme(String path) { - if (path.length >= 2 && _isAlphabeticCharacter(path.codeUnitAt(0))) { - for (int i = 1; i < path.length; i++) { - int char = path.codeUnitAt(i); - if (char == _COLON) { - return "${path.substring(0, i)}%3A${path.substring(i + 1)}"; - } - if (char > 127 || - ((_schemeTable[char >> 4] & (1 << (char & 0x0f))) == 0)) { - break; - } - } - } - return path; - } - - Uri resolve(String reference) { - return resolveUri(Uri.parse(reference)); - } - - Uri resolveUri(Uri reference) { - // From RFC 3986. - String targetScheme; - String targetUserInfo = ""; - String? targetHost; - int? targetPort; - String targetPath; - String? targetQuery; - if (reference.scheme.isNotEmpty) { - targetScheme = reference.scheme; - if (reference.hasAuthority) { - targetUserInfo = reference.userInfo; - targetHost = reference.host; - targetPort = reference.hasPort ? reference.port : null; - } - targetPath = _removeDotSegments(reference.path); - if (reference.hasQuery) { - targetQuery = reference.query; - } - } else { - targetScheme = this.scheme; - if (reference.hasAuthority) { - targetUserInfo = reference.userInfo; - targetHost = reference.host; - targetPort = - _makePort(reference.hasPort ? reference.port : null, targetScheme); - targetPath = _removeDotSegments(reference.path); - if (reference.hasQuery) targetQuery = reference.query; - } else { - targetUserInfo = this._userInfo; - targetHost = this._host; - targetPort = this._port; - if (reference.path == "") { - targetPath = this.path; - if (reference.hasQuery) { - targetQuery = reference.query; - } else { - targetQuery = this._query; - } - } else { - if (reference.hasAbsolutePath) { - targetPath = _removeDotSegments(reference.path); - } else { - // This is the RFC 3986 behavior for merging. - if (this.hasEmptyPath) { - if (!this.hasAuthority) { - if (!this.hasScheme) { - // Keep the path relative if no scheme or authority. - targetPath = reference.path; - } else { - // Remove leading dot-segments if the path is put - // beneath a scheme. - targetPath = _removeDotSegments(reference.path); - } - } else { - // RFC algorithm for base with authority and empty path. - targetPath = _removeDotSegments("/" + reference.path); - } - } else { - var mergedPath = _mergePaths(this.path, reference.path); - if (this.hasScheme || this.hasAuthority || this.hasAbsolutePath) { - targetPath = _removeDotSegments(mergedPath); - } else { - // Non-RFC 3986 behavior. - // If both base and reference are relative paths, - // allow the merged path to start with "..". - // The RFC only specifies the case where the base has a scheme. - targetPath = _normalizeRelativePath( - mergedPath, this.hasScheme || this.hasAuthority); - } - } - } - if (reference.hasQuery) targetQuery = reference.query; - } - } - } - String? fragment = reference.hasFragment ? reference.fragment : null; - return _Uri._internal(targetScheme, targetUserInfo, targetHost, targetPort, - targetPath, targetQuery, fragment); - } - - bool get hasScheme => scheme.isNotEmpty; - - bool get hasAuthority => _host != null; - - bool get hasPort => _port != null; - - bool get hasQuery => _query != null; - - bool get hasFragment => _fragment != null; - - bool get hasEmptyPath => path.isEmpty; - - bool get hasAbsolutePath => path.startsWith('/'); - - String get origin { - if (scheme == "") { - throw StateError("Cannot use origin without a scheme: $this"); - } - if (scheme != "http" && scheme != "https") { - throw StateError( - "Origin is only applicable schemes http and https: $this"); - } - String? host = _host; - if (host == null || host == "") { - throw StateError( - "A $scheme: URI should have a non-empty host name: $this"); - } - int? port = _port; - if (port == null) return "$scheme://$host"; - return "$scheme://$host:$port"; - } - - String toFilePath({bool? windows}) { - if (scheme != "" && scheme != "file") { - throw UnsupportedError("Cannot extract a file path from a $scheme URI"); - } - if (query != "") { - throw UnsupportedError( - "Cannot extract a file path from a URI with a query component"); - } - if (fragment != "") { - throw UnsupportedError( - "Cannot extract a file path from a URI with a fragment component"); - } - return (windows ?? _isWindows) ? _toWindowsFilePath(this) : _toFilePath(); - } - - String _toFilePath() { - if (hasAuthority && host != "") { - throw UnsupportedError( - "Cannot extract a non-Windows file path from a file URI " - "with an authority"); - } - // Use path segments to have any escapes unescaped. - var pathSegments = this.pathSegments; - _checkNonWindowsPathReservedCharacters(pathSegments, false); - var result = StringBuffer(); - if (hasAbsolutePath) result.write("/"); - result.writeAll(pathSegments, "/"); - return result.toString(); - } - - static String _toWindowsFilePath(Uri uri) { - bool hasDriveLetter = false; - var segments = uri.pathSegments; - if (segments.length > 0 && - segments[0].length == 2 && - segments[0].codeUnitAt(1) == _COLON) { - _checkWindowsDriveLetter(segments[0].codeUnitAt(0), false); - _checkWindowsPathReservedCharacters(segments, false, 1); - hasDriveLetter = true; - } else { - _checkWindowsPathReservedCharacters(segments, false, 0); - } - var result = StringBuffer(); - if (uri.hasAbsolutePath && !hasDriveLetter) result.write(r"\"); - if (uri.hasAuthority) { - var host = uri.host; - if (host.isNotEmpty) { - result.write(r"\"); - result.write(host); - result.write(r"\"); - } - } - result.writeAll(segments, r"\"); - if (hasDriveLetter && segments.length == 1) result.write(r"\"); - return result.toString(); - } - - void _writeAuthority(StringSink ss) { - if (_userInfo.isNotEmpty) { - ss.write(_userInfo); - ss.write("@"); - } - if (_host != null) ss.write(_host); - if (_port != null) { - ss.write(":"); - ss.write(_port); - } - } - - /** - * Access the structure of a `data:` URI. - * - * Returns a [UriData] object for `data:` URIs and `null` for all other - * URIs. - * The [UriData] object can be used to access the media type and data - * of a `data:` URI. - */ - UriData? get data => (scheme == "data") ? UriData.fromUri(this) : null; - - String toString() => _text; - - String _initializeText() { - StringBuffer sb = StringBuffer(); - if (scheme.isNotEmpty) sb..write(scheme)..write(":"); - if (hasAuthority || (scheme == "file")) { - // File URIS always have the authority, even if it is empty. - // The empty URI means "localhost". - sb.write("//"); - _writeAuthority(sb); - } - sb.write(path); - if (_query != null) sb..write("?")..write(_query); - if (_fragment != null) sb..write("#")..write(_fragment); - return sb.toString(); - } - - bool operator ==(Object other) { - if (identical(this, other)) return true; - return other is Uri && - scheme == other.scheme && - hasAuthority == other.hasAuthority && - userInfo == other.userInfo && - host == other.host && - port == other.port && - path == other.path && - hasQuery == other.hasQuery && - query == other.query && - hasFragment == other.hasFragment && - fragment == other.fragment; - } - - static List _createList() => []; - - static Map> _splitQueryStringAll(String query, - {Encoding encoding = utf8}) { - var result = >{}; - int i = 0; - int start = 0; - int equalsIndex = -1; - - void parsePair(int start, int equalsIndex, int end) { - String key; - String value; - if (start == end) return; - if (equalsIndex < 0) { - key = _uriDecode(query, start, end, encoding, true); - value = ""; - } else { - key = _uriDecode(query, start, equalsIndex, encoding, true); - value = _uriDecode(query, equalsIndex + 1, end, encoding, true); - } - result.putIfAbsent(key, _createList).add(value); - } - - while (i < query.length) { - int char = query.codeUnitAt(i); - if (char == _EQUALS) { - if (equalsIndex < 0) equalsIndex = i; - } else if (char == _AMPERSAND) { - parsePair(start, equalsIndex, i); - start = i + 1; - equalsIndex = -1; - } - i++; - } - parsePair(start, equalsIndex, i); - return result; - } - - external static String _uriEncode(List canonicalTable, String text, - Encoding encoding, bool spaceToPlus); - - /** - * Convert a byte (2 character hex sequence) in string [s] starting - * at position [pos] to its ordinal value - */ - static int _hexCharPairToByte(String s, int pos) { - int byte = 0; - for (int i = 0; i < 2; i++) { - var charCode = s.codeUnitAt(pos + i); - if (0x30 <= charCode && charCode <= 0x39) { - byte = byte * 16 + charCode - 0x30; - } else { - // Check ranges A-F (0x41-0x46) and a-f (0x61-0x66). - charCode |= 0x20; - if (0x61 <= charCode && charCode <= 0x66) { - byte = byte * 16 + charCode - 0x57; - } else { - throw ArgumentError("Invalid URL encoding"); - } - } - } - return byte; - } - - /** - * Uri-decode a percent-encoded string. - * - * It unescapes the string [text] and returns the unescaped string. - * - * This function is similar to the JavaScript-function `decodeURI`. - * - * If [plusToSpace] is `true`, plus characters will be converted to spaces. - * - * The decoder will create a byte-list of the percent-encoded parts, and then - * decode the byte-list using [encoding]. The default encodings UTF-8. - */ - static String _uriDecode( - String text, int start, int end, Encoding encoding, bool plusToSpace) { - assert(0 <= start); - assert(start <= end); - assert(end <= text.length); - // First check whether there is any characters which need special handling. - bool simple = true; - for (int i = start; i < end; i++) { - var codeUnit = text.codeUnitAt(i); - if (codeUnit > 127 || - codeUnit == _PERCENT || - (plusToSpace && codeUnit == _PLUS)) { - simple = false; - break; - } - } - List bytes; - if (simple) { - if (utf8 == encoding || latin1 == encoding || ascii == encoding) { - return text.substring(start, end); - } else { - bytes = text.substring(start, end).codeUnits; - } - } else { - bytes = []; - for (int i = start; i < end; i++) { - var codeUnit = text.codeUnitAt(i); - if (codeUnit > 127) { - throw ArgumentError("Illegal percent encoding in URI"); - } - if (codeUnit == _PERCENT) { - if (i + 3 > text.length) { - throw ArgumentError('Truncated URI'); - } - bytes.add(_hexCharPairToByte(text, i + 1)); - i += 2; - } else if (plusToSpace && codeUnit == _PLUS) { - bytes.add(_SPACE); - } else { - bytes.add(codeUnit); - } - } - } - return encoding.decode(bytes); - } - - static bool _isAlphabeticCharacter(int codeUnit) { - var lowerCase = codeUnit | 0x20; - return (_LOWER_CASE_A <= lowerCase && lowerCase <= _LOWER_CASE_Z); - } - - static bool _isUnreservedChar(int char) { - return char < 127 && - ((_unreservedTable[char >> 4] & (1 << (char & 0x0f))) != 0); - } - - // Tables of char-codes organized as a bit vector of 128 bits where - // each bit indicate whether a character code on the 0-127 needs to - // be escaped or not. - - // The unreserved characters of RFC 3986. - static const _unreservedTable = [ - // LSB MSB - // | | - 0x0000, // 0x00 - 0x0f 0000000000000000 - 0x0000, // 0x10 - 0x1f 0000000000000000 - // -. - 0x6000, // 0x20 - 0x2f 0000000000000110 - // 0123456789 - 0x03ff, // 0x30 - 0x3f 1111111111000000 - // ABCDEFGHIJKLMNO - 0xfffe, // 0x40 - 0x4f 0111111111111111 - // PQRSTUVWXYZ _ - 0x87ff, // 0x50 - 0x5f 1111111111100001 - // abcdefghijklmno - 0xfffe, // 0x60 - 0x6f 0111111111111111 - // pqrstuvwxyz ~ - 0x47ff, // 0x70 - 0x7f 1111111111100010 - ]; - - // The unreserved characters of RFC 2396. - static const _unreserved2396Table = [ - // LSB MSB - // | | - 0x0000, // 0x00 - 0x0f 0000000000000000 - 0x0000, // 0x10 - 0x1f 0000000000000000 - // ! '()* -. - 0x6782, // 0x20 - 0x2f 0100000111100110 - // 0123456789 - 0x03ff, // 0x30 - 0x3f 1111111111000000 - // ABCDEFGHIJKLMNO - 0xfffe, // 0x40 - 0x4f 0111111111111111 - // PQRSTUVWXYZ _ - 0x87ff, // 0x50 - 0x5f 1111111111100001 - // abcdefghijklmno - 0xfffe, // 0x60 - 0x6f 0111111111111111 - // pqrstuvwxyz ~ - 0x47ff, // 0x70 - 0x7f 1111111111100010 - ]; - - // Table of reserved characters specified by ECMAScript 5. - static const _encodeFullTable = [ - // LSB MSB - // | | - 0x0000, // 0x00 - 0x0f 0000000000000000 - 0x0000, // 0x10 - 0x1f 0000000000000000 - // ! #$ &'()*+,-./ - 0xffda, // 0x20 - 0x2f 0101101111111111 - // 0123456789:; = ? - 0xafff, // 0x30 - 0x3f 1111111111110101 - // @ABCDEFGHIJKLMNO - 0xffff, // 0x40 - 0x4f 1111111111111111 - // PQRSTUVWXYZ _ - 0x87ff, // 0x50 - 0x5f 1111111111100001 - // abcdefghijklmno - 0xfffe, // 0x60 - 0x6f 0111111111111111 - // pqrstuvwxyz ~ - 0x47ff, // 0x70 - 0x7f 1111111111100010 - ]; - - // Characters allowed in the scheme. - static const _schemeTable = [ - // LSB MSB - // | | - 0x0000, // 0x00 - 0x0f 0000000000000000 - 0x0000, // 0x10 - 0x1f 0000000000000000 - // + -. - 0x6800, // 0x20 - 0x2f 0000000000010110 - // 0123456789 - 0x03ff, // 0x30 - 0x3f 1111111111000000 - // ABCDEFGHIJKLMNO - 0xfffe, // 0x40 - 0x4f 0111111111111111 - // PQRSTUVWXYZ - 0x07ff, // 0x50 - 0x5f 1111111111100001 - // abcdefghijklmno - 0xfffe, // 0x60 - 0x6f 0111111111111111 - // pqrstuvwxyz - 0x07ff, // 0x70 - 0x7f 1111111111100010 - ]; - - // General delimiter characters, RFC 3986 section 2.2. - // gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" - // - static const _genDelimitersTable = [ - // LSB MSB - // | | - 0x0000, // 0x00 - 0x0f 0000000000000000 - 0x0000, // 0x10 - 0x1f 0000000000000000 - // # / - 0x8008, // 0x20 - 0x2f 0001000000000001 - // : ? - 0x8400, // 0x30 - 0x3f 0000000000100001 - // @ - 0x0001, // 0x40 - 0x4f 1000000000000000 - // [ ] - 0x2800, // 0x50 - 0x5f 0000000000010100 - // - 0x0000, // 0x60 - 0x6f 0000000000000000 - // - 0x0000, // 0x70 - 0x7f 0000000000000000 - ]; - - // Characters allowed in the userinfo as of RFC 3986. - // RFC 3986 Appendix A - // userinfo = *( unreserved / pct-encoded / sub-delims / ':') - static const _userinfoTable = [ - // LSB MSB - // | | - 0x0000, // 0x00 - 0x0f 0000000000000000 - 0x0000, // 0x10 - 0x1f 0000000000000000 - // ! $ &'()*+,-. - 0x7fd2, // 0x20 - 0x2f 0100101111111110 - // 0123456789:; = - 0x2fff, // 0x30 - 0x3f 1111111111110100 - // ABCDEFGHIJKLMNO - 0xfffe, // 0x40 - 0x4f 0111111111111111 - // PQRSTUVWXYZ _ - 0x87ff, // 0x50 - 0x5f 1111111111100001 - // abcdefghijklmno - 0xfffe, // 0x60 - 0x6f 0111111111111111 - // pqrstuvwxyz ~ - 0x47ff, // 0x70 - 0x7f 1111111111100010 - ]; - - // Characters allowed in the reg-name as of RFC 3986. - // RFC 3986 Appendix A - // reg-name = *( unreserved / pct-encoded / sub-delims ) - static const _regNameTable = [ - // LSB MSB - // | | - 0x0000, // 0x00 - 0x0f 0000000000000000 - 0x0000, // 0x10 - 0x1f 0000000000000000 - // ! $%&'()*+,-. - 0x7ff2, // 0x20 - 0x2f 0100111111111110 - // 0123456789 ; = - 0x2bff, // 0x30 - 0x3f 1111111111010100 - // ABCDEFGHIJKLMNO - 0xfffe, // 0x40 - 0x4f 0111111111111111 - // PQRSTUVWXYZ _ - 0x87ff, // 0x50 - 0x5f 1111111111100001 - // abcdefghijklmno - 0xfffe, // 0x60 - 0x6f 0111111111111111 - // pqrstuvwxyz ~ - 0x47ff, // 0x70 - 0x7f 1111111111100010 - ]; - - // Characters allowed in the path as of RFC 3986. - // RFC 3986 section 3.3. - // pchar = unreserved / pct-encoded / sub-delims / ":" / "@" - static const _pathCharTable = [ - // LSB MSB - // | | - 0x0000, // 0x00 - 0x0f 0000000000000000 - 0x0000, // 0x10 - 0x1f 0000000000000000 - // ! $ &'()*+,-. - 0x7fd2, // 0x20 - 0x2f 0100101111111110 - // 0123456789:; = - 0x2fff, // 0x30 - 0x3f 1111111111110100 - // @ABCDEFGHIJKLMNO - 0xffff, // 0x40 - 0x4f 1111111111111111 - // PQRSTUVWXYZ _ - 0x87ff, // 0x50 - 0x5f 1111111111100001 - // abcdefghijklmno - 0xfffe, // 0x60 - 0x6f 0111111111111111 - // pqrstuvwxyz ~ - 0x47ff, // 0x70 - 0x7f 1111111111100010 - ]; - - // Characters allowed in the path as of RFC 3986. - // RFC 3986 section 3.3 *and* slash. - static const _pathCharOrSlashTable = [ - // LSB MSB - // | | - 0x0000, // 0x00 - 0x0f 0000000000000000 - 0x0000, // 0x10 - 0x1f 0000000000000000 - // ! $ &'()*+,-./ - 0xffd2, // 0x20 - 0x2f 0100101111111111 - // 0123456789:; = - 0x2fff, // 0x30 - 0x3f 1111111111110100 - // @ABCDEFGHIJKLMNO - 0xffff, // 0x40 - 0x4f 1111111111111111 - - // PQRSTUVWXYZ _ - 0x87ff, // 0x50 - 0x5f 1111111111100001 - // abcdefghijklmno - 0xfffe, // 0x60 - 0x6f 0111111111111111 - // pqrstuvwxyz ~ - 0x47ff, // 0x70 - 0x7f 1111111111100010 - ]; - - // Characters allowed in the query as of RFC 3986. - // RFC 3986 section 3.4. - // query = *( pchar / "/" / "?" ) - static const _queryCharTable = [ - // LSB MSB - // | | - 0x0000, // 0x00 - 0x0f 0000000000000000 - 0x0000, // 0x10 - 0x1f 0000000000000000 - // ! $ &'()*+,-./ - 0xffd2, // 0x20 - 0x2f 0100101111111111 - // 0123456789:; = ? - 0xafff, // 0x30 - 0x3f 1111111111110101 - // @ABCDEFGHIJKLMNO - 0xffff, // 0x40 - 0x4f 1111111111111111 - // PQRSTUVWXYZ _ - 0x87ff, // 0x50 - 0x5f 1111111111100001 - // abcdefghijklmno - 0xfffe, // 0x60 - 0x6f 0111111111111111 - // pqrstuvwxyz ~ - 0x47ff, // 0x70 - 0x7f 1111111111100010 - ]; - - // Characters allowed in the ZoneID as of RFC 6874. - // ZoneID = 1*( unreserved / pct-encoded ) - static const _zoneIDTable = [ - // LSB MSB - // | | - 0x0000, // 0x00 - 0x0f 0000000000000000 - 0x0000, // 0x10 - 0x1f 0000000000000000 - // ! $%&'()*+,-. - 0x6000, // 0x20 - 0x2f 0000000000000110 - // 0123456789 ; = - 0x03ff, // 0x30 - 0x3f 1111111111000000 - // ABCDEFGHIJKLMNO - 0xfffe, // 0x40 - 0x4f 0111111111111111 - // PQRSTUVWXYZ _ - 0x87ff, // 0x50 - 0x5f 1111111111100001 - // abcdefghijklmno - 0xfffe, // 0x60 - 0x6f 0111111111111111 - // pqrstuvwxyz ~ - 0x47ff, // 0x70 - 0x7f 1111111111100010 - ]; -} - -// -------------------------------------------------------------------- -// Data URI -// -------------------------------------------------------------------- - -/** - * A way to access the structure of a `data:` URI. - * - * Data URIs are non-hierarchical URIs that can contain any binary data. - * They are defined by [RFC 2397](https://tools.ietf.org/html/rfc2397). - * - * This class allows parsing the URI text and extracting individual parts of the - * URI, as well as building the URI text from structured parts. - */ -class UriData { - static const int _noScheme = -1; - /** - * Contains the text content of a `data:` URI, with or without a - * leading `data:`. - * - * If [_separatorIndices] starts with `4` (the index of the `:`), then - * there is a leading `data:`, otherwise [_separatorIndices] starts with - * `-1`. - */ - final String _text; - - /** - * List of the separators (';', '=' and ',') in the text. - * - * Starts with the index of the `:` in `data:` of the mimeType. - * That is always either -1 or 4, depending on whether `_text` includes the - * `data:` scheme or not. - * - * The first speparator ends the mime type. We don't bother with finding - * the '/' inside the mime type. - * - * Each two separators after that marks a parameter key and value. - * - * If there is a single separator left, it ends the "base64" marker. - * - * So the following separators are found for a text: - * ``` - * data:text/plain;foo=bar;base64,ARGLEBARGLE= - * ^ ^ ^ ^ ^ - * ``` - */ - final List _separatorIndices; - - /** - * Cache of the result returned by [uri]. - */ - Uri? _uriCache; - - UriData._(this._text, this._separatorIndices, this._uriCache); - - // Avoid shadowing by argument. - static const Base64Codec _base64 = base64; - - /** - * Creates a `data:` URI containing the [content] string. - * - * Equivalent to `new Uri.dataFromString(...).data`, but may - * be more efficient if the [uri] itself isn't used. - */ - factory UriData.fromString(String content, - {String? mimeType, - Encoding? encoding, - Map? parameters, - bool base64 = false}) { - StringBuffer buffer = StringBuffer(); - List indices = [_noScheme]; - String? charsetName = parameters?.["charset"]; - String? encodingName; - if (encoding == null) { - if (charsetName != null) { - encoding = Encoding.getByName(charsetName); - } - } else if (charsetName == null) { - // Non-null only if parameters does not contain "charset". - encodingName = encoding.name; - } - encoding ??= ascii; - _writeUri(mimeType, encodingName, parameters, buffer, indices); - indices.add(buffer.length); - if (base64) { - buffer.write(';base64,'); - indices.add(buffer.length - 1); - buffer.write(encoding.fuse(_base64).encode(content)); - } else { - buffer.write(','); - _uriEncodeBytes(_uricTable, encoding.encode(content), buffer); - } - return UriData._(buffer.toString(), indices, null); - } - - /** - * Creates a `data:` URI containing an encoding of [bytes]. - * - * Equivalent to `new Uri.dataFromBytes(...).data`, but may - * be more efficient if the [uri] itself isn't used. - */ - factory UriData.fromBytes(List bytes, - {String mimeType = "application/octet-stream", - Map? parameters, - bool percentEncoded = false}) { - StringBuffer buffer = StringBuffer(); - List indices = [_noScheme]; - _writeUri(mimeType, null, parameters, buffer, indices); - indices.add(buffer.length); - if (percentEncoded) { - buffer.write(','); - _uriEncodeBytes(_uricTable, bytes, buffer); - } else { - buffer.write(';base64,'); - indices.add(buffer.length - 1); - _base64.encoder - .startChunkedConversion(StringConversionSink.fromStringSink(buffer)) - .addSlice(bytes, 0, bytes.length, true); - } - - return UriData._(buffer.toString(), indices, null); - } - - /** - * Creates a `DataUri` from a [Uri] which must have `data` as [Uri.scheme]. - * - * The [uri] must have scheme `data` and no authority or fragment, - * and the path (concatenated with the query, if there is one) must be valid - * as data URI content with the same rules as [parse]. - */ - factory UriData.fromUri(Uri uri) { - if (uri.scheme != "data") { - throw ArgumentError.value(uri, "uri", "Scheme must be 'data'"); - } - if (uri.hasAuthority) { - throw ArgumentError.value(uri, "uri", "Data uri must not have authority"); - } - if (uri.hasFragment) { - throw ArgumentError.value( - uri, "uri", "Data uri must not have a fragment part"); - } - if (!uri.hasQuery) { - return _parse(uri.path, 0, uri); - } - // Includes path and query (and leading "data:"). - return _parse(uri.toString(), 5, uri); - } - - /** - * Writes the initial part of a `data:` uri, from after the "data:" - * until just before the ',' before the data, or before a `;base64,` - * marker. - * - * Of an [indices] list is passed, separator indices are stored in that - * list. - */ - static void _writeUri( - String? mimeType, - String? charsetName, - Map? parameters, - StringBuffer buffer, - List? indices) { - if (mimeType == null || mimeType == "text/plain") { - mimeType = ""; - } - - if (mimeType.isEmpty || identical(mimeType, "application/octet-stream")) { - buffer.write(mimeType); // Common cases need no escaping. - } else { - int slashIndex = _validateMimeType(mimeType); - if (slashIndex < 0) { - throw ArgumentError.value(mimeType, "mimeType", "Invalid MIME type"); - } - buffer.write(_Uri._uriEncode( - _tokenCharTable, mimeType.substring(0, slashIndex), utf8, false)); - buffer.write("/"); - buffer.write(_Uri._uriEncode( - _tokenCharTable, mimeType.substring(slashIndex + 1), utf8, false)); - } - if (charsetName != null) { - // TODO(39209): Use ?.. when sequences are properly supported. - if (indices != null) indices..add(buffer.length)..add(buffer.length + 8); - buffer.write(";charset="); - buffer.write(_Uri._uriEncode(_tokenCharTable, charsetName, utf8, false)); - } - parameters?.forEach((key, value) { - if (key.isEmpty) { - throw ArgumentError.value("", "Parameter names must not be empty"); - } - if (value.isEmpty) { - throw ArgumentError.value( - "", "Parameter values must not be empty", 'parameters["$key"]'); - } - indices?.add(buffer.length); - buffer.write(';'); - // Encode any non-RFC2045-token character and both '%' and '#'. - buffer.write(_Uri._uriEncode(_tokenCharTable, key, utf8, false)); - indices?.add(buffer.length); - buffer.write('='); - buffer.write(_Uri._uriEncode(_tokenCharTable, value, utf8, false)); - }); - } - - /** - * Checks mimeType is valid-ish (`token '/' token`). - * - * Returns the index of the slash, or -1 if the mime type is not - * considered valid. - * - * Currently only looks for slashes, all other characters will be - * percent-encoded as UTF-8 if necessary. - */ - static int _validateMimeType(String mimeType) { - int slashIndex = -1; - for (int i = 0; i < mimeType.length; i++) { - var char = mimeType.codeUnitAt(i); - if (char != _SLASH) continue; - if (slashIndex < 0) { - slashIndex = i; - continue; - } - return -1; - } - return slashIndex; - } - - /** - * Parses a string as a `data` URI. - * - * The string must have the format: - * - * ``` - * 'data:' (type '/' subtype)? (';' attribute '=' value)* (';base64')? ',' data - * ```` - * - * where `type`, `subtype`, `attribute` and `value` are specified in RFC-2045, - * and `data` is a sequence of URI-characters (RFC-2396 `uric`). - * - * This means that all the characters must be ASCII, but the URI may contain - * percent-escapes for non-ASCII byte values that need an interpretation - * to be converted to the corresponding string. - * - * Parsing checks that Base64 encoded data is valid, and it normalizes it - * to use the default Base64 alphabet and to use padding. - * Non-Base64 data is escaped using percent-escapes as necessary to make - * it valid, and existing escapes are case normalized. - * - * Accessing the individual parts may fail later if they turn out to have - * content that can't be decoded successfully as a string, for example if - * existing percent escapes represent bytes that cannot be decoded - * by the chosen [Encoding] (see [contentAsString]). - * - * A [FormatException] is thrown if [uri] is not a valid data URI. - */ - static UriData parse(String uri) { - if (uri.length >= 5) { - int dataDelta = _startsWithData(uri, 0); - if (dataDelta == 0) { - // Exact match on "data:". - return _parse(uri, 5, null); - } - if (dataDelta == 0x20) { - // Starts with a non-normalized "data" scheme containing upper-case - // letters. Parse anyway, but throw away the scheme. - return _parse(uri.substring(5), 0, null); - } - } - throw FormatException("Does not start with 'data:'", uri, 0); - } - - /** - * The [Uri] that this `UriData` is giving access to. - * - * Returns a `Uri` with scheme `data` and the remainder of the data URI - * as path. - */ - Uri get uri { - return _uriCache ??= _computeUri(); - } - - Uri _computeUri() { - String path = _text; - String? query; - int colonIndex = _separatorIndices[0]; - int queryIndex = _text.indexOf('?', colonIndex + 1); - int end = _text.length; - if (queryIndex >= 0) { - query = _Uri._normalizeOrSubstring( - _text, queryIndex + 1, end, _Uri._queryCharTable); - end = queryIndex; - } - path = _Uri._normalizeOrSubstring( - _text, colonIndex + 1, end, _Uri._pathCharOrSlashTable); - return _DataUri(this, path, query); - } - - /** - * The MIME type of the data URI. - * - * A data URI consists of a "media type" followed by data. - * The media type starts with a MIME type and can be followed by - * extra parameters. - * If the MIME type representation in the URI text contains URI escapes, - * they are unescaped in the returned string. - * If the value contain non-ASCII percent escapes, they are decoded as UTF-8. - * - * Example: - * - * data:text/plain;charset=utf-8,Hello%20World! - * - * This data URI has the media type `text/plain;charset=utf-8`, which is the - * MIME type `text/plain` with the parameter `charset` with value `utf-8`. - * See [RFC 2045](https://tools.ietf.org/html/rfc2045) for more detail. - * - * If the first part of the data URI is empty, it defaults to `text/plain`. - */ - String get mimeType { - int start = _separatorIndices[0] + 1; - int end = _separatorIndices[1]; - if (start == end) return "text/plain"; - return _Uri._uriDecode(_text, start, end, utf8, false); - } - - /** - * The charset parameter of the media type. - * - * If the parameters of the media type contains a `charset` parameter - * then this returns its value, otherwise it returns `US-ASCII`, - * which is the default charset for data URIs. - * If the value contain non-ASCII percent escapes, they are decoded as UTF-8. - * - * If the MIME type representation in the URI text contains URI escapes, - * they are unescaped in the returned string. - */ - String get charset { - int parameterStart = 1; - int parameterEnd = _separatorIndices.length - 1; // The ',' before data. - if (isBase64) { - // There is a ";base64" separator, so subtract one for that as well. - parameterEnd -= 1; - } - for (int i = parameterStart; i < parameterEnd; i += 2) { - var keyStart = _separatorIndices[i] + 1; - var keyEnd = _separatorIndices[i + 1]; - if (keyEnd == keyStart + 7 && _text.startsWith("charset", keyStart)) { - return _Uri._uriDecode( - _text, keyEnd + 1, _separatorIndices[i + 2], utf8, false); - } - } - return "US-ASCII"; - } - - /** - * Whether the data is Base64 encoded or not. - */ - bool get isBase64 => _separatorIndices.length.isOdd; - - /** - * The content part of the data URI, as its actual representation. - * - * This string may contain percent escapes. - */ - String get contentText => _text.substring(_separatorIndices.last + 1); - - /** - * The content part of the data URI as bytes. - * - * If the data is Base64 encoded, it will be decoded to bytes. - * - * If the data is not Base64 encoded, it will be decoded by unescaping - * percent-escaped characters and returning byte values of each unescaped - * character. The bytes will not be, e.g., UTF-8 decoded. - */ - Uint8List contentAsBytes() { - String text = _text; - int start = _separatorIndices.last + 1; - if (isBase64) { - return base64.decoder.convert(text, start); - } - - // Not base64, do percent-decoding and return the remaining bytes. - // Compute result size. - const int percent = 0x25; - int length = text.length - start; - for (int i = start; i < text.length; i++) { - var codeUnit = text.codeUnitAt(i); - if (codeUnit == percent) { - i += 2; - length -= 2; - } - } - // Fill result array. - Uint8List result = Uint8List(length); - if (length == text.length) { - result.setRange(0, length, text.codeUnits, start); - return result; - } - int index = 0; - for (int i = start; i < text.length; i++) { - var codeUnit = text.codeUnitAt(i); - if (codeUnit != percent) { - result[index++] = codeUnit; - } else { - if (i + 2 < text.length) { - int byte = parseHexByte(text, i + 1); - if (byte >= 0) { - result[index++] = byte; - i += 2; - continue; - } - } - throw FormatException("Invalid percent escape", text, i); - } - } - assert(index == result.length); - return result; - } - - /** - * Returns a string created from the content of the data URI. - * - * If the content is Base64 encoded, it will be decoded to bytes and then - * decoded to a string using [encoding]. - * If encoding is omitted, the value of a `charset` parameter is used - * if it is recognized by [Encoding.getByName], otherwise it defaults to - * the [ascii] encoding, which is the default encoding for data URIs - * that do not specify an encoding. - * - * If the content is not Base64 encoded, it will first have percent-escapes - * converted to bytes and then the character codes and byte values are - * decoded using [encoding]. - */ - String contentAsString({Encoding? encoding}) { - if (encoding == null) { - var charset = this.charset; // Returns "US-ASCII" if not present. - encoding = Encoding.getByName(charset); - if (encoding == null) { - throw UnsupportedError("Unknown charset: $charset"); - } - } - String text = _text; - int start = _separatorIndices.last + 1; - if (isBase64) { - var converter = base64.decoder.fuse(encoding.decoder); - return converter.convert(text.substring(start)); - } - return _Uri._uriDecode(text, start, text.length, encoding, false); - } - - /** - * A map representing the parameters of the media type. - * - * A data URI may contain parameters between the MIME type and the - * data. This converts these parameters to a map from parameter name - * to parameter value. - * The map only contains parameters that actually occur in the URI. - * The `charset` parameter has a default value even if it doesn't occur - * in the URI, which is reflected by the [charset] getter. This means that - * [charset] may return a value even if `parameters["charset"]` is `null`. - * - * If the values contain non-ASCII values or percent escapes, - * they are decoded as UTF-8. - */ - Map get parameters { - var result = {}; - for (int i = 3; i < _separatorIndices.length; i += 2) { - var start = _separatorIndices[i - 2] + 1; - var equals = _separatorIndices[i - 1]; - var end = _separatorIndices[i]; - String key = _Uri._uriDecode(_text, start, equals, utf8, false); - String value = _Uri._uriDecode(_text, equals + 1, end, utf8, false); - result[key] = value; - } - return result; - } - - static UriData _parse(String text, int start, Uri? sourceUri) { - assert(start == 0 || start == 5); - assert((start == 5) == text.startsWith("data:")); - - /// Character codes. - const int comma = 0x2c; - const int slash = 0x2f; - const int semicolon = 0x3b; - const int equals = 0x3d; - List indices = [start - 1]; - int slashIndex = -1; - var char; - int i = start; - for (; i < text.length; i++) { - char = text.codeUnitAt(i); - if (char == comma || char == semicolon) break; - if (char == slash) { - if (slashIndex < 0) { - slashIndex = i; - continue; - } - throw FormatException("Invalid MIME type", text, i); - } - } - if (slashIndex < 0 && i > start) { - // An empty MIME type is allowed, but if non-empty it must contain - // exactly one slash. - throw FormatException("Invalid MIME type", text, i); - } - while (char != comma) { - // Parse parameters and/or "base64". - indices.add(i); - i++; - int equalsIndex = -1; - for (; i < text.length; i++) { - char = text.codeUnitAt(i); - if (char == equals) { - if (equalsIndex < 0) equalsIndex = i; - } else if (char == semicolon || char == comma) { - break; - } - } - if (equalsIndex >= 0) { - indices.add(equalsIndex); - } else { - // Have to be final "base64". - var lastSeparator = indices.last; - if (char != comma || - i != lastSeparator + 7 /* "base64,".length */ || - !text.startsWith("base64", lastSeparator + 1)) { - throw FormatException("Expecting '='", text, i); - } - break; - } - } - indices.add(i); - bool isBase64 = indices.length.isOdd; - if (isBase64) { - text = base64.normalize(text, i + 1, text.length); - } else { - // Validate "data" part, must only contain RFC 2396 'uric' characters - // (reserved, unreserved, or escape sequences). - // Normalize to this (throws on a fragment separator). - var data = _Uri._normalize(text, i + 1, text.length, _uricTable, - escapeDelimiters: true); - if (data != null) { - text = text.replaceRange(i + 1, text.length, data); - } - } - return UriData._(text, indices, sourceUri); - } - - /** - * Like [Uri._uriEncode] but takes the input as bytes, not a string. - * - * Encodes into [buffer] instead of creating its own buffer. - */ - static void _uriEncodeBytes( - List canonicalTable, List bytes, StringSink buffer) { - // Encode the string into bytes then generate an ASCII only string - // by percent encoding selected bytes. - int byteOr = 0; - for (int i = 0; i < bytes.length; i++) { - int byte = bytes[i]; - byteOr |= byte; - if (byte < 128 && - ((canonicalTable[byte >> 4] & (1 << (byte & 0x0f))) != 0)) { - buffer.writeCharCode(byte); - } else { - buffer.writeCharCode(_PERCENT); - buffer.writeCharCode(_hexDigits.codeUnitAt(byte >> 4)); - buffer.writeCharCode(_hexDigits.codeUnitAt(byte & 0x0f)); - } - } - if ((byteOr & ~0xFF) != 0) { - for (int i = 0; i < bytes.length; i++) { - var byte = bytes[i]; - if (byte < 0 || byte > 255) { - throw ArgumentError.value(byte, "non-byte value"); - } - } - } - } - - String toString() => - (_separatorIndices[0] == _noScheme) ? "data:$_text" : _text; - - // Table of the `token` characters of RFC 2045 in a URI. - // - // A token is any US-ASCII character except SPACE, control characters and - // `tspecial` characters. The `tspecial` category is: - // '(', ')', '<', '>', '@', ',', ';', ':', '\', '"', '/', '[, ']', '?', '='. - // - // In a data URI, we also need to escape '%' and '#' characters. - static const _tokenCharTable = [ - // LSB MSB - // | | - 0x0000, // 0x00 - 0x0f 00000000 00000000 - 0x0000, // 0x10 - 0x1f 00000000 00000000 - // ! $ &' *+ -. - 0x6cd2, // 0x20 - 0x2f 01001011 00110110 - // 01234567 89 - 0x03ff, // 0x30 - 0x3f 11111111 11000000 - // ABCDEFG HIJKLMNO - 0xfffe, // 0x40 - 0x4f 01111111 11111111 - // PQRSTUVW XYZ ^_ - 0xc7ff, // 0x50 - 0x5f 11111111 11100011 - // `abcdefg hijklmno - 0xffff, // 0x60 - 0x6f 11111111 11111111 - // pqrstuvw xyz{|}~ - 0x7fff, // 0x70 - 0x7f 11111111 11111110 - ]; - - // All non-escape RFC-2396 uric characters. - // - // uric = reserved | unreserved | escaped - // reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | "," - // unreserved = alphanum | mark - // mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")" - // - // This is the same characters as in a URI query (which is URI pchar plus '?') - static const _uricTable = _Uri._queryCharTable; -} - -// -------------------------------------------------------------------- -// Constants used to read the scanner result. -// The indices points into the table filled by [_scan] which contains -// recognized positions in the scanned URI. -// The `0` index is only used internally. - -/// Index of the position of that `:` after a scheme. -const int _schemeEndIndex = 1; - -/// Index of the position of the character just before the host name. -const int _hostStartIndex = 2; - -/// Index of the position of the `:` before a port value. -const int _portStartIndex = 3; - -/// Index of the position of the first character of a path. -const int _pathStartIndex = 4; - -/// Index of the position of the `?` before a query. -const int _queryStartIndex = 5; - -/// Index of the position of the `#` before a fragment. -const int _fragmentStartIndex = 6; - -/// Index of a position where the URI was determined to be "non-simple". -const int _notSimpleIndex = 7; - -// Initial state for scanner. -const int _uriStart = 00; - -// If scanning of a URI terminates in this state or above, -// consider the URI non-simple -const int _nonSimpleEndStates = 14; - -// Initial state for scheme validation. -const int _schemeStart = 20; - -/// Transition tables used to scan a URI to determine its structure. -/// -/// The tables represent a state machine with output. -/// -/// To scan the URI, start in the [_uriStart] state, then read each character -/// of the URI in order, from start to end, and for each character perform a -/// transition to a new state while writing the current position into the output -/// buffer at a designated index. -/// -/// Each state, represented by an integer which is an index into -/// [_scannerTables], has a set of transitions, one for each character. -/// The transitions are encoded as a 5-bit integer representing the next state -/// and a 3-bit index into the output table. -/// -/// For URI scanning, only characters in the range U+0020 through U+007E are -/// interesting, all characters outside that range are treated the same. -/// The tables only contain 96 entries, representing that characters in the -/// interesting range, plus one more to represent all values outside the range. -/// The character entries are stored in one `Uint8List` per state, with the -/// transition for a character at position `character ^ 0x60`, -/// which maps the range U+0020 .. U+007F into positions 0 .. 95. -/// All remaining characters are mapped to position 31 (`0x7f ^ 0x60`) which -/// represents the transition for all remaining characters. -final List _scannerTables = _createTables(); - -// ---------------------------------------------------------------------- -// Code to create the URI scanner table. - -/// Creates the tables for [_scannerTables] used by [Uri.parse]. -/// -/// See [_scannerTables] for the generated format. -/// -/// The concrete tables are chosen as a trade-off between the number of states -/// needed and the precision of the result. -/// This allows definitely recognizing the general structure of the URI -/// (presence and location of scheme, user-info, host, port, path, query and -/// fragment) while at the same time detecting that some components are not -/// in canonical form (anything containing a `%`, a host-name containing a -/// capital letter). Since the scanner doesn't know whether something is a -/// scheme or a path until it sees `:`, or user-info or host until it sees -/// a `@`, a second pass is needed to validate the scheme and any user-info -/// is considered non-canonical by default. -/// -/// The states (starting from [_uriStart]) write positions while scanning -/// a string from `start` to `end` as follows: -/// -/// - [_schemeEndIndex]: Should be initialized to `start-1`. -/// If the URI has a scheme, it is set to the position of the `:` after -/// the scheme. -/// - [_hostStartIndex]: Should be initialized to `start - 1`. -/// If the URI has an authority, it is set to the character before the -/// host name - either the second `/` in the `//` leading the authority, -/// or the `@` after a user-info. Comparing this value to the scheme end -/// position can be used to detect that there is a user-info component. -/// - [_portStartIndex]: Should be initialized to `start`. -/// Set to the position of the last `:` in an authority, and unchanged -/// if there is no authority or no `:` in an authority. -/// If this position is after the host start, there is a port, otherwise it -/// is just marking a colon in the user-info component. -/// - [_pathStartIndex]: Should be initialized to `start`. -/// Is set to the first path character unless the path is empty. -/// If the path is empty, the position is either unchanged (`start`) or -/// the first slash of an authority. So, if the path start is before a -/// host start or scheme end, the path is empty. -/// - [_queryStartIndex]: Should be initialized to `end`. -/// The position of the `?` leading a query if the URI contains a query. -/// - [_fragmentStartIndex]: Should be initialized to `end`. -/// The position of the `#` leading a fragment if the URI contains a fragment. -/// - [_notSimpleIndex]: Should be initialized to `start - 1`. -/// Set to another value if the URI is considered "not simple". -/// This is elaborated below. -/// -/// # Simple URIs -/// A URI is considered "simple" if it is in a normalized form containing no -/// escapes. This allows us to skip normalization and checking whether escapes -/// are valid, and to extract components without worrying about unescaping. -/// -/// The scanner computes a conservative approximation of being "simple". -/// It rejects any URI with an escape, with a user-info component (mainly -/// because they are rare and would increase the number of states in the -/// scanner significantly), with an IPV6 host or with a capital letter in -/// the scheme or host name (the scheme is handled in a second scan using -/// a separate two-state table). -/// Further, paths containing `..` or `.` path segments are considered -/// non-simple except for pure relative paths (no scheme or authority) starting -/// with a sequence of "../" segments. -/// -/// The transition tables cannot detect a trailing ".." in the path, -/// followed by a query or fragment, because the segment is not known to be -/// complete until we are past it, and we then need to store the query/fragment -/// start instead. This cast is checked manually post-scanning (such a path -/// needs to be normalized to end in "../", so the URI shouldn't be considered -/// simple). -List _createTables() { - // TODO(lrn): Use a precomputed table. - - // Total number of states for the scanner. - const int stateCount = 22; - - // States used to scan a URI from scratch. - const int schemeOrPath = 01; - const int authOrPath = 02; - const int authOrPathSlash = 03; - const int uinfoOrHost0 = 04; - const int uinfoOrHost = 05; - const int uinfoOrPort0 = 06; - const int uinfoOrPort = 07; - const int ipv6Host = 08; - const int relPathSeg = 09; - const int pathSeg = 10; - const int path = 11; - const int query = 12; - const int fragment = 13; - const int schemeOrPathDot = 14; - const int schemeOrPathDot2 = 15; - const int relPathSegDot = 16; - const int relPathSegDot2 = 17; - const int pathSegDot = 18; - const int pathSegDot2 = 19; - - // States used to validate a scheme after its end position has been found. - const int scheme0 = _schemeStart; - const int scheme = 21; - - // Constants encoding the write-index for the state transition into the top 5 - // bits of a byte. - const int schemeEnd = _schemeEndIndex << 5; - const int hostStart = _hostStartIndex << 5; - const int portStart = _portStartIndex << 5; - const int pathStart = _pathStartIndex << 5; - const int queryStart = _queryStartIndex << 5; - const int fragmentStart = _fragmentStartIndex << 5; - const int notSimple = _notSimpleIndex << 5; - - /// The `unreserved` characters of RFC 3986. - const unreserved = - "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-._~"; - - /// The `sub-delim` characters of RFC 3986. - const subDelims = r"!$&'()*+,;="; - // The `pchar` characters of RFC 3986: characters that may occur in a path, - // excluding escapes. - const pchar = "$unreserved$subDelims"; - - var tables = List.generate(stateCount, (_) => Uint8List(96)); - - // Helper function which initialize the table for [state] with a default - // transition and returns the table. - Uint8List build(state, defaultTransition) => - tables[state]..fillRange(0, 96, defaultTransition); - - // Helper function which sets the transition for each character in [chars] - // to [transition] in the [target] table. - // The [chars] string must contain only characters in the U+0020 .. U+007E - // range. - void setChars(Uint8List target, String chars, int transition) { - for (int i = 0; i < chars.length; i++) { - var char = chars.codeUnitAt(i); - target[char ^ 0x60] = transition; - } - } - - /// Helper function which sets the transition for all characters in the - /// range from `range[0]` to `range[1]` to [transition] in the [target] table. - /// - /// The [range] must be a two-character string where both characters are in - /// the U+0020 .. U+007E range and the former character must have a lower - /// code point than the latter. - void setRange(Uint8List target, String range, int transition) { - for (int i = range.codeUnitAt(0), n = range.codeUnitAt(1); i <= n; i++) { - target[i ^ 0x60] = transition; - } - } - - // Create the transitions for each state. - var b; - - // Validate as path, if it is a scheme, we handle it later. - b = build(_uriStart, schemeOrPath | notSimple); - setChars(b, pchar, schemeOrPath); - setChars(b, ".", schemeOrPathDot); - setChars(b, ":", authOrPath | schemeEnd); // Handle later. - setChars(b, "/", authOrPathSlash); - setChars(b, "?", query | queryStart); - setChars(b, "#", fragment | fragmentStart); - - b = build(schemeOrPathDot, schemeOrPath | notSimple); - setChars(b, pchar, schemeOrPath); - setChars(b, ".", schemeOrPathDot2); - setChars(b, ':', authOrPath | schemeEnd); - setChars(b, "/", pathSeg | notSimple); - setChars(b, "?", query | queryStart); - setChars(b, "#", fragment | fragmentStart); - - b = build(schemeOrPathDot2, schemeOrPath | notSimple); - setChars(b, pchar, schemeOrPath); - setChars(b, "%", schemeOrPath | notSimple); - setChars(b, ':', authOrPath | schemeEnd); - setChars(b, "/", relPathSeg); - setChars(b, "?", query | queryStart); - setChars(b, "#", fragment | fragmentStart); - - b = build(schemeOrPath, schemeOrPath | notSimple); - setChars(b, pchar, schemeOrPath); - setChars(b, ':', authOrPath | schemeEnd); - setChars(b, "/", pathSeg); - setChars(b, "?", query | queryStart); - setChars(b, "#", fragment | fragmentStart); - - b = build(authOrPath, path | notSimple); - setChars(b, pchar, path | pathStart); - setChars(b, "/", authOrPathSlash | pathStart); - setChars(b, ".", pathSegDot | pathStart); - setChars(b, "?", query | queryStart); - setChars(b, "#", fragment | fragmentStart); - - b = build(authOrPathSlash, path | notSimple); - setChars(b, pchar, path); - setChars(b, "/", uinfoOrHost0 | hostStart); - setChars(b, ".", pathSegDot); - setChars(b, "?", query | queryStart); - setChars(b, "#", fragment | fragmentStart); - - b = build(uinfoOrHost0, uinfoOrHost | notSimple); - setChars(b, pchar, uinfoOrHost); - setRange(b, "AZ", uinfoOrHost | notSimple); - setChars(b, ":", uinfoOrPort0 | portStart); - setChars(b, "@", uinfoOrHost0 | hostStart); - setChars(b, "[", ipv6Host | notSimple); - setChars(b, "/", pathSeg | pathStart); - setChars(b, "?", query | queryStart); - setChars(b, "#", fragment | fragmentStart); - - b = build(uinfoOrHost, uinfoOrHost | notSimple); - setChars(b, pchar, uinfoOrHost); - setRange(b, "AZ", uinfoOrHost | notSimple); - setChars(b, ":", uinfoOrPort0 | portStart); - setChars(b, "@", uinfoOrHost0 | hostStart); - setChars(b, "/", pathSeg | pathStart); - setChars(b, "?", query | queryStart); - setChars(b, "#", fragment | fragmentStart); - - b = build(uinfoOrPort0, uinfoOrPort | notSimple); - setRange(b, "19", uinfoOrPort); - setChars(b, "@", uinfoOrHost0 | hostStart); - setChars(b, "/", pathSeg | pathStart); - setChars(b, "?", query | queryStart); - setChars(b, "#", fragment | fragmentStart); - - b = build(uinfoOrPort, uinfoOrPort | notSimple); - setRange(b, "09", uinfoOrPort); - setChars(b, "@", uinfoOrHost0 | hostStart); - setChars(b, "/", pathSeg | pathStart); - setChars(b, "?", query | queryStart); - setChars(b, "#", fragment | fragmentStart); - - b = build(ipv6Host, ipv6Host); - setChars(b, "]", uinfoOrHost); - - b = build(relPathSeg, path | notSimple); - setChars(b, pchar, path); - setChars(b, ".", relPathSegDot); - setChars(b, "/", pathSeg | notSimple); - setChars(b, "?", query | queryStart); - setChars(b, "#", fragment | fragmentStart); - - b = build(relPathSegDot, path | notSimple); - setChars(b, pchar, path); - setChars(b, ".", relPathSegDot2); - setChars(b, "/", pathSeg | notSimple); - setChars(b, "?", query | queryStart); - setChars(b, "#", fragment | fragmentStart); - - b = build(relPathSegDot2, path | notSimple); - setChars(b, pchar, path); - setChars(b, "/", relPathSeg); - setChars(b, "?", query | queryStart); // This should be non-simple. - setChars(b, "#", fragment | fragmentStart); // This should be non-simple. - - b = build(pathSeg, path | notSimple); - setChars(b, pchar, path); - setChars(b, ".", pathSegDot); - setChars(b, "/", pathSeg | notSimple); - setChars(b, "?", query | queryStart); - setChars(b, "#", fragment | fragmentStart); - - b = build(pathSegDot, path | notSimple); - setChars(b, pchar, path); - setChars(b, ".", pathSegDot2); - setChars(b, "/", pathSeg | notSimple); - setChars(b, "?", query | queryStart); - setChars(b, "#", fragment | fragmentStart); - - b = build(pathSegDot2, path | notSimple); - setChars(b, pchar, path); - setChars(b, "/", pathSeg | notSimple); - setChars(b, "?", query | queryStart); - setChars(b, "#", fragment | fragmentStart); - - b = build(path, path | notSimple); - setChars(b, pchar, path); - setChars(b, "/", pathSeg); - setChars(b, "?", query | queryStart); - setChars(b, "#", fragment | fragmentStart); - - b = build(query, query | notSimple); - setChars(b, pchar, query); - setChars(b, "?", query); - setChars(b, "#", fragment | fragmentStart); - - b = build(fragment, fragment | notSimple); - setChars(b, pchar, fragment); - setChars(b, "?", fragment); - - // A separate two-state validator for lower-case scheme names. - // Any non-scheme character or upper-case letter is marked as non-simple. - b = build(scheme0, scheme | notSimple); - setRange(b, "az", scheme); - - b = build(scheme, scheme | notSimple); - setRange(b, "az", scheme); - setRange(b, "09", scheme); - setChars(b, "+-.", scheme); - - return tables; -} - -// -------------------------------------------------------------------- -// Code that uses the URI scanner table. - -/// Scan a string using the [_scannerTables] state machine. -/// -/// Scans [uri] from [start] to [end], starting in state [state] and -/// writing output into [indices]. -/// -/// Returns the final state. -int _scan(String uri, int start, int end, int state, List indices) { - var tables = _scannerTables; - assert(end <= uri.length); - for (int i = start; i < end; i++) { - var table = tables[state]; - // Xor with 0x60 to move range 0x20-0x7f into 0x00-0x5f - int char = uri.codeUnitAt(i) ^ 0x60; - // Use 0x1f (nee 0x7f) to represent all unhandled characters. - if (char > 0x5f) char = 0x1f; - int transition = table[char]; - state = transition & 0x1f; - indices[transition >> 5] = i; - } - return state; -} - -class _SimpleUri implements Uri { - final String _uri; - final int _schemeEnd; - final int _hostStart; - final int _portStart; - final int _pathStart; - final int _queryStart; - final int _fragmentStart; - - /// The scheme is often used to distinguish URIs. - /// To make comparisons more efficient, we cache the value, and - /// canonicalize a few known types. - String? _schemeCache; - int? _hashCodeCache; - - _SimpleUri( - this._uri, - this._schemeEnd, - this._hostStart, - this._portStart, - this._pathStart, - this._queryStart, - this._fragmentStart, - this._schemeCache); - - bool get hasScheme => _schemeEnd > 0; - bool get hasAuthority => _hostStart > 0; - bool get hasUserInfo => _hostStart > _schemeEnd + 4; - bool get hasPort => _hostStart > 0 && _portStart + 1 < _pathStart; - bool get hasQuery => _queryStart < _fragmentStart; - bool get hasFragment => _fragmentStart < _uri.length; - - bool get _isFile => _schemeEnd == 4 && _uri.startsWith("file"); - bool get _isHttp => _schemeEnd == 4 && _uri.startsWith("http"); - bool get _isHttps => _schemeEnd == 5 && _uri.startsWith("https"); - bool get _isPackage => _schemeEnd == 7 && _uri.startsWith("package"); - - /// Like [isScheme] but expects argument to be case normalized. - bool _isScheme(String scheme) => - _schemeEnd == scheme.length && _uri.startsWith(scheme); - - bool get hasAbsolutePath => _uri.startsWith("/", _pathStart); - bool get hasEmptyPath => _pathStart == _queryStart; - - bool get isAbsolute => hasScheme && !hasFragment; - - bool isScheme(String scheme) { - if (scheme == null || scheme.isEmpty) return _schemeEnd < 0; - if (scheme.length != _schemeEnd) return false; - return _Uri._compareScheme(scheme, _uri); - } - - String get scheme { - return _schemeCache ??= _computeScheme(); - } - - String _computeScheme() { - if (_schemeEnd <= 0) return ""; - if (_isHttp) return "http"; - if (_isHttps) return "https"; - if (_isFile) return "file"; - if (_isPackage) return "package"; - return _uri.substring(0, _schemeEnd); - } - - String get authority => - _hostStart > 0 ? _uri.substring(_schemeEnd + 3, _pathStart) : ""; - String get userInfo => (_hostStart > _schemeEnd + 3) - ? _uri.substring(_schemeEnd + 3, _hostStart - 1) - : ""; - String get host => - _hostStart > 0 ? _uri.substring(_hostStart, _portStart) : ""; - int get port { - if (hasPort) return int.parse(_uri.substring(_portStart + 1, _pathStart)); - if (_isHttp) return 80; - if (_isHttps) return 443; - return 0; - } - - String get path => _uri.substring(_pathStart, _queryStart); - String get query => (_queryStart < _fragmentStart) - ? _uri.substring(_queryStart + 1, _fragmentStart) - : ""; - String get fragment => - (_fragmentStart < _uri.length) ? _uri.substring(_fragmentStart + 1) : ""; - - String get origin { - // Check original behavior - W3C spec is wonky! - bool isHttp = _isHttp; - if (_schemeEnd < 0) { - throw StateError("Cannot use origin without a scheme: $this"); - } - if (!isHttp && !_isHttps) { - throw StateError( - "Origin is only applicable to schemes http and https: $this"); - } - if (_hostStart == _portStart) { - throw StateError( - "A $scheme: URI should have a non-empty host name: $this"); - } - if (_hostStart == _schemeEnd + 3) { - return _uri.substring(0, _pathStart); - } - // Need to drop anon-empty userInfo. - return _uri.substring(0, _schemeEnd + 3) + - _uri.substring(_hostStart, _pathStart); - } - - List get pathSegments { - int start = _pathStart; - int end = _queryStart; - if (_uri.startsWith("/", start)) start++; - if (start == end) return const []; - List parts = []; - for (int i = start; i < end; i++) { - var char = _uri.codeUnitAt(i); - if (char == _SLASH) { - parts.add(_uri.substring(start, i)); - start = i + 1; - } - } - parts.add(_uri.substring(start, end)); - return List.unmodifiable(parts); - } - - Map get queryParameters { - if (!hasQuery) return const {}; - return UnmodifiableMapView(Uri.splitQueryString(query)); - } - - Map> get queryParametersAll { - if (!hasQuery) return const >{}; - Map> queryParameterLists = - _Uri._splitQueryStringAll(query); - queryParameterLists.updateAll(_toUnmodifiableStringList); - return Map>.unmodifiable(queryParameterLists); - } - - bool _isPort(String port) { - int portDigitStart = _portStart + 1; - return portDigitStart + port.length == _pathStart && - _uri.startsWith(port, portDigitStart); - } - - Uri normalizePath() => this; - - Uri removeFragment() { - if (!hasFragment) return this; - return _SimpleUri(_uri.substring(0, _fragmentStart), _schemeEnd, _hostStart, - _portStart, _pathStart, _queryStart, _fragmentStart, _schemeCache); - } - - Uri replace( - {String? scheme, - String? userInfo, - String? host, - int? port, - String? path, - Iterable? pathSegments, - String? query, - Map*/ >? queryParameters, - String? fragment}) { - bool schemeChanged = false; - if (scheme != null) { - scheme = _Uri._makeScheme(scheme, 0, scheme.length); - schemeChanged = !_isScheme(scheme); - } else { - scheme = this.scheme; - } - bool isFile = (scheme == "file"); - if (userInfo != null) { - userInfo = _Uri._makeUserInfo(userInfo, 0, userInfo.length); - } else if (_hostStart > 0) { - userInfo = _uri.substring(_schemeEnd + 3, _hostStart); - } else { - userInfo = ""; - } - if (port != null) { - port = _Uri._makePort(port, scheme); - } else { - port = this.hasPort ? this.port : null; - if (schemeChanged) { - // The default port might have changed. - port = _Uri._makePort(port, scheme); - } - } - if (host != null) { - host = _Uri._makeHost(host, 0, host.length, false); - } else if (_hostStart > 0) { - host = _uri.substring(_hostStart, _portStart); - } else if (userInfo.isNotEmpty || port != null || isFile) { - host = ""; - } - - bool hasAuthority = host != null; - if (path != null || pathSegments != null) { - path = _Uri._makePath(path, 0, _stringOrNullLength(path), pathSegments, - scheme, hasAuthority); - } else { - path = _uri.substring(_pathStart, _queryStart); - if ((isFile || (hasAuthority && !path.isEmpty)) && - !path.startsWith('/')) { - path = "/" + path; - } - } - - if (query != null || queryParameters != null) { - query = _Uri._makeQuery( - query, 0, _stringOrNullLength(query), queryParameters); - } else if (_queryStart < _fragmentStart) { - query = _uri.substring(_queryStart + 1, _fragmentStart); - } - - if (fragment != null) { - fragment = _Uri._makeFragment(fragment, 0, fragment.length); - } else if (_fragmentStart < _uri.length) { - fragment = _uri.substring(_fragmentStart + 1); - } - - return _Uri._internal(scheme, userInfo, host, port, path, query, fragment); - } - - Uri resolve(String reference) { - return resolveUri(Uri.parse(reference)); - } - - Uri resolveUri(Uri reference) { - if (reference is _SimpleUri) { - return _simpleMerge(this, reference); - } - return _toNonSimple().resolveUri(reference); - } - - // Merge two simple URIs. This should always result in a prefix of - // one concatenated with a suffix of the other, possibly with a `/` in - // the middle of two merged paths, which is again simple. - // In a few cases, there might be a need for extra normalization, when - // resolving on top of a known scheme. - Uri _simpleMerge(_SimpleUri base, _SimpleUri ref) { - if (ref.hasScheme) return ref; - if (ref.hasAuthority) { - if (!base.hasScheme) return ref; - bool isSimple = true; - if (base._isFile) { - isSimple = !ref.hasEmptyPath; - } else if (base._isHttp) { - isSimple = !ref._isPort("80"); - } else if (base._isHttps) { - isSimple = !ref._isPort("443"); - } - if (isSimple) { - var delta = base._schemeEnd + 1; - var newUri = base._uri.substring(0, base._schemeEnd + 1) + - ref._uri.substring(ref._schemeEnd + 1); - return _SimpleUri( - newUri, - base._schemeEnd, - ref._hostStart + delta, - ref._portStart + delta, - ref._pathStart + delta, - ref._queryStart + delta, - ref._fragmentStart + delta, - base._schemeCache); - } else { - // This will require normalization, so use the _Uri implementation. - return _toNonSimple().resolveUri(ref); - } - } - if (ref.hasEmptyPath) { - if (ref.hasQuery) { - int delta = base._queryStart - ref._queryStart; - var newUri = base._uri.substring(0, base._queryStart) + - ref._uri.substring(ref._queryStart); - return _SimpleUri( - newUri, - base._schemeEnd, - base._hostStart, - base._portStart, - base._pathStart, - ref._queryStart + delta, - ref._fragmentStart + delta, - base._schemeCache); - } - if (ref.hasFragment) { - int delta = base._fragmentStart - ref._fragmentStart; - var newUri = base._uri.substring(0, base._fragmentStart) + - ref._uri.substring(ref._fragmentStart); - return _SimpleUri( - newUri, - base._schemeEnd, - base._hostStart, - base._portStart, - base._pathStart, - base._queryStart, - ref._fragmentStart + delta, - base._schemeCache); - } - return base.removeFragment(); - } - if (ref.hasAbsolutePath) { - var delta = base._pathStart - ref._pathStart; - var newUri = base._uri.substring(0, base._pathStart) + - ref._uri.substring(ref._pathStart); - return _SimpleUri( - newUri, - base._schemeEnd, - base._hostStart, - base._portStart, - base._pathStart, - ref._queryStart + delta, - ref._fragmentStart + delta, - base._schemeCache); - } - if (base.hasEmptyPath && base.hasAuthority) { - // ref has relative non-empty path. - // Add a "/" in front, then leading "/../" segments are folded to "/". - int refStart = ref._pathStart; - while (ref._uri.startsWith("../", refStart)) { - refStart += 3; - } - var delta = base._pathStart - refStart + 1; - var newUri = "${base._uri.substring(0, base._pathStart)}/" - "${ref._uri.substring(refStart)}"; - return _SimpleUri( - newUri, - base._schemeEnd, - base._hostStart, - base._portStart, - base._pathStart, - ref._queryStart + delta, - ref._fragmentStart + delta, - base._schemeCache); - } - // Merge paths. - - // The RFC 3986 algorithm merges the base path without its final segment - // (anything after the final "/", or everything if the base path doesn't - // contain any "/"), and the reference path. - // Then it removes "." and ".." segments using the remove-dot-segment - // algorithm. - // This code combines the two steps. It is simplified by knowing that - // the base path contains no "." or ".." segments, and the reference - // path can only contain leading ".." segments. - - String baseUri = base._uri; - String refUri = ref._uri; - int baseStart = base._pathStart; - int baseEnd = base._queryStart; - while (baseUri.startsWith("../", baseStart)) baseStart += 3; - int refStart = ref._pathStart; - int refEnd = ref._queryStart; - - /// Count of leading ".." segments in reference path. - /// The count is decremented when the segment is matched with a - /// segment of the base path, and both are then omitted from the result. - int backCount = 0; - - /// Count "../" segments and advance `refStart` to after the segments. - while (refStart + 3 <= refEnd && refUri.startsWith("../", refStart)) { - refStart += 3; - backCount += 1; - } - - // Extra slash inserted between base and reference path parts if - // the base path contains any slashes, or empty string if none. - // (We could use a slash from the base path in most cases, but not if - // we remove the entire base path). - String insert = ""; - - /// Remove segments from the base path. - /// Start with the segment trailing the last slash, - /// then remove segments for each leading "../" segment - /// from the reference path, or as many of them as are available. - while (baseEnd > baseStart) { - baseEnd--; - int char = baseUri.codeUnitAt(baseEnd); - if (char == _SLASH) { - insert = "/"; - if (backCount == 0) break; - backCount--; - } - } - - if (baseEnd == baseStart && !base.hasScheme && !base.hasAbsolutePath) { - // If the base is *just* a relative path (no scheme or authority), - // then merging with another relative path doesn't follow the - // RFC-3986 behavior. - // Don't need to check `base.hasAuthority` since the base path is - // non-empty - if there is an authority, a non-empty path is absolute. - - // We reached the start of the base path, and want to stay relative, - // so don't insert a slash. - insert = ""; - // If we reached the start of the base path with more "../" left over - // in the reference path, include those segments in the result. - refStart -= backCount * 3; - } - - var delta = baseEnd - refStart + insert.length; - var newUri = "${base._uri.substring(0, baseEnd)}$insert" - "${ref._uri.substring(refStart)}"; - - return _SimpleUri( - newUri, - base._schemeEnd, - base._hostStart, - base._portStart, - base._pathStart, - ref._queryStart + delta, - ref._fragmentStart + delta, - base._schemeCache); - } - - String toFilePath({bool? windows}) { - if (_schemeEnd >= 0 && !_isFile) { - throw UnsupportedError("Cannot extract a file path from a $scheme URI"); - } - if (_queryStart < _uri.length) { - if (_queryStart < _fragmentStart) { - throw UnsupportedError( - "Cannot extract a file path from a URI with a query component"); - } - throw UnsupportedError( - "Cannot extract a file path from a URI with a fragment component"); - } - return (windows ?? _Uri._isWindows) - ? _Uri._toWindowsFilePath(this) - : _toFilePath(); - } - - String _toFilePath() { - if (_hostStart < _portStart) { - // Has authority and non-empty host. - throw UnsupportedError( - "Cannot extract a non-Windows file path from a file URI " - "with an authority"); - } - return this.path; - } - - UriData? get data { - assert(scheme != "data"); - return null; - } - - int get hashCode => _hashCodeCache ??= _uri.hashCode; - - bool operator ==(Object other) { - if (identical(this, other)) return true; - return other is Uri && _uri == other.toString(); - } - - Uri _toNonSimple() { - return _Uri._internal( - this.scheme, - this.userInfo, - this.hasAuthority ? this.host : null, - this.hasPort ? this.port : null, - this.path, - this.hasQuery ? this.query : null, - this.hasFragment ? this.fragment : null); - } - - String toString() => _uri; -} - -/// Special [_Uri] created from an existing [UriData]. -class _DataUri extends _Uri { - final UriData _data; - - _DataUri(this._data, String path, String? query) - : super._internal("data", "", null, null, path, query, null); - - UriData? get data => _data; -} - -/// Checks whether [text] starts with "data:" at position [start]. -/// -/// The text must be long enough to allow reading five characters -/// from the [start] position. -/// -/// Returns an integer value which is zero if text starts with all-lowercase -/// "data:" and 0x20 if the text starts with "data:" that isn't all lower-case. -/// All other values means the text starts with some other character. -int _startsWithData(String text, int start) { - // Multiply by 3 to avoid a non-colon character making delta be 0x20. - int delta = (text.codeUnitAt(start + 4) ^ _COLON) * 3; - delta |= text.codeUnitAt(start) ^ 0x64 /*d*/; - delta |= text.codeUnitAt(start + 1) ^ 0x61 /*a*/; - delta |= text.codeUnitAt(start + 2) ^ 0x74 /*t*/; - delta |= text.codeUnitAt(start + 3) ^ 0x61 /*a*/; - return delta; -} - -/// Helper function returning the length of a string, or `0` for `null`. -int _stringOrNullLength(String? s) => (s == null) ? 0 : s.length; - -List _toUnmodifiableStringList(String key, List list) => - List.unmodifiable(list); diff --git a/sdk_nnbd/lib/developer/developer.dart b/sdk_nnbd/lib/developer/developer.dart deleted file mode 100644 index e9df841ba85..00000000000 --- a/sdk_nnbd/lib/developer/developer.dart +++ /dev/null @@ -1,67 +0,0 @@ -// 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. - -/// Interact with developer tools such as the debugger and inspector. -/// -/// This library is platform dependent and has separate implementations for -/// both web and the Dart VM. A specific platform may not support all -/// operations. -/// -/// To use this library in your code: -/// -/// import 'dart:developer'; -/// -/// {@category Core} -library dart.developer; - -import 'dart:async'; -import 'dart:convert'; -import 'dart:isolate' show Isolate, RawReceivePort, SendPort; - -part 'extension.dart'; -part 'profiler.dart'; -part 'service.dart'; -part 'timeline.dart'; - -/// If [when] is true, stop the program as if a breakpoint were hit at the -/// following statement. -/// -/// Returns the value of [when]. Some debuggers may display [message]. -/// -/// NOTE: When invoked, the isolate will not return until a debugger -/// continues execution. When running in the Dart VM, the behaviour is the same -/// regardless of whether or not a debugger is connected. When compiled to -/// JavaScript, this uses the "debugger" statement, and behaves exactly as -/// that does. -external bool debugger({bool when = true, String? message}); - -/// Send a reference to [object] to any attached debuggers. -/// -/// Debuggers may open an inspector on the object. Returns the argument. -external Object? inspect(Object? object); - -/// Emit a log event. -/// -/// This function was designed to map closely to the logging information -/// collected by `package:logging`. -/// -/// - [message] is the log message -/// - [time] (optional) is the timestamp -/// - [sequenceNumber] (optional) is a monotonically increasing sequence number -/// - [level] (optional) is the severity level (a value between 0 and 2000); see -/// the `package:logging` `Level` class for an overview of the possible values -/// - [name] (optional) is the name of the source of the log message -/// - [zone] (optional) the zone where the log was emitted -/// - [error] (optional) an error object associated with this log event -/// - [stackTrace] (optional) a stack trace associated with this log event -external void log( - String message, { - DateTime? time, - int? sequenceNumber, - int level = 0, - String name = '', - Zone? zone, - Object? error, - StackTrace? stackTrace, -}); diff --git a/sdk_nnbd/lib/developer/developer_sources.gni b/sdk_nnbd/lib/developer/developer_sources.gni deleted file mode 100644 index df0dbc2e4db..00000000000 --- a/sdk_nnbd/lib/developer/developer_sources.gni +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright (c) 2017, 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. - -developer_sdk_sources = [ - "developer.dart", - - # The above file needs to be first if additional parts are added to the lib. - "extension.dart", - "profiler.dart", - "service.dart", - "timeline.dart", -] diff --git a/sdk_nnbd/lib/developer/extension.dart b/sdk_nnbd/lib/developer/extension.dart deleted file mode 100644 index 184a00f956b..00000000000 --- a/sdk_nnbd/lib/developer/extension.dart +++ /dev/null @@ -1,162 +0,0 @@ -// 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. - -part of dart.developer; - -/// A response to a service protocol extension RPC. -/// -/// If the RPC was successful, use [ServiceExtensionResponse.result], otherwise -/// use [ServiceExtensionResponse.error]. -class ServiceExtensionResponse { - /// The result of a successful service protocol extension RPC. - final String? result; - - /// The error code associated with a failed service protocol extension RPC. - final int? errorCode; - - /// The details of a failed service protocol extension RPC. - final String? errorDetail; - - /// Creates a successful response to a service protocol extension RPC. - /// - /// Requires [result] to be a JSON object encoded as a string. When forming - /// the JSON-RPC message [result] will be inlined directly. - ServiceExtensionResponse.result(String result) - : result = result, - errorCode = null, - errorDetail = null { - // TODO: When NNBD is complete, delete the following line. - ArgumentError.checkNotNull(result, "result"); - } - - /// Creates an error response to a service protocol extension RPC. - /// - /// Requires [errorCode] to be [invalidParams] or between [extensionErrorMin] - /// and [extensionErrorMax]. Requires [errorDetail] to be a JSON object - /// encoded as a string. When forming the JSON-RPC message [errorDetail] will - /// be inlined directly. - ServiceExtensionResponse.error(int errorCode, String errorDetail) - : result = null, - errorCode = errorCode, - errorDetail = errorDetail { - _validateErrorCode(errorCode); - // TODO: When NNBD is complete, delete the following line. - ArgumentError.checkNotNull(errorDetail, "errorDetail"); - } - - /// Invalid method parameter(s) error code. - @deprecated - static const kInvalidParams = invalidParams; - - /// Generic extension error code. - @deprecated - static const kExtensionError = extensionError; - - /// Maximum extension provided error code. - @deprecated - static const kExtensionErrorMax = extensionErrorMax; - - /// Minimum extension provided error code. - @deprecated - static const kExtensionErrorMin = extensionErrorMin; - - /// Invalid method parameter(s) error code. - static const invalidParams = -32602; - - /// Generic extension error code. - static const extensionError = -32000; - - /// Maximum extension provided error code. - static const extensionErrorMax = -32000; - - /// Minimum extension provided error code. - static const extensionErrorMin = -32016; - - static String _errorCodeMessage(int errorCode) { - _validateErrorCode(errorCode); - if (errorCode == invalidParams) { - return "Invalid params"; - } - return "Server error"; - } - - static _validateErrorCode(int errorCode) { - // TODO: When NNBD is complete, delete the following line. - ArgumentError.checkNotNull(errorCode, "errorCode"); - if (errorCode == invalidParams) return; - if ((errorCode >= extensionErrorMin) && (errorCode <= extensionErrorMax)) { - return; - } - throw new ArgumentError.value(errorCode, "errorCode", "Out of range"); - } - - /// Determines if this response represents an error. - bool isError() => (errorCode != null) && (errorDetail != null); - - // ignore: unused_element, called from runtime/lib/developer.dart - String _toString() { - return result ?? - json.encode({ - 'code': errorCode!, - 'message': _errorCodeMessage(errorCode!), - 'data': {'details': errorDetail!} - }); - } -} - -/// A service protocol extension handler. Registered with [registerExtension]. -/// -/// Must complete to a [ServiceExtensionResponse]. [method] is the method name -/// of the service protocol request, and [parameters] is a map holding the -/// parameters to the service protocol request. -/// -/// *NOTE*: all parameter names and values are encoded as strings. -typedef Future ServiceExtensionHandler( - String method, Map parameters); - -/// Register a [ServiceExtensionHandler] that will be invoked in this isolate -/// for [method]. *NOTE*: Service protocol extensions must be registered -/// in each isolate. -/// -/// *NOTE*: [method] must begin with 'ext.' and you should use the following -/// structure to avoid conflicts with other packages: 'ext.package.command'. -/// That is, immediately following the 'ext.' prefix, should be the registering -/// package name followed by another period ('.') and then the command name. -/// For example: 'ext.dart.io.getOpenFiles'. -/// -/// Because service extensions are isolate specific, clients using extensions -/// must always include an 'isolateId' parameter with each RPC. -void registerExtension(String method, ServiceExtensionHandler handler) { - // TODO: When NNBD is complete, delete the following line. - ArgumentError.checkNotNull(method, 'method'); - if (!method.startsWith('ext.')) { - throw new ArgumentError.value(method, 'method', 'Must begin with ext.'); - } - if (_lookupExtension(method) != null) { - throw new ArgumentError('Extension already registered: $method'); - } - // TODO: When NNBD is complete, delete the following line. - ArgumentError.checkNotNull(handler, 'handler'); - _registerExtension(method, handler); -} - -/// Post an event of [eventKind] with payload of [eventData] to the `Extension` -/// event stream. -void postEvent(String eventKind, Map eventData) { - // TODO: When NNBD is complete, delete the following two lines. - ArgumentError.checkNotNull(eventKind, 'eventKind'); - ArgumentError.checkNotNull(eventData, 'eventData'); - String eventDataAsString = json.encode(eventData); - _postEvent(eventKind, eventDataAsString); -} - -external void _postEvent(String eventKind, String eventData); - -// Both of these functions are written inside C++ to avoid updating the data -// structures in Dart, getting an OOB, and observing stale state. Do not move -// these into Dart code unless you can ensure that the operations will can be -// done atomically. Native code lives in vm/isolate.cc- -// LookupServiceExtensionHandler and RegisterServiceExtensionHandler. -external ServiceExtensionHandler? _lookupExtension(String method); -external _registerExtension(String method, ServiceExtensionHandler handler); diff --git a/sdk_nnbd/lib/developer/profiler.dart b/sdk_nnbd/lib/developer/profiler.dart deleted file mode 100644 index 07fb6255fe7..00000000000 --- a/sdk_nnbd/lib/developer/profiler.dart +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright (c) 2014, 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. - -part of dart.developer; - -/// A UserTag can be used to group samples in the Observatory profiler. -abstract class UserTag { - /// The maximum number of UserTag instances that can be created by a program. - static const MAX_USER_TAGS = 64; - - external factory UserTag(String label); - - /// Label of [this]. - String get label; - - /// Make [this] the current tag for the isolate. Returns the current tag - /// before setting. - UserTag makeCurrent(); - - /// The default [UserTag] with label 'Default'. - external static UserTag get defaultTag; -} - -/// Returns the current [UserTag] for the isolate. -external UserTag getCurrentTag(); - -/// Abstract [Metric] class. Metric names must be unique, are hierarchical, -/// and use periods as separators. For example, 'a.b.c'. Uniqueness is only -/// enforced when a Metric is registered. The name of a metric cannot contain -/// the slash ('/') character. -abstract class Metric { - /// [name] of this metric. - final String name; - - /// [description] of this metric. - final String description; - - Metric(this.name, this.description) { - if ((name == 'vm') || name.contains('/')) { - throw new ArgumentError('Invalid Metric name.'); - } - } - - Map _toJSON(); -} - -/// A measured value with a min and max. Initial value is min. Value will -/// be clamped to the interval [min, max]. -class Gauge extends Metric { - final double min; - final double max; - - double _value; - double get value => _value; - set value(double v) { - if (v < min) { - v = min; - } else if (v > max) { - v = max; - } - _value = v; - } - - Gauge(String name, String description, this.min, this.max) - : _value = min, - super(name, description) { - // TODO: When NNBD is complete, delete the following two lines. - ArgumentError.checkNotNull(min, 'min'); - ArgumentError.checkNotNull(max, 'max'); - if (!(min < max)) throw new ArgumentError('min must be less than max'); - } - - Map _toJSON() { - var map = { - 'type': 'Gauge', - 'id': 'metrics/$name', - 'name': name, - 'description': description, - 'value': value, - 'min': min, - 'max': max, - }; - return map; - } -} - -/// A changing value. Initial value is 0.0. -class Counter extends Metric { - Counter(String name, String description) : super(name, description); - - double _value = 0.0; - double get value => _value; - set value(double v) { - _value = v; - } - - Map _toJSON() { - var map = { - 'type': 'Counter', - 'id': 'metrics/$name', - 'name': name, - 'description': description, - 'value': value, - }; - return map; - } -} - -class Metrics { - static final Map _metrics = new Map(); - - /// Register [Metric]s to make them visible to Observatory. - static void register(Metric metric) { - // TODO: When NNBD is complete, delete the following line. - ArgumentError.checkNotNull(metric, 'metric'); - if (_metrics[metric.name] != null) { - throw new ArgumentError('Registered metrics have unique names'); - } - _metrics[metric.name] = metric; - } - - /// Deregister [Metric]s to make them not visible to Observatory. - static void deregister(Metric metric) { - // TODO: When NNBD is complete, delete the following line. - ArgumentError.checkNotNull(metric, 'metric'); - _metrics.remove(metric.name); - } - - // ignore: unused_element, called from native code - @pragma("vm:entry-point", !const bool.fromEnvironment("dart.vm.product")) - static String? _printMetric(String id) { - var metric = _metrics[id]; - if (metric == null) { - return null; - } - return json.encode(metric._toJSON()); - } - - // ignore: unused_element, called from native code - @pragma("vm:entry-point", !const bool.fromEnvironment("dart.vm.product")) - static String _printMetrics() { - var metrics = []; - for (var metric in _metrics.values) { - metrics.add(metric._toJSON()); - } - var map = { - 'type': 'MetricList', - 'metrics': metrics, - }; - return json.encode(map); - } -} diff --git a/sdk_nnbd/lib/developer/service.dart b/sdk_nnbd/lib/developer/service.dart deleted file mode 100644 index 6d90667441c..00000000000 --- a/sdk_nnbd/lib/developer/service.dart +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright (c) 2016, 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. - -part of dart.developer; - -/// Service protocol is the protocol that a client like the Observatory -/// could use to access the services provided by the Dart VM for -/// debugging and inspecting Dart programs. This class encapsulates the -/// version number and Uri for accessing this service. -class ServiceProtocolInfo { - /// The major version of the protocol. If the running Dart environment does - /// not support the service protocol, this is 0. - final int majorVersion = _getServiceMajorVersion(); - - /// The minor version of the protocol. If the running Dart environment does - /// not support the service protocol, this is 0. - final int minorVersion = _getServiceMinorVersion(); - - /// The Uri to access the service. If the web server is not running, this - /// will be null. - final Uri? serverUri; - - ServiceProtocolInfo(this.serverUri); - - String toString() { - if (serverUri != null) { - return 'Dart VM Service Protocol v$majorVersion.$minorVersion ' - 'listening on $serverUri'; - } else { - return 'Dart VM Service Protocol v$majorVersion.$minorVersion'; - } - } -} - -/// Access information about the service protocol and control the web server -/// that provides access to the services provided by the Dart VM for -/// debugging and inspecting Dart programs. -class Service { - /// Get information about the service protocol (version number and - /// Uri to access the service). - static Future getInfo() async { - // Port to receive response from service isolate. - final RawReceivePort receivePort = new RawReceivePort(); - final Completer uriCompleter = new Completer(); - receivePort.handler = (Uri? uri) => uriCompleter.complete(uri); - // Request the information from the service isolate. - _getServerInfo(receivePort.sendPort); - // Await the response from the service isolate. - Uri? uri = await uriCompleter.future; - // Close the port. - receivePort.close(); - return new ServiceProtocolInfo(uri); - } - - /// Control the web server that the service protocol is accessed through. - /// The [enable] argument must be a boolean and is used as a toggle to - /// enable (true) or disable (false) the web server servicing requests. - static Future controlWebServer( - {bool enable: false}) async { - // TODO: When NNBD is complete, delete the following line. - ArgumentError.checkNotNull(enable, 'enable'); - // Port to receive response from service isolate. - final RawReceivePort receivePort = new RawReceivePort(); - final Completer uriCompleter = new Completer(); - receivePort.handler = (Uri uri) => uriCompleter.complete(uri); - // Request the information from the service isolate. - _webServerControl(receivePort.sendPort, enable); - // Await the response from the service isolate. - Uri uri = await uriCompleter.future; - // Close the port. - receivePort.close(); - return new ServiceProtocolInfo(uri); - } - - /// Returns a [String] token representing the ID of [isolate]. - /// - /// Returns null if the running Dart environment does not support the service - /// protocol. - static String? getIsolateID(Isolate isolate) { - // TODO: When NNBD is complete, delete the following line. - ArgumentError.checkNotNull(isolate, 'isolate'); - return _getIsolateIDFromSendPort(isolate.controlPort); - } -} - -/// [sendPort] will receive a Uri or null. -external void _getServerInfo(SendPort sendPort); - -/// [sendPort] will receive a Uri or null. -external void _webServerControl(SendPort sendPort, bool enable); - -/// Returns the major version of the service protocol. -external int _getServiceMajorVersion(); - -/// Returns the minor version of the service protocol. -external int _getServiceMinorVersion(); - -/// Returns the service id for the isolate that owns [sendPort]. -external String? _getIsolateIDFromSendPort(SendPort sendPort); diff --git a/sdk_nnbd/lib/developer/timeline.dart b/sdk_nnbd/lib/developer/timeline.dart deleted file mode 100644 index cc9cf4045ee..00000000000 --- a/sdk_nnbd/lib/developer/timeline.dart +++ /dev/null @@ -1,385 +0,0 @@ -// 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. - -part of dart.developer; - -const bool _hasTimeline = - const bool.fromEnvironment("dart.developer.timeline", defaultValue: true); - -/// A typedef for the function argument to [Timeline.timeSync]. -typedef TimelineSyncFunction = T Function(); - -// TODO: This typedef is not used. -typedef Future TimelineAsyncFunction(); - -/// A class to represent Flow events. -/// -/// [Flow] objects are used to thread flow events between timeline slices, -/// for example, those created with the [Timeline] class below. Adding -/// [Flow] objects cause arrows to be drawn between slices in Chrome's trace -/// viewer. The arrows start at e.g [Timeline] events that are passed a -/// [Flow.begin] object, go through [Timeline] events that are passed a -/// [Flow.step] object, and end at [Timeline] events that are passed a -/// [Flow.end] object, all having the same [Flow.id]. For example: -/// -/// ```dart -/// var flow = Flow.begin(); -/// Timeline.timeSync('flow_test', () { -/// doSomething(); -/// }, flow: flow); -/// -/// Timeline.timeSync('flow_test', () { -/// doSomething(); -/// }, flow: Flow.step(flow.id)); -/// -/// Timeline.timeSync('flow_test', () { -/// doSomething(); -/// }, flow: Flow.end(flow.id)); -/// ``` -class Flow { - // These values must be kept in sync with the enum "EventType" in - // runtime/vm/timeline.h. - static const int _begin = 9; - static const int _step = 10; - static const int _end = 11; - - final int _type; - - /// The flow id of the flow event. - final int id; - - Flow._(this._type, this.id); - - /// A "begin" Flow event. - /// - /// When passed to a [Timeline] method, generates a "begin" Flow event. - /// If [id] is not provided, an id that conflicts with no other Dart-generated - /// flow id's will be generated. - static Flow begin({int? id}) { - return new Flow._(_begin, id ?? _getNextAsyncId()); - } - - /// A "step" Flow event. - /// - /// When passed to a [Timeline] method, generates a "step" Flow event. - /// The [id] argument is required. It can come either from another [Flow] - /// event, or some id that comes from the environment. - static Flow step(int id) => new Flow._(_step, id); - - /// An "end" Flow event. - /// - /// When passed to a [Timeline] method, generates a "end" Flow event. - /// The [id] argument is required. It can come either from another [Flow] - /// event, or some id that comes from the environment. - static Flow end(int id) => new Flow._(_end, id); -} - -/// Add to the timeline. -/// -/// [Timeline]'s methods add synchronous events to the timeline. When -/// generating a timeline in Chrome's tracing format, using [Timeline] generates -/// "Complete" events. [Timeline]'s [startSync] and [finishSync] can be used -/// explicitly, or implicitly by wrapping a closure in [timeSync]. For example: -/// -/// ```dart -/// Timeline.startSync("Doing Something"); -/// doSomething(); -/// Timeline.finishSync(); -/// ``` -/// -/// Or: -/// -/// ```dart -/// Timeline.timeSync("Doing Something", () { -/// doSomething(); -/// }); -/// ``` -class Timeline { - /// Start a synchronous operation labeled [name]. Optionally takes - /// a [Map] of [arguments]. This slice may also optionally be associated with - /// a [Flow] event. This operation must be finished before - /// returning to the event queue. - static void startSync(String name, {Map? arguments, Flow? flow}) { - if (!_hasTimeline) return; - // TODO: When NNBD is complete, delete the following line. - ArgumentError.checkNotNull(name, 'name'); - if (!_isDartStreamEnabled()) { - // Push a null onto the stack and return. - _stack.add(null); - return; - } - var block = new _SyncBlock._(name); - if (arguments != null) { - block._arguments = arguments; - } - if (flow != null) { - block.flow = flow; - } - _stack.add(block); - block._startSync(); - } - - /// Finish the last synchronous operation that was started. - static void finishSync() { - if (!_hasTimeline) { - return; - } - if (_stack.length == 0) { - throw new StateError('Uneven calls to startSync and finishSync'); - } - // Pop top item off of stack. - var block = _stack.removeLast(); - if (block == null) { - // Dart stream was disabled when startSync was called. - return; - } - // Finish it. - block.finish(); - } - - /// Emit an instant event. - static void instantSync(String name, {Map? arguments}) { - if (!_hasTimeline) return; - // TODO: When NNBD is complete, delete the following line. - ArgumentError.checkNotNull(name, 'name'); - if (!_isDartStreamEnabled()) { - // Stream is disabled. - return; - } - Map? instantArguments; - if (arguments != null) { - instantArguments = new Map.from(arguments); - } - _reportInstantEvent('Dart', name, _argumentsAsJson(instantArguments)); - } - - /// A utility method to time a synchronous [function]. Internally calls - /// [function] bracketed by calls to [startSync] and [finishSync]. - static T timeSync(String name, TimelineSyncFunction function, - {Map? arguments, Flow? flow}) { - startSync(name, arguments: arguments, flow: flow); - try { - return function(); - } finally { - finishSync(); - } - } - - /// The current time stamp from the clock used by the timeline. Units are - /// microseconds. - /// - /// When run on the Dart VM, uses the same monotonic clock as the embedding - /// API's `Dart_TimelineGetMicros`. - static int get now => _getTraceClock(); - static final List<_SyncBlock?> _stack = []; -} - -/// An asynchronous task on the timeline. An asynchronous task can have many -/// (nested) synchronous operations. Synchronous operations can live longer than -/// the current isolate event. To pass a [TimelineTask] to another isolate, -/// you must first call [pass] to get the task id and then construct a new -/// [TimelineTask] in the other isolate. -class TimelineTask { - /// Create a task. The task ID will be set by the system. - /// - /// If [parent] is provided, the parent's task ID is provided as argument - /// 'parentId' when [start] is called. In DevTools, this argument will result - /// in this [TimelineTask] being linked to the [parent] [TimelineTask]. - /// - /// If [filterKey] is provided, a property named `filterKey` will be inserted - /// into the arguments of each event associated with this task. The - /// `filterKey` will be set to the value of [filterKey]. - TimelineTask({TimelineTask? parent, String? filterKey}) - : _parent = parent, - _filterKey = filterKey, - _taskId = _getNextAsyncId() {} - - /// Create a task with an explicit [taskId]. This is useful if you are - /// passing a task from one isolate to another. - /// - /// Important note: only provide task IDs which have been obtained as a - /// result of invoking [TimelineTask.pass]. Specifying a custom ID can lead - /// to ID collisions, resulting in incorrect rendering of timeline events. - /// - /// If [filterKey] is provided, a property named `filterKey` will be inserted - /// into the arguments of each event associated with this task. The - /// `filterKey` will be set to the value of [filterKey]. - TimelineTask.withTaskId(int taskId, {String? filterKey}) - : _parent = null, - _filterKey = filterKey, - _taskId = taskId { - // TODO: When NNBD is complete, delete the following line. - ArgumentError.checkNotNull(taskId, 'taskId'); - } - - /// Start a synchronous operation within this task named [name]. - /// Optionally takes a [Map] of [arguments]. - void start(String name, {Map? arguments}) { - if (!_hasTimeline) return; - // TODO: When NNBD is complete, delete the following line. - ArgumentError.checkNotNull(name, 'name'); - var block = new _AsyncBlock._(name, _taskId); - _stack.add(block); - // TODO(39115): Spurious error about collection literal ambiguity. - // TODO(39117): Spurious error about typing of `...?arguments`. - // TODO(39120): Spurious error even about `...arguments`. - // When these TODOs are done, we can use spread and if elements. - var map = {}; - if (arguments != null) { - for (var key in arguments.keys) { - map[key] = arguments[key]; - } - } - if (_parent != null) map['parentId'] = _parent!._taskId.toRadixString(16); - if (_filterKey != null) map[_kFilterKey] = _filterKey; - block._start(map); - } - - /// Emit an instant event for this task. - /// Optionally takes a [Map] of [arguments]. - void instant(String name, {Map? arguments}) { - if (!_hasTimeline) return; - // TODO: When NNBD is complete, delete the following line. - ArgumentError.checkNotNull(name, 'name'); - Map? instantArguments; - if (arguments != null) { - instantArguments = new Map.from(arguments); - } - if (_filterKey != null) { - instantArguments ??= {}; - instantArguments[_kFilterKey] = _filterKey; - } - _reportTaskEvent( - _taskId, 'n', 'Dart', name, _argumentsAsJson(instantArguments)); - } - - /// Finish the last synchronous operation that was started. - /// Optionally takes a [Map] of [arguments]. - void finish({Map? arguments}) { - if (!_hasTimeline) { - return; - } - if (_stack.length == 0) { - throw new StateError('Uneven calls to start and finish'); - } - if (_filterKey != null) { - arguments ??= {}; - arguments[_kFilterKey] = _filterKey; - } - // Pop top item off of stack. - var block = _stack.removeLast(); - block._finish(arguments); - } - - /// Retrieve the [TimelineTask]'s task id. Will throw an exception if the - /// stack is not empty. - int pass() { - if (_stack.length > 0) { - throw new StateError( - 'You cannot pass a TimelineTask without finishing all started ' - 'operations'); - } - int r = _taskId; - return r; - } - - static const String _kFilterKey = 'filterKey'; - final TimelineTask? _parent; - final String? _filterKey; - final int _taskId; - final List<_AsyncBlock> _stack = []; -} - -/// An asynchronous block of time on the timeline. This block can be kept -/// open across isolate messages. -class _AsyncBlock { - /// The category this block belongs to. - final String category = 'Dart'; - - /// The name of this block. - final String name; - - /// The asynchronous task id. - final int _taskId; - - _AsyncBlock._(this.name, this._taskId); - - // Emit the start event. - void _start(Map arguments) { - _reportTaskEvent(_taskId, 'b', category, name, _argumentsAsJson(arguments)); - } - - // Emit the finish event. - void _finish(Map? arguments) { - _reportTaskEvent(_taskId, 'e', category, name, _argumentsAsJson(arguments)); - } -} - -/// A synchronous block of time on the timeline. This block should not be -/// kept open across isolate messages. -class _SyncBlock { - /// The category this block belongs to. - final String category = 'Dart'; - - /// The name of this block. - final String name; - - /// An (optional) set of arguments which will be serialized to JSON and - /// associated with this block. - Map? _arguments; - - /// An (optional) flow event associated with this block. - Flow? _flow; - - _SyncBlock._(this.name); - - /// Start this block of time. - void _startSync() { - _reportTaskEvent(0, 'B', category, name, _argumentsAsJson(_arguments)); - } - - /// Finish this block of time. At this point, this block can no longer be - /// used. - void finish() { - // Report event to runtime. - _reportTaskEvent(0, 'E', category, name, _argumentsAsJson(_arguments)); - if (_flow != null) { - _reportFlowEvent(category, "${_flow!.id}", _flow!._type, _flow!.id, - _argumentsAsJson(null)); - } - } - - void set flow(Flow f) { - _flow = f; - } -} - -String _argumentsAsJson(Map? arguments) { - if ((arguments == null) || (arguments.length == 0)) { - // Fast path no arguments. Avoid calling jsonEncode. - return '{}'; - } - return json.encode(arguments); -} - -/// Returns true if the Dart Timeline stream is enabled. -external bool _isDartStreamEnabled(); - -/// Returns the next async task id. -external int _getNextAsyncId(); - -/// Returns the current value from the trace clock. -external int _getTraceClock(); - -/// Reports an event for a task. -external void _reportTaskEvent(int taskId, String phase, String category, - String name, String argumentsAsJson); - -/// Reports a flow event. -external void _reportFlowEvent( - String category, String name, int type, int id, String argumentsAsJson); - -/// Reports an instant event. -external void _reportInstantEvent( - String category, String name, String argumentsAsJson); diff --git a/sdk_nnbd/lib/ffi/annotations.dart b/sdk_nnbd/lib/ffi/annotations.dart deleted file mode 100644 index f68e5250753..00000000000 --- a/sdk_nnbd/lib/ffi/annotations.dart +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) 2019, 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. - -part of dart.ffi; - -class DartRepresentationOf { - /// Represents the Dart type corresponding to a [NativeType]. - /// - /// [Int8] -> [int] - /// [Int16] -> [int] - /// [Int32] -> [int] - /// [Int64] -> [int] - /// [Uint8] -> [int] - /// [Uint16] -> [int] - /// [Uint32] -> [int] - /// [Uint64] -> [int] - /// [IntPtr] -> [int] - /// [Double] -> [double] - /// [Float] -> [double] - /// [Pointer] -> [Pointer] - /// [NativeFunction] S1 Function(S2, S3) - /// where DartRepresentationOf(Tn) -> Sn - /// T extends Struct -> T - const DartRepresentationOf(String nativeType); -} - -class Unsized { - const Unsized(); -} - -/// This [NativeType] does not have predefined size. -/// -/// Unsized NativeTypes do not support [sizeOf] because their size is unknown. -/// Consequently, [allocate], [Pointer.load], [Pointer.store], and -/// [Pointer.elementAt] are not available. -const unsized = const Unsized(); diff --git a/sdk_nnbd/lib/ffi/dynamic_library.dart b/sdk_nnbd/lib/ffi/dynamic_library.dart deleted file mode 100644 index d11c945cb72..00000000000 --- a/sdk_nnbd/lib/ffi/dynamic_library.dart +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) 2019, 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. - -part of dart.ffi; - -/// Represents a dynamically loaded C library. -class DynamicLibrary { - /// Creates a dynamic library holding all global symbols. - /// - /// Any symbol in a library currently loaded with global visibility (including - /// the executable itself) may be resolved in this library. - /// - /// This feature is not available on Windows, instead an exception is thrown. - external factory DynamicLibrary.process(); - - /// Creates a dynamic library representing the running executable. - external factory DynamicLibrary.executable(); - - /// Loads a dynamic library file with local visibility. - /// - /// Throws an [ArgumentError] if loading the dynamic library fails. - external factory DynamicLibrary.open(String name); - - /// Looks up a symbol in the [DynamicLibrary] and returns its address in - /// memory. Equivalent of dlsym. - /// - /// Throws an [ArgumentError] if it fails to lookup the symbol. - external Pointer lookup(String symbolName); - - /// Dynamic libraries are equal if they load the same library. - external bool operator ==(Object other); - - /// The hash code for a DynamicLibrary only depends on the loaded library - external int get hashCode; - - /// The handle to the dynamic library. - external Pointer get handle; -} - -/// Methods which cannot be invoked dynamically. -extension DynamicLibraryExtension on DynamicLibrary { - /// Helper that combines lookup and cast to a Dart function. - external F lookupFunction( - String symbolName); -} diff --git a/sdk_nnbd/lib/ffi/ffi.dart b/sdk_nnbd/lib/ffi/ffi.dart deleted file mode 100644 index 3b6e236b74b..00000000000 --- a/sdk_nnbd/lib/ffi/ffi.dart +++ /dev/null @@ -1,593 +0,0 @@ -// Copyright (c) 2019, 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 - -/** - * Foreign Function Interface for interoperability with the C programming language. - * - * **NOTE**: Dart:FFI is in beta, and breaking API changes might still happen. - * - * For further details, please see: https://dart.dev/server/c-interop - * - * {@category VM} - */ -library dart.ffi; - -import 'dart:isolate'; -import 'dart:typed_data'; - -part "native_type.dart"; -part "annotations.dart"; -part "dynamic_library.dart"; -part "struct.dart"; - -/// Number of bytes used by native type T. -/// -/// Includes padding and alignment of structs. -external int sizeOf(); - -/// Represents a pointer into the native C memory corresponding to "NULL", e.g. -/// a pointer with address 0. -final Pointer nullptr = Pointer.fromAddress(0); - -/// Represents a pointer into the native C memory. Cannot be extended. -@pragma("vm:entry-point") -class Pointer extends NativeType { - /// Construction from raw integer. - external factory Pointer.fromAddress(int ptr); - - /// Convert Dart function to a C function pointer, automatically marshalling - /// the arguments and return value - /// - /// If an exception is thrown while calling `f()`, the native function will - /// return `exceptionalReturn`, which must be assignable to return type of `f`. - /// - /// The returned function address can only be invoked on the mutator (main) - /// thread of the current isolate. It will abort the process if invoked on any - /// other thread. - /// - /// The pointer returned will remain alive for the duration of the current - /// isolate's lifetime. After the isolate it was created in is terminated, - /// invoking it from native code will cause undefined behavior. - /// - /// Does not accept dynamic invocations -- where the type of the receiver is - /// [dynamic]. - external static Pointer> fromFunction( - @DartRepresentationOf("T") Function f, - [Object? exceptionalReturn]); - - /// Access to the raw pointer value. - /// On 32-bit systems, the upper 32-bits of the result are 0. - external int get address; - - /// Pointer arithmetic (takes element size into account). - external Pointer elementAt(int index); - - /// Cast Pointer to a Pointer. - external Pointer cast(); - - /// Equality for Pointers only depends on their address. - bool operator ==(Object other) { - if (other is! Pointer) return false; - Pointer otherPointer = other; - return address == otherPointer.address; - } - - /// The hash code for a Pointer only depends on its address. - int get hashCode { - return address.hashCode; - } -} - -/// Extension on [Pointer] specialized for the type argument [NativeFunction]. -extension NativeFunctionPointer - on Pointer> { - /// Convert to Dart function, automatically marshalling the arguments - /// and return value. - external DF asFunction<@DartRepresentationOf("NF") DF extends Function>(); -} - -// -// The following code is generated, do not edit by hand. -// -// Code generated by `runtime/tools/ffi/sdk_lib_ffi_generator.dart`. -// - -/// Extension on [Pointer] specialized for the type argument [Int8]. -extension Int8Pointer on Pointer { - /// The 8-bit two's complement integer at [address]. - /// - /// A Dart integer is truncated to 8 bits (as if by `.toSigned(8)`) before - /// being stored, and the 8-bit value is sign-extended when it is loaded. - external int get value; - - external void set value(int value); - - /// The 8-bit two's complement integer at `address + index`. - /// - /// A Dart integer is truncated to 8 bits (as if by `.toSigned(8)`) before - /// being stored, and the 8-bit value is sign-extended when it is loaded. - external int operator [](int index); - - /// The 8-bit two's complement integer at `address + index`. - /// - /// A Dart integer is truncated to 8 bits (as if by `.toSigned(8)`) before - /// being stored, and the 8-bit value is sign-extended when it is loaded. - external void operator []=(int index, int value); - - /// Creates a typed list view backed by memory in the address space. - /// - /// The returned view will allow access to the memory range from [address] - /// to `address + length`. - /// - /// The user has to ensure the memory range is accessible while using the - /// returned list. - external Int8List asTypedList(int length); -} - -/// Extension on [Pointer] specialized for the type argument [Int16]. -extension Int16Pointer on Pointer { - /// The 16-bit two's complement integer at [address]. - /// - /// A Dart integer is truncated to 16 bits (as if by `.toSigned(16)`) before - /// being stored, and the 16-bit value is sign-extended when it is loaded. - /// - /// The [address] must be 2-byte aligned. - external int get value; - - external void set value(int value); - - /// The 16-bit two's complement integer at `address + 2 * index`. - /// - /// A Dart integer is truncated to 16 bits (as if by `.toSigned(16)`) before - /// being stored, and the 16-bit value is sign-extended when it is loaded. - /// - /// The [address] must be 2-byte aligned. - external int operator [](int index); - - /// The 16-bit two's complement integer at `address + 2 * index`. - /// - /// A Dart integer is truncated to 16 bits (as if by `.toSigned(16)`) before - /// being stored, and the 16-bit value is sign-extended when it is loaded. - /// - /// The [address] must be 2-byte aligned. - external void operator []=(int index, int value); - - /// Creates a typed list view backed by memory in the address space. - /// - /// The returned view will allow access to the memory range from [address] - /// to `address + 2 * length`. - /// - /// The user has to ensure the memory range is accessible while using the - /// returned list. - /// - /// The [address] must be 2-byte aligned. - external Int16List asTypedList(int length); -} - -/// Extension on [Pointer] specialized for the type argument [Int32]. -extension Int32Pointer on Pointer { - /// The 32-bit two's complement integer at [address]. - /// - /// A Dart integer is truncated to 32 bits (as if by `.toSigned(32)`) before - /// being stored, and the 32-bit value is sign-extended when it is loaded. - /// - /// The [address] must be 4-byte aligned. - external int get value; - - external void set value(int value); - - /// The 32-bit two's complement integer at `address + 4 * index`. - /// - /// A Dart integer is truncated to 32 bits (as if by `.toSigned(32)`) before - /// being stored, and the 32-bit value is sign-extended when it is loaded. - /// - /// The [address] must be 4-byte aligned. - external int operator [](int index); - - /// The 32-bit two's complement integer at `address + 4 * index`. - /// - /// A Dart integer is truncated to 32 bits (as if by `.toSigned(32)`) before - /// being stored, and the 32-bit value is sign-extended when it is loaded. - /// - /// The [address] must be 4-byte aligned. - external void operator []=(int index, int value); - - /// Creates a typed list view backed by memory in the address space. - /// - /// The returned view will allow access to the memory range from [address] - /// to `address + 4 * length`. - /// - /// The user has to ensure the memory range is accessible while using the - /// returned list. - /// - /// The [address] must be 4-byte aligned. - external Int32List asTypedList(int length); -} - -/// Extension on [Pointer] specialized for the type argument [Int64]. -extension Int64Pointer on Pointer { - /// The 64-bit two's complement integer at [address]. - /// - /// The [address] must be 8-byte aligned. - external int get value; - - external void set value(int value); - - /// The 64-bit two's complement integer at `address + 8 * index`. - /// - /// The [address] must be 8-byte aligned. - external int operator [](int index); - - /// The 64-bit two's complement integer at `address + 8 * index`. - /// - /// The [address] must be 8-byte aligned. - external void operator []=(int index, int value); - - /// Creates a typed list view backed by memory in the address space. - /// - /// The returned view will allow access to the memory range from [address] - /// to `address + 8 * length`. - /// - /// The user has to ensure the memory range is accessible while using the - /// returned list. - /// - /// The [address] must be 8-byte aligned. - external Int64List asTypedList(int length); -} - -/// Extension on [Pointer] specialized for the type argument [Uint8]. -extension Uint8Pointer on Pointer { - /// The 8-bit unsigned integer at [address]. - /// - /// A Dart integer is truncated to 8 bits (as if by `.toUnsigned(8)`) before - /// being stored, and the 8-bit value is zero-extended when it is loaded. - external int get value; - - external void set value(int value); - - /// The 8-bit unsigned integer at `address + index`. - /// - /// A Dart integer is truncated to 8 bits (as if by `.toUnsigned(8)`) before - /// being stored, and the 8-bit value is zero-extended when it is loaded. - external int operator [](int index); - - /// The 8-bit unsigned integer at `address + index`. - /// - /// A Dart integer is truncated to 8 bits (as if by `.toUnsigned(8)`) before - /// being stored, and the 8-bit value is zero-extended when it is loaded. - external void operator []=(int index, int value); - - /// Creates a typed list view backed by memory in the address space. - /// - /// The returned view will allow access to the memory range from [address] - /// to `address + length`. - /// - /// The user has to ensure the memory range is accessible while using the - /// returned list. - external Uint8List asTypedList(int length); -} - -/// Extension on [Pointer] specialized for the type argument [Uint16]. -extension Uint16Pointer on Pointer { - /// The 16-bit unsigned integer at [address]. - /// - /// A Dart integer is truncated to 16 bits (as if by `.toUnsigned(16)`) before - /// being stored, and the 16-bit value is zero-extended when it is loaded. - /// - /// The [address] must be 2-byte aligned. - external int get value; - - external void set value(int value); - - /// The 16-bit unsigned integer at `address + 2 * index`. - /// - /// A Dart integer is truncated to 16 bits (as if by `.toUnsigned(16)`) before - /// being stored, and the 16-bit value is zero-extended when it is loaded. - /// - /// The [address] must be 2-byte aligned. - external int operator [](int index); - - /// The 16-bit unsigned integer at `address + 2 * index`. - /// - /// A Dart integer is truncated to 16 bits (as if by `.toUnsigned(16)`) before - /// being stored, and the 16-bit value is zero-extended when it is loaded. - /// - /// The [address] must be 2-byte aligned. - external void operator []=(int index, int value); - - /// Creates a typed list view backed by memory in the address space. - /// - /// The returned view will allow access to the memory range from [address] - /// to `address + 2 * length`. - /// - /// The user has to ensure the memory range is accessible while using the - /// returned list. - /// - /// The [address] must be 2-byte aligned. - external Uint16List asTypedList(int length); -} - -/// Extension on [Pointer] specialized for the type argument [Uint32]. -extension Uint32Pointer on Pointer { - /// The 32-bit unsigned integer at [address]. - /// - /// A Dart integer is truncated to 32 bits (as if by `.toUnsigned(32)`) before - /// being stored, and the 32-bit value is zero-extended when it is loaded. - /// - /// The [address] must be 4-byte aligned. - external int get value; - - external void set value(int value); - - /// The 32-bit unsigned integer at `address + 4 * index`. - /// - /// A Dart integer is truncated to 32 bits (as if by `.toUnsigned(32)`) before - /// being stored, and the 32-bit value is zero-extended when it is loaded. - /// - /// The [address] must be 4-byte aligned. - external int operator [](int index); - - /// The 32-bit unsigned integer at `address + 4 * index`. - /// - /// A Dart integer is truncated to 32 bits (as if by `.toUnsigned(32)`) before - /// being stored, and the 32-bit value is zero-extended when it is loaded. - /// - /// The [address] must be 4-byte aligned. - external void operator []=(int index, int value); - - /// Creates a typed list view backed by memory in the address space. - /// - /// The returned view will allow access to the memory range from [address] - /// to `address + 4 * length`. - /// - /// The user has to ensure the memory range is accessible while using the - /// returned list. - /// - /// The [address] must be 4-byte aligned. - external Uint32List asTypedList(int length); -} - -/// Extension on [Pointer] specialized for the type argument [Uint64]. -extension Uint64Pointer on Pointer { - /// The 64-bit unsigned integer at [address]. - /// - /// The [address] must be 8-byte aligned. - external int get value; - - external void set value(int value); - - /// The 64-bit unsigned integer at `address + 8 * index`. - /// - /// The [address] must be 8-byte aligned. - external int operator [](int index); - - /// The 64-bit unsigned integer at `address + 8 * index`. - /// - /// The [address] must be 8-byte aligned. - external void operator []=(int index, int value); - - /// Creates a typed list view backed by memory in the address space. - /// - /// The returned view will allow access to the memory range from [address] - /// to `address + 8 * length`. - /// - /// The user has to ensure the memory range is accessible while using the - /// returned list. - /// - /// The [address] must be 8-byte aligned. - external Uint64List asTypedList(int length); -} - -/// Extension on [Pointer] specialized for the type argument [IntPtr]. -extension IntPtrPointer on Pointer { - /// The 32 or 64-bit two's complement integer at [address]. - /// - /// On 32-bit platforms this is a 32-bit integer, and on 64-bit platforms - /// this is a 64-bit integer. - /// - /// On 32-bit platforms a Dart integer is truncated to 32 bits (as if by - /// `.toSigned(32)`) before being stored, and the 32-bit value is - /// sign-extended when it is loaded. - /// - /// On 32-bit platforms the [address] must be 4-byte aligned, and on 64-bit - /// platforms the [address] must be 8-byte aligned. - external int get value; - - external void set value(int value); - - /// The 32 or 64-bit two's complement integer at `address + (4 or 8) * index`. - /// - /// On 32-bit platforms this is a 32-bit integer, and on 64-bit platforms - /// this is a 64-bit integer. - /// - /// On 32-bit platforms a Dart integer is truncated to 32 bits (as if by - /// `.toSigned(32)`) before being stored, and the 32-bit value is - /// sign-extended when it is loaded. - /// - /// On 32-bit platforms the [address] must be 4-byte aligned, and on 64-bit - /// platforms the [address] must be 8-byte aligned. - external int operator [](int index); - - /// The 32 or 64-bit two's complement integer at `address + (4 or 8) * index`. - /// - /// On 32-bit platforms this is a 32-bit integer, and on 64-bit platforms - /// this is a 64-bit integer. - /// - /// On 32-bit platforms a Dart integer is truncated to 32 bits (as if by - /// `.toSigned(32)`) before being stored, and the 32-bit value is - /// sign-extended when it is loaded. - /// - /// On 32-bit platforms the [address] must be 4-byte aligned, and on 64-bit - /// platforms the [address] must be 8-byte aligned. - external void operator []=(int index, int value); -} - -/// Extension on [Pointer] specialized for the type argument [Float]. -extension FloatPointer on Pointer { - /// The float at [address]. - /// - /// A Dart double loses precision before being stored, and the float value is - /// converted to a double when it is loaded. - /// - /// The [address] must be 4-byte aligned. - external double get value; - - external void set value(double value); - - /// The float at `address + 4 * index`. - /// - /// A Dart double loses precision before being stored, and the float value is - /// converted to a double when it is loaded. - /// - /// The [address] must be 4-byte aligned. - external double operator [](int index); - - /// The float at `address + 4 * index`. - /// - /// A Dart double loses precision before being stored, and the float value is - /// converted to a double when it is loaded. - /// - /// The [address] must be 4-byte aligned. - external void operator []=(int index, double value); - - /// Creates a typed list view backed by memory in the address space. - /// - /// The returned view will allow access to the memory range from [address] - /// to `address + 4 * length`. - /// - /// The user has to ensure the memory range is accessible while using the - /// returned list. - /// - /// The [address] must be 4-byte aligned. - external Float32List asTypedList(int length); -} - -/// Extension on [Pointer] specialized for the type argument [Double]. -extension DoublePointer on Pointer { - /// The double at [address]. - /// - /// The [address] must be 8-byte aligned. - external double get value; - - external void set value(double value); - - /// The double at `address + 8 * index`. - /// - /// The [address] must be 8-byte aligned. - external double operator [](int index); - - /// The double at `address + 8 * index`. - /// - /// The [address] must be 8-byte aligned. - external void operator []=(int index, double value); - - /// Creates a typed list view backed by memory in the address space. - /// - /// The returned view will allow access to the memory range from [address] - /// to `address + 8 * length`. - /// - /// The user has to ensure the memory range is accessible while using the - /// returned list. - /// - /// The [address] must be 8-byte aligned. - external Float64List asTypedList(int length); -} - -// -// End of generated code. -// - -/// Extension on [Pointer] specialized for the type argument [Pointer]. -extension PointerPointer on Pointer> { - /// The pointer at [address]. - /// - /// A [Pointer] is unboxed before being stored (as if by `.address`), and the - /// pointer is boxed (as if by `Pointer.fromAddress`) when loaded. - /// - /// On 32-bit platforms the [address] must be 4-byte aligned, and on 64-bit - /// platforms the [address] must be 8-byte aligned. - external Pointer get value; - - external void set value(Pointer value); - - /// Load a Dart value from this location offset by [index]. - /// - /// A [Pointer] is unboxed before being stored (as if by `.address`), and the - /// pointer is boxed (as if by `Pointer.fromAddress`) when loaded. - /// - /// On 32-bit platforms the [address] must be 4-byte aligned, and on 64-bit - /// platforms the [address] must be 8-byte aligned. - external Pointer operator [](int index); - - /// Store a Dart value into this location offset by [index]. - /// - /// A [Pointer] is unboxed before being stored (as if by `.address`), and the - /// pointer is boxed (as if by `Pointer.fromAddress`) when loaded. - /// - /// On 32-bit platforms the [address] must be 4-byte aligned, and on 64-bit - /// platforms the [address] must be 8-byte aligned. - external void operator []=(int index, Pointer value); -} - -/// Extension on [Pointer] specialized for the type argument [Struct]. -extension StructPointer on Pointer { - /// Creates a reference to access the fields of this struct backed by native - /// memory at [address]. - /// - /// The [address] must be aligned according to the struct alignment rules of - /// the platform. - external T get ref; - - /// Creates a reference to access the fields of this struct backed by native - /// memory at `address + sizeOf() * index`. - /// - /// The [address] must be aligned according to the struct alignment rules of - /// the platform. - external T operator [](int index); -} - -/// Extension to retrieve the native `Dart_Port` from a [SendPort]. -extension NativePort on SendPort { - /// The native port of this [SendPort]. - /// - /// The returned native port can for example be used by C code to post - /// messages to the connected [ReceivePort] via `Dart_PostCObject()` - see - /// `dart_native_api.h`. - external int get nativePort; -} - -/// Opaque, not exposing it's members. -class Dart_CObject extends Struct {} - -typedef Dart_NativeMessageHandler = Void Function(Int64, Pointer); - -/// Exposes function pointers to functions in `dart_native_api.h`. -abstract class NativeApi { - /// A function pointer to - /// `bool Dart_PostCObject(Dart_Port port_id, Dart_CObject* message)` - /// in `dart_native_api.h`. - external static Pointer< - NativeFunction)>> - get postCObject; - - /// A function pointer to - /// ``` - /// Dart_Port Dart_NewNativePort(const char* name, - /// Dart_NativeMessageHandler handler, - /// bool handle_concurrently) - /// ``` - /// in `dart_native_api.h`. - external static Pointer< - NativeFunction< - Int64 Function( - Pointer, - Pointer>, - Int8)>> get newNativePort; - - /// A function pointer to - /// `bool Dart_CloseNativePort(Dart_Port native_port_id)` - /// in `dart_native_api.h`. - external static Pointer> - get closeNativePort; -} diff --git a/sdk_nnbd/lib/ffi/ffi_sources.gni b/sdk_nnbd/lib/ffi/ffi_sources.gni deleted file mode 100644 index 5b34b9c2dc1..00000000000 --- a/sdk_nnbd/lib/ffi/ffi_sources.gni +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright (c) 2019, 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. - -ffi_sdk_sources = [ - "ffi.dart", - - # The above file needs to be first as it lists the parts below. - "annotations.dart", - "dynamic_library.dart", - "native_type.dart", - "struct.dart", -] diff --git a/sdk_nnbd/lib/ffi/native_type.dart b/sdk_nnbd/lib/ffi/native_type.dart deleted file mode 100644 index e3193423912..00000000000 --- a/sdk_nnbd/lib/ffi/native_type.dart +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright (c) 2019, 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. - -part of dart.ffi; - -/// [NativeType]'s subtypes represent a native type in C. -/// -/// [NativeType]'s subtypes are not constructible in the Dart code and serve -/// purely as markers in type signatures. -abstract class NativeType { - const NativeType(); -} - -/// [_NativeInteger]'s subtypes represent a native integer in C. -/// -/// [_NativeInteger]'s subtypes are not constructible in the Dart code and serve -/// purely as markers in type signatures. -class _NativeInteger extends NativeType { - const _NativeInteger(); -} - -/// [_NativeDouble]'s subtypes represent a native float or double in C. -/// -/// [_NativeDouble]'s subtypes are not constructible in the Dart code and serve -/// purely as markers in type signatures. -class _NativeDouble extends NativeType { - const _NativeDouble(); -} - -/// Represents a native signed 8 bit integer in C. -/// -/// [Int8] is not constructible in the Dart code and serves purely as marker in -/// type signatures. -class Int8 extends _NativeInteger { - const Int8(); -} - -/// Represents a native signed 16 bit integer in C. -/// -/// [Int16] is not constructible in the Dart code and serves purely as marker in -/// type signatures. -class Int16 extends _NativeInteger { - const Int16(); -} - -/// Represents a native signed 32 bit integer in C. -/// -/// [Int32] is not constructible in the Dart code and serves purely as marker in -/// type signatures. -class Int32 extends _NativeInteger { - const Int32(); -} - -/// Represents a native signed 64 bit integer in C. -/// -/// [Int64] is not constructible in the Dart code and serves purely as marker in -/// type signatures. -class Int64 extends _NativeInteger { - const Int64(); -} - -/// Represents a native unsigned 8 bit integer in C. -/// -/// [Uint8] is not constructible in the Dart code and serves purely as marker in -/// type signatures. -class Uint8 extends _NativeInteger { - const Uint8(); -} - -/// Represents a native unsigned 16 bit integer in C. -/// -/// [Uint16] is not constructible in the Dart code and serves purely as marker -/// in type signatures. -class Uint16 extends _NativeInteger { - const Uint16(); -} - -/// Represents a native unsigned 32 bit integer in C. -/// -/// [Uint32] is not constructible in the Dart code and serves purely as marker -/// in type signatures. -class Uint32 extends _NativeInteger { - const Uint32(); -} - -/// Represents a native unsigned 64 bit integer in C. -/// -/// [Uint64] is not constructible in the Dart code and serves purely as marker -/// in type signatures. -class Uint64 extends _NativeInteger { - const Uint64(); -} - -/// Represents a native pointer-sized integer in C. -/// -/// [IntPtr] is not constructible in the Dart code and serves purely as marker -/// in type signatures. -class IntPtr extends _NativeInteger { - const IntPtr(); -} - -/// Represents a native 32 bit float in C. -/// -/// [Float] is not constructible in the Dart code and serves purely as marker -/// in type signatures. -class Float extends _NativeDouble { - const Float(); -} - -/// Represents a native 64 bit double in C. -/// -/// [Double] is not constructible in the Dart code and serves purely as marker -/// in type signatures. -class Double extends _NativeDouble { - const Double(); -} - -/// Represents a void type in C. -/// -/// [Void] is not constructible in the Dart code and serves purely as marker in -/// type signatures. -@unsized -abstract class Void extends NativeType {} - -/// Represents `Dart_Handle` in C. -/// -/// [Handle] is not constructible in the Dart code and serves purely as marker in -/// type signatures. -abstract class Handle extends NativeType {} - -/// Represents a function type in C. -/// -/// [NativeFunction] is not constructible in the Dart code and serves purely as -/// marker in type signatures. -@unsized -abstract class NativeFunction extends NativeType {} diff --git a/sdk_nnbd/lib/ffi/struct.dart b/sdk_nnbd/lib/ffi/struct.dart deleted file mode 100644 index c6605d8ce03..00000000000 --- a/sdk_nnbd/lib/ffi/struct.dart +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) 2019, 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. - -part of dart.ffi; - -/// This class is extended to define structs. -/// -/// Fields in a struct, annotated with a subtype of [NativeType], are -/// automatically transformed into wrappers to access the fields of the struct -/// in native memory. -/// -/// All fields in a struct must either have a type which extends [NativeType] or -/// else have an annotation indicating the corresponding native type (e.g. -/// "@Int32()" for "int"). -/// -/// Instances of a subclass of [Struct] have reference semantics and are backed -/// by native memory. The may allocated via allocation or loaded from a -/// [Pointer], but not by a generative constructor. -abstract class Struct extends NativeType { - final Pointer _addressOf; - - /// Construct a reference to the [nullptr]. - /// - /// Use [StructPointer]'s `.ref` to gain references to native memory backed - /// structs. - Struct() : _addressOf = nullptr; - - Struct._fromPointer(this._addressOf); -} - -/// Extension on [Struct] specialized for it's subtypes. -extension StructAddressOf on T { - /// Returns the address backing the reference. - Pointer get addressOf => _addressOf as Pointer; -} diff --git a/sdk_nnbd/lib/html/dart2js/html_dart2js.dart b/sdk_nnbd/lib/html/dart2js/html_dart2js.dart deleted file mode 100644 index 04dcc3d96ea..00000000000 --- a/sdk_nnbd/lib/html/dart2js/html_dart2js.dart +++ /dev/null @@ -1,41043 +0,0 @@ -/** - * HTML elements and other resources for web-based applications that need to - * interact with the browser and the DOM (Document Object Model). - * - * This library includes DOM element types, CSS styling, local storage, - * media, speech, events, and more. - * To get started, - * check out the [Element] class, the base class for many of the HTML - * DOM types. - * - * For information on writing web apps with Dart, see https://webdev.dartlang.org. - * - * {@category Web} - */ -library dart.dom.html; - -import 'dart:async'; -import 'dart:collection' hide LinkedList, LinkedListEntry; -import 'dart:_internal' hide Symbol; -import 'dart:html_common'; -import 'dart:indexed_db'; -import "dart:convert"; -import 'dart:math'; -import 'dart:_native_typed_data'; -import 'dart:typed_data'; -import 'dart:svg' as svg; -import 'dart:svg' show Matrix; -import 'dart:svg' show SvgSvgElement; -import 'dart:web_audio' as web_audio; -import 'dart:web_audio' show AudioBuffer, AudioTrack, AudioTrackList; -import 'dart:web_gl' as gl; -import 'dart:web_gl' show RenderingContext, RenderingContext2; -import 'dart:web_sql'; -import 'dart:_foreign_helper' show JS, JS_INTERCEPTOR_CONSTANT; -// Copyright (c) 2012, 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. - -// DO NOT EDIT - unless you are editing documentation as per: -// https://code.google.com/p/dart/wiki/ContributingHTMLDocumentation -// Auto-generated dart:html library. - -// Not actually used, but imported since dart:html can generate these objects. -import 'dart:_js_helper' - show - convertDartClosureToJS, - Creates, - JavaScriptIndexingBehavior, - JSName, - Native, - Returns, - ForceInline, - findDispatchTagForInterceptorClass, - setNativeSubclassDispatchRecord, - makeLeafDispatchRecord, - registerGlobalObject, - applyExtension; -import 'dart:_interceptors' - show - Interceptor, - JavaScriptFunction, - JSExtendableArray, - JSUInt31, - findInterceptorConstructorForType, - findConstructorForNativeSubclassType, - getNativeInterceptor, - setDispatchProperty; - -export 'dart:_internal' show HttpStatus; -export 'dart:html_common' show promiseToFuture; -export 'dart:math' show Rectangle, Point; - -/** - * Top-level container for a web page, which is usually a browser tab or window. - * - * Each web page loaded in the browser has its own [Window], which is a - * container for the web page. - * - * If the web page has any `